e09a39e113dbe7b9f083d41704b39dcd67e142bd
[openwrt/staging/luka.git] / target / linux / layerscape / patches-4.14 / 707-dpaa-ethernet-support-layerscape.patch
1 From b443452fe13292b12295757f57e04c04834b3fc0 Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Wed, 22 May 2019 17:49:18 +0800
4 Subject: [PATCH] dpaa-ethernet: support layerscape
5
6 This is an integrated patch of dpaa-ethernet for 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: Biwen Li <biwen.li@nxp.com>
11 Signed-off-by: Camelia Groza <camelia.groza@nxp.com>
12 Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
13 Signed-off-by: David S. Miller <davem@davemloft.net>
14 Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
15 Signed-off-by: Florinel Iordache <florinel.iordache@nxp.com>
16 Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
17 Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
18 Signed-off-by: Iordache Florinel-R70177 <florinel.iordache@nxp.com>
19 Signed-off-by: Jake Moroni <mail@jakemoroni.com>
20 Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
21 Signed-off-by: Madalin Bucur <madalin.bucur@nxp.com>
22 Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
23 Signed-off-by: Radu Bulie <radu-andrei.bulie@nxp.com>
24 Signed-off-by: Roy Pledge <roy.pledge@nxp.com>
25 Signed-off-by: Vakul Garg <vakul.garg@nxp.com>
26 Signed-off-by: Vicentiu Galanopulo <vicentiu.galanopulo@nxp.com>
27 Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
28 Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
29 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
30 Signed-off-by: yuan linyu <Linyu.Yuan@alcatel-sbell.com.cn>
31 Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
32 ---
33 drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 616 +-
34 drivers/net/ethernet/freescale/dpaa/dpaa_eth.h | 3 +
35 drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 41 +-
36 drivers/net/ethernet/freescale/fman/Kconfig | 1 -
37 drivers/net/ethernet/freescale/fman/Makefile | 12 +-
38 drivers/net/ethernet/freescale/fman/fman.c | 38 +-
39 drivers/net/ethernet/freescale/fman/fman.h | 5 +
40 drivers/net/ethernet/freescale/fman/fman_dtsec.c | 46 +
41 drivers/net/ethernet/freescale/fman/fman_dtsec.h | 2 +
42 drivers/net/ethernet/freescale/fman/fman_memac.c | 37 +-
43 drivers/net/ethernet/freescale/fman/fman_memac.h | 2 +
44 drivers/net/ethernet/freescale/fman/fman_port.c | 28 +
45 drivers/net/ethernet/freescale/fman/fman_port.h | 4 +
46 drivers/net/ethernet/freescale/fman/fman_tgec.c | 54 +-
47 drivers/net/ethernet/freescale/fman/fman_tgec.h | 2 +
48 drivers/net/ethernet/freescale/fman/mac.c | 152 +-
49 drivers/net/ethernet/freescale/fman/mac.h | 9 +-
50 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig | 184 +
51 drivers/net/ethernet/freescale/sdk_dpaa/Makefile | 45 +
52 .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.c | 580 ++
53 .../net/ethernet/freescale/sdk_dpaa/dpaa_1588.h | 138 +
54 .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c | 180 +
55 .../net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h | 43 +
56 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c | 1223 ++++
57 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h | 674 ++
58 .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.c | 205 +
59 .../ethernet/freescale/sdk_dpaa/dpaa_eth_base.h | 49 +
60 .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c | 2076 ++++++
61 .../ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h | 241 +
62 .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 1745 +++++
63 .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 226 +
64 .../ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c | 381 +
65 .../net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c | 1195 +++
66 .../ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c | 278 +
67 .../ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h | 144 +
68 .../net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c | 587 ++
69 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c | 931 +++
70 drivers/net/ethernet/freescale/sdk_dpaa/mac.c | 490 ++
71 drivers/net/ethernet/freescale/sdk_dpaa/mac.h | 134 +
72 .../net/ethernet/freescale/sdk_dpaa/offline_port.c | 848 +++
73 .../net/ethernet/freescale/sdk_dpaa/offline_port.h | 59 +
74 drivers/net/ethernet/freescale/sdk_fman/Kconfig | 153 +
75 drivers/net/ethernet/freescale/sdk_fman/Makefile | 11 +
76 .../freescale/sdk_fman/Peripherals/FM/HC/Makefile | 15 +
77 .../freescale/sdk_fman/Peripherals/FM/HC/hc.c | 1232 ++++
78 .../freescale/sdk_fman/Peripherals/FM/MAC/Makefile | 28 +
79 .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c | 1504 ++++
80 .../freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h | 228 +
81 .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c | 97 +
82 .../sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h | 42 +
83 .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c | 674 ++
84 .../freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h | 226 +
85 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.c | 119 +
86 .../sdk_fman/Peripherals/FM/MAC/fman_crc32.h | 43 +
87 .../sdk_fman/Peripherals/FM/MAC/fman_dtsec.c | 847 +++
88 .../Peripherals/FM/MAC/fman_dtsec_mii_acc.c | 165 +
89 .../sdk_fman/Peripherals/FM/MAC/fman_memac.c | 532 ++
90 .../Peripherals/FM/MAC/fman_memac_mii_acc.c | 215 +
91 .../sdk_fman/Peripherals/FM/MAC/fman_tgec.c | 367 +
92 .../freescale/sdk_fman/Peripherals/FM/MAC/memac.c | 1166 +++
93 .../freescale/sdk_fman/Peripherals/FM/MAC/memac.h | 110 +
94 .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c | 78 +
95 .../sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h | 73 +
96 .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.c | 1017 +++
97 .../freescale/sdk_fman/Peripherals/FM/MAC/tgec.h | 151 +
98 .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c | 139 +
99 .../sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h | 80 +
100 .../sdk_fman/Peripherals/FM/MACSEC/Makefile | 15 +
101 .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c | 237 +
102 .../sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h | 203 +
103 .../Peripherals/FM/MACSEC/fm_macsec_guest.c | 59 +
104 .../Peripherals/FM/MACSEC/fm_macsec_master.c | 1031 +++
105 .../Peripherals/FM/MACSEC/fm_macsec_master.h | 479 ++
106 .../Peripherals/FM/MACSEC/fm_macsec_secy.c | 883 +++
107 .../Peripherals/FM/MACSEC/fm_macsec_secy.h | 144 +
108 .../freescale/sdk_fman/Peripherals/FM/Makefile | 23 +
109 .../freescale/sdk_fman/Peripherals/FM/Pcd/Makefile | 26 +
110 .../freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h | 360 +
111 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c | 7582 ++++++++++++++++++++
112 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h | 399 +
113 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c | 3242 +++++++++
114 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h | 206 +
115 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.c | 5571 ++++++++++++++
116 .../sdk_fman/Peripherals/FM/Pcd/fm_manip.h | 555 ++
117 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c | 2095 ++++++
118 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h | 543 ++
119 .../sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h | 280 +
120 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.c | 1847 +++++
121 .../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h | 165 +
122 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c | 423 ++
123 .../freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h | 316 +
124 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.c | 984 +++
125 .../sdk_fman/Peripherals/FM/Pcd/fm_replic.h | 101 +
126 .../sdk_fman/Peripherals/FM/Pcd/fman_kg.c | 890 +++
127 .../sdk_fman/Peripherals/FM/Pcd/fman_prs.c | 129 +
128 .../sdk_fman/Peripherals/FM/Port/Makefile | 15 +
129 .../sdk_fman/Peripherals/FM/Port/fm_port.c | 6437 +++++++++++++++++
130 .../sdk_fman/Peripherals/FM/Port/fm_port.h | 999 +++
131 .../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h | 494 ++
132 .../sdk_fman/Peripherals/FM/Port/fm_port_im.c | 753 ++
133 .../sdk_fman/Peripherals/FM/Port/fman_port.c | 1570 ++++
134 .../freescale/sdk_fman/Peripherals/FM/Rtc/Makefile | 15 +
135 .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c | 692 ++
136 .../freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h | 96 +
137 .../sdk_fman/Peripherals/FM/Rtc/fman_rtc.c | 334 +
138 .../freescale/sdk_fman/Peripherals/FM/SP/Makefile | 15 +
139 .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c | 757 ++
140 .../freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h | 85 +
141 .../freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c | 197 +
142 .../freescale/sdk_fman/Peripherals/FM/fm.c | 5216 ++++++++++++++
143 .../freescale/sdk_fman/Peripherals/FM/fm.h | 648 ++
144 .../freescale/sdk_fman/Peripherals/FM/fm_ipc.h | 465 ++
145 .../freescale/sdk_fman/Peripherals/FM/fm_muram.c | 174 +
146 .../freescale/sdk_fman/Peripherals/FM/fman.c | 1400 ++++
147 .../sdk_fman/Peripherals/FM/inc/fm_common.h | 1214 ++++
148 .../freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h | 93 +
149 .../sdk_fman/Peripherals/FM/inc/fm_sp_common.h | 117 +
150 .../net/ethernet/freescale/sdk_fman/etc/Makefile | 12 +
151 .../net/ethernet/freescale/sdk_fman/etc/error.c | 95 +
152 drivers/net/ethernet/freescale/sdk_fman/etc/list.c | 71 +
153 .../net/ethernet/freescale/sdk_fman/etc/memcpy.c | 620 ++
154 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c | 1155 +++
155 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h | 105 +
156 .../net/ethernet/freescale/sdk_fman/etc/sprint.c | 81 +
157 .../ethernet/freescale/sdk_fman/fmanv3h_dflags.h | 57 +
158 .../ethernet/freescale/sdk_fman/fmanv3l_dflags.h | 56 +
159 .../sdk_fman/inc/Peripherals/crc_mac_addr_ext.h | 364 +
160 .../freescale/sdk_fman/inc/Peripherals/dpaa_ext.h | 210 +
161 .../freescale/sdk_fman/inc/Peripherals/fm_ext.h | 1731 +++++
162 .../sdk_fman/inc/Peripherals/fm_mac_ext.h | 887 +++
163 .../sdk_fman/inc/Peripherals/fm_macsec_ext.h | 1271 ++++
164 .../sdk_fman/inc/Peripherals/fm_muram_ext.h | 170 +
165 .../sdk_fman/inc/Peripherals/fm_pcd_ext.h | 3974 ++++++++++
166 .../sdk_fman/inc/Peripherals/fm_port_ext.h | 2608 +++++++
167 .../sdk_fman/inc/Peripherals/fm_rtc_ext.h | 619 ++
168 .../sdk_fman/inc/Peripherals/fm_vsp_ext.h | 411 ++
169 .../sdk_fman/inc/Peripherals/mii_acc_ext.h | 76 +
170 .../net/ethernet/freescale/sdk_fman/inc/core_ext.h | 90 +
171 .../freescale/sdk_fman/inc/cores/arm_ext.h | 55 +
172 .../freescale/sdk_fman/inc/cores/e500v2_ext.h | 476 ++
173 .../freescale/sdk_fman/inc/cores/ppc_ext.h | 141 +
174 .../ethernet/freescale/sdk_fman/inc/ddr_std_ext.h | 77 +
175 .../ethernet/freescale/sdk_fman/inc/debug_ext.h | 233 +
176 .../ethernet/freescale/sdk_fman/inc/endian_ext.h | 447 ++
177 .../net/ethernet/freescale/sdk_fman/inc/enet_ext.h | 205 +
178 .../ethernet/freescale/sdk_fman/inc/error_ext.h | 529 ++
179 .../ethernet/freescale/sdk_fman/inc/etc/list_ext.h | 358 +
180 .../ethernet/freescale/sdk_fman/inc/etc/mem_ext.h | 318 +
181 .../freescale/sdk_fman/inc/etc/memcpy_ext.h | 208 +
182 .../ethernet/freescale/sdk_fman/inc/etc/mm_ext.h | 310 +
183 .../freescale/sdk_fman/inc/etc/sprint_ext.h | 118 +
184 .../sdk_fman/inc/flib/common/arch/ppc_access.h | 37 +
185 .../freescale/sdk_fman/inc/flib/common/general.h | 52 +
186 .../freescale/sdk_fman/inc/flib/fman_common.h | 78 +
187 .../freescale/sdk_fman/inc/flib/fsl_enet.h | 273 +
188 .../freescale/sdk_fman/inc/flib/fsl_fman.h | 825 +++
189 .../freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h | 1096 +++
190 .../sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h | 107 +
191 .../freescale/sdk_fman/inc/flib/fsl_fman_kg.h | 514 ++
192 .../freescale/sdk_fman/inc/flib/fsl_fman_memac.h | 434 ++
193 .../sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h | 78 +
194 .../freescale/sdk_fman/inc/flib/fsl_fman_port.h | 593 ++
195 .../freescale/sdk_fman/inc/flib/fsl_fman_prs.h | 102 +
196 .../freescale/sdk_fman/inc/flib/fsl_fman_rtc.h | 449 ++
197 .../freescale/sdk_fman/inc/flib/fsl_fman_sp.h | 138 +
198 .../freescale/sdk_fman/inc/flib/fsl_fman_tgec.h | 479 ++
199 .../integrations/FMANV3H/dpaa_integration_ext.h | 291 +
200 .../sdk_fman/inc/integrations/FMANV3H/part_ext.h | 71 +
201 .../integrations/FMANV3H/part_integration_ext.h | 304 +
202 .../integrations/FMANV3L/dpaa_integration_ext.h | 293 +
203 .../sdk_fman/inc/integrations/FMANV3L/part_ext.h | 59 +
204 .../integrations/FMANV3L/part_integration_ext.h | 304 +
205 .../inc/integrations/LS1043/dpaa_integration_ext.h | 291 +
206 .../sdk_fman/inc/integrations/LS1043/part_ext.h | 64 +
207 .../inc/integrations/LS1043/part_integration_ext.h | 185 +
208 .../inc/integrations/P1023/dpaa_integration_ext.h | 213 +
209 .../sdk_fman/inc/integrations/P1023/part_ext.h | 82 +
210 .../inc/integrations/P1023/part_integration_ext.h | 635 ++
211 .../P3040_P4080_P5020/dpaa_integration_ext.h | 276 +
212 .../inc/integrations/P3040_P4080_P5020/part_ext.h | 83 +
213 .../P3040_P4080_P5020/part_integration_ext.h | 336 +
214 .../net/ethernet/freescale/sdk_fman/inc/math_ext.h | 100 +
215 .../net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h | 435 ++
216 .../net/ethernet/freescale/sdk_fman/inc/net_ext.h | 430 ++
217 .../net/ethernet/freescale/sdk_fman/inc/std_ext.h | 48 +
218 .../ethernet/freescale/sdk_fman/inc/stdarg_ext.h | 49 +
219 .../ethernet/freescale/sdk_fman/inc/stdlib_ext.h | 162 +
220 .../ethernet/freescale/sdk_fman/inc/string_ext.h | 56 +
221 .../ethernet/freescale/sdk_fman/inc/types_ext.h | 62 +
222 .../ethernet/freescale/sdk_fman/inc/xx_common.h | 56 +
223 .../net/ethernet/freescale/sdk_fman/inc/xx_ext.h | 791 ++
224 .../ethernet/freescale/sdk_fman/ls1043_dflags.h | 56 +
225 .../net/ethernet/freescale/sdk_fman/ncsw_config.mk | 53 +
226 .../net/ethernet/freescale/sdk_fman/p1023_dflags.h | 65 +
227 .../freescale/sdk_fman/p3040_4080_5020_dflags.h | 62 +
228 .../net/ethernet/freescale/sdk_fman/src/Makefile | 11 +
229 .../freescale/sdk_fman/src/inc/system/sys_ext.h | 118 +
230 .../freescale/sdk_fman/src/inc/system/sys_io_ext.h | 46 +
231 .../freescale/sdk_fman/src/inc/types_linux.h | 208 +
232 .../sdk_fman/src/inc/wrapper/fsl_fman_test.h | 84 +
233 .../sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h | 130 +
234 .../sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h | 163 +
235 .../sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h | 921 +++
236 .../ethernet/freescale/sdk_fman/src/inc/xx/xx.h | 50 +
237 .../freescale/sdk_fman/src/system/Makefile | 10 +
238 .../freescale/sdk_fman/src/system/sys_io.c | 171 +
239 .../freescale/sdk_fman/src/wrapper/Makefile | 19 +
240 .../freescale/sdk_fman/src/wrapper/fman_test.c | 1665 +++++
241 .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.c | 2910 ++++++++
242 .../freescale/sdk_fman/src/wrapper/lnxwrp_fm.h | 294 +
243 .../sdk_fman/src/wrapper/lnxwrp_fm_port.c | 1512 ++++
244 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c | 4854 +++++++++++++
245 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c | 1297 ++++
246 .../sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h | 755 ++
247 .../sdk_fman/src/wrapper/lnxwrp_resources.h | 121 +
248 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.c | 191 +
249 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.h | 144 +
250 .../sdk_fman/src/wrapper/lnxwrp_resources_ut.make | 28 +
251 .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c | 60 +
252 .../freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h | 60 +
253 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c | 1855 +++++
254 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h | 136 +
255 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c | 1268 ++++
256 .../sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h | 56 +
257 .../ethernet/freescale/sdk_fman/src/xx/Makefile | 18 +
258 .../freescale/sdk_fman/src/xx/module_strings.c | 46 +
259 .../freescale/sdk_fman/src/xx/xx_arm_linux.c | 905 +++
260 .../ethernet/freescale/sdk_fman/src/xx/xx_linux.c | 918 +++
261 drivers/staging/fsl_qbman/Kconfig | 228 +
262 drivers/staging/fsl_qbman/Makefile | 28 +
263 drivers/staging/fsl_qbman/bman_config.c | 720 ++
264 drivers/staging/fsl_qbman/bman_debugfs.c | 119 +
265 drivers/staging/fsl_qbman/bman_driver.c | 559 ++
266 drivers/staging/fsl_qbman/bman_high.c | 1145 +++
267 drivers/staging/fsl_qbman/bman_low.h | 565 ++
268 drivers/staging/fsl_qbman/bman_private.h | 166 +
269 drivers/staging/fsl_qbman/bman_test.c | 56 +
270 drivers/staging/fsl_qbman/bman_test.h | 44 +
271 drivers/staging/fsl_qbman/bman_test_high.c | 183 +
272 drivers/staging/fsl_qbman/bman_test_thresh.c | 196 +
273 drivers/staging/fsl_qbman/dpa_alloc.c | 706 ++
274 drivers/staging/fsl_qbman/dpa_sys.h | 259 +
275 drivers/staging/fsl_qbman/dpa_sys_arm.h | 95 +
276 drivers/staging/fsl_qbman/dpa_sys_arm64.h | 102 +
277 drivers/staging/fsl_qbman/dpa_sys_ppc32.h | 70 +
278 drivers/staging/fsl_qbman/dpa_sys_ppc64.h | 79 +
279 drivers/staging/fsl_qbman/fsl_usdpaa.c | 2008 ++++++
280 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c | 289 +
281 drivers/staging/fsl_qbman/qbman_driver.c | 88 +
282 drivers/staging/fsl_qbman/qman_config.c | 1224 ++++
283 drivers/staging/fsl_qbman/qman_debugfs.c | 1594 ++++
284 drivers/staging/fsl_qbman/qman_driver.c | 961 +++
285 drivers/staging/fsl_qbman/qman_high.c | 5655 +++++++++++++++
286 drivers/staging/fsl_qbman/qman_low.h | 1445 ++++
287 drivers/staging/fsl_qbman/qman_private.h | 398 +
288 drivers/staging/fsl_qbman/qman_test.c | 57 +
289 drivers/staging/fsl_qbman/qman_test.h | 45 +
290 drivers/staging/fsl_qbman/qman_test_high.c | 216 +
291 drivers/staging/fsl_qbman/qman_test_hotpotato.c | 502 ++
292 drivers/staging/fsl_qbman/qman_utility.c | 129 +
293 include/linux/fsl/svr.h | 97 +
294 include/linux/fsl_bman.h | 532 ++
295 include/linux/fsl_qman.h | 3910 ++++++++++
296 include/linux/fsl_usdpaa.h | 372 +
297 include/linux/netdev_features.h | 2 +
298 include/uapi/linux/fmd/Kbuild | 5 +
299 include/uapi/linux/fmd/Peripherals/Kbuild | 4 +
300 include/uapi/linux/fmd/Peripherals/fm_ioctls.h | 628 ++
301 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h | 3084 ++++++++
302 .../uapi/linux/fmd/Peripherals/fm_port_ioctls.h | 973 +++
303 .../uapi/linux/fmd/Peripherals/fm_test_ioctls.h | 208 +
304 include/uapi/linux/fmd/integrations/Kbuild | 1 +
305 .../linux/fmd/integrations/integration_ioctls.h | 56 +
306 include/uapi/linux/fmd/ioctls.h | 96 +
307 include/uapi/linux/fmd/net_ioctls.h | 430 ++
308 net/sched/sch_generic.c | 7 +
309 276 files changed, 153982 insertions(+), 277 deletions(-)
310 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
311 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/Makefile
312 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
313 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
314 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
315 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
316 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
317 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
318 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
319 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
320 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
321 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
322 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
323 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
324 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
325 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
326 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
327 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
328 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
329 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
330 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.c
331 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/mac.h
332 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
333 create mode 100644 drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
334 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Kconfig
335 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Makefile
336 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
337 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
338 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
339 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
340 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
341 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
342 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
343 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
344 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
345 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
346 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
347 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
348 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
349 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
350 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
351 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
352 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
353 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
354 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
355 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
356 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
357 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
358 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
359 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
360 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
361 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
362 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
363 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
364 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
365 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
366 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
367 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
368 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
369 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
370 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
371 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
372 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
373 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
374 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
375 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
376 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
377 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
378 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
379 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
380 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
381 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
382 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
383 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
384 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
385 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
386 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
387 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
388 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
389 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
390 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
391 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
392 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
393 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
394 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
395 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
396 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
397 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
398 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
399 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
400 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
401 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
402 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
403 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
404 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
405 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
406 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
407 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
408 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
409 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
410 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
411 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/error.c
412 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/list.c
413 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
414 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
415 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
416 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
417 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
418 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
419 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
420 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
421 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
422 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
423 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
424 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
425 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
426 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
427 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
428 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
429 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
430 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
431 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
432 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
433 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
434 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
435 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
436 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
437 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
438 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
439 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
440 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
441 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
442 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
443 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
444 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
445 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
446 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
447 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
448 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
449 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
450 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
451 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
452 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
453 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
454 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
455 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
456 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
457 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
458 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
459 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
460 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
461 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
462 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
463 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
464 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
465 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
466 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
467 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
468 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
469 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
470 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
471 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
472 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
473 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
474 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
475 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
476 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
477 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
478 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
479 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
480 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
481 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
482 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
483 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
484 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
485 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
486 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
487 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
488 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/Makefile
489 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
490 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
491 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
492 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
493 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
494 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
495 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
496 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
497 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
498 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
499 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
500 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
501 create mode 100755 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
502 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
503 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
504 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
505 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
506 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
507 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
508 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
509 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
510 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
511 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
512 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
513 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
514 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
515 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
516 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
517 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
518 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
519 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
520 create mode 100644 drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
521 create mode 100644 drivers/staging/fsl_qbman/Kconfig
522 create mode 100644 drivers/staging/fsl_qbman/Makefile
523 create mode 100644 drivers/staging/fsl_qbman/bman_config.c
524 create mode 100644 drivers/staging/fsl_qbman/bman_debugfs.c
525 create mode 100644 drivers/staging/fsl_qbman/bman_driver.c
526 create mode 100644 drivers/staging/fsl_qbman/bman_high.c
527 create mode 100644 drivers/staging/fsl_qbman/bman_low.h
528 create mode 100644 drivers/staging/fsl_qbman/bman_private.h
529 create mode 100644 drivers/staging/fsl_qbman/bman_test.c
530 create mode 100644 drivers/staging/fsl_qbman/bman_test.h
531 create mode 100644 drivers/staging/fsl_qbman/bman_test_high.c
532 create mode 100644 drivers/staging/fsl_qbman/bman_test_thresh.c
533 create mode 100644 drivers/staging/fsl_qbman/dpa_alloc.c
534 create mode 100644 drivers/staging/fsl_qbman/dpa_sys.h
535 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm.h
536 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_arm64.h
537 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc32.h
538 create mode 100644 drivers/staging/fsl_qbman/dpa_sys_ppc64.h
539 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa.c
540 create mode 100644 drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
541 create mode 100644 drivers/staging/fsl_qbman/qbman_driver.c
542 create mode 100644 drivers/staging/fsl_qbman/qman_config.c
543 create mode 100644 drivers/staging/fsl_qbman/qman_debugfs.c
544 create mode 100644 drivers/staging/fsl_qbman/qman_driver.c
545 create mode 100644 drivers/staging/fsl_qbman/qman_high.c
546 create mode 100644 drivers/staging/fsl_qbman/qman_low.h
547 create mode 100644 drivers/staging/fsl_qbman/qman_private.h
548 create mode 100644 drivers/staging/fsl_qbman/qman_test.c
549 create mode 100644 drivers/staging/fsl_qbman/qman_test.h
550 create mode 100644 drivers/staging/fsl_qbman/qman_test_high.c
551 create mode 100644 drivers/staging/fsl_qbman/qman_test_hotpotato.c
552 create mode 100644 drivers/staging/fsl_qbman/qman_utility.c
553 create mode 100644 include/linux/fsl/svr.h
554 create mode 100644 include/linux/fsl_bman.h
555 create mode 100644 include/linux/fsl_qman.h
556 create mode 100644 include/linux/fsl_usdpaa.h
557 create mode 100644 include/uapi/linux/fmd/Kbuild
558 create mode 100644 include/uapi/linux/fmd/Peripherals/Kbuild
559 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_ioctls.h
560 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
561 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
562 create mode 100644 include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
563 create mode 100644 include/uapi/linux/fmd/integrations/Kbuild
564 create mode 100644 include/uapi/linux/fmd/integrations/integration_ioctls.h
565 create mode 100644 include/uapi/linux/fmd/ioctls.h
566 create mode 100644 include/uapi/linux/fmd/net_ioctls.h
567
568 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
569 +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
570 @@ -50,9 +50,13 @@
571 #include <linux/highmem.h>
572 #include <linux/percpu.h>
573 #include <linux/dma-mapping.h>
574 +#include <linux/iommu.h>
575 #include <linux/sort.h>
576 #include <soc/fsl/bman.h>
577 #include <soc/fsl/qman.h>
578 +#if !defined(CONFIG_PPC) && defined(CONFIG_SOC_BUS)
579 +#include <linux/sys_soc.h> /* soc_device_match */
580 +#endif
581
582 #include "fman.h"
583 #include "fman_port.h"
584 @@ -73,6 +77,10 @@ static u16 tx_timeout = 1000;
585 module_param(tx_timeout, ushort, 0444);
586 MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
587
588 +#ifndef CONFIG_PPC
589 +bool dpaa_errata_a010022;
590 +#endif
591 +
592 #define FM_FD_STAT_RX_ERRORS \
593 (FM_FD_ERR_DMA | FM_FD_ERR_PHYSICAL | \
594 FM_FD_ERR_SIZE | FM_FD_ERR_CLS_DISCARD | \
595 @@ -388,34 +396,19 @@ out:
596
597 static struct mac_device *dpaa_mac_dev_get(struct platform_device *pdev)
598 {
599 - struct platform_device *of_dev;
600 struct dpaa_eth_data *eth_data;
601 - struct device *dpaa_dev, *dev;
602 - struct device_node *mac_node;
603 + struct device *dpaa_dev;
604 struct mac_device *mac_dev;
605
606 dpaa_dev = &pdev->dev;
607 eth_data = dpaa_dev->platform_data;
608 - if (!eth_data)
609 + if (!eth_data) {
610 + dev_err(dpaa_dev, "eth_data missing\n");
611 return ERR_PTR(-ENODEV);
612 -
613 - mac_node = eth_data->mac_node;
614 -
615 - of_dev = of_find_device_by_node(mac_node);
616 - if (!of_dev) {
617 - dev_err(dpaa_dev, "of_find_device_by_node(%pOF) failed\n",
618 - mac_node);
619 - of_node_put(mac_node);
620 - return ERR_PTR(-EINVAL);
621 }
622 - of_node_put(mac_node);
623 -
624 - dev = &of_dev->dev;
625 -
626 - mac_dev = dev_get_drvdata(dev);
627 + mac_dev = eth_data->mac_dev;
628 if (!mac_dev) {
629 - dev_err(dpaa_dev, "dev_get_drvdata(%s) failed\n",
630 - dev_name(dev));
631 + dev_err(dpaa_dev, "mac_dev missing\n");
632 return ERR_PTR(-EINVAL);
633 }
634
635 @@ -472,6 +465,16 @@ static void dpaa_set_rx_mode(struct net_
636 err);
637 }
638
639 + if (!!(net_dev->flags & IFF_ALLMULTI) != priv->mac_dev->allmulti) {
640 + priv->mac_dev->allmulti = !priv->mac_dev->allmulti;
641 + err = priv->mac_dev->set_allmulti(priv->mac_dev->fman_mac,
642 + priv->mac_dev->allmulti);
643 + if (err < 0)
644 + netif_err(priv, drv, net_dev,
645 + "mac_dev->set_allmulti() = %d\n",
646 + err);
647 + }
648 +
649 err = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
650 if (err < 0)
651 netif_err(priv, drv, net_dev, "mac_dev->set_multi() = %d\n",
652 @@ -1176,7 +1179,7 @@ static int dpaa_eth_init_tx_port(struct
653 buf_prefix_content.priv_data_size = buf_layout->priv_data_size;
654 buf_prefix_content.pass_prs_result = true;
655 buf_prefix_content.pass_hash_result = true;
656 - buf_prefix_content.pass_time_stamp = false;
657 + buf_prefix_content.pass_time_stamp = true;
658 buf_prefix_content.data_align = DPAA_FD_DATA_ALIGNMENT;
659
660 params.specific_params.non_rx_params.err_fqid = errq->fqid;
661 @@ -1218,7 +1221,7 @@ static int dpaa_eth_init_rx_port(struct
662 buf_prefix_content.priv_data_size = buf_layout->priv_data_size;
663 buf_prefix_content.pass_prs_result = true;
664 buf_prefix_content.pass_hash_result = true;
665 - buf_prefix_content.pass_time_stamp = false;
666 + buf_prefix_content.pass_time_stamp = true;
667 buf_prefix_content.data_align = DPAA_FD_DATA_ALIGNMENT;
668
669 rx_p = &params.specific_params.rx_params;
670 @@ -1500,7 +1503,19 @@ static int dpaa_bp_add_8_bufs(const stru
671 u8 i;
672
673 for (i = 0; i < 8; i++) {
674 +#ifndef CONFIG_PPC
675 + if (dpaa_errata_a010022) {
676 + struct page *page = alloc_page(GFP_KERNEL);
677 +
678 + if (unlikely(!page))
679 + goto release_previous_buffs;
680 + new_buf = page_address(page);
681 + } else {
682 + new_buf = netdev_alloc_frag(dpaa_bp->raw_size);
683 + }
684 +#else
685 new_buf = netdev_alloc_frag(dpaa_bp->raw_size);
686 +#endif
687 if (unlikely(!new_buf)) {
688 dev_err(dev, "netdev_alloc_frag() failed, size %zu\n",
689 dpaa_bp->raw_size);
690 @@ -1600,6 +1615,17 @@ static int dpaa_eth_refill_bpools(struct
691 return 0;
692 }
693
694 +static phys_addr_t dpaa_iova_to_phys(struct device *dev, dma_addr_t addr)
695 +{
696 + struct iommu_domain *domain;
697 +
698 + domain = iommu_get_domain_for_dev(dev);
699 + if (domain)
700 + return iommu_iova_to_phys(domain, addr);
701 + else
702 + return addr;
703 +}
704 +
705 /* Cleanup function for outgoing frame descriptors that were built on Tx path,
706 * either contiguous frames or scatter/gather ones.
707 * Skb freeing is not handled here.
708 @@ -1615,24 +1641,41 @@ static struct sk_buff *dpaa_cleanup_tx_f
709 {
710 const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
711 struct device *dev = priv->net_dev->dev.parent;
712 + struct skb_shared_hwtstamps shhwtstamps;
713 dma_addr_t addr = qm_fd_addr(fd);
714 const struct qm_sg_entry *sgt;
715 struct sk_buff **skbh, *skb;
716 int nr_frags, i;
717 + u64 ns;
718
719 - skbh = (struct sk_buff **)phys_to_virt(addr);
720 + skbh = (struct sk_buff **)phys_to_virt(dpaa_iova_to_phys(dev, addr));
721 skb = *skbh;
722
723 + if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
724 + memset(&shhwtstamps, 0, sizeof(shhwtstamps));
725 +
726 + if (!fman_port_get_tstamp(priv->mac_dev->port[TX], (void *)skbh,
727 + &ns)) {
728 + shhwtstamps.hwtstamp = ns_to_ktime(ns);
729 + skb_tstamp_tx(skb, &shhwtstamps);
730 + } else {
731 + dev_warn(dev, "fman_port_get_tstamp failed!\n");
732 + }
733 + }
734 +
735 if (unlikely(qm_fd_get_format(fd) == qm_fd_sg)) {
736 nr_frags = skb_shinfo(skb)->nr_frags;
737 - dma_unmap_single(dev, addr,
738 - qm_fd_get_offset(fd) + DPAA_SGT_SIZE,
739 - dma_dir);
740
741 /* The sgt buffer has been allocated with netdev_alloc_frag(),
742 * it's from lowmem.
743 */
744 - sgt = phys_to_virt(addr + qm_fd_get_offset(fd));
745 + sgt = phys_to_virt(dpaa_iova_to_phys(dev,
746 + addr +
747 + qm_fd_get_offset(fd)));
748 +
749 + dma_unmap_single(dev, addr,
750 + qm_fd_get_offset(fd) + DPAA_SGT_SIZE,
751 + dma_dir);
752
753 /* sgt[0] is from lowmem, was dma_map_single()-ed */
754 dma_unmap_single(dev, qm_sg_addr(&sgt[0]),
755 @@ -1645,9 +1688,13 @@ static struct sk_buff *dpaa_cleanup_tx_f
756 dma_unmap_page(dev, qm_sg_addr(&sgt[i]),
757 qm_sg_entry_get_len(&sgt[i]), dma_dir);
758 }
759 -
760 - /* Free the page frag that we allocated on Tx */
761 - skb_free_frag(phys_to_virt(addr));
762 +#ifndef CONFIG_PPC
763 + if (dpaa_errata_a010022)
764 + put_page(virt_to_page(sgt));
765 + else
766 +#endif
767 + /* Free the page frag that we allocated on Tx */
768 + skb_free_frag(skbh);
769 } else {
770 dma_unmap_single(dev, addr,
771 skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
772 @@ -1678,26 +1725,21 @@ static u8 rx_csum_offload(const struct d
773 * accommodate the shared info area of the skb.
774 */
775 static struct sk_buff *contig_fd_to_skb(const struct dpaa_priv *priv,
776 - const struct qm_fd *fd)
777 + const struct qm_fd *fd,
778 + struct dpaa_bp *dpaa_bp,
779 + void *vaddr)
780 {
781 ssize_t fd_off = qm_fd_get_offset(fd);
782 - dma_addr_t addr = qm_fd_addr(fd);
783 - struct dpaa_bp *dpaa_bp;
784 struct sk_buff *skb;
785 - void *vaddr;
786
787 - vaddr = phys_to_virt(addr);
788 WARN_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
789
790 - dpaa_bp = dpaa_bpid2pool(fd->bpid);
791 - if (!dpaa_bp)
792 - goto free_buffer;
793 -
794 skb = build_skb(vaddr, dpaa_bp->size +
795 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
796 if (unlikely(!skb)) {
797 WARN_ONCE(1, "Build skb failure on Rx\n");
798 - goto free_buffer;
799 + skb_free_frag(vaddr);
800 + return NULL;
801 }
802 WARN_ON(fd_off != priv->rx_headroom);
803 skb_reserve(skb, fd_off);
804 @@ -1706,10 +1748,6 @@ static struct sk_buff *contig_fd_to_skb(
805 skb->ip_summed = rx_csum_offload(priv, fd);
806
807 return skb;
808 -
809 -free_buffer:
810 - skb_free_frag(vaddr);
811 - return NULL;
812 }
813
814 /* Build an skb with the data of the first S/G entry in the linear portion and
815 @@ -1718,14 +1756,14 @@ free_buffer:
816 * The page fragment holding the S/G Table is recycled here.
817 */
818 static struct sk_buff *sg_fd_to_skb(const struct dpaa_priv *priv,
819 - const struct qm_fd *fd)
820 + const struct qm_fd *fd,
821 + struct dpaa_bp *dpaa_bp,
822 + void *vaddr)
823 {
824 ssize_t fd_off = qm_fd_get_offset(fd);
825 - dma_addr_t addr = qm_fd_addr(fd);
826 const struct qm_sg_entry *sgt;
827 struct page *page, *head_page;
828 - struct dpaa_bp *dpaa_bp;
829 - void *vaddr, *sg_vaddr;
830 + void *sg_vaddr;
831 int frag_off, frag_len;
832 struct sk_buff *skb;
833 dma_addr_t sg_addr;
834 @@ -1734,29 +1772,33 @@ static struct sk_buff *sg_fd_to_skb(cons
835 int *count_ptr;
836 int i;
837
838 - vaddr = phys_to_virt(addr);
839 WARN_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
840
841 /* Iterate through the SGT entries and add data buffers to the skb */
842 sgt = vaddr + fd_off;
843 + skb = NULL;
844 for (i = 0; i < DPAA_SGT_MAX_ENTRIES; i++) {
845 /* Extension bit is not supported */
846 WARN_ON(qm_sg_entry_is_ext(&sgt[i]));
847
848 sg_addr = qm_sg_addr(&sgt[i]);
849 - sg_vaddr = phys_to_virt(sg_addr);
850 - WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
851 - SMP_CACHE_BYTES));
852
853 /* We may use multiple Rx pools */
854 dpaa_bp = dpaa_bpid2pool(sgt[i].bpid);
855 - if (!dpaa_bp)
856 + if (!dpaa_bp) {
857 + pr_info("%s: fail to get dpaa_bp for sg bpid %d\n",
858 + __func__, sgt[i].bpid);
859 goto free_buffers;
860 + }
861 + sg_vaddr = phys_to_virt(dpaa_iova_to_phys(dpaa_bp->dev,
862 + sg_addr));
863 + WARN_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
864 + SMP_CACHE_BYTES));
865
866 count_ptr = this_cpu_ptr(dpaa_bp->percpu_count);
867 dma_unmap_single(dpaa_bp->dev, sg_addr, dpaa_bp->size,
868 DMA_FROM_DEVICE);
869 - if (i == 0) {
870 + if (!skb) {
871 sz = dpaa_bp->size +
872 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
873 skb = build_skb(sg_vaddr, sz);
874 @@ -1823,10 +1865,11 @@ free_buffers:
875 /* free all the SG entries */
876 for (i = 0; i < DPAA_SGT_MAX_ENTRIES ; i++) {
877 sg_addr = qm_sg_addr(&sgt[i]);
878 - sg_vaddr = phys_to_virt(sg_addr);
879 - skb_free_frag(sg_vaddr);
880 dpaa_bp = dpaa_bpid2pool(sgt[i].bpid);
881 if (dpaa_bp) {
882 + sg_addr = dpaa_iova_to_phys(dpaa_bp->dev, sg_addr);
883 + sg_vaddr = phys_to_virt(sg_addr);
884 + skb_free_frag(sg_vaddr);
885 count_ptr = this_cpu_ptr(dpaa_bp->percpu_count);
886 (*count_ptr)--;
887 }
888 @@ -1909,16 +1952,28 @@ static int skb_to_sg_fd(struct dpaa_priv
889 size_t frag_len;
890 void *sgt_buf;
891
892 - /* get a page frag to store the SGTable */
893 - sz = SKB_DATA_ALIGN(priv->tx_headroom + DPAA_SGT_SIZE);
894 - sgt_buf = netdev_alloc_frag(sz);
895 - if (unlikely(!sgt_buf)) {
896 - netdev_err(net_dev, "netdev_alloc_frag() failed for size %d\n",
897 - sz);
898 - return -ENOMEM;
899 +#ifndef CONFIG_PPC
900 + if (unlikely(dpaa_errata_a010022)) {
901 + struct page *page = alloc_page(GFP_ATOMIC);
902 + if (unlikely(!page))
903 + return -ENOMEM;
904 + sgt_buf = page_address(page);
905 + } else {
906 +#endif
907 + /* get a page frag to store the SGTable */
908 + sz = SKB_DATA_ALIGN(priv->tx_headroom + DPAA_SGT_SIZE);
909 + sgt_buf = netdev_alloc_frag(sz);
910 + if (unlikely(!sgt_buf)) {
911 + netdev_err(net_dev,
912 + "netdev_alloc_frag() failed for size %d\n",
913 + sz);
914 + return -ENOMEM;
915 + }
916 +#ifndef CONFIG_PPC
917 }
918 +#endif
919
920 - /* Enable L3/L4 hardware checksum computation.
921 + /* Enable L3/L4 hardware checksum computation.
922 *
923 * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
924 * need to write into the skb.
925 @@ -2036,6 +2091,121 @@ static inline int dpaa_xmit(struct dpaa_
926 return 0;
927 }
928
929 +#ifndef CONFIG_PPC
930 +/* On LS1043A SoC there is a known erratum ERR010022 that results in split DMA
931 + * transfers in the FMan under certain conditions. This, combined with a fixed
932 + * size FIFO of ongoing DMA transfers that may overflow when a split occurs,
933 + * results in the FMan stalling DMA transfers under high traffic. To avoid the
934 + * problem, one needs to prevent the DMA transfer splits to occur by preparing
935 + * the buffers
936 + */
937 +
938 +#define DPAA_A010022_HEADROOM 256
939 +#define CROSS_4K_BOUND(start, size) \
940 + (((start) + (size)) > (((start) + 0x1000) & ~0xFFF))
941 +
942 +static bool dpaa_errata_a010022_has_dma_issue(struct sk_buff *skb,
943 + struct dpaa_priv *priv)
944 +{
945 + int nr_frags, i = 0;
946 + skb_frag_t *frag;
947 +
948 + /* Transfers that do not start at 16B aligned addresses will be split;
949 + * Transfers that cross a 4K page boundary will also be split
950 + */
951 +
952 + /* Check if the frame data is aligned to 16 bytes */
953 + if ((uintptr_t)skb->data % DPAA_FD_DATA_ALIGNMENT)
954 + return true;
955 +
956 + /* Check if the headroom crosses a boundary */
957 + if (CROSS_4K_BOUND((uintptr_t)skb->head, skb_headroom(skb)))
958 + return true;
959 +
960 + /* Check if the non-paged data crosses a boundary */
961 + if (CROSS_4K_BOUND((uintptr_t)skb->data, skb_headlen(skb)))
962 + return true;
963 +
964 + nr_frags = skb_shinfo(skb)->nr_frags;
965 +
966 + while (i < nr_frags) {
967 + frag = &skb_shinfo(skb)->frags[i];
968 +
969 + /* Check if a paged fragment crosses a boundary from its
970 + * offset to its end.
971 + */
972 + if (CROSS_4K_BOUND((uintptr_t)frag->page_offset, frag->size))
973 + return true;
974 +
975 + i++;
976 + }
977 +
978 + return false;
979 +}
980 +
981 +static struct sk_buff *dpaa_errata_a010022_prevent(struct sk_buff *skb,
982 + struct dpaa_priv *priv)
983 +{
984 + int trans_offset = skb_transport_offset(skb);
985 + int net_offset = skb_network_offset(skb);
986 + int nsize, npage_order, headroom;
987 + struct sk_buff *nskb = NULL;
988 + struct page *npage;
989 + void *npage_addr;
990 +
991 + if (!dpaa_errata_a010022_has_dma_issue(skb, priv))
992 + return skb;
993 +
994 + /* For the new skb we only need the old one's data (both non-paged and
995 + * paged). We can skip the old tailroom.
996 + *
997 + * The headroom also needs to fit our private info (64 bytes) but we
998 + * reserve 256 bytes instead in order to guarantee that the data is
999 + * aligned to 256.
1000 + */
1001 + headroom = DPAA_A010022_HEADROOM;
1002 + nsize = headroom + skb->len +
1003 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
1004 +
1005 + /* Reserve enough memory to accommodate Jumbo frames */
1006 + npage_order = (nsize - 1) / PAGE_SIZE;
1007 + npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order);
1008 + if (unlikely(!npage)) {
1009 + WARN_ONCE(1, "Memory allocation failure\n");
1010 + return NULL;
1011 + }
1012 + npage_addr = page_address(npage);
1013 +
1014 + nskb = build_skb(npage_addr, nsize);
1015 + if (unlikely(!nskb))
1016 + goto err;
1017 +
1018 + /* Code borrowed and adapted from skb_copy() */
1019 + skb_reserve(nskb, headroom);
1020 + skb_put(nskb, skb->len);
1021 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
1022 + WARN_ONCE(1, "skb parsing failure\n");
1023 + goto err;
1024 + }
1025 + copy_skb_header(nskb, skb);
1026 + /* We move the headroom when we align it so we have to reset the
1027 + * network and transport header offsets relative to the new data
1028 + * pointer. The checksum offload relies on these offsets.
1029 + */
1030 + skb_set_network_header(nskb, net_offset);
1031 + skb_set_transport_header(nskb, trans_offset);
1032 +
1033 + dev_kfree_skb(skb);
1034 + return nskb;
1035 +
1036 +err:
1037 + if (nskb)
1038 + dev_kfree_skb(nskb);
1039 + put_page(npage);
1040 + return NULL;
1041 +}
1042 +#endif
1043 +
1044 static netdev_tx_t
1045 dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
1046 {
1047 @@ -2043,6 +2213,7 @@ dpaa_start_xmit(struct sk_buff *skb, str
1048 bool nonlinear = skb_is_nonlinear(skb);
1049 struct rtnl_link_stats64 *percpu_stats;
1050 struct dpaa_percpu_priv *percpu_priv;
1051 + struct netdev_queue *txq;
1052 struct dpaa_priv *priv;
1053 struct qm_fd fd;
1054 int offset = 0;
1055 @@ -2070,24 +2241,47 @@ dpaa_start_xmit(struct sk_buff *skb, str
1056 /* MAX_SKB_FRAGS is equal or larger than our dpaa_SGT_MAX_ENTRIES;
1057 * make sure we don't feed FMan with more fragments than it supports.
1058 */
1059 - if (nonlinear &&
1060 - likely(skb_shinfo(skb)->nr_frags < DPAA_SGT_MAX_ENTRIES)) {
1061 - /* Just create a S/G fd based on the skb */
1062 - err = skb_to_sg_fd(priv, skb, &fd);
1063 - percpu_priv->tx_frag_skbuffs++;
1064 - } else {
1065 + if (unlikely(nonlinear &&
1066 + (skb_shinfo(skb)->nr_frags >= DPAA_SGT_MAX_ENTRIES))) {
1067 /* If the egress skb contains more fragments than we support
1068 * we have no choice but to linearize it ourselves.
1069 */
1070 - if (unlikely(nonlinear) && __skb_linearize(skb))
1071 + if (__skb_linearize(skb))
1072 goto enomem;
1073
1074 - /* Finally, create a contig FD from this skb */
1075 + nonlinear = skb_is_nonlinear(skb);
1076 + }
1077 +
1078 +#ifndef CONFIG_PPC
1079 + if (unlikely(dpaa_errata_a010022)) {
1080 + skb = dpaa_errata_a010022_prevent(skb, priv);
1081 + if (!skb)
1082 + goto enomem;
1083 + nonlinear = skb_is_nonlinear(skb);
1084 + }
1085 +#endif
1086 +
1087 + if (nonlinear) {
1088 + /* Just create a S/G fd based on the skb */
1089 + err = skb_to_sg_fd(priv, skb, &fd);
1090 + percpu_priv->tx_frag_skbuffs++;
1091 + } else {
1092 + /* Create a contig FD from this skb */
1093 err = skb_to_contig_fd(priv, skb, &fd, &offset);
1094 }
1095 if (unlikely(err < 0))
1096 goto skb_to_fd_failed;
1097
1098 + txq = netdev_get_tx_queue(net_dev, queue_mapping);
1099 +
1100 + /* LLTX requires to do our own update of trans_start */
1101 + txq->trans_start = jiffies;
1102 +
1103 + if (priv->tx_tstamp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
1104 + fd.cmd |= cpu_to_be32(FM_FD_CMD_UPD);
1105 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
1106 + }
1107 +
1108 if (likely(dpaa_xmit(priv, percpu_stats, queue_mapping, &fd) == 0))
1109 return NETDEV_TX_OK;
1110
1111 @@ -2219,14 +2413,8 @@ static enum qman_cb_dqrr_result rx_error
1112 if (dpaa_eth_napi_schedule(percpu_priv, portal))
1113 return qman_cb_dqrr_stop;
1114
1115 - if (dpaa_eth_refill_bpools(priv))
1116 - /* Unable to refill the buffer pool due to insufficient
1117 - * system memory. Just release the frame back into the pool,
1118 - * otherwise we'll soon end up with an empty buffer pool.
1119 - */
1120 - dpaa_fd_release(net_dev, &dq->fd);
1121 - else
1122 - dpaa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
1123 + dpaa_eth_refill_bpools(priv);
1124 + dpaa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
1125
1126 return qman_cb_dqrr_consume;
1127 }
1128 @@ -2235,6 +2423,7 @@ static enum qman_cb_dqrr_result rx_defau
1129 struct qman_fq *fq,
1130 const struct qm_dqrr_entry *dq)
1131 {
1132 + struct skb_shared_hwtstamps *shhwtstamps;
1133 struct rtnl_link_stats64 *percpu_stats;
1134 struct dpaa_percpu_priv *percpu_priv;
1135 const struct qm_fd *fd = &dq->fd;
1136 @@ -2248,6 +2437,7 @@ static enum qman_cb_dqrr_result rx_defau
1137 struct sk_buff *skb;
1138 int *count_ptr;
1139 void *vaddr;
1140 + u64 ns;
1141
1142 fd_status = be32_to_cpu(fd->status);
1143 fd_format = qm_fd_get_format(fd);
1144 @@ -2290,12 +2480,12 @@ static enum qman_cb_dqrr_result rx_defau
1145 if (!dpaa_bp)
1146 return qman_cb_dqrr_consume;
1147
1148 - dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE);
1149 -
1150 /* prefetch the first 64 bytes of the frame or the SGT start */
1151 - vaddr = phys_to_virt(addr);
1152 + vaddr = phys_to_virt(dpaa_iova_to_phys(dpaa_bp->dev, addr));
1153 prefetch(vaddr + qm_fd_get_offset(fd));
1154
1155 + dma_unmap_single(dpaa_bp->dev, addr, dpaa_bp->size, DMA_FROM_DEVICE);
1156 +
1157 /* The only FD types that we may receive are contig and S/G */
1158 WARN_ON((fd_format != qm_fd_contig) && (fd_format != qm_fd_sg));
1159
1160 @@ -2306,12 +2496,22 @@ static enum qman_cb_dqrr_result rx_defau
1161 (*count_ptr)--;
1162
1163 if (likely(fd_format == qm_fd_contig))
1164 - skb = contig_fd_to_skb(priv, fd);
1165 + skb = contig_fd_to_skb(priv, fd, dpaa_bp, vaddr);
1166 else
1167 - skb = sg_fd_to_skb(priv, fd);
1168 + skb = sg_fd_to_skb(priv, fd, dpaa_bp, vaddr);
1169 if (!skb)
1170 return qman_cb_dqrr_consume;
1171
1172 + if (priv->rx_tstamp) {
1173 + shhwtstamps = skb_hwtstamps(skb);
1174 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
1175 +
1176 + if (!fman_port_get_tstamp(priv->mac_dev->port[RX], vaddr, &ns))
1177 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
1178 + else
1179 + dev_warn(net_dev->dev.parent, "fman_port_get_tstamp failed!\n");
1180 + }
1181 +
1182 skb->protocol = eth_type_trans(skb, net_dev);
1183
1184 if (net_dev->features & NETIF_F_RXHASH && priv->keygen_in_use &&
1185 @@ -2440,6 +2640,44 @@ static void dpaa_eth_napi_disable(struct
1186 }
1187 }
1188
1189 +static void dpaa_adjust_link(struct net_device *net_dev)
1190 +{
1191 + struct mac_device *mac_dev;
1192 + struct dpaa_priv *priv;
1193 +
1194 + priv = netdev_priv(net_dev);
1195 + mac_dev = priv->mac_dev;
1196 + mac_dev->adjust_link(mac_dev);
1197 +}
1198 +
1199 +static int dpaa_phy_init(struct net_device *net_dev)
1200 +{
1201 + struct mac_device *mac_dev;
1202 + struct phy_device *phy_dev;
1203 + struct dpaa_priv *priv;
1204 +
1205 + priv = netdev_priv(net_dev);
1206 + mac_dev = priv->mac_dev;
1207 +
1208 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
1209 + &dpaa_adjust_link, 0,
1210 + mac_dev->phy_if);
1211 + if (!phy_dev) {
1212 + netif_err(priv, ifup, net_dev, "init_phy() failed\n");
1213 + return -ENODEV;
1214 + }
1215 +
1216 + /* Remove any features not supported by the controller */
1217 + phy_dev->supported &= mac_dev->if_support;
1218 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
1219 + phy_dev->advertising = phy_dev->supported;
1220 +
1221 + mac_dev->phy_dev = phy_dev;
1222 + net_dev->phydev = phy_dev;
1223 +
1224 + return 0;
1225 +}
1226 +
1227 static int dpaa_open(struct net_device *net_dev)
1228 {
1229 struct mac_device *mac_dev;
1230 @@ -2450,12 +2688,9 @@ static int dpaa_open(struct net_device *
1231 mac_dev = priv->mac_dev;
1232 dpaa_eth_napi_enable(priv);
1233
1234 - net_dev->phydev = mac_dev->init_phy(net_dev, priv->mac_dev);
1235 - if (!net_dev->phydev) {
1236 - netif_err(priv, ifup, net_dev, "init_phy() failed\n");
1237 - err = -ENODEV;
1238 + err = dpaa_phy_init(net_dev);
1239 + if (err)
1240 goto phy_init_failed;
1241 - }
1242
1243 for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
1244 err = fman_port_enable(mac_dev->port[i]);
1245 @@ -2496,11 +2731,58 @@ static int dpaa_eth_stop(struct net_devi
1246 return err;
1247 }
1248
1249 +static int dpaa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1250 +{
1251 + struct dpaa_priv *priv = netdev_priv(dev);
1252 + struct hwtstamp_config config;
1253 +
1254 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
1255 + return -EFAULT;
1256 +
1257 + switch (config.tx_type) {
1258 + case HWTSTAMP_TX_OFF:
1259 + /* Couldn't disable rx/tx timestamping separately.
1260 + * Do nothing here.
1261 + */
1262 + priv->tx_tstamp = false;
1263 + break;
1264 + case HWTSTAMP_TX_ON:
1265 + priv->mac_dev->set_tstamp(priv->mac_dev->fman_mac, true);
1266 + priv->tx_tstamp = true;
1267 + break;
1268 + default:
1269 + return -ERANGE;
1270 + }
1271 +
1272 + if (config.rx_filter == HWTSTAMP_FILTER_NONE) {
1273 + /* Couldn't disable rx/tx timestamping separately.
1274 + * Do nothing here.
1275 + */
1276 + priv->rx_tstamp = false;
1277 + } else {
1278 + priv->mac_dev->set_tstamp(priv->mac_dev->fman_mac, true);
1279 + priv->rx_tstamp = true;
1280 + /* TS is set for all frame types, not only those requested */
1281 + config.rx_filter = HWTSTAMP_FILTER_ALL;
1282 + }
1283 +
1284 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
1285 + -EFAULT : 0;
1286 +}
1287 +
1288 static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
1289 {
1290 - if (!net_dev->phydev)
1291 - return -EINVAL;
1292 - return phy_mii_ioctl(net_dev->phydev, rq, cmd);
1293 + int ret = -EINVAL;
1294 +
1295 + if (cmd == SIOCGMIIREG) {
1296 + if (net_dev->phydev)
1297 + return phy_mii_ioctl(net_dev->phydev, rq, cmd);
1298 + }
1299 +
1300 + if (cmd == SIOCSHWTSTAMP)
1301 + return dpaa_ts_ioctl(net_dev, rq, cmd);
1302 +
1303 + return ret;
1304 }
1305
1306 static const struct net_device_ops dpaa_ops = {
1307 @@ -2654,7 +2936,6 @@ static inline u16 dpaa_get_headroom(stru
1308 static int dpaa_eth_probe(struct platform_device *pdev)
1309 {
1310 struct dpaa_bp *dpaa_bps[DPAA_BPS_NUM] = {NULL};
1311 - struct dpaa_percpu_priv *percpu_priv;
1312 struct net_device *net_dev = NULL;
1313 struct dpaa_fq *dpaa_fq, *tmp;
1314 struct dpaa_priv *priv = NULL;
1315 @@ -2663,7 +2944,51 @@ static int dpaa_eth_probe(struct platfor
1316 int err = 0, i, channel;
1317 struct device *dev;
1318
1319 - dev = &pdev->dev;
1320 + err = bman_is_probed();
1321 + if (!err)
1322 + return -EPROBE_DEFER;
1323 + if (err < 0) {
1324 + dev_err(&pdev->dev, "failing probe due to bman probe error\n");
1325 + return -ENODEV;
1326 + }
1327 + err = qman_is_probed();
1328 + if (!err)
1329 + return -EPROBE_DEFER;
1330 + if (err < 0) {
1331 + dev_err(&pdev->dev, "failing probe due to qman probe error\n");
1332 + return -ENODEV;
1333 + }
1334 + err = bman_portals_probed();
1335 + if (!err)
1336 + return -EPROBE_DEFER;
1337 + if (err < 0) {
1338 + dev_err(&pdev->dev,
1339 + "failing probe due to bman portals probe error\n");
1340 + return -ENODEV;
1341 + }
1342 + err = qman_portals_probed();
1343 + if (!err)
1344 + return -EPROBE_DEFER;
1345 + if (err < 0) {
1346 + dev_err(&pdev->dev,
1347 + "failing probe due to qman portals probe error\n");
1348 + return -ENODEV;
1349 + }
1350 +
1351 + mac_dev = dpaa_mac_dev_get(pdev);
1352 + if (IS_ERR(mac_dev)) {
1353 + dev_err(&pdev->dev, "dpaa_mac_dev_get() failed\n");
1354 + err = PTR_ERR(mac_dev);
1355 + goto probe_err;
1356 + }
1357 +
1358 + /* device used for DMA mapping */
1359 + dev = fman_port_get_device(mac_dev->port[RX]);
1360 + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
1361 + if (err) {
1362 + dev_err(dev, "dma_coerce_mask_and_coherent() failed\n");
1363 + return err;
1364 + }
1365
1366 /* Allocate this early, so we can store relevant information in
1367 * the private area
1368 @@ -2671,7 +2996,7 @@ static int dpaa_eth_probe(struct platfor
1369 net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TXQ_NUM);
1370 if (!net_dev) {
1371 dev_err(dev, "alloc_etherdev_mq() failed\n");
1372 - goto alloc_etherdev_mq_failed;
1373 + return -ENOMEM;
1374 }
1375
1376 /* Do this here, so we can be verbose early */
1377 @@ -2683,13 +3008,6 @@ static int dpaa_eth_probe(struct platfor
1378
1379 priv->msg_enable = netif_msg_init(debug, DPAA_MSG_DEFAULT);
1380
1381 - mac_dev = dpaa_mac_dev_get(pdev);
1382 - if (IS_ERR(mac_dev)) {
1383 - dev_err(dev, "dpaa_mac_dev_get() failed\n");
1384 - err = PTR_ERR(mac_dev);
1385 - goto mac_probe_failed;
1386 - }
1387 -
1388 /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
1389 * we choose conservatively and let the user explicitly set a higher
1390 * MTU via ifconfig. Otherwise, the user may end up with different MTUs
1391 @@ -2705,21 +3023,13 @@ static int dpaa_eth_probe(struct platfor
1392 priv->buf_layout[RX].priv_data_size = DPAA_RX_PRIV_DATA_SIZE; /* Rx */
1393 priv->buf_layout[TX].priv_data_size = DPAA_TX_PRIV_DATA_SIZE; /* Tx */
1394
1395 - /* device used for DMA mapping */
1396 - set_dma_ops(dev, get_dma_ops(&pdev->dev));
1397 - err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
1398 - if (err) {
1399 - dev_err(dev, "dma_coerce_mask_and_coherent() failed\n");
1400 - goto dev_mask_failed;
1401 - }
1402 -
1403 /* bp init */
1404 for (i = 0; i < DPAA_BPS_NUM; i++) {
1405 - int err;
1406 -
1407 dpaa_bps[i] = dpaa_bp_alloc(dev);
1408 - if (IS_ERR(dpaa_bps[i]))
1409 - return PTR_ERR(dpaa_bps[i]);
1410 + if (IS_ERR(dpaa_bps[i])) {
1411 + err = PTR_ERR(dpaa_bps[i]);
1412 + goto free_dpaa_bps;
1413 + }
1414 /* the raw size of the buffers used for reception */
1415 dpaa_bps[i]->raw_size = bpool_buffer_raw_size(i, DPAA_BPS_NUM);
1416 /* avoid runtime computations by keeping the usable size here */
1417 @@ -2727,11 +3037,8 @@ static int dpaa_eth_probe(struct platfor
1418 dpaa_bps[i]->dev = dev;
1419
1420 err = dpaa_bp_alloc_pool(dpaa_bps[i]);
1421 - if (err < 0) {
1422 - dpaa_bps_free(priv);
1423 - priv->dpaa_bps[i] = NULL;
1424 - goto bp_create_failed;
1425 - }
1426 + if (err < 0)
1427 + goto free_dpaa_bps;
1428 priv->dpaa_bps[i] = dpaa_bps[i];
1429 }
1430
1431 @@ -2742,7 +3049,7 @@ static int dpaa_eth_probe(struct platfor
1432 err = dpaa_alloc_all_fqs(dev, &priv->dpaa_fq_list, &port_fqs);
1433 if (err < 0) {
1434 dev_err(dev, "dpaa_alloc_all_fqs() failed\n");
1435 - goto fq_probe_failed;
1436 + goto free_dpaa_bps;
1437 }
1438
1439 priv->mac_dev = mac_dev;
1440 @@ -2751,12 +3058,12 @@ static int dpaa_eth_probe(struct platfor
1441 if (channel < 0) {
1442 dev_err(dev, "dpaa_get_channel() failed\n");
1443 err = channel;
1444 - goto get_channel_failed;
1445 + goto free_dpaa_bps;
1446 }
1447
1448 priv->channel = (u16)channel;
1449
1450 - /* Start a thread that will walk the CPUs with affine portals
1451 + /* Walk the CPUs with affine portals
1452 * and add this pool channel to each's dequeue mask.
1453 */
1454 dpaa_eth_add_channel(priv->channel);
1455 @@ -2771,20 +3078,20 @@ static int dpaa_eth_probe(struct platfor
1456 err = dpaa_eth_cgr_init(priv);
1457 if (err < 0) {
1458 dev_err(dev, "Error initializing CGR\n");
1459 - goto tx_cgr_init_failed;
1460 + goto free_dpaa_bps;
1461 }
1462
1463 err = dpaa_ingress_cgr_init(priv);
1464 if (err < 0) {
1465 dev_err(dev, "Error initializing ingress CGR\n");
1466 - goto rx_cgr_init_failed;
1467 + goto delete_egress_cgr;
1468 }
1469
1470 /* Add the FQs to the interface, and make them active */
1471 list_for_each_entry_safe(dpaa_fq, tmp, &priv->dpaa_fq_list, list) {
1472 err = dpaa_fq_init(dpaa_fq, false);
1473 if (err < 0)
1474 - goto fq_alloc_failed;
1475 + goto free_dpaa_fqs;
1476 }
1477
1478 priv->tx_headroom = dpaa_get_headroom(&priv->buf_layout[TX]);
1479 @@ -2794,7 +3101,7 @@ static int dpaa_eth_probe(struct platfor
1480 err = dpaa_eth_init_ports(mac_dev, dpaa_bps, DPAA_BPS_NUM, &port_fqs,
1481 &priv->buf_layout[0], dev);
1482 if (err)
1483 - goto init_ports_failed;
1484 + goto free_dpaa_fqs;
1485
1486 /* Rx traffic distribution based on keygen hashing defaults to on */
1487 priv->keygen_in_use = true;
1488 @@ -2803,11 +3110,7 @@ static int dpaa_eth_probe(struct platfor
1489 if (!priv->percpu_priv) {
1490 dev_err(dev, "devm_alloc_percpu() failed\n");
1491 err = -ENOMEM;
1492 - goto alloc_percpu_failed;
1493 - }
1494 - for_each_possible_cpu(i) {
1495 - percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
1496 - memset(percpu_priv, 0, sizeof(*percpu_priv));
1497 + goto free_dpaa_fqs;
1498 }
1499
1500 priv->num_tc = 1;
1501 @@ -2816,11 +3119,11 @@ static int dpaa_eth_probe(struct platfor
1502 /* Initialize NAPI */
1503 err = dpaa_napi_add(net_dev);
1504 if (err < 0)
1505 - goto napi_add_failed;
1506 + goto delete_dpaa_napi;
1507
1508 err = dpaa_netdev_init(net_dev, &dpaa_ops, tx_timeout);
1509 if (err < 0)
1510 - goto netdev_init_failed;
1511 + goto delete_dpaa_napi;
1512
1513 dpaa_eth_sysfs_init(&net_dev->dev);
1514
1515 @@ -2829,32 +3132,21 @@ static int dpaa_eth_probe(struct platfor
1516
1517 return 0;
1518
1519 -netdev_init_failed:
1520 -napi_add_failed:
1521 +delete_dpaa_napi:
1522 dpaa_napi_del(net_dev);
1523 -alloc_percpu_failed:
1524 -init_ports_failed:
1525 +free_dpaa_fqs:
1526 dpaa_fq_free(dev, &priv->dpaa_fq_list);
1527 -fq_alloc_failed:
1528 qman_delete_cgr_safe(&priv->ingress_cgr);
1529 qman_release_cgrid(priv->ingress_cgr.cgrid);
1530 -rx_cgr_init_failed:
1531 +delete_egress_cgr:
1532 qman_delete_cgr_safe(&priv->cgr_data.cgr);
1533 qman_release_cgrid(priv->cgr_data.cgr.cgrid);
1534 -tx_cgr_init_failed:
1535 -get_channel_failed:
1536 +free_dpaa_bps:
1537 dpaa_bps_free(priv);
1538 -bp_create_failed:
1539 -fq_probe_failed:
1540 -dev_mask_failed:
1541 -mac_probe_failed:
1542 dev_set_drvdata(dev, NULL);
1543 free_netdev(net_dev);
1544 -alloc_etherdev_mq_failed:
1545 - for (i = 0; i < DPAA_BPS_NUM && dpaa_bps[i]; i++) {
1546 - if (atomic_read(&dpaa_bps[i]->refs) == 0)
1547 - devm_kfree(dev, dpaa_bps[i]);
1548 - }
1549 +probe_err:
1550 +
1551 return err;
1552 }
1553
1554 @@ -2891,6 +3183,23 @@ static int dpaa_remove(struct platform_d
1555 return err;
1556 }
1557
1558 +#ifndef CONFIG_PPC
1559 +static bool __init soc_has_errata_a010022(void)
1560 +{
1561 +#ifdef CONFIG_SOC_BUS
1562 + const struct soc_device_attribute soc_msi_matches[] = {
1563 + { .family = "QorIQ LS1043A",
1564 + .data = NULL },
1565 + { },
1566 + };
1567 +
1568 + if (!soc_device_match(soc_msi_matches))
1569 + return false;
1570 +#endif
1571 + return true; /* cannot identify SoC or errata applies */
1572 +}
1573 +#endif
1574 +
1575 static const struct platform_device_id dpaa_devtype[] = {
1576 {
1577 .name = "dpaa-ethernet",
1578 @@ -2915,6 +3224,10 @@ static int __init dpaa_load(void)
1579
1580 pr_debug("FSL DPAA Ethernet driver\n");
1581
1582 +#ifndef CONFIG_PPC
1583 + /* Detect if the current SoC requires the DMA transfer alignment workaround */
1584 + dpaa_errata_a010022 = soc_has_errata_a010022();
1585 +#endif
1586 /* initialize dpaa_eth mirror values */
1587 dpaa_rx_extra_headroom = fman_get_rx_extra_headroom();
1588 dpaa_max_frm = fman_get_max_frm();
1589 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
1590 +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.h
1591 @@ -182,6 +182,9 @@ struct dpaa_priv {
1592
1593 struct dpaa_buffer_layout buf_layout[2];
1594 u16 rx_headroom;
1595 +
1596 + bool tx_tstamp; /* Tx timestamping enabled */
1597 + bool rx_tstamp; /* Rx timestamping enabled */
1598 };
1599
1600 /* from dpaa_ethtool.c */
1601 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
1602 +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
1603 @@ -32,6 +32,9 @@
1604 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1605
1606 #include <linux/string.h>
1607 +#include <linux/of_platform.h>
1608 +#include <linux/net_tstamp.h>
1609 +#include <linux/fsl/ptp_qoriq.h>
1610
1611 #include "dpaa_eth.h"
1612 #include "mac.h"
1613 @@ -344,7 +347,7 @@ static void dpaa_get_ethtool_stats(struc
1614
1615 /* gather congestion related counters */
1616 cg_num = 0;
1617 - cg_status = 0;
1618 + cg_status = false;
1619 cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
1620 if (qman_query_cgr_congested(&priv->cgr_data.cgr, &cg_status) == 0) {
1621 cg_num = priv->cgr_data.cgr_congested_count;
1622 @@ -515,6 +518,41 @@ static int dpaa_set_rxnfc(struct net_dev
1623 return ret;
1624 }
1625
1626 +static int dpaa_get_ts_info(struct net_device *net_dev,
1627 + struct ethtool_ts_info *info)
1628 +{
1629 + struct device *dev = net_dev->dev.parent;
1630 + struct device_node *mac_node = dev->of_node;
1631 + struct device_node *fman_node = NULL, *ptp_node = NULL;
1632 + struct platform_device *ptp_dev = NULL;
1633 + struct qoriq_ptp *ptp = NULL;
1634 +
1635 + info->phc_index = -1;
1636 +
1637 + fman_node = of_get_parent(mac_node);
1638 + if (fman_node)
1639 + ptp_node = of_parse_phandle(fman_node, "ptimer-handle", 0);
1640 +
1641 + if (ptp_node)
1642 + ptp_dev = of_find_device_by_node(ptp_node);
1643 +
1644 + if (ptp_dev)
1645 + ptp = platform_get_drvdata(ptp_dev);
1646 +
1647 + if (ptp)
1648 + info->phc_index = ptp->phc_index;
1649 +
1650 + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
1651 + SOF_TIMESTAMPING_RX_HARDWARE |
1652 + SOF_TIMESTAMPING_RAW_HARDWARE;
1653 + info->tx_types = (1 << HWTSTAMP_TX_OFF) |
1654 + (1 << HWTSTAMP_TX_ON);
1655 + info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
1656 + (1 << HWTSTAMP_FILTER_ALL);
1657 +
1658 + return 0;
1659 +}
1660 +
1661 const struct ethtool_ops dpaa_ethtool_ops = {
1662 .get_drvinfo = dpaa_get_drvinfo,
1663 .get_msglevel = dpaa_get_msglevel,
1664 @@ -530,4 +568,5 @@ const struct ethtool_ops dpaa_ethtool_op
1665 .set_link_ksettings = dpaa_set_link_ksettings,
1666 .get_rxnfc = dpaa_get_rxnfc,
1667 .set_rxnfc = dpaa_set_rxnfc,
1668 + .get_ts_info = dpaa_get_ts_info,
1669 };
1670 --- a/drivers/net/ethernet/freescale/fman/Kconfig
1671 +++ b/drivers/net/ethernet/freescale/fman/Kconfig
1672 @@ -2,7 +2,6 @@ config FSL_FMAN
1673 tristate "FMan support"
1674 depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
1675 select GENERIC_ALLOCATOR
1676 - depends on HAS_DMA
1677 select PHYLIB
1678 default n
1679 help
1680 --- a/drivers/net/ethernet/freescale/fman/Makefile
1681 +++ b/drivers/net/ethernet/freescale/fman/Makefile
1682 @@ -1,10 +1,10 @@
1683 # SPDX-License-Identifier: GPL-2.0
1684 subdir-ccflags-y += -I$(srctree)/drivers/net/ethernet/freescale/fman
1685
1686 -obj-$(CONFIG_FSL_FMAN) += fsl_fman.o
1687 -obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o
1688 -obj-$(CONFIG_FSL_FMAN) += fsl_mac.o
1689 +obj-$(CONFIG_FSL_FMAN) += fsl_dpaa_fman.o
1690 +obj-$(CONFIG_FSL_FMAN) += fsl_dpaa_fman_port.o
1691 +obj-$(CONFIG_FSL_FMAN) += fsl_dpaa_mac.o
1692
1693 -fsl_fman-objs := fman_muram.o fman.o fman_sp.o fman_keygen.o
1694 -fsl_fman_port-objs := fman_port.o
1695 -fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
1696 +fsl_dpaa_fman-objs := fman_muram.o fman.o fman_sp.o fman_keygen.o
1697 +fsl_dpaa_fman_port-objs := fman_port.o
1698 +fsl_dpaa_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
1699 --- a/drivers/net/ethernet/freescale/fman/fman.c
1700 +++ b/drivers/net/ethernet/freescale/fman/fman.c
1701 @@ -629,6 +629,7 @@ static void set_port_order_restoration(s
1702 iowrite32be(tmp, &fpm_rg->fmfp_prc);
1703 }
1704
1705 +#ifdef CONFIG_PPC
1706 static void set_port_liodn(struct fman *fman, u8 port_id,
1707 u32 liodn_base, u32 liodn_ofst)
1708 {
1709 @@ -646,6 +647,27 @@ static void set_port_liodn(struct fman *
1710 iowrite32be(tmp, &fman->dma_regs->fmdmplr[port_id / 2]);
1711 iowrite32be(liodn_ofst, &fman->bmi_regs->fmbm_spliodn[port_id - 1]);
1712 }
1713 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
1714 +static void save_restore_port_icids(struct fman *fman, bool save)
1715 +{
1716 + int port_idxes[] = {
1717 + 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc,
1718 + 0xd, 0xe, 0xf, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
1719 + 0x10, 0x11, 0x30, 0x31
1720 + };
1721 + int idx, i;
1722 +
1723 + for (i = 0; i < ARRAY_SIZE(port_idxes); i++) {
1724 + idx = port_idxes[i];
1725 + if (save)
1726 + fman->sp_icids[idx] =
1727 + ioread32be(&fman->bmi_regs->fmbm_spliodn[idx]);
1728 + else
1729 + iowrite32be(fman->sp_icids[idx],
1730 + &fman->bmi_regs->fmbm_spliodn[idx]);
1731 + }
1732 +}
1733 +#endif
1734
1735 static void enable_rams_ecc(struct fman_fpm_regs __iomem *fpm_rg)
1736 {
1737 @@ -1914,7 +1936,10 @@ _return:
1738 static int fman_init(struct fman *fman)
1739 {
1740 struct fman_cfg *cfg = NULL;
1741 - int err = 0, i, count;
1742 + int err = 0, count;
1743 +#ifdef CONFIG_PPC
1744 + int i;
1745 +#endif
1746
1747 if (is_init_done(fman->cfg))
1748 return -EINVAL;
1749 @@ -1934,6 +1959,7 @@ static int fman_init(struct fman *fman)
1750 memset_io((void __iomem *)(fman->base_addr + CGP_OFFSET), 0,
1751 fman->state->fm_port_num_of_cg);
1752
1753 +#ifdef CONFIG_PPC
1754 /* Save LIODN info before FMan reset
1755 * Skipping non-existent port 0 (i = 1)
1756 */
1757 @@ -1953,6 +1979,9 @@ static int fman_init(struct fman *fman)
1758 }
1759 fman->liodn_base[i] = liodn_base;
1760 }
1761 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
1762 + save_restore_port_icids(fman, true);
1763 +#endif
1764
1765 err = fman_reset(fman);
1766 if (err)
1767 @@ -2181,8 +2210,12 @@ int fman_set_port_params(struct fman *fm
1768 if (err)
1769 goto return_err;
1770
1771 +#ifdef CONFIG_PPC
1772 set_port_liodn(fman, port_id, fman->liodn_base[port_id],
1773 fman->liodn_offset[port_id]);
1774 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
1775 + save_restore_port_icids(fman, false);
1776 +#endif
1777
1778 if (fman->state->rev_info.major < 6)
1779 set_port_order_restoration(fman->fpm_regs, port_id);
1780 @@ -2800,7 +2833,8 @@ static struct fman *read_dts_node(struct
1781
1782 of_node_put(muram_node);
1783
1784 - err = devm_request_irq(&of_dev->dev, irq, fman_irq, 0, "fman", fman);
1785 + err = devm_request_irq(&of_dev->dev, irq, fman_irq, IRQF_SHARED,
1786 + "fman", fman);
1787 if (err < 0) {
1788 dev_err(&of_dev->dev, "%s: irq %d allocation failed (error = %d)\n",
1789 __func__, irq, err);
1790 --- a/drivers/net/ethernet/freescale/fman/fman.h
1791 +++ b/drivers/net/ethernet/freescale/fman/fman.h
1792 @@ -41,6 +41,7 @@
1793 /* Frame queue Context Override */
1794 #define FM_FD_CMD_FCO 0x80000000
1795 #define FM_FD_CMD_RPD 0x40000000 /* Read Prepended Data */
1796 +#define FM_FD_CMD_UPD 0x20000000 /* Update Prepended Data */
1797 #define FM_FD_CMD_DTC 0x10000000 /* Do L4 Checksum */
1798
1799 /* TX-Port: Unsupported Format */
1800 @@ -345,8 +346,12 @@ struct fman {
1801 unsigned long fifo_offset;
1802 size_t fifo_size;
1803
1804 +#ifdef CONFIG_PPC
1805 u32 liodn_base[64];
1806 u32 liodn_offset[64];
1807 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
1808 + u32 sp_icids[64];
1809 +#endif
1810
1811 struct fman_dts_params dts_params;
1812 };
1813 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
1814 +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
1815 @@ -123,11 +123,13 @@
1816 #define DTSEC_ECNTRL_R100M 0x00000008
1817 #define DTSEC_ECNTRL_QSGMIIM 0x00000001
1818
1819 +#define TCTRL_TTSE 0x00000040
1820 #define TCTRL_GTS 0x00000020
1821
1822 #define RCTRL_PAL_MASK 0x001f0000
1823 #define RCTRL_PAL_SHIFT 16
1824 #define RCTRL_GHTX 0x00000400
1825 +#define RCTRL_RTSE 0x00000040
1826 #define RCTRL_GRS 0x00000020
1827 #define RCTRL_MPROM 0x00000008
1828 #define RCTRL_RSF 0x00000004
1829 @@ -1116,6 +1118,50 @@ int dtsec_add_hash_mac_address(struct fm
1830
1831 return 0;
1832 }
1833 +
1834 +int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable)
1835 +{
1836 + u32 tmp;
1837 + struct dtsec_regs __iomem *regs = dtsec->regs;
1838 +
1839 + if (!is_init_done(dtsec->dtsec_drv_param))
1840 + return -EINVAL;
1841 +
1842 + tmp = ioread32be(&regs->rctrl);
1843 + if (enable)
1844 + tmp |= RCTRL_MPROM;
1845 + else
1846 + tmp &= ~RCTRL_MPROM;
1847 +
1848 + iowrite32be(tmp, &regs->rctrl);
1849 +
1850 + return 0;
1851 +}
1852 +
1853 +int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable)
1854 +{
1855 + struct dtsec_regs __iomem *regs = dtsec->regs;
1856 + u32 rctrl, tctrl;
1857 +
1858 + if (!is_init_done(dtsec->dtsec_drv_param))
1859 + return -EINVAL;
1860 +
1861 + rctrl = ioread32be(&regs->rctrl);
1862 + tctrl = ioread32be(&regs->tctrl);
1863 +
1864 + if (enable) {
1865 + rctrl |= RCTRL_RTSE;
1866 + tctrl |= TCTRL_TTSE;
1867 + } else {
1868 + rctrl &= ~RCTRL_RTSE;
1869 + tctrl &= ~TCTRL_TTSE;
1870 + }
1871 +
1872 + iowrite32be(rctrl, &regs->rctrl);
1873 + iowrite32be(tctrl, &regs->tctrl);
1874 +
1875 + return 0;
1876 +}
1877
1878 int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
1879 {
1880 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.h
1881 +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.h
1882 @@ -55,5 +55,7 @@ int dtsec_set_exception(struct fman_mac
1883 int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
1884 int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
1885 int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version);
1886 +int dtsec_set_allmulti(struct fman_mac *dtsec, bool enable);
1887 +int dtsec_set_tstamp(struct fman_mac *dtsec, bool enable);
1888
1889 #endif /* __DTSEC_H */
1890 --- a/drivers/net/ethernet/freescale/fman/fman_memac.c
1891 +++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
1892 @@ -350,6 +350,7 @@ struct fman_mac {
1893 struct fman_rev_info fm_rev_info;
1894 bool basex_if;
1895 struct phy_device *pcsphy;
1896 + bool allmulti_enabled;
1897 };
1898
1899 static void add_addr_in_paddr(struct memac_regs __iomem *regs, u8 *adr,
1900 @@ -940,6 +941,34 @@ int memac_add_hash_mac_address(struct fm
1901 return 0;
1902 }
1903
1904 +int memac_set_allmulti(struct fman_mac *memac, bool enable)
1905 +{
1906 + u32 entry;
1907 + struct memac_regs __iomem *regs = memac->regs;
1908 +
1909 + if (!is_init_done(memac->memac_drv_param))
1910 + return -EINVAL;
1911 +
1912 + if (enable) {
1913 + for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
1914 + iowrite32be(entry | HASH_CTRL_MCAST_EN,
1915 + &regs->hashtable_ctrl);
1916 + } else {
1917 + for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
1918 + iowrite32be(entry & ~HASH_CTRL_MCAST_EN,
1919 + &regs->hashtable_ctrl);
1920 + }
1921 +
1922 + memac->allmulti_enabled = enable;
1923 +
1924 + return 0;
1925 +}
1926 +
1927 +int memac_set_tstamp(struct fman_mac *memac, bool enable)
1928 +{
1929 + return 0; /* Always enabled. */
1930 +}
1931 +
1932 int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
1933 {
1934 struct memac_regs __iomem *regs = memac->regs;
1935 @@ -963,8 +992,12 @@ int memac_del_hash_mac_address(struct fm
1936 break;
1937 }
1938 }
1939 - if (list_empty(&memac->multicast_addr_hash->lsts[hash]))
1940 - iowrite32be(hash & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
1941 +
1942 + if (!memac->allmulti_enabled) {
1943 + if (list_empty(&memac->multicast_addr_hash->lsts[hash]))
1944 + iowrite32be(hash & ~HASH_CTRL_MCAST_EN,
1945 + &regs->hashtable_ctrl);
1946 + }
1947
1948 return 0;
1949 }
1950 --- a/drivers/net/ethernet/freescale/fman/fman_memac.h
1951 +++ b/drivers/net/ethernet/freescale/fman/fman_memac.h
1952 @@ -57,5 +57,7 @@ int memac_set_exception(struct fman_mac
1953 enum fman_mac_exceptions exception, bool enable);
1954 int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
1955 int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
1956 +int memac_set_allmulti(struct fman_mac *memac, bool enable);
1957 +int memac_set_tstamp(struct fman_mac *memac, bool enable);
1958
1959 #endif /* __MEMAC_H */
1960 --- a/drivers/net/ethernet/freescale/fman/fman_port.c
1961 +++ b/drivers/net/ethernet/freescale/fman/fman_port.c
1962 @@ -1347,8 +1347,10 @@ int fman_port_config(struct fman_port *p
1963 switch (port->port_type) {
1964 case FMAN_PORT_TYPE_RX:
1965 set_rx_dflt_cfg(port, params);
1966 + /* fall through */
1967 case FMAN_PORT_TYPE_TX:
1968 set_tx_dflt_cfg(port, params, &port->dts_params);
1969 + /* fall through */
1970 default:
1971 set_dflt_cfg(port, params);
1972 }
1973 @@ -1728,6 +1730,20 @@ u32 fman_port_get_qman_channel_id(struct
1974 }
1975 EXPORT_SYMBOL(fman_port_get_qman_channel_id);
1976
1977 +/**
1978 + * fman_port_get_device
1979 + * port: Pointer to the FMan port device
1980 + *
1981 + * Get the 'struct device' associated to the specified FMan port device
1982 + *
1983 + * Return: pointer to associated 'struct device'
1984 + */
1985 +struct device *fman_port_get_device(struct fman_port *port)
1986 +{
1987 + return port->dev;
1988 +}
1989 +EXPORT_SYMBOL(fman_port_get_device);
1990 +
1991 int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset)
1992 {
1993 if (port->buffer_offsets.hash_result_offset == ILLEGAL_BASE)
1994 @@ -1739,6 +1755,18 @@ int fman_port_get_hash_result_offset(str
1995 }
1996 EXPORT_SYMBOL(fman_port_get_hash_result_offset);
1997
1998 +int fman_port_get_tstamp(struct fman_port *port, const void *data, u64 *tstamp)
1999 +{
2000 + if (port->buffer_offsets.time_stamp_offset == ILLEGAL_BASE)
2001 + return -EINVAL;
2002 +
2003 + *tstamp = be64_to_cpu(*(__be64 *)(data +
2004 + port->buffer_offsets.time_stamp_offset));
2005 +
2006 + return 0;
2007 +}
2008 +EXPORT_SYMBOL(fman_port_get_tstamp);
2009 +
2010 static int fman_port_probe(struct platform_device *of_dev)
2011 {
2012 struct fman_port *port;
2013 --- a/drivers/net/ethernet/freescale/fman/fman_port.h
2014 +++ b/drivers/net/ethernet/freescale/fman/fman_port.h
2015 @@ -153,6 +153,10 @@ u32 fman_port_get_qman_channel_id(struct
2016
2017 int fman_port_get_hash_result_offset(struct fman_port *port, u32 *offset);
2018
2019 +int fman_port_get_tstamp(struct fman_port *port, const void *data, u64 *tstamp);
2020 +
2021 struct fman_port *fman_port_bind(struct device *dev);
2022
2023 +struct device *fman_port_get_device(struct fman_port *port);
2024 +
2025 #endif /* __FMAN_PORT_H */
2026 --- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
2027 +++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
2028 @@ -44,6 +44,7 @@
2029 #define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
2030
2031 /* Command and Configuration Register (COMMAND_CONFIG) */
2032 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
2033 #define CMD_CFG_NO_LEN_CHK 0x00020000
2034 #define CMD_CFG_PAUSE_IGNORE 0x00000100
2035 #define CMF_CFG_CRC_FWD 0x00000040
2036 @@ -217,6 +218,7 @@ struct fman_mac {
2037 struct tgec_cfg *cfg;
2038 void *fm;
2039 struct fman_rev_info fm_rev_info;
2040 + bool allmulti_enabled;
2041 };
2042
2043 static void set_mac_address(struct tgec_regs __iomem *regs, u8 *adr)
2044 @@ -564,6 +566,49 @@ int tgec_add_hash_mac_address(struct fma
2045 return 0;
2046 }
2047
2048 +int tgec_set_allmulti(struct fman_mac *tgec, bool enable)
2049 +{
2050 + u32 entry;
2051 + struct tgec_regs __iomem *regs = tgec->regs;
2052 +
2053 + if (!is_init_done(tgec->cfg))
2054 + return -EINVAL;
2055 +
2056 + if (enable) {
2057 + for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
2058 + iowrite32be(entry | TGEC_HASH_MCAST_EN,
2059 + &regs->hashtable_ctrl);
2060 + } else {
2061 + for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
2062 + iowrite32be(entry & ~TGEC_HASH_MCAST_EN,
2063 + &regs->hashtable_ctrl);
2064 + }
2065 +
2066 + tgec->allmulti_enabled = enable;
2067 +
2068 + return 0;
2069 +}
2070 +
2071 +int tgec_set_tstamp(struct fman_mac *tgec, bool enable)
2072 +{
2073 + struct tgec_regs __iomem *regs = tgec->regs;
2074 + u32 tmp;
2075 +
2076 + if (!is_init_done(tgec->cfg))
2077 + return -EINVAL;
2078 +
2079 + tmp = ioread32be(&regs->command_config);
2080 +
2081 + if (enable)
2082 + tmp |= CMD_CFG_EN_TIMESTAMP;
2083 + else
2084 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
2085 +
2086 + iowrite32be(tmp, &regs->command_config);
2087 +
2088 + return 0;
2089 +}
2090 +
2091 int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
2092 {
2093 struct tgec_regs __iomem *regs = tgec->regs;
2094 @@ -591,9 +636,12 @@ int tgec_del_hash_mac_address(struct fma
2095 break;
2096 }
2097 }
2098 - if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
2099 - iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
2100 - &regs->hashtable_ctrl);
2101 +
2102 + if (!tgec->allmulti_enabled) {
2103 + if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
2104 + iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
2105 + &regs->hashtable_ctrl);
2106 + }
2107
2108 return 0;
2109 }
2110 --- a/drivers/net/ethernet/freescale/fman/fman_tgec.h
2111 +++ b/drivers/net/ethernet/freescale/fman/fman_tgec.h
2112 @@ -51,5 +51,7 @@ int tgec_set_exception(struct fman_mac *
2113 int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
2114 int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
2115 int tgec_get_version(struct fman_mac *tgec, u32 *mac_version);
2116 +int tgec_set_allmulti(struct fman_mac *tgec, bool enable);
2117 +int tgec_set_tstamp(struct fman_mac *tgec, bool enable);
2118
2119 #endif /* __TGEC_H */
2120 --- a/drivers/net/ethernet/freescale/fman/mac.c
2121 +++ b/drivers/net/ethernet/freescale/fman/mac.c
2122 @@ -57,9 +57,7 @@ struct mac_priv_s {
2123 struct device *dev;
2124 void __iomem *vaddr;
2125 u8 cell_index;
2126 - phy_interface_t phy_if;
2127 struct fman *fman;
2128 - struct device_node *phy_node;
2129 struct device_node *internal_phy_node;
2130 /* List of multicast addresses */
2131 struct list_head mc_addr_list;
2132 @@ -106,7 +104,7 @@ static void set_fman_mac_params(struct m
2133 resource_size(mac_dev->res));
2134 memcpy(&params->addr, mac_dev->addr, sizeof(mac_dev->addr));
2135 params->max_speed = priv->max_speed;
2136 - params->phy_if = priv->phy_if;
2137 + params->phy_if = mac_dev->phy_if;
2138 params->basex_if = false;
2139 params->mac_id = priv->cell_index;
2140 params->fm = (void *)priv->fman;
2141 @@ -419,15 +417,12 @@ void fman_get_pause_cfg(struct mac_devic
2142 }
2143 EXPORT_SYMBOL(fman_get_pause_cfg);
2144
2145 -static void adjust_link_void(struct net_device *net_dev)
2146 +static void adjust_link_void(struct mac_device *mac_dev)
2147 {
2148 }
2149
2150 -static void adjust_link_dtsec(struct net_device *net_dev)
2151 +static void adjust_link_dtsec(struct mac_device *mac_dev)
2152 {
2153 - struct device *dev = net_dev->dev.parent;
2154 - struct dpaa_eth_data *eth_data = dev->platform_data;
2155 - struct mac_device *mac_dev = eth_data->mac_dev;
2156 struct phy_device *phy_dev = mac_dev->phy_dev;
2157 struct fman_mac *fman_mac;
2158 bool rx_pause, tx_pause;
2159 @@ -444,14 +439,12 @@ static void adjust_link_dtsec(struct net
2160 fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
2161 err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
2162 if (err < 0)
2163 - netdev_err(net_dev, "fman_set_mac_active_pause() = %d\n", err);
2164 + dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
2165 + err);
2166 }
2167
2168 -static void adjust_link_memac(struct net_device *net_dev)
2169 +static void adjust_link_memac(struct mac_device *mac_dev)
2170 {
2171 - struct device *dev = net_dev->dev.parent;
2172 - struct dpaa_eth_data *eth_data = dev->platform_data;
2173 - struct mac_device *mac_dev = eth_data->mac_dev;
2174 struct phy_device *phy_dev = mac_dev->phy_dev;
2175 struct fman_mac *fman_mac;
2176 bool rx_pause, tx_pause;
2177 @@ -463,60 +456,12 @@ static void adjust_link_memac(struct net
2178 fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
2179 err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
2180 if (err < 0)
2181 - netdev_err(net_dev, "fman_set_mac_active_pause() = %d\n", err);
2182 -}
2183 -
2184 -/* Initializes driver's PHY state, and attaches to the PHY.
2185 - * Returns 0 on success.
2186 - */
2187 -static struct phy_device *init_phy(struct net_device *net_dev,
2188 - struct mac_device *mac_dev,
2189 - void (*adj_lnk)(struct net_device *))
2190 -{
2191 - struct phy_device *phy_dev;
2192 - struct mac_priv_s *priv = mac_dev->priv;
2193 -
2194 - phy_dev = of_phy_connect(net_dev, priv->phy_node, adj_lnk, 0,
2195 - priv->phy_if);
2196 - if (!phy_dev) {
2197 - netdev_err(net_dev, "Could not connect to PHY\n");
2198 - return NULL;
2199 - }
2200 -
2201 - /* Remove any features not supported by the controller */
2202 - phy_dev->supported &= mac_dev->if_support;
2203 - /* Enable the symmetric and asymmetric PAUSE frame advertisements,
2204 - * as most of the PHY drivers do not enable them by default.
2205 - */
2206 - phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
2207 - phy_dev->advertising = phy_dev->supported;
2208 -
2209 - mac_dev->phy_dev = phy_dev;
2210 -
2211 - return phy_dev;
2212 -}
2213 -
2214 -static struct phy_device *dtsec_init_phy(struct net_device *net_dev,
2215 - struct mac_device *mac_dev)
2216 -{
2217 - return init_phy(net_dev, mac_dev, &adjust_link_dtsec);
2218 -}
2219 -
2220 -static struct phy_device *tgec_init_phy(struct net_device *net_dev,
2221 - struct mac_device *mac_dev)
2222 -{
2223 - return init_phy(net_dev, mac_dev, adjust_link_void);
2224 -}
2225 -
2226 -static struct phy_device *memac_init_phy(struct net_device *net_dev,
2227 - struct mac_device *mac_dev)
2228 -{
2229 - return init_phy(net_dev, mac_dev, &adjust_link_memac);
2230 + dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
2231 + err);
2232 }
2233
2234 static void setup_dtsec(struct mac_device *mac_dev)
2235 {
2236 - mac_dev->init_phy = dtsec_init_phy;
2237 mac_dev->init = dtsec_initialization;
2238 mac_dev->set_promisc = dtsec_set_promiscuous;
2239 mac_dev->change_addr = dtsec_modify_mac_address;
2240 @@ -525,17 +470,18 @@ static void setup_dtsec(struct mac_devic
2241 mac_dev->set_tx_pause = dtsec_set_tx_pause_frames;
2242 mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
2243 mac_dev->set_exception = dtsec_set_exception;
2244 + mac_dev->set_allmulti = dtsec_set_allmulti;
2245 + mac_dev->set_tstamp = dtsec_set_tstamp;
2246 mac_dev->set_multi = set_multi;
2247 mac_dev->start = start;
2248 mac_dev->stop = stop;
2249 -
2250 + mac_dev->adjust_link = adjust_link_dtsec;
2251 mac_dev->priv->enable = dtsec_enable;
2252 mac_dev->priv->disable = dtsec_disable;
2253 }
2254
2255 static void setup_tgec(struct mac_device *mac_dev)
2256 {
2257 - mac_dev->init_phy = tgec_init_phy;
2258 mac_dev->init = tgec_initialization;
2259 mac_dev->set_promisc = tgec_set_promiscuous;
2260 mac_dev->change_addr = tgec_modify_mac_address;
2261 @@ -544,17 +490,18 @@ static void setup_tgec(struct mac_device
2262 mac_dev->set_tx_pause = tgec_set_tx_pause_frames;
2263 mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
2264 mac_dev->set_exception = tgec_set_exception;
2265 + mac_dev->set_allmulti = tgec_set_allmulti;
2266 + mac_dev->set_tstamp = tgec_set_tstamp;
2267 mac_dev->set_multi = set_multi;
2268 mac_dev->start = start;
2269 mac_dev->stop = stop;
2270 -
2271 + mac_dev->adjust_link = adjust_link_void;
2272 mac_dev->priv->enable = tgec_enable;
2273 mac_dev->priv->disable = tgec_disable;
2274 }
2275
2276 static void setup_memac(struct mac_device *mac_dev)
2277 {
2278 - mac_dev->init_phy = memac_init_phy;
2279 mac_dev->init = memac_initialization;
2280 mac_dev->set_promisc = memac_set_promiscuous;
2281 mac_dev->change_addr = memac_modify_mac_address;
2282 @@ -563,10 +510,12 @@ static void setup_memac(struct mac_devic
2283 mac_dev->set_tx_pause = memac_set_tx_pause_frames;
2284 mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
2285 mac_dev->set_exception = memac_set_exception;
2286 + mac_dev->set_allmulti = memac_set_allmulti;
2287 + mac_dev->set_tstamp = memac_set_tstamp;
2288 mac_dev->set_multi = set_multi;
2289 mac_dev->start = start;
2290 mac_dev->stop = stop;
2291 -
2292 + mac_dev->adjust_link = adjust_link_memac;
2293 mac_dev->priv->enable = memac_enable;
2294 mac_dev->priv->disable = memac_disable;
2295 }
2296 @@ -599,8 +548,7 @@ static const u16 phy2speed[] = {
2297 };
2298
2299 static struct platform_device *dpaa_eth_add_device(int fman_id,
2300 - struct mac_device *mac_dev,
2301 - struct device_node *node)
2302 + struct mac_device *mac_dev)
2303 {
2304 struct platform_device *pdev;
2305 struct dpaa_eth_data data;
2306 @@ -613,19 +561,15 @@ static struct platform_device *dpaa_eth_
2307 data.mac_dev = mac_dev;
2308 data.mac_hw_id = priv->cell_index;
2309 data.fman_hw_id = fman_id;
2310 - data.mac_node = node;
2311
2312 mutex_lock(&eth_lock);
2313 -
2314 pdev = platform_device_alloc("dpaa-ethernet", dpaa_eth_dev_cnt);
2315 if (!pdev) {
2316 ret = -ENOMEM;
2317 goto no_mem;
2318 }
2319
2320 - pdev->dev.of_node = node;
2321 pdev->dev.parent = priv->dev;
2322 - set_dma_ops(&pdev->dev, get_dma_ops(priv->dev));
2323
2324 ret = platform_device_add_data(pdev, &data, sizeof(data));
2325 if (ret)
2326 @@ -676,7 +620,6 @@ static int mac_probe(struct platform_dev
2327 mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL);
2328 if (!mac_dev) {
2329 err = -ENOMEM;
2330 - dev_err(dev, "devm_kzalloc() = %d\n", err);
2331 goto _return;
2332 }
2333 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
2334 @@ -706,9 +649,6 @@ static int mac_probe(struct platform_dev
2335 goto _return;
2336 }
2337
2338 - /* Register mac_dev */
2339 - dev_set_drvdata(dev, mac_dev);
2340 -
2341 INIT_LIST_HEAD(&priv->mc_addr_list);
2342
2343 /* Get the FM node */
2344 @@ -717,7 +657,7 @@ static int mac_probe(struct platform_dev
2345 dev_err(dev, "of_get_parent(%pOF) failed\n",
2346 mac_node);
2347 err = -EINVAL;
2348 - goto _return_dev_set_drvdata;
2349 + goto _return_of_get_parent;
2350 }
2351
2352 of_dev = of_find_device_by_node(dev_node);
2353 @@ -751,7 +691,7 @@ static int mac_probe(struct platform_dev
2354 if (err < 0) {
2355 dev_err(dev, "of_address_to_resource(%pOF) = %d\n",
2356 mac_node, err);
2357 - goto _return_dev_set_drvdata;
2358 + goto _return_of_get_parent;
2359 }
2360
2361 mac_dev->res = __devm_request_region(dev,
2362 @@ -761,7 +701,7 @@ static int mac_probe(struct platform_dev
2363 if (!mac_dev->res) {
2364 dev_err(dev, "__devm_request_mem_region(mac) failed\n");
2365 err = -EBUSY;
2366 - goto _return_dev_set_drvdata;
2367 + goto _return_of_get_parent;
2368 }
2369
2370 priv->vaddr = devm_ioremap(dev, mac_dev->res->start,
2371 @@ -769,16 +709,12 @@ static int mac_probe(struct platform_dev
2372 if (!priv->vaddr) {
2373 dev_err(dev, "devm_ioremap() failed\n");
2374 err = -EIO;
2375 - goto _return_dev_set_drvdata;
2376 + goto _return_of_get_parent;
2377 }
2378
2379 if (!of_device_is_available(mac_node)) {
2380 - devm_iounmap(dev, priv->vaddr);
2381 - __devm_release_region(dev, fman_get_mem_region(priv->fman),
2382 - res.start, res.end + 1 - res.start);
2383 - devm_kfree(dev, mac_dev);
2384 - dev_set_drvdata(dev, NULL);
2385 - return -ENODEV;
2386 + err = -ENODEV;
2387 + goto _return_of_get_parent;
2388 }
2389
2390 /* Get the cell-index */
2391 @@ -786,7 +722,7 @@ static int mac_probe(struct platform_dev
2392 if (err) {
2393 dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
2394 err = -EINVAL;
2395 - goto _return_dev_set_drvdata;
2396 + goto _return_of_get_parent;
2397 }
2398 priv->cell_index = (u8)val;
2399
2400 @@ -795,7 +731,7 @@ static int mac_probe(struct platform_dev
2401 if (!mac_addr) {
2402 dev_err(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
2403 err = -EINVAL;
2404 - goto _return_dev_set_drvdata;
2405 + goto _return_of_get_parent;
2406 }
2407 memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
2408
2409 @@ -805,14 +741,14 @@ static int mac_probe(struct platform_dev
2410 dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
2411 mac_node);
2412 err = nph;
2413 - goto _return_dev_set_drvdata;
2414 + goto _return_of_get_parent;
2415 }
2416
2417 if (nph != ARRAY_SIZE(mac_dev->port)) {
2418 dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
2419 mac_node);
2420 err = -EINVAL;
2421 - goto _return_dev_set_drvdata;
2422 + goto _return_of_get_parent;
2423 }
2424
2425 for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
2426 @@ -851,13 +787,13 @@ static int mac_probe(struct platform_dev
2427 mac_node);
2428 phy_if = PHY_INTERFACE_MODE_SGMII;
2429 }
2430 - priv->phy_if = phy_if;
2431 + mac_dev->phy_if = phy_if;
2432
2433 - priv->speed = phy2speed[priv->phy_if];
2434 + priv->speed = phy2speed[mac_dev->phy_if];
2435 priv->max_speed = priv->speed;
2436 mac_dev->if_support = DTSEC_SUPPORTED;
2437 /* We don't support half-duplex in SGMII mode */
2438 - if (priv->phy_if == PHY_INTERFACE_MODE_SGMII)
2439 + if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
2440 mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
2441 SUPPORTED_100baseT_Half);
2442
2443 @@ -866,30 +802,31 @@ static int mac_probe(struct platform_dev
2444 mac_dev->if_support |= SUPPORTED_1000baseT_Full;
2445
2446 /* The 10G interface only supports one mode */
2447 - if (priv->phy_if == PHY_INTERFACE_MODE_XGMII)
2448 + if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
2449 mac_dev->if_support = SUPPORTED_10000baseT_Full;
2450
2451 /* Get the rest of the PHY information */
2452 - priv->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
2453 - if (!priv->phy_node && of_phy_is_fixed_link(mac_node)) {
2454 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
2455 + if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
2456 struct phy_device *phy;
2457
2458 err = of_phy_register_fixed_link(mac_node);
2459 if (err)
2460 - goto _return_dev_set_drvdata;
2461 + goto _return_of_get_parent;
2462
2463 priv->fixed_link = kzalloc(sizeof(*priv->fixed_link),
2464 GFP_KERNEL);
2465 if (!priv->fixed_link) {
2466 err = -ENOMEM;
2467 - goto _return_dev_set_drvdata;
2468 + goto _return_of_get_parent;
2469 }
2470
2471 - priv->phy_node = of_node_get(mac_node);
2472 - phy = of_phy_find_device(priv->phy_node);
2473 + mac_dev->phy_node = of_node_get(mac_node);
2474 + phy = of_phy_find_device(mac_dev->phy_node);
2475 if (!phy) {
2476 err = -EINVAL;
2477 - goto _return_dev_set_drvdata;
2478 + of_node_put(mac_dev->phy_node);
2479 + goto _return_of_get_parent;
2480 }
2481
2482 priv->fixed_link->link = phy->link;
2483 @@ -904,8 +841,8 @@ static int mac_probe(struct platform_dev
2484 err = mac_dev->init(mac_dev);
2485 if (err < 0) {
2486 dev_err(dev, "mac_dev->init() = %d\n", err);
2487 - of_node_put(priv->phy_node);
2488 - goto _return_dev_set_drvdata;
2489 + of_node_put(mac_dev->phy_node);
2490 + goto _return_of_get_parent;
2491 }
2492
2493 /* pause frame autonegotiation enabled */
2494 @@ -926,7 +863,7 @@ static int mac_probe(struct platform_dev
2495 mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
2496 mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
2497
2498 - priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev, mac_node);
2499 + priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
2500 if (IS_ERR(priv->eth_dev)) {
2501 dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
2502 priv->cell_index);
2503 @@ -937,9 +874,8 @@ static int mac_probe(struct platform_dev
2504
2505 _return_of_node_put:
2506 of_node_put(dev_node);
2507 -_return_dev_set_drvdata:
2508 +_return_of_get_parent:
2509 kfree(priv->fixed_link);
2510 - dev_set_drvdata(dev, NULL);
2511 _return:
2512 return err;
2513 }
2514 --- a/drivers/net/ethernet/freescale/fman/mac.h
2515 +++ b/drivers/net/ethernet/freescale/fman/mac.h
2516 @@ -50,6 +50,8 @@ struct mac_device {
2517 struct fman_port *port[2];
2518 u32 if_support;
2519 struct phy_device *phy_dev;
2520 + phy_interface_t phy_if;
2521 + struct device_node *phy_node;
2522
2523 bool autoneg_pause;
2524 bool rx_pause_req;
2525 @@ -57,14 +59,16 @@ struct mac_device {
2526 bool rx_pause_active;
2527 bool tx_pause_active;
2528 bool promisc;
2529 + bool allmulti;
2530
2531 - struct phy_device *(*init_phy)(struct net_device *net_dev,
2532 - struct mac_device *mac_dev);
2533 int (*init)(struct mac_device *mac_dev);
2534 int (*start)(struct mac_device *mac_dev);
2535 int (*stop)(struct mac_device *mac_dev);
2536 + void (*adjust_link)(struct mac_device *mac_dev);
2537 int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
2538 int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr);
2539 + int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
2540 + int (*set_tstamp)(struct fman_mac *mac_dev, bool enable);
2541 int (*set_multi)(struct net_device *net_dev,
2542 struct mac_device *mac_dev);
2543 int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
2544 @@ -82,7 +86,6 @@ struct mac_device {
2545 };
2546
2547 struct dpaa_eth_data {
2548 - struct device_node *mac_node;
2549 struct mac_device *mac_dev;
2550 int mac_hw_id;
2551 int fman_hw_id;
2552 --- /dev/null
2553 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Kconfig
2554 @@ -0,0 +1,184 @@
2555 +menuconfig FSL_SDK_DPAA_ETH
2556 + tristate "DPAA Ethernet"
2557 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && FSL_SDK_FMAN && !FSL_DPAA_ETH
2558 + select PHYLIB
2559 + help
2560 + Data Path Acceleration Architecture Ethernet driver,
2561 + supporting the Freescale QorIQ chips.
2562 + Depends on Freescale Buffer Manager and Queue Manager
2563 + driver and Frame Manager Driver.
2564 +
2565 +if FSL_SDK_DPAA_ETH
2566 +
2567 +config FSL_DPAA_HOOKS
2568 + bool "DPAA Ethernet driver hooks"
2569 +
2570 +config FSL_DPAA_CEETM
2571 + bool "DPAA CEETM QoS"
2572 + depends on NET_SCHED
2573 + default n
2574 + help
2575 + Enable QoS offloading support through the CEETM hardware block.
2576 +
2577 +config FSL_DPAA_CEETM_CCS_THRESHOLD_1G
2578 + hex "CEETM egress congestion threshold on 1G ports"
2579 + depends on FSL_DPAA_CEETM
2580 + range 0x1000 0x10000000
2581 + default "0x00005000"
2582 + help
2583 + The size in bytes of the CEETM egress Class Congestion State threshold on 1G ports.
2584 + The threshold needs to be configured keeping in mind the following factors:
2585 + - A threshold too large will buffer frames for a long time in the TX queues,
2586 + when a small shaping rate is configured. This will cause buffer pool depletion
2587 + or out of memory errors. This in turn will cause frame loss on RX;
2588 + - A threshold too small will cause unnecessary frame loss by entering
2589 + congestion too often.
2590 +
2591 +config FSL_DPAA_CEETM_CCS_THRESHOLD_10G
2592 + hex "CEETM egress congestion threshold on 10G ports"
2593 + depends on FSL_DPAA_CEETM
2594 + range 0x1000 0x20000000
2595 + default "0x00032000"
2596 + help
2597 + The size in bytes of the CEETM egress Class Congestion State threshold on 10G ports.
2598 + See FSL_DPAA_CEETM_CCS_THRESHOLD_1G for details.
2599 +
2600 +config FSL_DPAA_OFFLINE_PORTS
2601 + bool "Offline Ports support"
2602 + depends on FSL_SDK_DPAA_ETH
2603 + default y
2604 + help
2605 + The Offline Parsing / Host Command ports (short: OH ports, of Offline ports) provide
2606 + most of the functionality of the regular, online ports, except they receive their
2607 + frames from a core or an accelerator on the SoC, via QMan frame queues,
2608 + rather than directly from the network.
2609 + Offline ports are configured via PCD (Parse-Classify-Distribute) schemes, just like
2610 + any online FMan port. They deliver the processed frames to frame queues, according
2611 + to the applied PCD configurations.
2612 +
2613 + Choosing this feature will not impact the functionality and/or performance of the system,
2614 + so it is safe to have it.
2615 +
2616 +config FSL_DPAA_ADVANCED_DRIVERS
2617 + bool "Advanced DPAA Ethernet drivers"
2618 + depends on FSL_SDK_DPAA_ETH
2619 + default y
2620 + help
2621 + Besides the standard DPAA Ethernet driver the DPAA Proxy initialization driver
2622 + is needed to support advanced scenarios. Select this to also build the advanced
2623 + drivers.
2624 +
2625 +config FSL_DPAA_ETH_JUMBO_FRAME
2626 + bool "Optimize for jumbo frames"
2627 + default n
2628 + help
2629 + Optimize the DPAA Ethernet driver throughput for large frames
2630 + termination traffic (e.g. 4K and above).
2631 + NOTE: This option can only be used if FSL_FM_MAX_FRAME_SIZE
2632 + is set to 9600 bytes.
2633 + Using this option in combination with small frames increases
2634 + significantly the driver's memory footprint and may even deplete
2635 + the system memory. Also, the skb truesize is altered and messages
2636 + from the stack that warn against this are bypassed.
2637 +
2638 +config FSL_DPAA_TS
2639 + bool "Linux compliant timestamping"
2640 + depends on FSL_SDK_DPAA_ETH
2641 + default n
2642 + help
2643 + Enable Linux API compliant timestamping support.
2644 +
2645 +config FSL_DPAA_1588
2646 + bool "IEEE 1588-compliant timestamping"
2647 + depends on FSL_SDK_DPAA_ETH
2648 + select FSL_DPAA_TS
2649 + default n
2650 + help
2651 + Enable IEEE1588 support code.
2652 +
2653 +config FSL_DPAA_ETH_MAX_BUF_COUNT
2654 + int "Maximum nuber of buffers in private bpool"
2655 + depends on FSL_SDK_DPAA_ETH
2656 + range 64 2048
2657 + default "128"
2658 + help
2659 + The maximum number of buffers to be by default allocated in the DPAA-Ethernet private port's
2660 + buffer pool. One needn't normally modify this, as it has probably been tuned for performance
2661 + already. This cannot be lower than DPAA_ETH_REFILL_THRESHOLD.
2662 +
2663 +config FSL_DPAA_ETH_REFILL_THRESHOLD
2664 + int "Private bpool refill threshold"
2665 + depends on FSL_SDK_DPAA_ETH
2666 + range 32 FSL_DPAA_ETH_MAX_BUF_COUNT
2667 + default "80"
2668 + help
2669 + The DPAA-Ethernet driver will start replenishing buffer pools whose count
2670 + falls below this threshold. This must be related to DPAA_ETH_MAX_BUF_COUNT. One needn't normally
2671 + modify this value unless one has very specific performance reasons.
2672 +
2673 +config FSL_DPAA_CS_THRESHOLD_1G
2674 + hex "Egress congestion threshold on 1G ports"
2675 + depends on FSL_SDK_DPAA_ETH
2676 + range 0x1000 0x10000000
2677 + default "0x06000000"
2678 + help
2679 + The size in bytes of the egress Congestion State notification threshold on 1G ports.
2680 + The 1G dTSECs can quite easily be flooded by cores doing Tx in a tight loop
2681 + (e.g. by sending UDP datagrams at "while(1) speed"),
2682 + and the larger the frame size, the more acute the problem.
2683 + So we have to find a balance between these factors:
2684 + - avoiding the device staying congested for a prolonged time (risking
2685 + the netdev watchdog to fire - see also the tx_timeout module param);
2686 + - affecting performance of protocols such as TCP, which otherwise
2687 + behave well under the congestion notification mechanism;
2688 + - preventing the Tx cores from tightly-looping (as if the congestion
2689 + threshold was too low to be effective);
2690 + - running out of memory if the CS threshold is set too high.
2691 +
2692 +config FSL_DPAA_CS_THRESHOLD_10G
2693 + hex "Egress congestion threshold on 10G ports"
2694 + depends on FSL_SDK_DPAA_ETH
2695 + range 0x1000 0x20000000
2696 + default "0x10000000"
2697 + help
2698 + The size in bytes of the egress Congestion State notification threshold on 10G ports.
2699 +
2700 +config FSL_DPAA_INGRESS_CS_THRESHOLD
2701 + hex "Ingress congestion threshold on FMan ports"
2702 + depends on FSL_SDK_DPAA_ETH
2703 + default "0x10000000"
2704 + help
2705 + The size in bytes of the ingress tail-drop threshold on FMan ports.
2706 + Traffic piling up above this value will be rejected by QMan and discarded by FMan.
2707 +
2708 +config FSL_DPAA_ETH_DEBUGFS
2709 + bool "DPAA Ethernet debugfs interface"
2710 + depends on DEBUG_FS && FSL_SDK_DPAA_ETH
2711 + default y
2712 + help
2713 + This option compiles debugfs code for the DPAA Ethernet driver.
2714 +
2715 +config FSL_DPAA_ETH_DEBUG
2716 + bool "DPAA Ethernet Debug Support"
2717 + depends on FSL_SDK_DPAA_ETH
2718 + default n
2719 + help
2720 + This option compiles debug code for the DPAA Ethernet driver.
2721 +
2722 +config FSL_DPAA_DBG_LOOP
2723 + bool "DPAA Ethernet Debug loopback"
2724 + depends on FSL_DPAA_ETH_DEBUGFS
2725 + default n
2726 + help
2727 + This option allows to divert all received traffic on a certain interface A towards a
2728 + selected interface B. This option is used to benchmark the HW + Ethernet driver in
2729 + isolation from the Linux networking stack. The loops are controlled by debugfs entries,
2730 + one for each interface. By default all loops are disabled (target value is -1). I.e. to
2731 + change the loop setting for interface 4 and divert all received traffic to interface 5
2732 + write Tx interface number in the receive interface debugfs file:
2733 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
2734 + 4->-1
2735 + # echo 5 > /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
2736 + # cat /sys/kernel/debug/powerpc/fsl_dpa/eth4_loop
2737 + 4->5
2738 +endif # FSL_SDK_DPAA_ETH
2739 --- /dev/null
2740 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/Makefile
2741 @@ -0,0 +1,45 @@
2742 +#
2743 +# Makefile for the Freescale Ethernet controllers
2744 +#
2745 +ccflags-y += -DVERSION=\"\"
2746 +#
2747 +# Include netcomm SW specific definitions
2748 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
2749 +
2750 +ccflags-y += -I$(NET_DPA)
2751 +
2752 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_mac.o fsl_dpa.o
2753 +
2754 +fsl_dpa-objs += dpaa_ethtool.o dpaa_eth_sysfs.o dpaa_eth.o dpaa_eth_sg.o dpaa_eth_common.o
2755 +ifeq ($(CONFIG_FSL_DPAA_DBG_LOOP),y)
2756 +fsl_dpa-objs += dpaa_debugfs.o
2757 +endif
2758 +ifeq ($(CONFIG_FSL_DPAA_1588),y)
2759 +fsl_dpa-objs += dpaa_1588.o
2760 +endif
2761 +ifeq ($(CONFIG_FSL_DPAA_CEETM),y)
2762 +ccflags-y += -Idrivers/net/ethernet/freescale/sdk_fman/src/wrapper
2763 +fsl_dpa-objs += dpaa_eth_ceetm.o
2764 +endif
2765 +
2766 +fsl_mac-objs += mac.o mac-api.o
2767 +
2768 +# Advanced drivers
2769 +ifeq ($(CONFIG_FSL_DPAA_ADVANCED_DRIVERS),y)
2770 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_advanced.o
2771 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_proxy.o
2772 +
2773 +fsl_advanced-objs += dpaa_eth_base.o
2774 +# suport for multiple drivers per kernel module comes in kernel 3.14
2775 +# so we are forced to generate several modules for the advanced drivers
2776 +fsl_proxy-objs += dpaa_eth_proxy.o
2777 +
2778 +ifeq ($(CONFIG_FSL_DPAA_OFFLINE_PORTS),y)
2779 +obj-$(CONFIG_FSL_SDK_DPAA_ETH) += fsl_oh.o
2780 +
2781 +fsl_oh-objs += offline_port.o
2782 +endif
2783 +endif
2784 +
2785 +# Needed by the tracing framework
2786 +CFLAGS_dpaa_eth.o := -I$(src)
2787 --- /dev/null
2788 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.c
2789 @@ -0,0 +1,580 @@
2790 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
2791 + * Copyright (C) 2009 IXXAT Automation, GmbH
2792 + *
2793 + * DPAA Ethernet Driver -- IEEE 1588 interface functionality
2794 + *
2795 + * This program is free software; you can redistribute it and/or modify
2796 + * it under the terms of the GNU General Public License as published by
2797 + * the Free Software Foundation; either version 2 of the License, or
2798 + * (at your option) any later version.
2799 + *
2800 + * This program is distributed in the hope that it will be useful,
2801 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2802 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2803 + * GNU General Public License for more details.
2804 + *
2805 + * You should have received a copy of the GNU General Public License along
2806 + * with this program; if not, write to the Free Software Foundation, Inc.,
2807 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2808 + *
2809 + */
2810 +#include <linux/io.h>
2811 +#include <linux/device.h>
2812 +#include <linux/fs.h>
2813 +#include <linux/vmalloc.h>
2814 +#include <linux/spinlock.h>
2815 +#include <linux/ip.h>
2816 +#include <linux/ipv6.h>
2817 +#include <linux/udp.h>
2818 +#include <asm/div64.h>
2819 +#include "dpaa_eth.h"
2820 +#include "dpaa_eth_common.h"
2821 +#include "dpaa_1588.h"
2822 +#include "mac.h"
2823 +
2824 +static int dpa_ptp_init_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
2825 +{
2826 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
2827 +
2828 + circ_buf->buf = vmalloc(sizeof(struct dpa_ptp_data) * size);
2829 + if (!circ_buf->buf)
2830 + return 1;
2831 +
2832 + circ_buf->head = 0;
2833 + circ_buf->tail = 0;
2834 + ptp_buf->size = size;
2835 + spin_lock_init(&ptp_buf->ptp_lock);
2836 +
2837 + return 0;
2838 +}
2839 +
2840 +static void dpa_ptp_reset_circ(struct dpa_ptp_circ_buf *ptp_buf, u32 size)
2841 +{
2842 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
2843 +
2844 + circ_buf->head = 0;
2845 + circ_buf->tail = 0;
2846 + ptp_buf->size = size;
2847 +}
2848 +
2849 +static int dpa_ptp_insert(struct dpa_ptp_circ_buf *ptp_buf,
2850 + struct dpa_ptp_data *data)
2851 +{
2852 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
2853 + int size = ptp_buf->size;
2854 + struct dpa_ptp_data *tmp;
2855 + unsigned long flags;
2856 + int head, tail;
2857 +
2858 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
2859 +
2860 + head = circ_buf->head;
2861 + tail = circ_buf->tail;
2862 +
2863 + if (CIRC_SPACE(head, tail, size) <= 0)
2864 + circ_buf->tail = (tail + 1) & (size - 1);
2865 +
2866 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + head;
2867 + memcpy(tmp, data, sizeof(struct dpa_ptp_data));
2868 +
2869 + circ_buf->head = (head + 1) & (size - 1);
2870 +
2871 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
2872 +
2873 + return 0;
2874 +}
2875 +
2876 +static int dpa_ptp_is_ident_match(struct dpa_ptp_ident *dst,
2877 + struct dpa_ptp_ident *src)
2878 +{
2879 + int ret;
2880 +
2881 + if ((dst->version != src->version) || (dst->msg_type != src->msg_type))
2882 + return 0;
2883 +
2884 + if ((dst->netw_prot == src->netw_prot)
2885 + || src->netw_prot == DPA_PTP_PROT_DONTCARE) {
2886 + if (dst->seq_id != src->seq_id)
2887 + return 0;
2888 +
2889 + ret = memcmp(dst->snd_port_id, src->snd_port_id,
2890 + DPA_PTP_SOURCE_PORT_LENGTH);
2891 + if (ret)
2892 + return 0;
2893 + else
2894 + return 1;
2895 + }
2896 +
2897 + return 0;
2898 +}
2899 +
2900 +static int dpa_ptp_find_and_remove(struct dpa_ptp_circ_buf *ptp_buf,
2901 + struct dpa_ptp_ident *ident,
2902 + struct dpa_ptp_time *ts)
2903 +{
2904 + struct circ_buf *circ_buf = &ptp_buf->circ_buf;
2905 + int size = ptp_buf->size;
2906 + int head, tail, idx;
2907 + unsigned long flags;
2908 + struct dpa_ptp_data *tmp, *tmp2;
2909 + struct dpa_ptp_ident *tmp_ident;
2910 +
2911 + spin_lock_irqsave(&ptp_buf->ptp_lock, flags);
2912 +
2913 + head = circ_buf->head;
2914 + tail = idx = circ_buf->tail;
2915 +
2916 + if (CIRC_CNT(head, tail, size) == 0) {
2917 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
2918 + return 1;
2919 + }
2920 +
2921 + while (idx != head) {
2922 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
2923 + tmp_ident = &tmp->ident;
2924 + if (dpa_ptp_is_ident_match(tmp_ident, ident))
2925 + break;
2926 + idx = (idx + 1) & (size - 1);
2927 + }
2928 +
2929 + if (idx == head) {
2930 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
2931 + return 1;
2932 + }
2933 +
2934 + ts->sec = tmp->ts.sec;
2935 + ts->nsec = tmp->ts.nsec;
2936 +
2937 + if (idx != tail) {
2938 + if (CIRC_CNT(idx, tail, size) > TS_ACCUMULATION_THRESHOLD) {
2939 + tail = circ_buf->tail =
2940 + (idx - TS_ACCUMULATION_THRESHOLD) & (size - 1);
2941 + }
2942 +
2943 + while (CIRC_CNT(idx, tail, size) > 0) {
2944 + tmp = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
2945 + idx = (idx - 1) & (size - 1);
2946 + tmp2 = (struct dpa_ptp_data *)(circ_buf->buf) + idx;
2947 + *tmp = *tmp2;
2948 + }
2949 + }
2950 + circ_buf->tail = (tail + 1) & (size - 1);
2951 +
2952 + spin_unlock_irqrestore(&ptp_buf->ptp_lock, flags);
2953 +
2954 + return 0;
2955 +}
2956 +
2957 +/* Parse the PTP packets
2958 + *
2959 + * The PTP header can be found in an IPv4 packet, IPv6 patcket or in
2960 + * an IEEE802.3 ethernet frame. This function returns the position of
2961 + * the PTP packet or NULL if no PTP found
2962 + */
2963 +static u8 *dpa_ptp_parse_packet(struct sk_buff *skb, u16 *eth_type)
2964 +{
2965 + u8 *pos = skb->data + ETH_ALEN + ETH_ALEN;
2966 + u8 *ptp_loc = NULL;
2967 + u8 msg_type;
2968 + u32 access_len = ETH_ALEN + ETH_ALEN + DPA_ETYPE_LEN;
2969 + struct iphdr *iph;
2970 + struct udphdr *udph;
2971 + struct ipv6hdr *ipv6h;
2972 +
2973 + /* when we can receive S/G frames we need to check the data we want to
2974 + * access is in the linear skb buffer
2975 + */
2976 + if (!pskb_may_pull(skb, access_len))
2977 + return NULL;
2978 +
2979 + *eth_type = *((u16 *)pos);
2980 +
2981 + /* Check if inner tag is here */
2982 + if (*eth_type == ETH_P_8021Q) {
2983 + access_len += DPA_VLAN_TAG_LEN;
2984 +
2985 + if (!pskb_may_pull(skb, access_len))
2986 + return NULL;
2987 +
2988 + pos += DPA_VLAN_TAG_LEN;
2989 + *eth_type = *((u16 *)pos);
2990 + }
2991 +
2992 + pos += DPA_ETYPE_LEN;
2993 +
2994 + switch (*eth_type) {
2995 + /* Transport of PTP over Ethernet */
2996 + case ETH_P_1588:
2997 + ptp_loc = pos;
2998 +
2999 + if (!pskb_may_pull(skb, access_len + PTP_OFFS_MSG_TYPE + 1))
3000 + return NULL;
3001 +
3002 + msg_type = *((u8 *)(ptp_loc + PTP_OFFS_MSG_TYPE)) & 0xf;
3003 + if ((msg_type == PTP_MSGTYPE_SYNC)
3004 + || (msg_type == PTP_MSGTYPE_DELREQ)
3005 + || (msg_type == PTP_MSGTYPE_PDELREQ)
3006 + || (msg_type == PTP_MSGTYPE_PDELRESP))
3007 + return ptp_loc;
3008 + break;
3009 + /* Transport of PTP over IPv4 */
3010 + case ETH_P_IP:
3011 + iph = (struct iphdr *)pos;
3012 + access_len += sizeof(struct iphdr);
3013 +
3014 + if (!pskb_may_pull(skb, access_len))
3015 + return NULL;
3016 +
3017 + if (ntohs(iph->protocol) != IPPROTO_UDP)
3018 + return NULL;
3019 +
3020 + access_len += iph->ihl * 4 - sizeof(struct iphdr) +
3021 + sizeof(struct udphdr);
3022 +
3023 + if (!pskb_may_pull(skb, access_len))
3024 + return NULL;
3025 +
3026 + pos += iph->ihl * 4;
3027 + udph = (struct udphdr *)pos;
3028 + if (ntohs(udph->dest) != 319)
3029 + return NULL;
3030 + ptp_loc = pos + sizeof(struct udphdr);
3031 + break;
3032 + /* Transport of PTP over IPv6 */
3033 + case ETH_P_IPV6:
3034 + ipv6h = (struct ipv6hdr *)pos;
3035 +
3036 + access_len += sizeof(struct ipv6hdr) + sizeof(struct udphdr);
3037 +
3038 + if (ntohs(ipv6h->nexthdr) != IPPROTO_UDP)
3039 + return NULL;
3040 +
3041 + pos += sizeof(struct ipv6hdr);
3042 + udph = (struct udphdr *)pos;
3043 + if (ntohs(udph->dest) != 319)
3044 + return NULL;
3045 + ptp_loc = pos + sizeof(struct udphdr);
3046 + break;
3047 + default:
3048 + break;
3049 + }
3050 +
3051 + return ptp_loc;
3052 +}
3053 +
3054 +static int dpa_ptp_store_stamp(const struct dpa_priv_s *priv,
3055 + struct sk_buff *skb, void *data, enum port_type rx_tx,
3056 + struct dpa_ptp_data *ptp_data)
3057 +{
3058 + u64 nsec;
3059 + u32 mod;
3060 + u8 *ptp_loc;
3061 + u16 eth_type;
3062 +
3063 + ptp_loc = dpa_ptp_parse_packet(skb, &eth_type);
3064 + if (!ptp_loc)
3065 + return -EINVAL;
3066 +
3067 + switch (eth_type) {
3068 + case ETH_P_IP:
3069 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV4;
3070 + break;
3071 + case ETH_P_IPV6:
3072 + ptp_data->ident.netw_prot = DPA_PTP_PROT_IPV6;
3073 + break;
3074 + case ETH_P_1588:
3075 + ptp_data->ident.netw_prot = DPA_PTP_PROT_802_3;
3076 + break;
3077 + default:
3078 + return -EINVAL;
3079 + }
3080 +
3081 + if (!pskb_may_pull(skb, ptp_loc - skb->data + PTP_OFFS_SEQ_ID + 2))
3082 + return -EINVAL;
3083 +
3084 + ptp_data->ident.version = *(ptp_loc + PTP_OFFS_VER_PTP) & 0xf;
3085 + ptp_data->ident.msg_type = *(ptp_loc + PTP_OFFS_MSG_TYPE) & 0xf;
3086 + ptp_data->ident.seq_id = *((u16 *)(ptp_loc + PTP_OFFS_SEQ_ID));
3087 + memcpy(ptp_data->ident.snd_port_id, ptp_loc + PTP_OFFS_SRCPRTID,
3088 + DPA_PTP_SOURCE_PORT_LENGTH);
3089 +
3090 + nsec = dpa_get_timestamp_ns(priv, rx_tx, data);
3091 + mod = do_div(nsec, NANOSEC_PER_SECOND);
3092 + ptp_data->ts.sec = nsec;
3093 + ptp_data->ts.nsec = mod;
3094 +
3095 + return 0;
3096 +}
3097 +
3098 +void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
3099 + struct sk_buff *skb, void *data)
3100 +{
3101 + struct dpa_ptp_tsu *tsu = priv->tsu;
3102 + struct dpa_ptp_data ptp_tx_data;
3103 +
3104 + if (dpa_ptp_store_stamp(priv, skb, data, TX, &ptp_tx_data))
3105 + return;
3106 +
3107 + dpa_ptp_insert(&tsu->tx_timestamps, &ptp_tx_data);
3108 +}
3109 +
3110 +void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
3111 + struct sk_buff *skb, void *data)
3112 +{
3113 + struct dpa_ptp_tsu *tsu = priv->tsu;
3114 + struct dpa_ptp_data ptp_rx_data;
3115 +
3116 + if (dpa_ptp_store_stamp(priv, skb, data, RX, &ptp_rx_data))
3117 + return;
3118 +
3119 + dpa_ptp_insert(&tsu->rx_timestamps, &ptp_rx_data);
3120 +}
3121 +
3122 +static uint8_t dpa_get_tx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
3123 + struct dpa_ptp_ident *ident,
3124 + struct dpa_ptp_time *ts)
3125 +{
3126 + struct dpa_ptp_tsu *tsu = ptp_tsu;
3127 + struct dpa_ptp_time tmp;
3128 + int flag;
3129 +
3130 + flag = dpa_ptp_find_and_remove(&tsu->tx_timestamps, ident, &tmp);
3131 + if (!flag) {
3132 + ts->sec = tmp.sec;
3133 + ts->nsec = tmp.nsec;
3134 + return 0;
3135 + }
3136 +
3137 + return -1;
3138 +}
3139 +
3140 +static uint8_t dpa_get_rx_timestamp(struct dpa_ptp_tsu *ptp_tsu,
3141 + struct dpa_ptp_ident *ident,
3142 + struct dpa_ptp_time *ts)
3143 +{
3144 + struct dpa_ptp_tsu *tsu = ptp_tsu;
3145 + struct dpa_ptp_time tmp;
3146 + int flag;
3147 +
3148 + flag = dpa_ptp_find_and_remove(&tsu->rx_timestamps, ident, &tmp);
3149 + if (!flag) {
3150 + ts->sec = tmp.sec;
3151 + ts->nsec = tmp.nsec;
3152 + return 0;
3153 + }
3154 +
3155 + return -1;
3156 +}
3157 +
3158 +static void dpa_set_fiper_alarm(struct dpa_ptp_tsu *tsu,
3159 + struct dpa_ptp_time *cnt_time)
3160 +{
3161 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
3162 + u64 tmp, fiper;
3163 +
3164 + if (mac_dev->fm_rtc_disable)
3165 + mac_dev->fm_rtc_disable(get_fm_handle(tsu->dpa_priv->net_dev));
3166 +
3167 + /* TMR_FIPER1 will pulse every second after ALARM1 expired */
3168 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
3169 + fiper = NANOSEC_PER_SECOND - DPA_PTP_NOMINAL_FREQ_PERIOD_NS;
3170 + if (mac_dev->fm_rtc_set_alarm)
3171 + mac_dev->fm_rtc_set_alarm(get_fm_handle(tsu->dpa_priv->net_dev),
3172 + 0, tmp);
3173 + if (mac_dev->fm_rtc_set_fiper)
3174 + mac_dev->fm_rtc_set_fiper(get_fm_handle(tsu->dpa_priv->net_dev),
3175 + 0, fiper);
3176 +
3177 + if (mac_dev->fm_rtc_enable)
3178 + mac_dev->fm_rtc_enable(get_fm_handle(tsu->dpa_priv->net_dev));
3179 +}
3180 +
3181 +static void dpa_get_curr_cnt(struct dpa_ptp_tsu *tsu,
3182 + struct dpa_ptp_time *curr_time)
3183 +{
3184 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
3185 + u64 tmp;
3186 + u32 mod;
3187 +
3188 + if (mac_dev->fm_rtc_get_cnt)
3189 + mac_dev->fm_rtc_get_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
3190 + &tmp);
3191 +
3192 + mod = do_div(tmp, NANOSEC_PER_SECOND);
3193 + curr_time->sec = (u32)tmp;
3194 + curr_time->nsec = mod;
3195 +}
3196 +
3197 +static void dpa_set_1588cnt(struct dpa_ptp_tsu *tsu,
3198 + struct dpa_ptp_time *cnt_time)
3199 +{
3200 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
3201 + u64 tmp;
3202 +
3203 + tmp = (u64)cnt_time->sec * NANOSEC_PER_SECOND + (u64)cnt_time->nsec;
3204 +
3205 + if (mac_dev->fm_rtc_set_cnt)
3206 + mac_dev->fm_rtc_set_cnt(get_fm_handle(tsu->dpa_priv->net_dev),
3207 + tmp);
3208 +
3209 + /* Restart fiper two seconds later */
3210 + cnt_time->sec += 2;
3211 + cnt_time->nsec = 0;
3212 + dpa_set_fiper_alarm(tsu, cnt_time);
3213 +}
3214 +
3215 +static void dpa_get_drift(struct dpa_ptp_tsu *tsu, u32 *addend)
3216 +{
3217 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
3218 + u32 drift;
3219 +
3220 + if (mac_dev->fm_rtc_get_drift)
3221 + mac_dev->fm_rtc_get_drift(get_fm_handle(tsu->dpa_priv->net_dev),
3222 + &drift);
3223 +
3224 + *addend = drift;
3225 +}
3226 +
3227 +static void dpa_set_drift(struct dpa_ptp_tsu *tsu, u32 addend)
3228 +{
3229 + struct mac_device *mac_dev = tsu->dpa_priv->mac_dev;
3230 +
3231 + if (mac_dev->fm_rtc_set_drift)
3232 + mac_dev->fm_rtc_set_drift(get_fm_handle(tsu->dpa_priv->net_dev),
3233 + addend);
3234 +}
3235 +
3236 +static void dpa_flush_timestamp(struct dpa_ptp_tsu *tsu)
3237 +{
3238 + dpa_ptp_reset_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
3239 + dpa_ptp_reset_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
3240 +}
3241 +
3242 +int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd)
3243 +{
3244 + struct dpa_priv_s *priv = netdev_priv(dev);
3245 + struct dpa_ptp_tsu *tsu = priv->tsu;
3246 + struct mac_device *mac_dev = priv->mac_dev;
3247 + struct dpa_ptp_data ptp_data;
3248 + struct dpa_ptp_data *ptp_data_user;
3249 + struct dpa_ptp_time act_time;
3250 + u32 addend;
3251 + int retval = 0;
3252 +
3253 + if (!tsu || !tsu->valid)
3254 + return -ENODEV;
3255 +
3256 + switch (cmd) {
3257 + case PTP_ENBL_TXTS_IOCTL:
3258 + tsu->hwts_tx_en_ioctl = 1;
3259 + if (mac_dev->fm_rtc_enable)
3260 + mac_dev->fm_rtc_enable(get_fm_handle(dev));
3261 + if (mac_dev->ptp_enable)
3262 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
3263 + break;
3264 + case PTP_DSBL_TXTS_IOCTL:
3265 + tsu->hwts_tx_en_ioctl = 0;
3266 + if (mac_dev->fm_rtc_disable)
3267 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
3268 + if (mac_dev->ptp_disable)
3269 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
3270 + break;
3271 + case PTP_ENBL_RXTS_IOCTL:
3272 + tsu->hwts_rx_en_ioctl = 1;
3273 + break;
3274 + case PTP_DSBL_RXTS_IOCTL:
3275 + tsu->hwts_rx_en_ioctl = 0;
3276 + break;
3277 + case PTP_GET_RX_TIMESTAMP:
3278 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
3279 + if (copy_from_user(&ptp_data.ident,
3280 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
3281 + return -EINVAL;
3282 +
3283 + if (dpa_get_rx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
3284 + return -EAGAIN;
3285 +
3286 + if (copy_to_user((void __user *)&ptp_data_user->ts,
3287 + &ptp_data.ts, sizeof(ptp_data.ts)))
3288 + return -EFAULT;
3289 + break;
3290 + case PTP_GET_TX_TIMESTAMP:
3291 + ptp_data_user = (struct dpa_ptp_data *)ifr->ifr_data;
3292 + if (copy_from_user(&ptp_data.ident,
3293 + &ptp_data_user->ident, sizeof(ptp_data.ident)))
3294 + return -EINVAL;
3295 +
3296 + if (dpa_get_tx_timestamp(tsu, &ptp_data.ident, &ptp_data.ts))
3297 + return -EAGAIN;
3298 +
3299 + if (copy_to_user((void __user *)&ptp_data_user->ts,
3300 + &ptp_data.ts, sizeof(ptp_data.ts)))
3301 + return -EFAULT;
3302 + break;
3303 + case PTP_GET_TIME:
3304 + dpa_get_curr_cnt(tsu, &act_time);
3305 + if (copy_to_user(ifr->ifr_data, &act_time, sizeof(act_time)))
3306 + return -EFAULT;
3307 + break;
3308 + case PTP_SET_TIME:
3309 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
3310 + return -EINVAL;
3311 + dpa_set_1588cnt(tsu, &act_time);
3312 + break;
3313 + case PTP_GET_ADJ:
3314 + dpa_get_drift(tsu, &addend);
3315 + if (copy_to_user(ifr->ifr_data, &addend, sizeof(addend)))
3316 + return -EFAULT;
3317 + break;
3318 + case PTP_SET_ADJ:
3319 + if (copy_from_user(&addend, ifr->ifr_data, sizeof(addend)))
3320 + return -EINVAL;
3321 + dpa_set_drift(tsu, addend);
3322 + break;
3323 + case PTP_SET_FIPER_ALARM:
3324 + if (copy_from_user(&act_time, ifr->ifr_data, sizeof(act_time)))
3325 + return -EINVAL;
3326 + dpa_set_fiper_alarm(tsu, &act_time);
3327 + break;
3328 + case PTP_CLEANUP_TS:
3329 + dpa_flush_timestamp(tsu);
3330 + break;
3331 + default:
3332 + return -EINVAL;
3333 + }
3334 +
3335 + return retval;
3336 +}
3337 +
3338 +int dpa_ptp_init(struct dpa_priv_s *priv)
3339 +{
3340 + struct dpa_ptp_tsu *tsu;
3341 +
3342 + /* Allocate memory for PTP structure */
3343 + tsu = kzalloc(sizeof(struct dpa_ptp_tsu), GFP_KERNEL);
3344 + if (!tsu)
3345 + return -ENOMEM;
3346 +
3347 + tsu->valid = TRUE;
3348 + tsu->dpa_priv = priv;
3349 +
3350 + dpa_ptp_init_circ(&tsu->rx_timestamps, DEFAULT_PTP_RX_BUF_SZ);
3351 + dpa_ptp_init_circ(&tsu->tx_timestamps, DEFAULT_PTP_TX_BUF_SZ);
3352 +
3353 + priv->tsu = tsu;
3354 +
3355 + return 0;
3356 +}
3357 +EXPORT_SYMBOL(dpa_ptp_init);
3358 +
3359 +void dpa_ptp_cleanup(struct dpa_priv_s *priv)
3360 +{
3361 + struct dpa_ptp_tsu *tsu = priv->tsu;
3362 +
3363 + tsu->valid = FALSE;
3364 + vfree(tsu->rx_timestamps.circ_buf.buf);
3365 + vfree(tsu->tx_timestamps.circ_buf.buf);
3366 +
3367 + kfree(tsu);
3368 +}
3369 +EXPORT_SYMBOL(dpa_ptp_cleanup);
3370 --- /dev/null
3371 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_1588.h
3372 @@ -0,0 +1,138 @@
3373 +/* Copyright (C) 2011 Freescale Semiconductor, Inc.
3374 + *
3375 + * This program is free software; you can redistribute it and/or modify
3376 + * it under the terms of the GNU General Public License as published by
3377 + * the Free Software Foundation; either version 2 of the License, or
3378 + * (at your option) any later version.
3379 + *
3380 + * This program is distributed in the hope that it will be useful,
3381 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3382 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3383 + * GNU General Public License for more details.
3384 + *
3385 + * You should have received a copy of the GNU General Public License along
3386 + * with this program; if not, write to the Free Software Foundation, Inc.,
3387 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3388 + *
3389 + */
3390 +#ifndef __DPAA_1588_H__
3391 +#define __DPAA_1588_H__
3392 +
3393 +#include <linux/netdevice.h>
3394 +#include <linux/etherdevice.h>
3395 +#include <linux/circ_buf.h>
3396 +#include <linux/fsl_qman.h>
3397 +
3398 +#define DEFAULT_PTP_RX_BUF_SZ 256
3399 +#define DEFAULT_PTP_TX_BUF_SZ 256
3400 +
3401 +/* 1588 private ioctl calls */
3402 +#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
3403 +#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
3404 +#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
3405 +#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
3406 +#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
3407 +#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
3408 +#define PTP_SET_TIME (SIOCDEVPRIVATE + 6)
3409 +#define PTP_GET_TIME (SIOCDEVPRIVATE + 7)
3410 +#define PTP_SET_FIPER_ALARM (SIOCDEVPRIVATE + 8)
3411 +#define PTP_SET_ADJ (SIOCDEVPRIVATE + 9)
3412 +#define PTP_GET_ADJ (SIOCDEVPRIVATE + 10)
3413 +#define PTP_CLEANUP_TS (SIOCDEVPRIVATE + 11)
3414 +
3415 +/* PTP V2 message type */
3416 +enum {
3417 + PTP_MSGTYPE_SYNC = 0x0,
3418 + PTP_MSGTYPE_DELREQ = 0x1,
3419 + PTP_MSGTYPE_PDELREQ = 0x2,
3420 + PTP_MSGTYPE_PDELRESP = 0x3,
3421 + PTP_MSGTYPE_FLWUP = 0x8,
3422 + PTP_MSGTYPE_DELRESP = 0x9,
3423 + PTP_MSGTYPE_PDELRES_FLWUP = 0xA,
3424 + PTP_MSGTYPE_ANNOUNCE = 0xB,
3425 + PTP_MSGTYPE_SGNLNG = 0xC,
3426 + PTP_MSGTYPE_MNGMNT = 0xD,
3427 +};
3428 +
3429 +/* Byte offset of data in the PTP V2 headers */
3430 +#define PTP_OFFS_MSG_TYPE 0
3431 +#define PTP_OFFS_VER_PTP 1
3432 +#define PTP_OFFS_MSG_LEN 2
3433 +#define PTP_OFFS_DOM_NMB 4
3434 +#define PTP_OFFS_FLAGS 6
3435 +#define PTP_OFFS_CORFIELD 8
3436 +#define PTP_OFFS_SRCPRTID 20
3437 +#define PTP_OFFS_SEQ_ID 30
3438 +#define PTP_OFFS_CTRL 32
3439 +#define PTP_OFFS_LOGMEAN 33
3440 +
3441 +#define PTP_IP_OFFS 14
3442 +#define PTP_UDP_OFFS 34
3443 +#define PTP_HEADER_OFFS 42
3444 +#define PTP_MSG_TYPE_OFFS (PTP_HEADER_OFFS + PTP_OFFS_MSG_TYPE)
3445 +#define PTP_SPORT_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SRCPRTID)
3446 +#define PTP_SEQ_ID_OFFS (PTP_HEADER_OFFS + PTP_OFFS_SEQ_ID)
3447 +#define PTP_CTRL_OFFS (PTP_HEADER_OFFS + PTP_OFFS_CTRL)
3448 +
3449 +/* 1588-2008 network protocol enumeration values */
3450 +#define DPA_PTP_PROT_IPV4 1
3451 +#define DPA_PTP_PROT_IPV6 2
3452 +#define DPA_PTP_PROT_802_3 3
3453 +#define DPA_PTP_PROT_DONTCARE 0xFFFF
3454 +
3455 +#define DPA_PTP_SOURCE_PORT_LENGTH 10
3456 +#define DPA_PTP_HEADER_SZE 34
3457 +#define DPA_ETYPE_LEN 2
3458 +#define DPA_VLAN_TAG_LEN 4
3459 +#define NANOSEC_PER_SECOND 1000000000
3460 +
3461 +/* The threshold between the current found one and the oldest one */
3462 +#define TS_ACCUMULATION_THRESHOLD 50
3463 +
3464 +/* Struct needed to identify a timestamp */
3465 +struct dpa_ptp_ident {
3466 + u8 version;
3467 + u8 msg_type;
3468 + u16 netw_prot;
3469 + u16 seq_id;
3470 + u8 snd_port_id[DPA_PTP_SOURCE_PORT_LENGTH];
3471 +};
3472 +
3473 +/* Timestamp format in 1588-2008 */
3474 +struct dpa_ptp_time {
3475 + u64 sec; /* just 48 bit used */
3476 + u32 nsec;
3477 +};
3478 +
3479 +/* needed for timestamp data over ioctl */
3480 +struct dpa_ptp_data {
3481 + struct dpa_ptp_ident ident;
3482 + struct dpa_ptp_time ts;
3483 +};
3484 +
3485 +struct dpa_ptp_circ_buf {
3486 + struct circ_buf circ_buf;
3487 + u32 size;
3488 + spinlock_t ptp_lock;
3489 +};
3490 +
3491 +/* PTP TSU control structure */
3492 +struct dpa_ptp_tsu {
3493 + struct dpa_priv_s *dpa_priv;
3494 + bool valid;
3495 + struct dpa_ptp_circ_buf rx_timestamps;
3496 + struct dpa_ptp_circ_buf tx_timestamps;
3497 +
3498 + /* HW timestamping over ioctl enabled flag */
3499 + int hwts_tx_en_ioctl;
3500 + int hwts_rx_en_ioctl;
3501 +};
3502 +
3503 +extern int dpa_ptp_init(struct dpa_priv_s *priv);
3504 +extern void dpa_ptp_cleanup(struct dpa_priv_s *priv);
3505 +extern void dpa_ptp_store_txstamp(const struct dpa_priv_s *priv,
3506 + struct sk_buff *skb, void *data);
3507 +extern void dpa_ptp_store_rxstamp(const struct dpa_priv_s *priv,
3508 + struct sk_buff *skb, void *data);
3509 +extern int dpa_ioctl_1588(struct net_device *dev, struct ifreq *ifr, int cmd);
3510 +#endif
3511 --- /dev/null
3512 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.c
3513 @@ -0,0 +1,180 @@
3514 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
3515 + *
3516 + * Redistribution and use in source and binary forms, with or without
3517 + * modification, are permitted provided that the following conditions are met:
3518 + * * Redistributions of source code must retain the above copyright
3519 + * notice, this list of conditions and the following disclaimer.
3520 + * * Redistributions in binary form must reproduce the above copyright
3521 + * notice, this list of conditions and the following disclaimer in the
3522 + * documentation and/or other materials provided with the distribution.
3523 + * * Neither the name of Freescale Semiconductor nor the
3524 + * names of its contributors may be used to endorse or promote products
3525 + * derived from this software without specific prior written permission.
3526 + *
3527 + *
3528 + * ALTERNATIVELY, this software may be distributed under the terms of the
3529 + * GNU General Public License ("GPL") as published by the Free Software
3530 + * Foundation, either version 2 of that License or (at your option) any
3531 + * later version.
3532 + *
3533 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3534 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3535 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3536 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3537 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3538 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3539 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3540 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3541 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3542 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3543 + */
3544 +
3545 +#include <linux/module.h>
3546 +#include <linux/fsl_qman.h> /* struct qm_mcr_querycgr */
3547 +#include <linux/debugfs.h>
3548 +#include "dpaa_debugfs.h"
3549 +#include "dpaa_eth.h" /* struct dpa_priv_s, dpa_percpu_priv_s, dpa_bp */
3550 +
3551 +#define DPA_DEBUGFS_DESCRIPTION "FSL DPAA Ethernet debugfs entries"
3552 +#define DPA_ETH_DEBUGFS_ROOT "fsl_dpa"
3553 +
3554 +static struct dentry *dpa_debugfs_root;
3555 +
3556 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file);
3557 +static ssize_t dpa_loop_write(struct file *f,
3558 + const char __user *buf, size_t count, loff_t *off);
3559 +
3560 +static const struct file_operations dpa_debugfs_lp_fops = {
3561 + .open = dpa_debugfs_loop_open,
3562 + .write = dpa_loop_write,
3563 + .read = seq_read,
3564 + .llseek = seq_lseek,
3565 + .release = single_release,
3566 +};
3567 +
3568 +static int dpa_debugfs_loop_show(struct seq_file *file, void *offset)
3569 +{
3570 + struct dpa_priv_s *priv;
3571 +
3572 + BUG_ON(offset == NULL);
3573 +
3574 + priv = netdev_priv((struct net_device *)file->private);
3575 + seq_printf(file, "%d->%d\n", priv->loop_id, priv->loop_to);
3576 +
3577 + return 0;
3578 +}
3579 +
3580 +static int user_input_convert(const char __user *user_buf, size_t count,
3581 + long *val)
3582 +{
3583 + char buf[12];
3584 +
3585 + if (count > sizeof(buf) - 1)
3586 + return -EINVAL;
3587 + if (copy_from_user(buf, user_buf, count))
3588 + return -EFAULT;
3589 + buf[count] = '\0';
3590 + if (kstrtol(buf, 0, val))
3591 + return -EINVAL;
3592 + return 0;
3593 +}
3594 +
3595 +static ssize_t dpa_loop_write(struct file *f,
3596 + const char __user *buf, size_t count, loff_t *off)
3597 +{
3598 + struct dpa_priv_s *priv;
3599 + struct net_device *netdev;
3600 + struct seq_file *sf;
3601 + int ret;
3602 + long val;
3603 +
3604 + ret = user_input_convert(buf, count, &val);
3605 + if (ret)
3606 + return ret;
3607 +
3608 + sf = (struct seq_file *)f->private_data;
3609 + netdev = (struct net_device *)sf->private;
3610 + priv = netdev_priv(netdev);
3611 +
3612 + priv->loop_to = ((val < 0) || (val > 20)) ? -1 : val;
3613 +
3614 + return count;
3615 +}
3616 +
3617 +static int __cold dpa_debugfs_loop_open(struct inode *inode, struct file *file)
3618 +{
3619 + int _errno;
3620 + const struct net_device *net_dev;
3621 +
3622 + _errno = single_open(file, dpa_debugfs_loop_show, inode->i_private);
3623 + if (unlikely(_errno < 0)) {
3624 + net_dev = (struct net_device *)inode->i_private;
3625 +
3626 + if (netif_msg_drv((struct dpa_priv_s *)netdev_priv(net_dev)))
3627 + netdev_err(net_dev, "single_open() = %d\n",
3628 + _errno);
3629 + }
3630 +
3631 + return _errno;
3632 +}
3633 +
3634 +
3635 +int dpa_netdev_debugfs_create(struct net_device *net_dev)
3636 +{
3637 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3638 + static int cnt;
3639 + char loop_file_name[100];
3640 +
3641 + if (unlikely(dpa_debugfs_root == NULL)) {
3642 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): \t%s\n",
3643 + KBUILD_BASENAME".c", __LINE__, __func__,
3644 + "root debugfs missing, possible module ordering issue");
3645 + return -ENOMEM;
3646 + }
3647 +
3648 + sprintf(loop_file_name, "eth%d_loop", ++cnt);
3649 + priv->debugfs_loop_file = debugfs_create_file(loop_file_name,
3650 + S_IRUGO,
3651 + dpa_debugfs_root,
3652 + net_dev,
3653 + &dpa_debugfs_lp_fops);
3654 + if (unlikely(priv->debugfs_loop_file == NULL)) {
3655 + netdev_err(net_dev, "debugfs_create_file(%s/%s)",
3656 + dpa_debugfs_root->d_iname,
3657 + loop_file_name);
3658 +
3659 + return -ENOMEM;
3660 + }
3661 + return 0;
3662 +}
3663 +
3664 +void dpa_netdev_debugfs_remove(struct net_device *net_dev)
3665 +{
3666 + struct dpa_priv_s *priv = netdev_priv(net_dev);
3667 +
3668 + debugfs_remove(priv->debugfs_loop_file);
3669 +}
3670 +
3671 +int __init dpa_debugfs_module_init(void)
3672 +{
3673 + int _errno = 0;
3674 +
3675 + pr_info(KBUILD_MODNAME ": " DPA_DEBUGFS_DESCRIPTION "\n");
3676 +
3677 + dpa_debugfs_root = debugfs_create_dir(DPA_ETH_DEBUGFS_ROOT, NULL);
3678 +
3679 + if (unlikely(dpa_debugfs_root == NULL)) {
3680 + _errno = -ENOMEM;
3681 + pr_err(KBUILD_MODNAME ": %s:%hu:%s():\n",
3682 + KBUILD_BASENAME".c", __LINE__, __func__);
3683 + pr_err("\tdebugfs_create_dir(%s/"KBUILD_MODNAME") = %d\n",
3684 + DPA_ETH_DEBUGFS_ROOT, _errno);
3685 + }
3686 +
3687 + return _errno;
3688 +}
3689 +
3690 +void __exit dpa_debugfs_module_exit(void)
3691 +{
3692 + debugfs_remove(dpa_debugfs_root);
3693 +}
3694 --- /dev/null
3695 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_debugfs.h
3696 @@ -0,0 +1,43 @@
3697 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
3698 + *
3699 + * Redistribution and use in source and binary forms, with or without
3700 + * modification, are permitted provided that the following conditions are met:
3701 + * * Redistributions of source code must retain the above copyright
3702 + * notice, this list of conditions and the following disclaimer.
3703 + * * Redistributions in binary form must reproduce the above copyright
3704 + * notice, this list of conditions and the following disclaimer in the
3705 + * documentation and/or other materials provided with the distribution.
3706 + * * Neither the name of Freescale Semiconductor nor the
3707 + * names of its contributors may be used to endorse or promote products
3708 + * derived from this software without specific prior written permission.
3709 + *
3710 + *
3711 + * ALTERNATIVELY, this software may be distributed under the terms of the
3712 + * GNU General Public License ("GPL") as published by the Free Software
3713 + * Foundation, either version 2 of that License or (at your option) any
3714 + * later version.
3715 + *
3716 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3717 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3718 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3719 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3720 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3721 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3722 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3723 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3724 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3725 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3726 + */
3727 +
3728 +#ifndef DPAA_DEBUGFS_H_
3729 +#define DPAA_DEBUGFS_H_
3730 +
3731 +#include <linux/netdevice.h>
3732 +#include <linux/dcache.h> /* struct dentry needed in dpaa_eth.h */
3733 +
3734 +int dpa_netdev_debugfs_create(struct net_device *net_dev);
3735 +void dpa_netdev_debugfs_remove(struct net_device *net_dev);
3736 +int __init dpa_debugfs_module_init(void);
3737 +void __exit dpa_debugfs_module_exit(void);
3738 +
3739 +#endif /* DPAA_DEBUGFS_H_ */
3740 --- /dev/null
3741 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.c
3742 @@ -0,0 +1,1223 @@
3743 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
3744 + *
3745 + * Redistribution and use in source and binary forms, with or without
3746 + * modification, are permitted provided that the following conditions are met:
3747 + * * Redistributions of source code must retain the above copyright
3748 + * notice, this list of conditions and the following disclaimer.
3749 + * * Redistributions in binary form must reproduce the above copyright
3750 + * notice, this list of conditions and the following disclaimer in the
3751 + * documentation and/or other materials provided with the distribution.
3752 + * * Neither the name of Freescale Semiconductor nor the
3753 + * names of its contributors may be used to endorse or promote products
3754 + * derived from this software without specific prior written permission.
3755 + *
3756 + *
3757 + * ALTERNATIVELY, this software may be distributed under the terms of the
3758 + * GNU General Public License ("GPL") as published by the Free Software
3759 + * Foundation, either version 2 of that License or (at your option) any
3760 + * later version.
3761 + *
3762 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
3763 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3764 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3765 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
3766 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
3767 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
3768 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3769 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3770 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3771 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3772 + */
3773 +
3774 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
3775 +#define pr_fmt(fmt) \
3776 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
3777 + KBUILD_BASENAME".c", __LINE__, __func__
3778 +#else
3779 +#define pr_fmt(fmt) \
3780 + KBUILD_MODNAME ": " fmt
3781 +#endif
3782 +
3783 +#include <linux/init.h>
3784 +#include <linux/module.h>
3785 +#include <linux/of_mdio.h>
3786 +#include <linux/of_net.h>
3787 +#include <linux/kthread.h>
3788 +#include <linux/io.h>
3789 +#include <linux/if_arp.h> /* arp_hdr_len() */
3790 +#include <linux/if_vlan.h> /* VLAN_HLEN */
3791 +#include <linux/icmp.h> /* struct icmphdr */
3792 +#include <linux/ip.h> /* struct iphdr */
3793 +#include <linux/ipv6.h> /* struct ipv6hdr */
3794 +#include <linux/udp.h> /* struct udphdr */
3795 +#include <linux/tcp.h> /* struct tcphdr */
3796 +#include <linux/net.h> /* net_ratelimit() */
3797 +#include <linux/if_ether.h> /* ETH_P_IP and ETH_P_IPV6 */
3798 +#include <linux/highmem.h>
3799 +#include <linux/percpu.h>
3800 +#include <linux/dma-mapping.h>
3801 +#include <linux/fsl_bman.h>
3802 +#ifdef CONFIG_SOC_BUS
3803 +#include <linux/sys_soc.h> /* soc_device_match */
3804 +#endif
3805 +
3806 +#include "fsl_fman.h"
3807 +#include "fm_ext.h"
3808 +#include "fm_port_ext.h"
3809 +
3810 +#include "mac.h"
3811 +#include "dpaa_eth.h"
3812 +#include "dpaa_eth_common.h"
3813 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3814 +#include "dpaa_debugfs.h"
3815 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
3816 +
3817 +/* CREATE_TRACE_POINTS only needs to be defined once. Other dpa files
3818 + * using trace events only need to #include <trace/events/sched.h>
3819 + */
3820 +#define CREATE_TRACE_POINTS
3821 +#include "dpaa_eth_trace.h"
3822 +
3823 +#define DPA_NAPI_WEIGHT 64
3824 +
3825 +/* Valid checksum indication */
3826 +#define DPA_CSUM_VALID 0xFFFF
3827 +
3828 +#define DPA_DESCRIPTION "FSL DPAA Ethernet driver"
3829 +
3830 +MODULE_LICENSE("Dual BSD/GPL");
3831 +
3832 +MODULE_AUTHOR("Andy Fleming <afleming@freescale.com>");
3833 +
3834 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
3835 +
3836 +static uint8_t debug = -1;
3837 +module_param(debug, byte, S_IRUGO);
3838 +MODULE_PARM_DESC(debug, "Module/Driver verbosity level");
3839 +
3840 +/* This has to work in tandem with the DPA_CS_THRESHOLD_xxx values. */
3841 +static uint16_t tx_timeout = 1000;
3842 +module_param(tx_timeout, ushort, S_IRUGO);
3843 +MODULE_PARM_DESC(tx_timeout, "The Tx timeout in ms");
3844 +
3845 +static const char rtx[][3] = {
3846 + [RX] = "RX",
3847 + [TX] = "TX"
3848 +};
3849 +
3850 +#ifndef CONFIG_PPC
3851 +bool dpaa_errata_a010022;
3852 +EXPORT_SYMBOL(dpaa_errata_a010022);
3853 +#endif
3854 +
3855 +/* BM */
3856 +
3857 +#define DPAA_ETH_MAX_PAD (L1_CACHE_BYTES * 8)
3858 +
3859 +static uint8_t dpa_priv_common_bpid;
3860 +
3861 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
3862 +struct net_device *dpa_loop_netdevs[20];
3863 +#endif
3864 +
3865 +#ifdef CONFIG_PM
3866 +
3867 +static int dpaa_suspend(struct device *dev)
3868 +{
3869 + struct net_device *net_dev;
3870 + struct dpa_priv_s *priv;
3871 + struct mac_device *mac_dev;
3872 + int err = 0;
3873 +
3874 + net_dev = dev_get_drvdata(dev);
3875 +
3876 + if (net_dev->flags & IFF_UP) {
3877 + priv = netdev_priv(net_dev);
3878 + mac_dev = priv->mac_dev;
3879 +
3880 + if (priv->wol & DPAA_WOL_MAGIC) {
3881 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
3882 + priv->mac_dev->get_mac_handle(mac_dev), true);
3883 + if (err) {
3884 + netdev_err(net_dev, "set_wol() = %d\n", err);
3885 + goto set_wol_failed;
3886 + }
3887 + }
3888 +
3889 + err = fm_port_suspend(mac_dev->port_dev[RX]);
3890 + if (err) {
3891 + netdev_err(net_dev, "fm_port_suspend(RX) = %d\n", err);
3892 + goto rx_port_suspend_failed;
3893 + }
3894 +
3895 + err = fm_port_suspend(mac_dev->port_dev[TX]);
3896 + if (err) {
3897 + netdev_err(net_dev, "fm_port_suspend(TX) = %d\n", err);
3898 + goto tx_port_suspend_failed;
3899 + }
3900 + }
3901 +
3902 + return 0;
3903 +
3904 +tx_port_suspend_failed:
3905 + fm_port_resume(mac_dev->port_dev[RX]);
3906 +rx_port_suspend_failed:
3907 + if (priv->wol & DPAA_WOL_MAGIC) {
3908 + priv->mac_dev->set_wol(mac_dev->port_dev[RX],
3909 + priv->mac_dev->get_mac_handle(mac_dev), false);
3910 + }
3911 +set_wol_failed:
3912 + return err;
3913 +}
3914 +
3915 +static int dpaa_resume(struct device *dev)
3916 +{
3917 + struct net_device *net_dev;
3918 + struct dpa_priv_s *priv;
3919 + struct mac_device *mac_dev;
3920 + int err = 0;
3921 +
3922 + net_dev = dev_get_drvdata(dev);
3923 +
3924 + if (net_dev->flags & IFF_UP) {
3925 + priv = netdev_priv(net_dev);
3926 + mac_dev = priv->mac_dev;
3927 +
3928 + err = fm_mac_resume(mac_dev->get_mac_handle(mac_dev));
3929 + if (err) {
3930 + netdev_err(net_dev, "fm_mac_resume = %d\n", err);
3931 + goto resume_failed;
3932 + }
3933 +
3934 + err = fm_port_resume(mac_dev->port_dev[TX]);
3935 + if (err) {
3936 + netdev_err(net_dev, "fm_port_resume(TX) = %d\n", err);
3937 + goto resume_failed;
3938 + }
3939 +
3940 + err = fm_port_resume(mac_dev->port_dev[RX]);
3941 + if (err) {
3942 + netdev_err(net_dev, "fm_port_resume(RX) = %d\n", err);
3943 + goto resume_failed;
3944 + }
3945 +
3946 + if (priv->wol & DPAA_WOL_MAGIC) {
3947 + err = priv->mac_dev->set_wol(mac_dev->port_dev[RX],
3948 + priv->mac_dev->get_mac_handle(mac_dev), false);
3949 + if (err) {
3950 + netdev_err(net_dev, "set_wol() = %d\n", err);
3951 + goto resume_failed;
3952 + }
3953 + }
3954 + }
3955 +
3956 + return 0;
3957 +
3958 +resume_failed:
3959 + return err;
3960 +}
3961 +
3962 +static const struct dev_pm_ops dpaa_pm_ops = {
3963 + .suspend = dpaa_suspend,
3964 + .resume = dpaa_resume,
3965 +};
3966 +
3967 +#define DPAA_PM_OPS (&dpaa_pm_ops)
3968 +
3969 +#else /* CONFIG_PM */
3970 +
3971 +#define DPAA_PM_OPS NULL
3972 +
3973 +#endif /* CONFIG_PM */
3974 +
3975 +/* Checks whether the checksum field in Parse Results array is valid
3976 + * (equals 0xFFFF) and increments the .cse counter otherwise
3977 + */
3978 +static inline void
3979 +dpa_csum_validation(const struct dpa_priv_s *priv,
3980 + struct dpa_percpu_priv_s *percpu_priv,
3981 + const struct qm_fd *fd)
3982 +{
3983 + dma_addr_t addr = qm_fd_addr(fd);
3984 + struct dpa_bp *dpa_bp = priv->dpa_bp;
3985 + void *frm = phys_to_virt(addr);
3986 + fm_prs_result_t *parse_result;
3987 +
3988 + if (unlikely(!frm))
3989 + return;
3990 +
3991 + dma_sync_single_for_cpu(dpa_bp->dev, addr, DPA_RX_PRIV_DATA_SIZE +
3992 + DPA_PARSE_RESULTS_SIZE, DMA_BIDIRECTIONAL);
3993 +
3994 + parse_result = (fm_prs_result_t *)(frm + DPA_RX_PRIV_DATA_SIZE);
3995 +
3996 + if (parse_result->cksum != DPA_CSUM_VALID)
3997 + percpu_priv->rx_errors.cse++;
3998 +}
3999 +
4000 +static void _dpa_rx_error(struct net_device *net_dev,
4001 + const struct dpa_priv_s *priv,
4002 + struct dpa_percpu_priv_s *percpu_priv,
4003 + const struct qm_fd *fd,
4004 + u32 fqid)
4005 +{
4006 + /* limit common, possibly innocuous Rx FIFO Overflow errors'
4007 + * interference with zero-loss convergence benchmark results.
4008 + */
4009 + if (likely(fd->status & FM_FD_STAT_ERR_PHYSICAL))
4010 + pr_warn_once("fsl-dpa: non-zero error counters in fman statistics (sysfs)\n");
4011 + else
4012 + if (netif_msg_hw(priv) && net_ratelimit())
4013 + netdev_dbg(net_dev, "Err FD status = 0x%08x\n",
4014 + fd->status & FM_FD_STAT_RX_ERRORS);
4015 +#ifdef CONFIG_FSL_DPAA_HOOKS
4016 + if (dpaa_eth_hooks.rx_error &&
4017 + dpaa_eth_hooks.rx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
4018 + /* it's up to the hook to perform resource cleanup */
4019 + return;
4020 +#endif
4021 + percpu_priv->stats.rx_errors++;
4022 +
4023 + if (fd->status & FM_PORT_FRM_ERR_DMA)
4024 + percpu_priv->rx_errors.dme++;
4025 + if (fd->status & FM_PORT_FRM_ERR_PHYSICAL)
4026 + percpu_priv->rx_errors.fpe++;
4027 + if (fd->status & FM_PORT_FRM_ERR_SIZE)
4028 + percpu_priv->rx_errors.fse++;
4029 + if (fd->status & FM_PORT_FRM_ERR_PRS_HDR_ERR)
4030 + percpu_priv->rx_errors.phe++;
4031 + if (fd->status & FM_FD_STAT_L4CV)
4032 + dpa_csum_validation(priv, percpu_priv, fd);
4033 +
4034 + dpa_fd_release(net_dev, fd);
4035 +}
4036 +
4037 +static void _dpa_tx_error(struct net_device *net_dev,
4038 + const struct dpa_priv_s *priv,
4039 + struct dpa_percpu_priv_s *percpu_priv,
4040 + const struct qm_fd *fd,
4041 + u32 fqid)
4042 +{
4043 + struct sk_buff *skb;
4044 +
4045 + if (netif_msg_hw(priv) && net_ratelimit())
4046 + netdev_warn(net_dev, "FD status = 0x%08x\n",
4047 + fd->status & FM_FD_STAT_TX_ERRORS);
4048 +#ifdef CONFIG_FSL_DPAA_HOOKS
4049 + if (dpaa_eth_hooks.tx_error &&
4050 + dpaa_eth_hooks.tx_error(net_dev, fd, fqid) == DPAA_ETH_STOLEN)
4051 + /* now the hook must ensure proper cleanup */
4052 + return;
4053 +#endif
4054 + percpu_priv->stats.tx_errors++;
4055 +
4056 + /* If we intended the buffers from this frame to go into the bpools
4057 + * when the FMan transmit was done, we need to put it in manually.
4058 + */
4059 + if (fd->bpid != 0xff) {
4060 + dpa_fd_release(net_dev, fd);
4061 + return;
4062 + }
4063 +
4064 + skb = _dpa_cleanup_tx_fd(priv, fd);
4065 + dev_kfree_skb(skb);
4066 +}
4067 +
4068 +/* Helper function to factor out frame validation logic on all Rx paths. Its
4069 + * purpose is to extract from the Parse Results structure information about
4070 + * the integrity of the frame, its checksum, the length of the parsed headers
4071 + * and whether the frame is suitable for GRO.
4072 + *
4073 + * Assumes no parser errors, since any error frame is dropped before this
4074 + * function is called.
4075 + *
4076 + * @skb will have its ip_summed field overwritten;
4077 + * @use_gro will only be written with 0, if the frame is definitely not
4078 + * GRO-able; otherwise, it will be left unchanged;
4079 + * @hdr_size will be written with a safe value, at least the size of the
4080 + * headers' length.
4081 + */
4082 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
4083 + const struct qm_fd *fd,
4084 + struct sk_buff *skb, int *use_gro)
4085 +{
4086 + if (fd->status & FM_FD_STAT_L4CV) {
4087 + /* The parser has run and performed L4 checksum validation.
4088 + * We know there were no parser errors (and implicitly no
4089 + * L4 csum error), otherwise we wouldn't be here.
4090 + */
4091 + skb->ip_summed = CHECKSUM_UNNECESSARY;
4092 +
4093 + /* Don't go through GRO for certain types of traffic that
4094 + * we know are not GRO-able, such as dgram-based protocols.
4095 + * In the worst-case scenarios, such as small-pkt terminating
4096 + * UDP, the extra GRO processing would be overkill.
4097 + *
4098 + * The only protocol the Parser supports that is also GRO-able
4099 + * is currently TCP.
4100 + */
4101 + if (!fm_l4_frame_is_tcp(parse_results))
4102 + *use_gro = 0;
4103 +
4104 + return;
4105 + }
4106 +
4107 + /* We're here because either the parser didn't run or the L4 checksum
4108 + * was not verified. This may include the case of a UDP frame with
4109 + * checksum zero or an L4 proto other than TCP/UDP
4110 + */
4111 + skb->ip_summed = CHECKSUM_NONE;
4112 +
4113 + /* Bypass GRO for unknown traffic or if no PCDs are applied */
4114 + *use_gro = 0;
4115 +}
4116 +
4117 +int dpaa_eth_poll(struct napi_struct *napi, int budget)
4118 +{
4119 + struct dpa_napi_portal *np =
4120 + container_of(napi, struct dpa_napi_portal, napi);
4121 +
4122 + int cleaned = qman_p_poll_dqrr(np->p, budget);
4123 +
4124 + if (cleaned < budget) {
4125 + int tmp;
4126 + napi_complete(napi);
4127 + tmp = qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
4128 + DPA_BUG_ON(tmp);
4129 + }
4130 +
4131 + return cleaned;
4132 +}
4133 +EXPORT_SYMBOL(dpaa_eth_poll);
4134 +
4135 +static void __hot _dpa_tx_conf(struct net_device *net_dev,
4136 + const struct dpa_priv_s *priv,
4137 + struct dpa_percpu_priv_s *percpu_priv,
4138 + const struct qm_fd *fd,
4139 + u32 fqid)
4140 +{
4141 + struct sk_buff *skb;
4142 +
4143 + /* do we need the timestamp for the error frames? */
4144 +
4145 + if (unlikely(fd->status & FM_FD_STAT_TX_ERRORS) != 0) {
4146 + if (netif_msg_hw(priv) && net_ratelimit())
4147 + netdev_warn(net_dev, "FD status = 0x%08x\n",
4148 + fd->status & FM_FD_STAT_TX_ERRORS);
4149 +
4150 + percpu_priv->stats.tx_errors++;
4151 + }
4152 +
4153 + /* hopefully we need not get the timestamp before the hook */
4154 +#ifdef CONFIG_FSL_DPAA_HOOKS
4155 + if (dpaa_eth_hooks.tx_confirm && dpaa_eth_hooks.tx_confirm(net_dev,
4156 + fd, fqid) == DPAA_ETH_STOLEN)
4157 + /* it's the hook that must now perform cleanup */
4158 + return;
4159 +#endif
4160 + /* This might not perfectly reflect the reality, if the core dequeuing
4161 + * the Tx confirmation is different from the one that did the enqueue,
4162 + * but at least it'll show up in the total count.
4163 + */
4164 + percpu_priv->tx_confirm++;
4165 +
4166 + skb = _dpa_cleanup_tx_fd(priv, fd);
4167 +
4168 + dev_kfree_skb(skb);
4169 +}
4170 +
4171 +enum qman_cb_dqrr_result
4172 +priv_rx_error_dqrr(struct qman_portal *portal,
4173 + struct qman_fq *fq,
4174 + const struct qm_dqrr_entry *dq)
4175 +{
4176 + struct net_device *net_dev;
4177 + struct dpa_priv_s *priv;
4178 + struct dpa_percpu_priv_s *percpu_priv;
4179 + int *count_ptr;
4180 +
4181 + net_dev = ((struct dpa_fq *)fq)->net_dev;
4182 + priv = netdev_priv(net_dev);
4183 +
4184 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
4185 + count_ptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
4186 +
4187 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
4188 + return qman_cb_dqrr_stop;
4189 +
4190 + if (unlikely(dpaa_eth_refill_bpools(priv->dpa_bp, count_ptr)))
4191 + /* Unable to refill the buffer pool due to insufficient
4192 + * system memory. Just release the frame back into the pool,
4193 + * otherwise we'll soon end up with an empty buffer pool.
4194 + */
4195 + dpa_fd_release(net_dev, &dq->fd);
4196 + else
4197 + _dpa_rx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
4198 +
4199 + return qman_cb_dqrr_consume;
4200 +}
4201 +
4202 +
4203 +enum qman_cb_dqrr_result __hot
4204 +priv_rx_default_dqrr(struct qman_portal *portal,
4205 + struct qman_fq *fq,
4206 + const struct qm_dqrr_entry *dq)
4207 +{
4208 + struct net_device *net_dev;
4209 + struct dpa_priv_s *priv;
4210 + struct dpa_percpu_priv_s *percpu_priv;
4211 + int *count_ptr;
4212 + struct dpa_bp *dpa_bp;
4213 +
4214 + net_dev = ((struct dpa_fq *)fq)->net_dev;
4215 + priv = netdev_priv(net_dev);
4216 + dpa_bp = priv->dpa_bp;
4217 +
4218 + /* Trace the Rx fd */
4219 + trace_dpa_rx_fd(net_dev, fq, &dq->fd);
4220 +
4221 + /* IRQ handler, non-migratable; safe to use raw_cpu_ptr here */
4222 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
4223 + count_ptr = raw_cpu_ptr(dpa_bp->percpu_count);
4224 +
4225 + if (unlikely(dpaa_eth_napi_schedule(percpu_priv, portal)))
4226 + return qman_cb_dqrr_stop;
4227 +
4228 + /* Vale of plenty: make sure we didn't run out of buffers */
4229 +
4230 + if (unlikely(dpaa_eth_refill_bpools(dpa_bp, count_ptr)))
4231 + /* Unable to refill the buffer pool due to insufficient
4232 + * system memory. Just release the frame back into the pool,
4233 + * otherwise we'll soon end up with an empty buffer pool.
4234 + */
4235 + dpa_fd_release(net_dev, &dq->fd);
4236 + else
4237 + _dpa_rx(net_dev, portal, priv, percpu_priv, &dq->fd, fq->fqid,
4238 + count_ptr);
4239 +
4240 + return qman_cb_dqrr_consume;
4241 +}
4242 +
4243 +enum qman_cb_dqrr_result
4244 +priv_tx_conf_error_dqrr(struct qman_portal *portal,
4245 + struct qman_fq *fq,
4246 + const struct qm_dqrr_entry *dq)
4247 +{
4248 + struct net_device *net_dev;
4249 + struct dpa_priv_s *priv;
4250 + struct dpa_percpu_priv_s *percpu_priv;
4251 +
4252 + net_dev = ((struct dpa_fq *)fq)->net_dev;
4253 + priv = netdev_priv(net_dev);
4254 +
4255 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
4256 +
4257 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
4258 + return qman_cb_dqrr_stop;
4259 +
4260 + _dpa_tx_error(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
4261 +
4262 + return qman_cb_dqrr_consume;
4263 +}
4264 +
4265 +enum qman_cb_dqrr_result __hot
4266 +priv_tx_conf_default_dqrr(struct qman_portal *portal,
4267 + struct qman_fq *fq,
4268 + const struct qm_dqrr_entry *dq)
4269 +{
4270 + struct net_device *net_dev;
4271 + struct dpa_priv_s *priv;
4272 + struct dpa_percpu_priv_s *percpu_priv;
4273 +
4274 + net_dev = ((struct dpa_fq *)fq)->net_dev;
4275 + priv = netdev_priv(net_dev);
4276 +
4277 + /* Trace the fd */
4278 + trace_dpa_tx_conf_fd(net_dev, fq, &dq->fd);
4279 +
4280 + /* Non-migratable context, safe to use raw_cpu_ptr */
4281 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
4282 +
4283 + if (dpaa_eth_napi_schedule(percpu_priv, portal))
4284 + return qman_cb_dqrr_stop;
4285 +
4286 + _dpa_tx_conf(net_dev, priv, percpu_priv, &dq->fd, fq->fqid);
4287 +
4288 + return qman_cb_dqrr_consume;
4289 +}
4290 +
4291 +void priv_ern(struct qman_portal *portal,
4292 + struct qman_fq *fq,
4293 + const struct qm_mr_entry *msg)
4294 +{
4295 + struct net_device *net_dev;
4296 + const struct dpa_priv_s *priv;
4297 + struct sk_buff *skb;
4298 + struct dpa_percpu_priv_s *percpu_priv;
4299 + struct qm_fd fd = msg->ern.fd;
4300 +
4301 + net_dev = ((struct dpa_fq *)fq)->net_dev;
4302 + priv = netdev_priv(net_dev);
4303 + /* Non-migratable context, safe to use raw_cpu_ptr */
4304 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
4305 +
4306 + percpu_priv->stats.tx_dropped++;
4307 + percpu_priv->stats.tx_fifo_errors++;
4308 + count_ern(percpu_priv, msg);
4309 +
4310 + /* If we intended this buffer to go into the pool
4311 + * when the FM was done, we need to put it in
4312 + * manually.
4313 + */
4314 + if (msg->ern.fd.bpid != 0xff) {
4315 + dpa_fd_release(net_dev, &fd);
4316 + return;
4317 + }
4318 +
4319 + skb = _dpa_cleanup_tx_fd(priv, &fd);
4320 + dev_kfree_skb_any(skb);
4321 +}
4322 +
4323 +const struct dpa_fq_cbs_t private_fq_cbs = {
4324 + .rx_defq = { .cb = { .dqrr = priv_rx_default_dqrr } },
4325 + .tx_defq = { .cb = { .dqrr = priv_tx_conf_default_dqrr } },
4326 + .rx_errq = { .cb = { .dqrr = priv_rx_error_dqrr } },
4327 + .tx_errq = { .cb = { .dqrr = priv_tx_conf_error_dqrr } },
4328 + .egress_ern = { .cb = { .ern = priv_ern } }
4329 +};
4330 +EXPORT_SYMBOL(private_fq_cbs);
4331 +
4332 +static void dpaa_eth_napi_enable(struct dpa_priv_s *priv)
4333 +{
4334 + struct dpa_percpu_priv_s *percpu_priv;
4335 + int i, j;
4336 +
4337 + for_each_possible_cpu(i) {
4338 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
4339 +
4340 + for (j = 0; j < qman_portal_max; j++)
4341 + napi_enable(&percpu_priv->np[j].napi);
4342 + }
4343 +}
4344 +
4345 +static void dpaa_eth_napi_disable(struct dpa_priv_s *priv)
4346 +{
4347 + struct dpa_percpu_priv_s *percpu_priv;
4348 + int i, j;
4349 +
4350 + for_each_possible_cpu(i) {
4351 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
4352 +
4353 + for (j = 0; j < qman_portal_max; j++)
4354 + napi_disable(&percpu_priv->np[j].napi);
4355 + }
4356 +}
4357 +
4358 +static int __cold dpa_eth_priv_start(struct net_device *net_dev)
4359 +{
4360 + int err;
4361 + struct dpa_priv_s *priv;
4362 +
4363 + priv = netdev_priv(net_dev);
4364 +
4365 + dpaa_eth_napi_enable(priv);
4366 +
4367 + err = dpa_start(net_dev);
4368 + if (err < 0)
4369 + dpaa_eth_napi_disable(priv);
4370 +
4371 + return err;
4372 +}
4373 +
4374 +
4375 +
4376 +static int __cold dpa_eth_priv_stop(struct net_device *net_dev)
4377 +{
4378 + int _errno;
4379 + struct dpa_priv_s *priv;
4380 +
4381 + _errno = dpa_stop(net_dev);
4382 + /* Allow NAPI to consume any frame still in the Rx/TxConfirm
4383 + * ingress queues. This is to avoid a race between the current
4384 + * context and ksoftirqd which could leave NAPI disabled while
4385 + * in fact there's still Rx traffic to be processed.
4386 + */
4387 + usleep_range(5000, 10000);
4388 +
4389 + priv = netdev_priv(net_dev);
4390 + dpaa_eth_napi_disable(priv);
4391 +
4392 + return _errno;
4393 +}
4394 +
4395 +#ifdef CONFIG_NET_POLL_CONTROLLER
4396 +static void dpaa_eth_poll_controller(struct net_device *net_dev)
4397 +{
4398 + struct dpa_priv_s *priv = netdev_priv(net_dev);
4399 + struct dpa_percpu_priv_s *percpu_priv =
4400 + raw_cpu_ptr(priv->percpu_priv);
4401 + struct qman_portal *p;
4402 + const struct qman_portal_config *pc;
4403 + struct dpa_napi_portal *np;
4404 +
4405 + p = (struct qman_portal *)qman_get_affine_portal(smp_processor_id());
4406 + pc = qman_p_get_portal_config(p);
4407 + np = &percpu_priv->np[pc->index];
4408 +
4409 + qman_p_irqsource_remove(np->p, QM_PIRQ_DQRI);
4410 + qman_p_poll_dqrr(np->p, np->napi.weight);
4411 + qman_p_irqsource_add(np->p, QM_PIRQ_DQRI);
4412 +}
4413 +#endif
4414 +
4415 +static const struct net_device_ops dpa_private_ops = {
4416 + .ndo_open = dpa_eth_priv_start,
4417 + .ndo_start_xmit = dpa_tx,
4418 + .ndo_stop = dpa_eth_priv_stop,
4419 + .ndo_tx_timeout = dpa_timeout,
4420 + .ndo_get_stats64 = dpa_get_stats64,
4421 + .ndo_set_mac_address = dpa_set_mac_address,
4422 + .ndo_validate_addr = eth_validate_addr,
4423 +#ifdef CONFIG_FMAN_PFC
4424 + .ndo_select_queue = dpa_select_queue,
4425 +#endif
4426 + .ndo_set_rx_mode = dpa_set_rx_mode,
4427 + .ndo_init = dpa_ndo_init,
4428 + .ndo_set_features = dpa_set_features,
4429 + .ndo_fix_features = dpa_fix_features,
4430 + .ndo_do_ioctl = dpa_ioctl,
4431 +#ifdef CONFIG_NET_POLL_CONTROLLER
4432 + .ndo_poll_controller = dpaa_eth_poll_controller,
4433 +#endif
4434 +};
4435 +
4436 +static int dpa_private_napi_add(struct net_device *net_dev)
4437 +{
4438 + struct dpa_priv_s *priv = netdev_priv(net_dev);
4439 + struct dpa_percpu_priv_s *percpu_priv;
4440 + int i, cpu;
4441 +
4442 + for_each_possible_cpu(cpu) {
4443 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
4444 +
4445 + percpu_priv->np = devm_kzalloc(net_dev->dev.parent,
4446 + qman_portal_max * sizeof(struct dpa_napi_portal),
4447 + GFP_KERNEL);
4448 +
4449 + if (unlikely(percpu_priv->np == NULL)) {
4450 + dev_err(net_dev->dev.parent, "devm_kzalloc() failed\n");
4451 + return -ENOMEM;
4452 + }
4453 +
4454 + for (i = 0; i < qman_portal_max; i++)
4455 + netif_napi_add(net_dev, &percpu_priv->np[i].napi,
4456 + dpaa_eth_poll, DPA_NAPI_WEIGHT);
4457 + }
4458 +
4459 + return 0;
4460 +}
4461 +
4462 +void dpa_private_napi_del(struct net_device *net_dev)
4463 +{
4464 + struct dpa_priv_s *priv = netdev_priv(net_dev);
4465 + struct dpa_percpu_priv_s *percpu_priv;
4466 + int i, cpu;
4467 +
4468 + for_each_possible_cpu(cpu) {
4469 + percpu_priv = per_cpu_ptr(priv->percpu_priv, cpu);
4470 +
4471 + if (percpu_priv->np) {
4472 + for (i = 0; i < qman_portal_max; i++)
4473 + netif_napi_del(&percpu_priv->np[i].napi);
4474 +
4475 + devm_kfree(net_dev->dev.parent, percpu_priv->np);
4476 + }
4477 + }
4478 +}
4479 +EXPORT_SYMBOL(dpa_private_napi_del);
4480 +
4481 +static int dpa_private_netdev_init(struct net_device *net_dev)
4482 +{
4483 + int i;
4484 + struct dpa_priv_s *priv = netdev_priv(net_dev);
4485 + struct dpa_percpu_priv_s *percpu_priv;
4486 + const uint8_t *mac_addr;
4487 +
4488 + /* Although we access another CPU's private data here
4489 + * we do it at initialization so it is safe
4490 + */
4491 + for_each_possible_cpu(i) {
4492 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
4493 + percpu_priv->net_dev = net_dev;
4494 + }
4495 +
4496 + net_dev->netdev_ops = &dpa_private_ops;
4497 + mac_addr = priv->mac_dev->addr;
4498 +
4499 + net_dev->mem_start = priv->mac_dev->res->start;
4500 + net_dev->mem_end = priv->mac_dev->res->end;
4501 +
4502 + /* Configure the maximum MTU according to the FMan's MAXFRM */
4503 + net_dev->min_mtu = ETH_MIN_MTU;
4504 + net_dev->max_mtu = dpa_get_max_mtu();
4505 +
4506 + net_dev->hw_features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
4507 + NETIF_F_LLTX);
4508 +
4509 + /* Advertise S/G and HIGHDMA support for private interfaces */
4510 + net_dev->hw_features |= NETIF_F_SG | NETIF_F_HIGHDMA;
4511 + /* Recent kernels enable GSO automatically, if
4512 + * we declare NETIF_F_SG. For conformity, we'll
4513 + * still declare GSO explicitly.
4514 + */
4515 + net_dev->features |= NETIF_F_GSO;
4516 +
4517 + /* Advertise GRO support */
4518 + net_dev->features |= NETIF_F_GRO;
4519 +
4520 + /* Advertise NETIF_F_HW_ACCEL_MQ to avoid Tx timeout warnings */
4521 + net_dev->features |= NETIF_F_HW_ACCEL_MQ;
4522 +
4523 +#ifndef CONFIG_PPC
4524 + /* Due to the A010022 FMan errata, we can not use S/G frames. We need
4525 + * to stop advertising S/G and GSO support.
4526 + */
4527 + if (unlikely(dpaa_errata_a010022)) {
4528 + net_dev->hw_features &= ~NETIF_F_SG;
4529 + net_dev->features &= ~NETIF_F_GSO;
4530 + }
4531 +#endif
4532 +
4533 + return dpa_netdev_init(net_dev, mac_addr, tx_timeout);
4534 +}
4535 +
4536 +static struct dpa_bp * __cold
4537 +dpa_priv_bp_probe(struct device *dev)
4538 +{
4539 + struct dpa_bp *dpa_bp;
4540 +
4541 + dpa_bp = devm_kzalloc(dev, sizeof(*dpa_bp), GFP_KERNEL);
4542 + if (unlikely(dpa_bp == NULL)) {
4543 + dev_err(dev, "devm_kzalloc() failed\n");
4544 + return ERR_PTR(-ENOMEM);
4545 + }
4546 +
4547 + dpa_bp->percpu_count = devm_alloc_percpu(dev, *dpa_bp->percpu_count);
4548 + dpa_bp->target_count = CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
4549 +
4550 + dpa_bp->seed_cb = dpa_bp_priv_seed;
4551 + dpa_bp->free_buf_cb = _dpa_bp_free_pf;
4552 +
4553 + return dpa_bp;
4554 +}
4555 +
4556 +/* Place all ingress FQs (Rx Default, Rx Error, PCD FQs) in a dedicated CGR.
4557 + * We won't be sending congestion notifications to FMan; for now, we just use
4558 + * this CGR to generate enqueue rejections to FMan in order to drop the frames
4559 + * before they reach our ingress queues and eat up memory.
4560 + */
4561 +static int dpaa_eth_priv_ingress_cgr_init(struct dpa_priv_s *priv)
4562 +{
4563 + struct qm_mcc_initcgr initcgr;
4564 + u32 cs_th;
4565 + int err;
4566 +
4567 + err = qman_alloc_cgrid(&priv->ingress_cgr.cgrid);
4568 + if (err < 0) {
4569 + pr_err("Error %d allocating CGR ID\n", err);
4570 + goto out_error;
4571 + }
4572 +
4573 + /* Enable CS TD, but disable Congestion State Change Notifications. */
4574 + initcgr.we_mask = QM_CGR_WE_CS_THRES;
4575 + initcgr.cgr.cscn_en = QM_CGR_EN;
4576 + cs_th = CONFIG_FSL_DPAA_INGRESS_CS_THRESHOLD;
4577 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
4578 +
4579 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
4580 + initcgr.cgr.cstd_en = QM_CGR_EN;
4581 +
4582 + /* This is actually a hack, because this CGR will be associated with
4583 + * our affine SWP. However, we'll place our ingress FQs in it.
4584 + */
4585 + err = qman_create_cgr(&priv->ingress_cgr, QMAN_CGR_FLAG_USE_INIT,
4586 + &initcgr);
4587 + if (err < 0) {
4588 + pr_err("Error %d creating ingress CGR with ID %d\n", err,
4589 + priv->ingress_cgr.cgrid);
4590 + qman_release_cgrid(priv->ingress_cgr.cgrid);
4591 + goto out_error;
4592 + }
4593 + pr_debug("Created ingress CGR %d for netdev with hwaddr %pM\n",
4594 + priv->ingress_cgr.cgrid, priv->mac_dev->addr);
4595 +
4596 + /* struct qman_cgr allows special cgrid values (i.e. outside the 0..255
4597 + * range), but we have no common initialization path between the
4598 + * different variants of the DPAA Eth driver, so we do it here rather
4599 + * than modifying every other variant than "private Eth".
4600 + */
4601 + priv->use_ingress_cgr = true;
4602 +
4603 +out_error:
4604 + return err;
4605 +}
4606 +
4607 +static int dpa_priv_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
4608 + size_t count)
4609 +{
4610 + struct dpa_priv_s *priv = netdev_priv(net_dev);
4611 + int i;
4612 +
4613 + if (netif_msg_probe(priv))
4614 + dev_dbg(net_dev->dev.parent,
4615 + "Using private BM buffer pools\n");
4616 +
4617 + priv->bp_count = count;
4618 +
4619 + for (i = 0; i < count; i++) {
4620 + int err;
4621 + err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
4622 + if (err < 0) {
4623 + dpa_bp_free(priv);
4624 + priv->dpa_bp = NULL;
4625 + return err;
4626 + }
4627 +
4628 + priv->dpa_bp = &dpa_bp[i];
4629 + }
4630 +
4631 + dpa_priv_common_bpid = priv->dpa_bp->bpid;
4632 + return 0;
4633 +}
4634 +
4635 +static const struct of_device_id dpa_match[];
4636 +
4637 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4638 +static int dpa_new_loop_id(void)
4639 +{
4640 + static int if_id;
4641 +
4642 + return if_id++;
4643 +}
4644 +#endif
4645 +
4646 +static int
4647 +dpaa_eth_priv_probe(struct platform_device *_of_dev)
4648 +{
4649 + int err = 0, i, channel;
4650 + struct device *dev;
4651 + struct device_node *dpa_node;
4652 + struct dpa_bp *dpa_bp;
4653 + size_t count = 1;
4654 + struct net_device *net_dev = NULL;
4655 + struct dpa_priv_s *priv = NULL;
4656 + struct dpa_percpu_priv_s *percpu_priv;
4657 + struct fm_port_fqs port_fqs;
4658 + struct dpa_buffer_layout_s *buf_layout = NULL;
4659 + struct mac_device *mac_dev;
4660 +
4661 + dev = &_of_dev->dev;
4662 +
4663 + dpa_node = dev->of_node;
4664 +
4665 + if (!of_device_is_available(dpa_node))
4666 + return -ENODEV;
4667 +
4668 + /* Get the buffer pools assigned to this interface;
4669 + * run only once the default pool probing code
4670 + */
4671 + dpa_bp = (dpa_bpid2pool(dpa_priv_common_bpid)) ? :
4672 + dpa_priv_bp_probe(dev);
4673 + if (IS_ERR(dpa_bp))
4674 + return PTR_ERR(dpa_bp);
4675 +
4676 + /* Allocate this early, so we can store relevant information in
4677 + * the private area (needed by 1588 code in dpa_mac_probe)
4678 + */
4679 + net_dev = alloc_etherdev_mq(sizeof(*priv), DPAA_ETH_TX_QUEUES);
4680 + if (!net_dev) {
4681 + dev_err(dev, "alloc_etherdev_mq() failed\n");
4682 + goto alloc_etherdev_mq_failed;
4683 + }
4684 +
4685 + /* Do this here, so we can be verbose early */
4686 + SET_NETDEV_DEV(net_dev, dev);
4687 + dev_set_drvdata(dev, net_dev);
4688 +
4689 + priv = netdev_priv(net_dev);
4690 + priv->net_dev = net_dev;
4691 + strcpy(priv->if_type, "private");
4692 +
4693 + priv->msg_enable = netif_msg_init(debug, -1);
4694 +
4695 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4696 + priv->loop_id = dpa_new_loop_id();
4697 + priv->loop_to = -1; /* disabled by default */
4698 + dpa_loop_netdevs[priv->loop_id] = net_dev;
4699 +#endif
4700 +
4701 + mac_dev = dpa_mac_probe(_of_dev);
4702 + if (IS_ERR(mac_dev) || !mac_dev) {
4703 + err = PTR_ERR(mac_dev);
4704 + goto mac_probe_failed;
4705 + }
4706 +
4707 + /* We have physical ports, so we need to establish
4708 + * the buffer layout.
4709 + */
4710 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
4711 + GFP_KERNEL);
4712 + if (!buf_layout) {
4713 + dev_err(dev, "devm_kzalloc() failed\n");
4714 + goto alloc_failed;
4715 + }
4716 + dpa_set_buffers_layout(mac_dev, buf_layout);
4717 +
4718 + /* For private ports, need to compute the size of the default
4719 + * buffer pool, based on FMan port buffer layout;also update
4720 + * the maximum buffer size for private ports if necessary
4721 + */
4722 + dpa_bp->size = dpa_bp_size(&buf_layout[RX]);
4723 +
4724 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
4725 + /* We only want to use jumbo frame optimization if we actually have
4726 + * L2 MAX FRM set for jumbo frames as well.
4727 + */
4728 + if(fm_get_max_frm() < 9600)
4729 + dev_warn(dev,
4730 + "Invalid configuration: if jumbo frames support is on, FSL_FM_MAX_FRAME_SIZE should be set to 9600\n");
4731 +#endif
4732 +
4733 + INIT_LIST_HEAD(&priv->dpa_fq_list);
4734 +
4735 + memset(&port_fqs, 0, sizeof(port_fqs));
4736 +
4737 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list, &port_fqs, true, RX);
4738 + if (!err)
4739 + err = dpa_fq_probe_mac(dev, &priv->dpa_fq_list,
4740 + &port_fqs, true, TX);
4741 +
4742 + if (err < 0)
4743 + goto fq_probe_failed;
4744 +
4745 + /* bp init */
4746 +
4747 + err = dpa_priv_bp_create(net_dev, dpa_bp, count);
4748 +
4749 + if (err < 0)
4750 + goto bp_create_failed;
4751 +
4752 + priv->mac_dev = mac_dev;
4753 +
4754 + channel = dpa_get_channel();
4755 +
4756 + if (channel < 0) {
4757 + err = channel;
4758 + goto get_channel_failed;
4759 + }
4760 +
4761 + priv->channel = (uint16_t)channel;
4762 + dpaa_eth_add_channel(priv->channel);
4763 +
4764 + dpa_fq_setup(priv, &private_fq_cbs, priv->mac_dev->port_dev[TX]);
4765 +
4766 + /* Create a congestion group for this netdev, with
4767 + * dynamically-allocated CGR ID.
4768 + * Must be executed after probing the MAC, but before
4769 + * assigning the egress FQs to the CGRs.
4770 + */
4771 + err = dpaa_eth_cgr_init(priv);
4772 + if (err < 0) {
4773 + dev_err(dev, "Error initializing CGR\n");
4774 + goto tx_cgr_init_failed;
4775 + }
4776 + err = dpaa_eth_priv_ingress_cgr_init(priv);
4777 + if (err < 0) {
4778 + dev_err(dev, "Error initializing ingress CGR\n");
4779 + goto rx_cgr_init_failed;
4780 + }
4781 +
4782 + /* Add the FQs to the interface, and make them active */
4783 + err = dpa_fqs_init(dev, &priv->dpa_fq_list, false);
4784 + if (err < 0)
4785 + goto fq_alloc_failed;
4786 +
4787 + priv->buf_layout = buf_layout;
4788 + priv->tx_headroom = dpa_get_headroom(&priv->buf_layout[TX]);
4789 + priv->rx_headroom = dpa_get_headroom(&priv->buf_layout[RX]);
4790 +
4791 + /* All real interfaces need their ports initialized */
4792 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
4793 + buf_layout, dev);
4794 +
4795 +#ifdef CONFIG_FMAN_PFC
4796 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
4797 + err = fm_port_set_pfc_priorities_mapping_to_qman_wq(
4798 + mac_dev->port_dev[TX], i, i);
4799 + if (unlikely(err != 0)) {
4800 + dev_err(dev, "Error maping PFC %u to WQ %u\n", i, i);
4801 + goto pfc_mapping_failed;
4802 + }
4803 + }
4804 +#endif
4805 +
4806 + priv->percpu_priv = devm_alloc_percpu(dev, *priv->percpu_priv);
4807 +
4808 + if (priv->percpu_priv == NULL) {
4809 + dev_err(dev, "devm_alloc_percpu() failed\n");
4810 + err = -ENOMEM;
4811 + goto alloc_percpu_failed;
4812 + }
4813 + for_each_possible_cpu(i) {
4814 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
4815 + memset(percpu_priv, 0, sizeof(*percpu_priv));
4816 + }
4817 +
4818 + /* Initialize NAPI */
4819 + err = dpa_private_napi_add(net_dev);
4820 +
4821 + if (err < 0)
4822 + goto napi_add_failed;
4823 +
4824 + err = dpa_private_netdev_init(net_dev);
4825 +
4826 + if (err < 0)
4827 + goto netdev_init_failed;
4828 +
4829 + dpaa_eth_sysfs_init(&net_dev->dev);
4830 +
4831 +#ifdef CONFIG_PM
4832 + device_set_wakeup_capable(dev, true);
4833 +#endif
4834 +
4835 + pr_info("fsl_dpa: Probed interface %s\n", net_dev->name);
4836 +
4837 + return 0;
4838 +
4839 +netdev_init_failed:
4840 +napi_add_failed:
4841 + dpa_private_napi_del(net_dev);
4842 +alloc_percpu_failed:
4843 +#ifdef CONFIG_FMAN_PFC
4844 +pfc_mapping_failed:
4845 +#endif
4846 + dpa_fq_free(dev, &priv->dpa_fq_list);
4847 +fq_alloc_failed:
4848 + qman_delete_cgr_safe(&priv->ingress_cgr);
4849 + qman_release_cgrid(priv->ingress_cgr.cgrid);
4850 +rx_cgr_init_failed:
4851 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
4852 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
4853 +tx_cgr_init_failed:
4854 +get_channel_failed:
4855 + dpa_bp_free(priv);
4856 +bp_create_failed:
4857 +fq_probe_failed:
4858 +alloc_failed:
4859 +mac_probe_failed:
4860 + dev_set_drvdata(dev, NULL);
4861 + free_netdev(net_dev);
4862 +alloc_etherdev_mq_failed:
4863 + if (atomic_read(&dpa_bp->refs) == 0)
4864 + devm_kfree(dev, dpa_bp);
4865 +
4866 + return err;
4867 +}
4868 +
4869 +static const struct of_device_id dpa_match[] = {
4870 + {
4871 + .compatible = "fsl,dpa-ethernet"
4872 + },
4873 + {}
4874 +};
4875 +MODULE_DEVICE_TABLE(of, dpa_match);
4876 +
4877 +static struct platform_driver dpa_driver = {
4878 + .driver = {
4879 + .name = KBUILD_MODNAME,
4880 + .of_match_table = dpa_match,
4881 + .owner = THIS_MODULE,
4882 + .pm = DPAA_PM_OPS,
4883 + },
4884 + .probe = dpaa_eth_priv_probe,
4885 + .remove = dpa_remove
4886 +};
4887 +
4888 +#ifndef CONFIG_PPC
4889 +static bool __init __cold soc_has_errata_a010022(void)
4890 +{
4891 +#ifdef CONFIG_SOC_BUS
4892 + const struct soc_device_attribute soc_msi_matches[] = {
4893 + { .family = "QorIQ LS1043A",
4894 + .data = NULL },
4895 + { },
4896 + };
4897 +
4898 + if (soc_device_match(soc_msi_matches))
4899 + return true;
4900 +
4901 + return false;
4902 +#else
4903 + return true; /* cannot identify SoC */
4904 +#endif
4905 +}
4906 +#endif
4907 +
4908 +static int __init __cold dpa_load(void)
4909 +{
4910 + int _errno;
4911 +
4912 + pr_info(DPA_DESCRIPTION "\n");
4913 +
4914 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4915 + dpa_debugfs_module_init();
4916 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
4917 +
4918 + /* initialise dpaa_eth mirror values */
4919 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
4920 + dpa_max_frm = fm_get_max_frm();
4921 + dpa_num_cpus = num_possible_cpus();
4922 +
4923 +#ifndef CONFIG_PPC
4924 + /* Detect if the current SoC requires the 4K alignment workaround */
4925 + dpaa_errata_a010022 = soc_has_errata_a010022();
4926 +#endif
4927 +
4928 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4929 + memset(dpa_loop_netdevs, 0, sizeof(dpa_loop_netdevs));
4930 +#endif
4931 +
4932 + _errno = platform_driver_register(&dpa_driver);
4933 + if (unlikely(_errno < 0)) {
4934 + pr_err(KBUILD_MODNAME
4935 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
4936 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
4937 + }
4938 +
4939 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
4940 + KBUILD_BASENAME".c", __func__);
4941 +
4942 + return _errno;
4943 +}
4944 +module_init(dpa_load);
4945 +
4946 +static void __exit __cold dpa_unload(void)
4947 +{
4948 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
4949 + KBUILD_BASENAME".c", __func__);
4950 +
4951 + platform_driver_unregister(&dpa_driver);
4952 +
4953 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
4954 + dpa_debugfs_module_exit();
4955 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
4956 +
4957 + /* Only one channel is used and needs to be relased after all
4958 + * interfaces are removed
4959 + */
4960 + dpa_release_channel();
4961 +
4962 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
4963 + KBUILD_BASENAME".c", __func__);
4964 +}
4965 +module_exit(dpa_unload);
4966 --- /dev/null
4967 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth.h
4968 @@ -0,0 +1,674 @@
4969 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
4970 + *
4971 + * Redistribution and use in source and binary forms, with or without
4972 + * modification, are permitted provided that the following conditions are met:
4973 + * * Redistributions of source code must retain the above copyright
4974 + * notice, this list of conditions and the following disclaimer.
4975 + * * Redistributions in binary form must reproduce the above copyright
4976 + * notice, this list of conditions and the following disclaimer in the
4977 + * documentation and/or other materials provided with the distribution.
4978 + * * Neither the name of Freescale Semiconductor nor the
4979 + * names of its contributors may be used to endorse or promote products
4980 + * derived from this software without specific prior written permission.
4981 + *
4982 + *
4983 + * ALTERNATIVELY, this software may be distributed under the terms of the
4984 + * GNU General Public License ("GPL") as published by the Free Software
4985 + * Foundation, either version 2 of that License or (at your option) any
4986 + * later version.
4987 + *
4988 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
4989 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
4990 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
4991 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
4992 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
4993 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4994 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
4995 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
4996 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
4997 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4998 + */
4999 +
5000 +#ifndef __DPA_H
5001 +#define __DPA_H
5002 +
5003 +#include <linux/netdevice.h>
5004 +#include <linux/fsl_qman.h> /* struct qman_fq */
5005 +
5006 +#include "fm_ext.h"
5007 +#include "dpaa_eth_trace.h"
5008 +
5009 +extern int dpa_rx_extra_headroom;
5010 +extern int dpa_max_frm;
5011 +extern int dpa_num_cpus;
5012 +
5013 +#define dpa_get_rx_extra_headroom() dpa_rx_extra_headroom
5014 +#define dpa_get_max_frm() dpa_max_frm
5015 +
5016 +#define dpa_get_max_mtu() \
5017 + (dpa_get_max_frm() - (VLAN_ETH_HLEN + ETH_FCS_LEN))
5018 +
5019 +#define __hot
5020 +
5021 +/* Simple enum of FQ types - used for array indexing */
5022 +enum port_type {RX, TX};
5023 +
5024 +/* TODO: This structure should be renamed & moved to the FMD wrapper */
5025 +struct dpa_buffer_layout_s {
5026 + uint16_t priv_data_size;
5027 + bool parse_results;
5028 + bool time_stamp;
5029 + bool hash_results;
5030 + uint8_t manip_extra_space;
5031 + uint16_t data_align;
5032 +};
5033 +
5034 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
5035 +#define DPA_BUG_ON(cond) BUG_ON(cond)
5036 +#else
5037 +#define DPA_BUG_ON(cond)
5038 +#endif
5039 +
5040 +#define DPA_TX_PRIV_DATA_SIZE 16
5041 +#define DPA_PARSE_RESULTS_SIZE sizeof(fm_prs_result_t)
5042 +#define DPA_TIME_STAMP_SIZE 8
5043 +#define DPA_HASH_RESULTS_SIZE 8
5044 +#define DPA_RX_PRIV_DATA_SIZE (DPA_TX_PRIV_DATA_SIZE + \
5045 + dpa_get_rx_extra_headroom())
5046 +
5047 +#define FM_FD_STAT_RX_ERRORS \
5048 + (FM_PORT_FRM_ERR_DMA | FM_PORT_FRM_ERR_PHYSICAL | \
5049 + FM_PORT_FRM_ERR_SIZE | FM_PORT_FRM_ERR_CLS_DISCARD | \
5050 + FM_PORT_FRM_ERR_EXTRACTION | FM_PORT_FRM_ERR_NO_SCHEME | \
5051 + FM_PORT_FRM_ERR_ILL_PLCR | FM_PORT_FRM_ERR_PRS_TIMEOUT | \
5052 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | FM_PORT_FRM_ERR_PRS_HDR_ERR)
5053 +
5054 +#define FM_FD_STAT_TX_ERRORS \
5055 + (FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT | \
5056 + FM_PORT_FRM_ERR_LENGTH | FM_PORT_FRM_ERR_DMA)
5057 +
5058 +#ifndef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
5059 +/* The raw buffer size must be cacheline aligned.
5060 + * Normally we use 2K buffers.
5061 + */
5062 +#define DPA_BP_RAW_SIZE 2048
5063 +#else
5064 +/* For jumbo frame optimizations, use buffers large enough to accommodate
5065 + * 9.6K frames, FD maximum offset, skb sh_info overhead and some extra
5066 + * space to account for further alignments.
5067 + */
5068 +#define DPA_MAX_FRM_SIZE 9600
5069 +#ifdef CONFIG_PPC
5070 +#define DPA_BP_RAW_SIZE \
5071 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
5072 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1))
5073 +#else /* CONFIG_PPC */
5074 +#define DPA_BP_RAW_SIZE ((unlikely(dpaa_errata_a010022)) ? 2048 : \
5075 + ((DPA_MAX_FRM_SIZE + DPA_MAX_FD_OFFSET + \
5076 + sizeof(struct skb_shared_info) + 128) & ~(SMP_CACHE_BYTES - 1)))
5077 +#endif /* CONFIG_PPC */
5078 +#endif /* CONFIG_FSL_DPAA_ETH_JUMBO_FRAME */
5079 +
5080 +/* This is what FMan is ever allowed to use.
5081 + * FMan-DMA requires 16-byte alignment for Rx buffers, but SKB_DATA_ALIGN is
5082 + * even stronger (SMP_CACHE_BYTES-aligned), so we just get away with that,
5083 + * via SKB_WITH_OVERHEAD(). We can't rely on netdev_alloc_frag() giving us
5084 + * half-page-aligned buffers (can we?), so we reserve some more space
5085 + * for start-of-buffer alignment.
5086 + */
5087 +#define dpa_bp_size(buffer_layout) (SKB_WITH_OVERHEAD(DPA_BP_RAW_SIZE) - \
5088 + SMP_CACHE_BYTES)
5089 +/* We must ensure that skb_shinfo is always cacheline-aligned. */
5090 +#define DPA_SKB_SIZE(size) ((size) & ~(SMP_CACHE_BYTES - 1))
5091 +
5092 +/* Maximum size of a buffer for which recycling is allowed.
5093 + * We need an upper limit such that forwarded skbs that get reallocated on Tx
5094 + * aren't allowed to grow unboundedly. On the other hand, we need to make sure
5095 + * that skbs allocated by us will not fail to be recycled due to their size.
5096 + *
5097 + * For a requested size, the kernel allocator provides the next power of two
5098 + * sized block, which the stack will use as is, regardless of the actual size
5099 + * it required; since we must accommodate at most 9.6K buffers (L2 maximum
5100 + * supported frame size), set the recycling upper limit to 16K.
5101 + */
5102 +#define DPA_RECYCLE_MAX_SIZE 16384
5103 +
5104 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
5105 +/*TODO: temporary for fman pcd testing */
5106 +#define FMAN_PCD_TESTS_MAX_NUM_RANGES 20
5107 +#endif
5108 +
5109 +#define DPAA_ETH_FQ_DELTA 0x10000
5110 +
5111 +#define DPAA_ETH_PCD_FQ_BASE(device_addr) \
5112 + (((device_addr) & 0x1fffff) >> 6)
5113 +
5114 +#define DPAA_ETH_PCD_FQ_HI_PRIO_BASE(device_addr) \
5115 + (DPAA_ETH_FQ_DELTA + DPAA_ETH_PCD_FQ_BASE(device_addr))
5116 +
5117 +/* Largest value that the FQD's OAL field can hold.
5118 + * This is DPAA-1.x specific.
5119 + * TODO: This rather belongs in fsl_qman.h
5120 + */
5121 +#define FSL_QMAN_MAX_OAL 127
5122 +
5123 +/* Maximum offset value for a contig or sg FD (represented on 9 bits) */
5124 +#define DPA_MAX_FD_OFFSET ((1 << 9) - 1)
5125 +
5126 +/* Default alignment for start of data in an Rx FD */
5127 +#define DPA_FD_DATA_ALIGNMENT 16
5128 +
5129 +/* Values for the L3R field of the FM Parse Results
5130 + */
5131 +/* L3 Type field: First IP Present IPv4 */
5132 +#define FM_L3_PARSE_RESULT_IPV4 0x8000
5133 +/* L3 Type field: First IP Present IPv6 */
5134 +#define FM_L3_PARSE_RESULT_IPV6 0x4000
5135 +
5136 +/* Values for the L4R field of the FM Parse Results
5137 + * See $8.8.4.7.20 - L4 HXS - L4 Results from DPAA-Rev2 Reference Manual.
5138 + */
5139 +/* L4 Type field: UDP */
5140 +#define FM_L4_PARSE_RESULT_UDP 0x40
5141 +/* L4 Type field: TCP */
5142 +#define FM_L4_PARSE_RESULT_TCP 0x20
5143 +/* FD status field indicating whether the FM Parser has attempted to validate
5144 + * the L4 csum of the frame.
5145 + * Note that having this bit set doesn't necessarily imply that the checksum
5146 + * is valid. One would have to check the parse results to find that out.
5147 + */
5148 +#define FM_FD_STAT_L4CV 0x00000004
5149 +
5150 +
5151 +#define FM_FD_STAT_ERR_PHYSICAL FM_PORT_FRM_ERR_PHYSICAL
5152 +
5153 +/* Check if the parsed frame was found to be a TCP segment.
5154 + *
5155 + * @parse_result_ptr must be of type (fm_prs_result_t *).
5156 + */
5157 +#define fm_l4_frame_is_tcp(parse_result_ptr) \
5158 + ((parse_result_ptr)->l4r & FM_L4_PARSE_RESULT_TCP)
5159 +
5160 +/* number of Tx queues to FMan */
5161 +#ifdef CONFIG_FMAN_PFC
5162 +#define DPAA_ETH_TX_QUEUES (NR_CPUS * CONFIG_FMAN_PFC_COS_COUNT)
5163 +#else
5164 +#define DPAA_ETH_TX_QUEUES NR_CPUS
5165 +#endif
5166 +
5167 +#define DPAA_ETH_RX_QUEUES 128
5168 +
5169 +/* Convenience macros for storing/retrieving the skb back-pointers. They must
5170 + * accommodate both recycling and confirmation paths - i.e. cases when the buf
5171 + * was allocated by ourselves, respectively by the stack. In the former case,
5172 + * we could store the skb at negative offset; in the latter case, we can't,
5173 + * so we'll use 0 as offset.
5174 + *
5175 + * NB: @off is an offset from a (struct sk_buff **) pointer!
5176 + */
5177 +#define DPA_WRITE_SKB_PTR(skb, skbh, addr, off) \
5178 +{ \
5179 + skbh = (struct sk_buff **)addr; \
5180 + *(skbh + (off)) = skb; \
5181 +}
5182 +#define DPA_READ_SKB_PTR(skb, skbh, addr, off) \
5183 +{ \
5184 + skbh = (struct sk_buff **)addr; \
5185 + skb = *(skbh + (off)); \
5186 +}
5187 +
5188 +#ifdef CONFIG_PM
5189 +/* Magic Packet wakeup */
5190 +#define DPAA_WOL_MAGIC 0x00000001
5191 +#endif
5192 +
5193 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
5194 +struct pcd_range {
5195 + uint32_t base;
5196 + uint32_t count;
5197 +};
5198 +#endif
5199 +
5200 +/* More detailed FQ types - used for fine-grained WQ assignments */
5201 +enum dpa_fq_type {
5202 + FQ_TYPE_RX_DEFAULT = 1, /* Rx Default FQs */
5203 + FQ_TYPE_RX_ERROR, /* Rx Error FQs */
5204 + FQ_TYPE_RX_PCD, /* User-defined PCDs */
5205 + FQ_TYPE_TX, /* "Real" Tx FQs */
5206 + FQ_TYPE_TX_CONFIRM, /* Tx default Conf FQ (actually an Rx FQ) */
5207 + FQ_TYPE_TX_CONF_MQ, /* Tx conf FQs (one for each Tx FQ) */
5208 + FQ_TYPE_TX_ERROR, /* Tx Error FQs (these are actually Rx FQs) */
5209 + FQ_TYPE_RX_PCD_HI_PRIO, /* User-defined high-priority PCDs */
5210 +};
5211 +
5212 +struct dpa_fq {
5213 + struct qman_fq fq_base;
5214 + struct list_head list;
5215 + struct net_device *net_dev;
5216 + bool init;
5217 + uint32_t fqid;
5218 + uint32_t flags;
5219 + uint16_t channel;
5220 + uint8_t wq;
5221 + enum dpa_fq_type fq_type;
5222 +};
5223 +
5224 +struct dpa_fq_cbs_t {
5225 + struct qman_fq rx_defq;
5226 + struct qman_fq tx_defq;
5227 + struct qman_fq rx_errq;
5228 + struct qman_fq tx_errq;
5229 + struct qman_fq egress_ern;
5230 +};
5231 +
5232 +struct fqid_cell {
5233 + uint32_t start;
5234 + uint32_t count;
5235 +};
5236 +
5237 +struct dpa_bp {
5238 + struct bman_pool *pool;
5239 + uint8_t bpid;
5240 + struct device *dev;
5241 + union {
5242 + /* The buffer pools used for the private ports are initialized
5243 + * with target_count buffers for each CPU; at runtime the
5244 + * number of buffers per CPU is constantly brought back to this
5245 + * level
5246 + */
5247 + int target_count;
5248 + /* The configured value for the number of buffers in the pool,
5249 + * used for shared port buffer pools
5250 + */
5251 + int config_count;
5252 + };
5253 + size_t size;
5254 + bool seed_pool;
5255 + /* physical address of the contiguous memory used by the pool to store
5256 + * the buffers
5257 + */
5258 + dma_addr_t paddr;
5259 + /* virtual address of the contiguous memory used by the pool to store
5260 + * the buffers
5261 + */
5262 + void __iomem *vaddr;
5263 + /* current number of buffers in the bpool alloted to this CPU */
5264 + int __percpu *percpu_count;
5265 + atomic_t refs;
5266 + /* some bpools need to be seeded before use by this cb */
5267 + int (*seed_cb)(struct dpa_bp *);
5268 + /* some bpools need to be emptied before freeing; this cb is used
5269 + * for freeing of individual buffers taken from the pool
5270 + */
5271 + void (*free_buf_cb)(void *addr);
5272 +};
5273 +
5274 +struct dpa_rx_errors {
5275 + u64 dme; /* DMA Error */
5276 + u64 fpe; /* Frame Physical Error */
5277 + u64 fse; /* Frame Size Error */
5278 + u64 phe; /* Header Error */
5279 + u64 cse; /* Checksum Validation Error */
5280 +};
5281 +
5282 +/* Counters for QMan ERN frames - one counter per rejection code */
5283 +struct dpa_ern_cnt {
5284 + u64 cg_tdrop; /* Congestion group taildrop */
5285 + u64 wred; /* WRED congestion */
5286 + u64 err_cond; /* Error condition */
5287 + u64 early_window; /* Order restoration, frame too early */
5288 + u64 late_window; /* Order restoration, frame too late */
5289 + u64 fq_tdrop; /* FQ taildrop */
5290 + u64 fq_retired; /* FQ is retired */
5291 + u64 orp_zero; /* ORP disabled */
5292 +};
5293 +
5294 +struct dpa_napi_portal {
5295 + struct napi_struct napi;
5296 + struct qman_portal *p;
5297 +};
5298 +
5299 +struct dpa_percpu_priv_s {
5300 + struct net_device *net_dev;
5301 + struct dpa_napi_portal *np;
5302 + u64 in_interrupt;
5303 + u64 tx_returned;
5304 + u64 tx_confirm;
5305 + /* fragmented (non-linear) skbuffs received from the stack */
5306 + u64 tx_frag_skbuffs;
5307 + /* number of S/G frames received */
5308 + u64 rx_sg;
5309 +
5310 + struct rtnl_link_stats64 stats;
5311 + struct dpa_rx_errors rx_errors;
5312 + struct dpa_ern_cnt ern_cnt;
5313 +};
5314 +
5315 +struct dpa_priv_s {
5316 + struct dpa_percpu_priv_s __percpu *percpu_priv;
5317 + struct dpa_bp *dpa_bp;
5318 + /* Store here the needed Tx headroom for convenience and speed
5319 + * (even though it can be computed based on the fields of buf_layout)
5320 + */
5321 + uint16_t tx_headroom;
5322 + struct net_device *net_dev;
5323 + struct mac_device *mac_dev;
5324 + struct qman_fq *egress_fqs[DPAA_ETH_TX_QUEUES];
5325 + struct qman_fq *conf_fqs[DPAA_ETH_TX_QUEUES];
5326 +
5327 + size_t bp_count;
5328 +
5329 + uint16_t channel; /* "fsl,qman-channel-id" */
5330 + struct list_head dpa_fq_list;
5331 +
5332 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
5333 + struct dentry *debugfs_loop_file;
5334 +#endif
5335 +
5336 + uint32_t msg_enable; /* net_device message level */
5337 +#ifdef CONFIG_FSL_DPAA_1588
5338 + struct dpa_ptp_tsu *tsu;
5339 +#endif
5340 +
5341 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
5342 +/* TODO: this is temporary until pcd support is implemented in dpaa */
5343 + int priv_pcd_num_ranges;
5344 + struct pcd_range priv_pcd_ranges[FMAN_PCD_TESTS_MAX_NUM_RANGES];
5345 +#endif
5346 +
5347 + struct {
5348 + /**
5349 + * All egress queues to a given net device belong to one
5350 + * (and the same) congestion group.
5351 + */
5352 + struct qman_cgr cgr;
5353 + /* If congested, when it began. Used for performance stats. */
5354 + u32 congestion_start_jiffies;
5355 + /* Number of jiffies the Tx port was congested. */
5356 + u32 congested_jiffies;
5357 + /**
5358 + * Counter for the number of times the CGR
5359 + * entered congestion state
5360 + */
5361 + u32 cgr_congested_count;
5362 + } cgr_data;
5363 + /* Use a per-port CGR for ingress traffic. */
5364 + bool use_ingress_cgr;
5365 + struct qman_cgr ingress_cgr;
5366 +
5367 +#ifdef CONFIG_FSL_DPAA_TS
5368 + bool ts_tx_en; /* Tx timestamping enabled */
5369 + bool ts_rx_en; /* Rx timestamping enabled */
5370 +#endif /* CONFIG_FSL_DPAA_TS */
5371 +
5372 + struct dpa_buffer_layout_s *buf_layout;
5373 + uint16_t rx_headroom;
5374 + char if_type[30];
5375 +
5376 + void *peer;
5377 +#ifdef CONFIG_PM
5378 + u32 wol;
5379 +#endif
5380 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
5381 + int loop_id;
5382 + int loop_to;
5383 +#endif
5384 +#ifdef CONFIG_FSL_DPAA_CEETM
5385 + bool ceetm_en; /* CEETM QoS enabled */
5386 +#endif
5387 +};
5388 +
5389 +struct fm_port_fqs {
5390 + struct dpa_fq *tx_defq;
5391 + struct dpa_fq *tx_errq;
5392 + struct dpa_fq *rx_defq;
5393 + struct dpa_fq *rx_errq;
5394 +};
5395 +
5396 +
5397 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
5398 +extern struct net_device *dpa_loop_netdevs[20];
5399 +#endif
5400 +
5401 +/* functions with different implementation for SG and non-SG: */
5402 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp);
5403 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *count_ptr);
5404 +void __hot _dpa_rx(struct net_device *net_dev,
5405 + struct qman_portal *portal,
5406 + const struct dpa_priv_s *priv,
5407 + struct dpa_percpu_priv_s *percpu_priv,
5408 + const struct qm_fd *fd,
5409 + u32 fqid,
5410 + int *count_ptr);
5411 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev);
5412 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
5413 + struct qman_fq *egress_fq, struct qman_fq *conf_fq);
5414 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
5415 + const struct qm_fd *fd);
5416 +void __hot _dpa_process_parse_results(const fm_prs_result_t *parse_results,
5417 + const struct qm_fd *fd,
5418 + struct sk_buff *skb,
5419 + int *use_gro);
5420 +#ifndef CONFIG_FSL_DPAA_TS
5421 +bool dpa_skb_is_recyclable(struct sk_buff *skb);
5422 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
5423 + uint32_t min_size,
5424 + uint16_t min_offset,
5425 + unsigned char **new_buf_start);
5426 +#endif
5427 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
5428 + struct sk_buff *skb, struct qm_fd *fd,
5429 + int *count_ptr, int *offset);
5430 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
5431 + struct sk_buff *skb, struct qm_fd *fd);
5432 +int __cold __attribute__((nonnull))
5433 + _dpa_fq_free(struct device *dev, struct qman_fq *fq);
5434 +
5435 +/* Turn on HW checksum computation for this outgoing frame.
5436 + * If the current protocol is not something we support in this regard
5437 + * (or if the stack has already computed the SW checksum), we do nothing.
5438 + *
5439 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
5440 + * otherwise.
5441 + *
5442 + * Note that this function may modify the fd->cmd field and the skb data buffer
5443 + * (the Parse Results area).
5444 + */
5445 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
5446 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
5447 +
5448 +static inline int dpaa_eth_napi_schedule(struct dpa_percpu_priv_s *percpu_priv,
5449 + struct qman_portal *portal)
5450 +{
5451 + /* In case of threaded ISR for RT enable kernel,
5452 + * in_irq() does not return appropriate value, so use
5453 + * in_serving_softirq to distinguish softirq or irq context.
5454 + */
5455 + if (unlikely(in_irq() || !in_serving_softirq())) {
5456 + /* Disable QMan IRQ and invoke NAPI */
5457 + int ret = qman_p_irqsource_remove(portal, QM_PIRQ_DQRI);
5458 + if (likely(!ret)) {
5459 + const struct qman_portal_config *pc =
5460 + qman_p_get_portal_config(portal);
5461 + struct dpa_napi_portal *np =
5462 + &percpu_priv->np[pc->index];
5463 +
5464 + np->p = portal;
5465 + napi_schedule(&np->napi);
5466 + percpu_priv->in_interrupt++;
5467 + return 1;
5468 + }
5469 + }
5470 + return 0;
5471 +}
5472 +
5473 +static inline ssize_t __const __must_check __attribute__((nonnull))
5474 +dpa_fd_length(const struct qm_fd *fd)
5475 +{
5476 + return fd->length20;
5477 +}
5478 +
5479 +static inline ssize_t __const __must_check __attribute__((nonnull))
5480 +dpa_fd_offset(const struct qm_fd *fd)
5481 +{
5482 + return fd->offset;
5483 +}
5484 +
5485 +static inline uint16_t dpa_get_headroom(struct dpa_buffer_layout_s *bl)
5486 +{
5487 + uint16_t headroom;
5488 + /* The frame headroom must accommodate:
5489 + * - the driver private data area
5490 + * - parse results, hash results, timestamp if selected
5491 + * - manip extra space
5492 + * If either hash results or time stamp are selected, both will
5493 + * be copied to/from the frame headroom, as TS is located between PR and
5494 + * HR in the IC and IC copy size has a granularity of 16bytes
5495 + * (see description of FMBM_RICP and FMBM_TICP registers in DPAARM)
5496 + *
5497 + * Also make sure the headroom is a multiple of data_align bytes
5498 + */
5499 + headroom = (uint16_t)(bl->priv_data_size +
5500 + (bl->parse_results ? DPA_PARSE_RESULTS_SIZE : 0) +
5501 + (bl->hash_results || bl->time_stamp ?
5502 + DPA_TIME_STAMP_SIZE + DPA_HASH_RESULTS_SIZE : 0) +
5503 + bl->manip_extra_space);
5504 +
5505 + return bl->data_align ? ALIGN(headroom, bl->data_align) : headroom;
5506 +}
5507 +
5508 +int fm_mac_dump_regs(struct mac_device *h_dev, char *buf, int n);
5509 +int fm_mac_dump_rx_stats(struct mac_device *h_dev, char *buf, int n);
5510 +int fm_mac_dump_tx_stats(struct mac_device *h_dev, char *buf, int n);
5511 +
5512 +void dpaa_eth_sysfs_remove(struct device *dev);
5513 +void dpaa_eth_sysfs_init(struct device *dev);
5514 +int dpaa_eth_poll(struct napi_struct *napi, int budget);
5515 +
5516 +void dpa_private_napi_del(struct net_device *net_dev);
5517 +
5518 +/* Equivalent to a memset(0), but works faster */
5519 +static inline void clear_fd(struct qm_fd *fd)
5520 +{
5521 + fd->opaque_addr = 0;
5522 + fd->opaque = 0;
5523 + fd->cmd = 0;
5524 +}
5525 +
5526 +static inline int _dpa_tx_fq_to_id(const struct dpa_priv_s *priv,
5527 + struct qman_fq *tx_fq)
5528 +{
5529 + int i;
5530 +
5531 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i++)
5532 + if (priv->egress_fqs[i] == tx_fq)
5533 + return i;
5534 +
5535 + return -EINVAL;
5536 +}
5537 +
5538 +static inline int __hot dpa_xmit(struct dpa_priv_s *priv,
5539 + struct rtnl_link_stats64 *percpu_stats,
5540 + struct qm_fd *fd, struct qman_fq *egress_fq,
5541 + struct qman_fq *conf_fq)
5542 +{
5543 + int err, i;
5544 +
5545 + if (fd->bpid == 0xff)
5546 + fd->cmd |= qman_fq_fqid(conf_fq);
5547 +
5548 + /* Trace this Tx fd */
5549 + trace_dpa_tx_fd(priv->net_dev, egress_fq, fd);
5550 +
5551 + for (i = 0; i < 100000; i++) {
5552 + err = qman_enqueue(egress_fq, fd, 0);
5553 + if (err != -EBUSY)
5554 + break;
5555 + }
5556 +
5557 + if (unlikely(err < 0)) {
5558 + /* TODO differentiate b/w -EBUSY (EQCR full) and other codes? */
5559 + percpu_stats->tx_errors++;
5560 + percpu_stats->tx_fifo_errors++;
5561 + return err;
5562 + }
5563 +
5564 + percpu_stats->tx_packets++;
5565 + percpu_stats->tx_bytes += dpa_fd_length(fd);
5566 +
5567 + return 0;
5568 +}
5569 +
5570 +/* Use multiple WQs for FQ assignment:
5571 + * - Tx Confirmation queues go to WQ1.
5572 + * - Rx Default, Tx and PCD queues go to WQ3 (no differentiation between
5573 + * Rx and Tx traffic, or between Rx Default and Rx PCD frames).
5574 + * - Rx Error and Tx Error queues go to WQ2 (giving them a better chance
5575 + * to be scheduled, in case there are many more FQs in WQ3).
5576 + * This ensures that Tx-confirmed buffers are timely released. In particular,
5577 + * it avoids congestion on the Tx Confirm FQs, which can pile up PFDRs if they
5578 + * are greatly outnumbered by other FQs in the system (usually PCDs), while
5579 + * dequeue scheduling is round-robin.
5580 + */
5581 +static inline void _dpa_assign_wq(struct dpa_fq *fq)
5582 +{
5583 + switch (fq->fq_type) {
5584 + case FQ_TYPE_TX_CONFIRM:
5585 + case FQ_TYPE_TX_CONF_MQ:
5586 + fq->wq = 1;
5587 + break;
5588 + case FQ_TYPE_RX_DEFAULT:
5589 + case FQ_TYPE_TX:
5590 + fq->wq = 3;
5591 + break;
5592 + case FQ_TYPE_RX_ERROR:
5593 + case FQ_TYPE_TX_ERROR:
5594 + case FQ_TYPE_RX_PCD_HI_PRIO:
5595 + fq->wq = 2;
5596 + break;
5597 + case FQ_TYPE_RX_PCD:
5598 + fq->wq = 5;
5599 + break;
5600 + default:
5601 + WARN(1, "Invalid FQ type %d for FQID %d!\n",
5602 + fq->fq_type, fq->fqid);
5603 + }
5604 +}
5605 +
5606 +#ifdef CONFIG_FMAN_PFC
5607 +/* Use in lieu of skb_get_queue_mapping() */
5608 +#define dpa_get_queue_mapping(skb) \
5609 + (((skb)->priority < CONFIG_FMAN_PFC_COS_COUNT) ? \
5610 + ((skb)->priority * dpa_num_cpus + smp_processor_id()) : \
5611 + ((CONFIG_FMAN_PFC_COS_COUNT - 1) * \
5612 + dpa_num_cpus + smp_processor_id()));
5613 +#else
5614 +#define dpa_get_queue_mapping(skb) skb_get_queue_mapping(skb)
5615 +#endif
5616 +
5617 +static inline void _dpa_bp_free_pf(void *addr)
5618 +{
5619 + put_page(virt_to_head_page(addr));
5620 +}
5621 +
5622 +/* LS1043A SoC has a HW issue regarding FMan DMA transactions; The issue
5623 + * manifests itself at high traffic rates when frames cross 4K memory
5624 + * boundaries, when they are not aligned to 16 bytes or when they have
5625 + * Scatter/Gather fragments; For the moment, we use a SW workaround that
5626 + * realigns frames to 256 bytes. Scatter/Gather frames aren't supported
5627 + * on egress.
5628 + */
5629 +
5630 +#ifndef CONFIG_PPC
5631 +extern bool dpaa_errata_a010022; /* SoC affected by A010022 errata */
5632 +#define NONREC_MARK 0x01
5633 +#define HAS_DMA_ISSUE(start, size) \
5634 + (((uintptr_t)(start) + (size)) > \
5635 + (((uintptr_t)(start) + 0x1000) & ~0xFFF))
5636 +/* The headroom needs to accommodate our private data (64 bytes) but
5637 + * we reserve 256 bytes instead to guarantee 256 data alignment.
5638 + */
5639 +#define DPAA_A010022_HEADROOM 256
5640 +#endif /* !CONFIG_PPC */
5641 +
5642 +#endif /* __DPA_H */
5643 --- /dev/null
5644 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.c
5645 @@ -0,0 +1,205 @@
5646 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
5647 + *
5648 + * Redistribution and use in source and binary forms, with or without
5649 + * modification, are permitted provided that the following conditions are met:
5650 + * * Redistributions of source code must retain the above copyright
5651 + * notice, this list of conditions and the following disclaimer.
5652 + * * Redistributions in binary form must reproduce the above copyright
5653 + * notice, this list of conditions and the following disclaimer in the
5654 + * documentation and/or other materials provided with the distribution.
5655 + * * Neither the name of Freescale Semiconductor nor the
5656 + * names of its contributors may be used to endorse or promote products
5657 + * derived from this software without specific prior written permission.
5658 + *
5659 + *
5660 + * ALTERNATIVELY, this software may be distributed under the terms of the
5661 + * GNU General Public License ("GPL") as published by the Free Software
5662 + * Foundation, either version 2 of that License or (at your option) any
5663 + * later version.
5664 + *
5665 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5666 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5667 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5668 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5669 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5670 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5671 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5672 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5673 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5674 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5675 + */
5676 +
5677 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
5678 +#define pr_fmt(fmt) \
5679 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
5680 + KBUILD_BASENAME".c", __LINE__, __func__
5681 +#else
5682 +#define pr_fmt(fmt) \
5683 + KBUILD_MODNAME ": " fmt
5684 +#endif
5685 +
5686 +#include <linux/init.h>
5687 +#include <linux/module.h>
5688 +#include <linux/io.h>
5689 +#include <linux/of_platform.h>
5690 +#include <linux/of_net.h>
5691 +#include <linux/etherdevice.h>
5692 +#include <linux/kthread.h>
5693 +#include <linux/percpu.h>
5694 +#include <linux/highmem.h>
5695 +#include <linux/sort.h>
5696 +#include <linux/fsl_qman.h>
5697 +#include "dpaa_eth.h"
5698 +#include "dpaa_eth_common.h"
5699 +#include "dpaa_eth_base.h"
5700 +
5701 +#define DPA_DESCRIPTION "FSL DPAA Advanced drivers:"
5702 +
5703 +MODULE_LICENSE("Dual BSD/GPL");
5704 +
5705 +uint8_t advanced_debug = -1;
5706 +module_param(advanced_debug, byte, S_IRUGO);
5707 +MODULE_PARM_DESC(advanced_debug, "Module/Driver verbosity level");
5708 +EXPORT_SYMBOL(advanced_debug);
5709 +
5710 +static int dpa_bp_cmp(const void *dpa_bp0, const void *dpa_bp1)
5711 +{
5712 + return ((struct dpa_bp *)dpa_bp0)->size -
5713 + ((struct dpa_bp *)dpa_bp1)->size;
5714 +}
5715 +
5716 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
5717 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count)
5718 +{
5719 + int i, lenp, na, ns, err;
5720 + struct device *dev;
5721 + struct device_node *dev_node;
5722 + const __be32 *bpool_cfg;
5723 + struct dpa_bp *dpa_bp;
5724 + u32 bpid;
5725 +
5726 + dev = &_of_dev->dev;
5727 +
5728 + *count = of_count_phandle_with_args(dev->of_node,
5729 + "fsl,bman-buffer-pools", NULL);
5730 + if (*count < 1) {
5731 + dev_err(dev, "missing fsl,bman-buffer-pools device tree entry\n");
5732 + return ERR_PTR(-EINVAL);
5733 + }
5734 +
5735 + dpa_bp = devm_kzalloc(dev, *count * sizeof(*dpa_bp), GFP_KERNEL);
5736 + if (dpa_bp == NULL) {
5737 + dev_err(dev, "devm_kzalloc() failed\n");
5738 + return ERR_PTR(-ENOMEM);
5739 + }
5740 +
5741 + dev_node = of_find_node_by_path("/");
5742 + if (unlikely(dev_node == NULL)) {
5743 + dev_err(dev, "of_find_node_by_path(/) failed\n");
5744 + return ERR_PTR(-EINVAL);
5745 + }
5746 +
5747 + na = of_n_addr_cells(dev_node);
5748 + ns = of_n_size_cells(dev_node);
5749 +
5750 + for (i = 0; i < *count; i++) {
5751 + of_node_put(dev_node);
5752 +
5753 + dev_node = of_parse_phandle(dev->of_node,
5754 + "fsl,bman-buffer-pools", i);
5755 + if (dev_node == NULL) {
5756 + dev_err(dev, "of_find_node_by_phandle() failed\n");
5757 + return ERR_PTR(-EFAULT);
5758 + }
5759 +
5760 + if (unlikely(!of_device_is_compatible(dev_node, "fsl,bpool"))) {
5761 + dev_err(dev,
5762 + "!of_device_is_compatible(%s, fsl,bpool)\n",
5763 + dev_node->full_name);
5764 + dpa_bp = ERR_PTR(-EINVAL);
5765 + goto _return_of_node_put;
5766 + }
5767 +
5768 + err = of_property_read_u32(dev_node, "fsl,bpid", &bpid);
5769 + if (err) {
5770 + dev_err(dev, "Cannot find buffer pool ID in the device tree\n");
5771 + dpa_bp = ERR_PTR(-EINVAL);
5772 + goto _return_of_node_put;
5773 + }
5774 + dpa_bp[i].bpid = (uint8_t)bpid;
5775 +
5776 + bpool_cfg = of_get_property(dev_node, "fsl,bpool-ethernet-cfg",
5777 + &lenp);
5778 + if (bpool_cfg && (lenp == (2 * ns + na) * sizeof(*bpool_cfg))) {
5779 + const uint32_t *seed_pool;
5780 +
5781 + dpa_bp[i].config_count =
5782 + (int)of_read_number(bpool_cfg, ns);
5783 + dpa_bp[i].size =
5784 + (size_t)of_read_number(bpool_cfg + ns, ns);
5785 + dpa_bp[i].paddr =
5786 + of_read_number(bpool_cfg + 2 * ns, na);
5787 +
5788 + seed_pool = of_get_property(dev_node,
5789 + "fsl,bpool-ethernet-seeds", &lenp);
5790 + dpa_bp[i].seed_pool = !!seed_pool;
5791 +
5792 + } else {
5793 + dev_err(dev,
5794 + "Missing/invalid fsl,bpool-ethernet-cfg device tree entry for node %s\n",
5795 + dev_node->full_name);
5796 + dpa_bp = ERR_PTR(-EINVAL);
5797 + goto _return_of_node_put;
5798 + }
5799 + }
5800 +
5801 + sort(dpa_bp, *count, sizeof(*dpa_bp), dpa_bp_cmp, NULL);
5802 +
5803 + return dpa_bp;
5804 +
5805 +_return_of_node_put:
5806 + if (dev_node)
5807 + of_node_put(dev_node);
5808 +
5809 + return dpa_bp;
5810 +}
5811 +EXPORT_SYMBOL(dpa_bp_probe);
5812 +
5813 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
5814 + size_t count)
5815 +{
5816 + struct dpa_priv_s *priv = netdev_priv(net_dev);
5817 + int i;
5818 +
5819 + priv->dpa_bp = dpa_bp;
5820 + priv->bp_count = count;
5821 +
5822 + for (i = 0; i < count; i++) {
5823 + int err;
5824 + err = dpa_bp_alloc(&dpa_bp[i], net_dev->dev.parent);
5825 + if (err < 0) {
5826 + dpa_bp_free(priv);
5827 + priv->dpa_bp = NULL;
5828 + return err;
5829 + }
5830 + }
5831 +
5832 + return 0;
5833 +}
5834 +EXPORT_SYMBOL(dpa_bp_create);
5835 +
5836 +static int __init __cold dpa_advanced_load(void)
5837 +{
5838 + pr_info(DPA_DESCRIPTION "\n");
5839 +
5840 + return 0;
5841 +}
5842 +module_init(dpa_advanced_load);
5843 +
5844 +static void __exit __cold dpa_advanced_unload(void)
5845 +{
5846 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
5847 + KBUILD_BASENAME".c", __func__);
5848 +
5849 +}
5850 +module_exit(dpa_advanced_unload);
5851 --- /dev/null
5852 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_base.h
5853 @@ -0,0 +1,49 @@
5854 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
5855 + *
5856 + * Redistribution and use in source and binary forms, with or without
5857 + * modification, are permitted provided that the following conditions are met:
5858 + * * Redistributions of source code must retain the above copyright
5859 + * notice, this list of conditions and the following disclaimer.
5860 + * * Redistributions in binary form must reproduce the above copyright
5861 + * notice, this list of conditions and the following disclaimer in the
5862 + * documentation and/or other materials provided with the distribution.
5863 + * * Neither the name of Freescale Semiconductor nor the
5864 + * names of its contributors may be used to endorse or promote products
5865 + * derived from this software without specific prior written permission.
5866 + *
5867 + *
5868 + * ALTERNATIVELY, this software may be distributed under the terms of the
5869 + * GNU General Public License ("GPL") as published by the Free Software
5870 + * Foundation, either version 2 of that License or (at your option) any
5871 + * later version.
5872 + *
5873 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5874 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5875 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5876 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5877 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5878 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5879 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5880 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5881 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5882 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5883 + */
5884 +
5885 +#ifndef __DPAA_ETH_BASE_H
5886 +#define __DPAA_ETH_BASE_H
5887 +
5888 +#include <linux/etherdevice.h> /* struct net_device */
5889 +#include <linux/fsl_bman.h> /* struct bm_buffer */
5890 +#include <linux/of_platform.h> /* struct platform_device */
5891 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
5892 +
5893 +extern uint8_t advanced_debug;
5894 +extern const struct dpa_fq_cbs_t shared_fq_cbs;
5895 +extern int __hot dpa_shared_tx(struct sk_buff *skb, struct net_device *net_dev);
5896 +
5897 +struct dpa_bp * __cold __must_check /* __attribute__((nonnull)) */
5898 +dpa_bp_probe(struct platform_device *_of_dev, size_t *count);
5899 +int dpa_bp_create(struct net_device *net_dev, struct dpa_bp *dpa_bp,
5900 + size_t count);
5901 +
5902 +#endif /* __DPAA_ETH_BASE_H */
5903 --- /dev/null
5904 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.c
5905 @@ -0,0 +1,2076 @@
5906 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
5907 + *
5908 + * Redistribution and use in source and binary forms, with or without
5909 + * modification, are permitted provided that the following conditions are met:
5910 + * * Redistributions of source code must retain the above copyright
5911 + * notice, this list of conditions and the following disclaimer.
5912 + * * Redistributions in binary form must reproduce the above copyright
5913 + * notice, this list of conditions and the following disclaimer in the
5914 + * documentation and/or other materials provided with the distribution.
5915 + * * Neither the name of Freescale Semiconductor nor the
5916 + * names of its contributors may be used to endorse or promote products
5917 + * derived from this software without specific prior written permission.
5918 + *
5919 + *
5920 + * ALTERNATIVELY, this software may be distributed under the terms of the
5921 + * GNU General Public License ("GPL") as published by the Free Software
5922 + * Foundation, either version 2 of that License or (at your option) any
5923 + * later version.
5924 + *
5925 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
5926 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
5927 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5928 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
5929 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
5930 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5931 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5932 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5933 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
5934 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5935 + */
5936 +
5937 +#include <linux/init.h>
5938 +#include "dpaa_eth_ceetm.h"
5939 +
5940 +#define DPA_CEETM_DESCRIPTION "FSL DPAA CEETM qdisc"
5941 +
5942 +const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1] = {
5943 + [TCA_CEETM_COPT] = { .len = sizeof(struct tc_ceetm_copt) },
5944 + [TCA_CEETM_QOPS] = { .len = sizeof(struct tc_ceetm_qopt) },
5945 +};
5946 +
5947 +struct Qdisc_ops ceetm_qdisc_ops;
5948 +
5949 +/* Obtain the DCP and the SP ids from the FMan port */
5950 +static void get_dcp_and_sp(struct net_device *dev, enum qm_dc_portal *dcp_id,
5951 + unsigned int *sp_id)
5952 +{
5953 + uint32_t channel;
5954 + t_LnxWrpFmPortDev *port_dev;
5955 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
5956 + struct mac_device *mac_dev = dpa_priv->mac_dev;
5957 +
5958 + port_dev = (t_LnxWrpFmPortDev *)mac_dev->port_dev[TX];
5959 + channel = port_dev->txCh;
5960 +
5961 + *sp_id = channel & CHANNEL_SP_MASK;
5962 + pr_debug(KBUILD_BASENAME " : FM sub-portal ID %d\n", *sp_id);
5963 +
5964 + if (channel < DCP0_MAX_CHANNEL) {
5965 + *dcp_id = qm_dc_portal_fman0;
5966 + pr_debug(KBUILD_BASENAME " : DCP ID 0\n");
5967 + } else {
5968 + *dcp_id = qm_dc_portal_fman1;
5969 + pr_debug(KBUILD_BASENAME " : DCP ID 1\n");
5970 + }
5971 +}
5972 +
5973 +/* Wait for the DPAA Eth driver WQ TX FQs to empty */
5974 +static void dpaa_drain_fqs(struct net_device *dev)
5975 +{
5976 + const struct dpa_priv_s *priv = netdev_priv(dev);
5977 + struct qm_mcr_queryfq_np np;
5978 + struct qman_fq *fq;
5979 + int ret, i;
5980 +
5981 + for (i = 0; i < DPAA_ETH_TX_QUEUES; i ++) {
5982 + fq = priv->egress_fqs[i];
5983 + while (true) {
5984 + ret = qman_query_fq_np(fq, &np);
5985 + if (unlikely(ret)) {
5986 + pr_err(KBUILD_BASENAME
5987 + " : %s : unable to query FQ %x: %d\n",
5988 + __func__, fq->fqid, ret);
5989 + break;
5990 + }
5991 +
5992 + if (np.frm_cnt == 0)
5993 + break;
5994 + }
5995 + }
5996 +}
5997 +
5998 +/* Wait for the DPAA CEETM TX CQs to empty */
5999 +static void ceetm_drain_class(struct ceetm_class *cl)
6000 +{
6001 + struct qm_mcr_ceetm_cq_query cq_query;
6002 + struct qm_ceetm_cq *cq;
6003 + unsigned int idx;
6004 + int ret;
6005 +
6006 + if (!cl)
6007 + return;
6008 +
6009 + switch (cl->type) {
6010 + case CEETM_ROOT:
6011 + /* The ROOT classes aren't directly linked to CEETM CQs */
6012 + return;
6013 + case CEETM_PRIO:
6014 + cq = (struct qm_ceetm_cq*)cl->prio.cq;
6015 + break;
6016 + case CEETM_WBFS:
6017 + cq = (struct qm_ceetm_cq*)cl->wbfs.cq;
6018 + break;
6019 + }
6020 +
6021 + if (!cq || !cl->ch)
6022 + return;
6023 +
6024 + /* Build the query CQID by merging the channel and the CQ IDs */
6025 + idx = (cq->parent->idx << 4) | cq->idx;
6026 +
6027 + while (true) {
6028 + ret = qman_ceetm_query_cq(idx,
6029 + cl->ch->dcp_idx,
6030 + &cq_query);
6031 + if (unlikely(ret)) {
6032 + pr_err(KBUILD_BASENAME
6033 + " : %s : unable to query CQ %x: %d\n",
6034 + __func__, idx, ret);
6035 + break;
6036 + }
6037 +
6038 + if (cq_query.frm_cnt == 0)
6039 + break;
6040 + }
6041 +}
6042 +
6043 +/* Enqueue Rejection Notification callback */
6044 +static void ceetm_ern(struct qman_portal *portal, struct qman_fq *fq,
6045 + const struct qm_mr_entry *msg)
6046 +{
6047 + struct dpa_percpu_priv_s *dpa_percpu_priv;
6048 + struct ceetm_class_stats *cstats = NULL;
6049 + const struct dpa_priv_s *dpa_priv;
6050 + struct qm_fd fd = msg->ern.fd;
6051 + struct net_device *net_dev;
6052 + struct ceetm_fq *ceetm_fq;
6053 + struct ceetm_class *cls;
6054 + struct sk_buff *skb;
6055 +
6056 + ceetm_fq = container_of(fq, struct ceetm_fq, fq);
6057 + net_dev = ceetm_fq->net_dev;
6058 + dpa_priv = netdev_priv(net_dev);
6059 + dpa_percpu_priv = raw_cpu_ptr(dpa_priv->percpu_priv);
6060 +
6061 + /* Increment DPA counters */
6062 + dpa_percpu_priv->stats.tx_dropped++;
6063 + dpa_percpu_priv->stats.tx_fifo_errors++;
6064 + count_ern(dpa_percpu_priv, msg);
6065 +
6066 + /* Increment CEETM counters */
6067 + cls = ceetm_fq->ceetm_cls;
6068 + switch (cls->type) {
6069 + case CEETM_PRIO:
6070 + cstats = this_cpu_ptr(cls->prio.cstats);
6071 + break;
6072 + case CEETM_WBFS:
6073 + cstats = this_cpu_ptr(cls->wbfs.cstats);
6074 + break;
6075 + }
6076 +
6077 + if (cstats)
6078 + cstats->ern_drop_count++;
6079 +
6080 + /* Release the buffers that were supposed to be recycled. */
6081 + if (fd.bpid != 0xff) {
6082 + dpa_fd_release(net_dev, &fd);
6083 + return;
6084 + }
6085 +
6086 + /* Release the frames that were supposed to return on the
6087 + * confirmation path.
6088 + */
6089 + skb = _dpa_cleanup_tx_fd(dpa_priv, &fd);
6090 + dev_kfree_skb_any(skb);
6091 +}
6092 +
6093 +/* Congestion State Change Notification callback */
6094 +static void ceetm_cscn(struct qm_ceetm_ccg *ccg, void *cb_ctx, int congested)
6095 +{
6096 + struct ceetm_fq *ceetm_fq = (struct ceetm_fq *)cb_ctx;
6097 + struct dpa_priv_s *dpa_priv = netdev_priv(ceetm_fq->net_dev);
6098 + struct ceetm_class *cls = ceetm_fq->ceetm_cls;
6099 + struct ceetm_class_stats *cstats = NULL;
6100 +
6101 + switch (cls->type) {
6102 + case CEETM_PRIO:
6103 + cstats = this_cpu_ptr(cls->prio.cstats);
6104 + break;
6105 + case CEETM_WBFS:
6106 + cstats = this_cpu_ptr(cls->wbfs.cstats);
6107 + break;
6108 + }
6109 +
6110 + ceetm_fq->congested = congested;
6111 +
6112 + if (congested) {
6113 + dpa_priv->cgr_data.congestion_start_jiffies = jiffies;
6114 + dpa_priv->cgr_data.cgr_congested_count++;
6115 + if (cstats)
6116 + cstats->congested_count++;
6117 + } else {
6118 + dpa_priv->cgr_data.congested_jiffies +=
6119 + (jiffies - dpa_priv->cgr_data.congestion_start_jiffies);
6120 + }
6121 +}
6122 +
6123 +/* Allocate a ceetm fq */
6124 +static int ceetm_alloc_fq(struct ceetm_fq **fq, struct net_device *dev,
6125 + struct ceetm_class *cls)
6126 +{
6127 + *fq = kzalloc(sizeof(**fq), GFP_KERNEL);
6128 + if (!*fq)
6129 + return -ENOMEM;
6130 +
6131 + (*fq)->net_dev = dev;
6132 + (*fq)->ceetm_cls = cls;
6133 + (*fq)->congested = 0;
6134 + return 0;
6135 +}
6136 +
6137 +/* Configure a ceetm Class Congestion Group */
6138 +static int ceetm_config_ccg(struct qm_ceetm_ccg **ccg,
6139 + struct qm_ceetm_channel *channel, unsigned int id,
6140 + struct ceetm_fq *fq, struct dpa_priv_s *dpa_priv)
6141 +{
6142 + int err;
6143 + u32 cs_th;
6144 + u16 ccg_mask;
6145 + struct qm_ceetm_ccg_params ccg_params;
6146 +
6147 + err = qman_ceetm_ccg_claim(ccg, channel, id, ceetm_cscn, fq);
6148 + if (err)
6149 + return err;
6150 +
6151 + /* Configure the count mode (frames/bytes), enable congestion state
6152 + * notifications, configure the congestion entry and exit thresholds,
6153 + * enable tail-drop, configure the tail-drop mode, and set the
6154 + * overhead accounting limit
6155 + */
6156 + ccg_mask = QM_CCGR_WE_MODE |
6157 + QM_CCGR_WE_CSCN_EN |
6158 + QM_CCGR_WE_CS_THRES_IN | QM_CCGR_WE_CS_THRES_OUT |
6159 + QM_CCGR_WE_TD_EN | QM_CCGR_WE_TD_MODE |
6160 + QM_CCGR_WE_OAL;
6161 +
6162 + ccg_params.mode = 0; /* count bytes */
6163 + ccg_params.cscn_en = 1; /* generate notifications */
6164 + ccg_params.td_en = 1; /* enable tail-drop */
6165 + ccg_params.td_mode = 0; /* tail-drop on congestion state */
6166 + ccg_params.oal = (signed char)(min(sizeof(struct sk_buff) +
6167 + dpa_priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
6168 +
6169 + /* Set the congestion state thresholds according to the link speed */
6170 + if (dpa_priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
6171 + cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_10G;
6172 + else
6173 + cs_th = CONFIG_FSL_DPAA_CEETM_CCS_THRESHOLD_1G;
6174 +
6175 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_in, cs_th, 1);
6176 + qm_cgr_cs_thres_set64(&ccg_params.cs_thres_out,
6177 + cs_th * CEETM_CCGR_RATIO, 1);
6178 +
6179 + err = qman_ceetm_ccg_set(*ccg, ccg_mask, &ccg_params);
6180 + if (err)
6181 + return err;
6182 +
6183 + return 0;
6184 +}
6185 +
6186 +/* Configure a ceetm Logical Frame Queue */
6187 +static int ceetm_config_lfq(struct qm_ceetm_cq *cq, struct ceetm_fq *fq,
6188 + struct qm_ceetm_lfq **lfq)
6189 +{
6190 + int err;
6191 + u64 context_a;
6192 + u32 context_b;
6193 +
6194 + err = qman_ceetm_lfq_claim(lfq, cq);
6195 + if (err)
6196 + return err;
6197 +
6198 + /* Get the former contexts in order to preserve context B */
6199 + err = qman_ceetm_lfq_get_context(*lfq, &context_a, &context_b);
6200 + if (err)
6201 + return err;
6202 +
6203 + context_a = CEETM_CONTEXT_A;
6204 + err = qman_ceetm_lfq_set_context(*lfq, context_a, context_b);
6205 + if (err)
6206 + return err;
6207 +
6208 + (*lfq)->ern = ceetm_ern;
6209 +
6210 + err = qman_ceetm_create_fq(*lfq, &fq->fq);
6211 + if (err)
6212 + return err;
6213 +
6214 + return 0;
6215 +}
6216 +
6217 +/* Configure a prio ceetm class */
6218 +static int ceetm_config_prio_cls(struct ceetm_class *cls,
6219 + struct net_device *dev,
6220 + unsigned int id)
6221 +{
6222 + int err;
6223 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
6224 +
6225 + err = ceetm_alloc_fq(&cls->prio.fq, dev, cls);
6226 + if (err)
6227 + return err;
6228 +
6229 + /* Claim and configure the CCG */
6230 + err = ceetm_config_ccg(&cls->prio.ccg, cls->ch, id, cls->prio.fq,
6231 + dpa_priv);
6232 + if (err)
6233 + return err;
6234 +
6235 + /* Claim and configure the CQ */
6236 + err = qman_ceetm_cq_claim(&cls->prio.cq, cls->ch, id, cls->prio.ccg);
6237 + if (err)
6238 + return err;
6239 +
6240 + if (cls->shaped) {
6241 + err = qman_ceetm_channel_set_cq_cr_eligibility(cls->ch, id, 1);
6242 + if (err)
6243 + return err;
6244 +
6245 + err = qman_ceetm_channel_set_cq_er_eligibility(cls->ch, id, 1);
6246 + if (err)
6247 + return err;
6248 + }
6249 +
6250 + /* Claim and configure a LFQ */
6251 + err = ceetm_config_lfq(cls->prio.cq, cls->prio.fq, &cls->prio.lfq);
6252 + if (err)
6253 + return err;
6254 +
6255 + return 0;
6256 +}
6257 +
6258 +/* Configure a wbfs ceetm class */
6259 +static int ceetm_config_wbfs_cls(struct ceetm_class *cls,
6260 + struct net_device *dev,
6261 + unsigned int id, int type)
6262 +{
6263 + int err;
6264 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
6265 +
6266 + err = ceetm_alloc_fq(&cls->wbfs.fq, dev, cls);
6267 + if (err)
6268 + return err;
6269 +
6270 + /* Claim and configure the CCG */
6271 + err = ceetm_config_ccg(&cls->wbfs.ccg, cls->ch, id, cls->wbfs.fq,
6272 + dpa_priv);
6273 + if (err)
6274 + return err;
6275 +
6276 + /* Claim and configure the CQ */
6277 + if (type == WBFS_GRP_B)
6278 + err = qman_ceetm_cq_claim_B(&cls->wbfs.cq, cls->ch, id,
6279 + cls->wbfs.ccg);
6280 + else
6281 + err = qman_ceetm_cq_claim_A(&cls->wbfs.cq, cls->ch, id,
6282 + cls->wbfs.ccg);
6283 + if (err)
6284 + return err;
6285 +
6286 + /* Configure the CQ weight: real number multiplied by 100 to get rid
6287 + * of the fraction
6288 + */
6289 + err = qman_ceetm_set_queue_weight_in_ratio(cls->wbfs.cq,
6290 + cls->wbfs.weight * 100);
6291 + if (err)
6292 + return err;
6293 +
6294 + /* Claim and configure a LFQ */
6295 + err = ceetm_config_lfq(cls->wbfs.cq, cls->wbfs.fq, &cls->wbfs.lfq);
6296 + if (err)
6297 + return err;
6298 +
6299 + return 0;
6300 +}
6301 +
6302 +/* Find class in qdisc hash table using given handle */
6303 +static inline struct ceetm_class *ceetm_find(u32 handle, struct Qdisc *sch)
6304 +{
6305 + struct ceetm_qdisc *priv = qdisc_priv(sch);
6306 + struct Qdisc_class_common *clc;
6307 +
6308 + pr_debug(KBUILD_BASENAME " : %s : find class %X in qdisc %X\n",
6309 + __func__, handle, sch->handle);
6310 +
6311 + clc = qdisc_class_find(&priv->clhash, handle);
6312 + return clc ? container_of(clc, struct ceetm_class, common) : NULL;
6313 +}
6314 +
6315 +/* Insert a class in the qdisc's class hash */
6316 +static void ceetm_link_class(struct Qdisc *sch,
6317 + struct Qdisc_class_hash *clhash,
6318 + struct Qdisc_class_common *common)
6319 +{
6320 + sch_tree_lock(sch);
6321 + qdisc_class_hash_insert(clhash, common);
6322 + sch_tree_unlock(sch);
6323 + qdisc_class_hash_grow(sch, clhash);
6324 +}
6325 +
6326 +/* Destroy a ceetm class */
6327 +static void ceetm_cls_destroy(struct Qdisc *sch, struct ceetm_class *cl)
6328 +{
6329 + struct net_device *dev = qdisc_dev(sch);
6330 +
6331 + if (!cl)
6332 + return;
6333 +
6334 + pr_debug(KBUILD_BASENAME " : %s : destroy class %X from under %X\n",
6335 + __func__, cl->common.classid, sch->handle);
6336 +
6337 + switch (cl->type) {
6338 + case CEETM_ROOT:
6339 + if (cl->root.child) {
6340 + qdisc_destroy(cl->root.child);
6341 + cl->root.child = NULL;
6342 + }
6343 +
6344 + if (cl->ch && qman_ceetm_channel_release(cl->ch))
6345 + pr_err(KBUILD_BASENAME
6346 + " : %s : error releasing the channel %d\n",
6347 + __func__, cl->ch->idx);
6348 +
6349 + break;
6350 +
6351 + case CEETM_PRIO:
6352 + if (cl->prio.child) {
6353 + qdisc_destroy(cl->prio.child);
6354 + cl->prio.child = NULL;
6355 + }
6356 +
6357 + /* We must make sure the CQ is empty before releasing it.
6358 + * Pause all transmissions while we wait for it to drain.
6359 + */
6360 + netif_tx_stop_all_queues(dev);
6361 + ceetm_drain_class(cl);
6362 +
6363 + if (cl->prio.lfq && qman_ceetm_lfq_release(cl->prio.lfq))
6364 + pr_err(KBUILD_BASENAME
6365 + " : %s : error releasing the LFQ %d\n",
6366 + __func__, cl->prio.lfq->idx);
6367 +
6368 + if (cl->prio.cq && qman_ceetm_cq_release(cl->prio.cq))
6369 + pr_err(KBUILD_BASENAME
6370 + " : %s : error releasing the CQ %d\n",
6371 + __func__, cl->prio.cq->idx);
6372 +
6373 + if (cl->prio.ccg && qman_ceetm_ccg_release(cl->prio.ccg))
6374 + pr_err(KBUILD_BASENAME
6375 + " : %s : error releasing the CCG %d\n",
6376 + __func__, cl->prio.ccg->idx);
6377 +
6378 + kfree(cl->prio.fq);
6379 +
6380 + if (cl->prio.cstats)
6381 + free_percpu(cl->prio.cstats);
6382 +
6383 + netif_tx_wake_all_queues(dev);
6384 + break;
6385 +
6386 + case CEETM_WBFS:
6387 + /* We must make sure the CQ is empty before releasing it.
6388 + * Pause all transmissions while we wait for it to drain.
6389 + */
6390 + netif_tx_stop_all_queues(dev);
6391 + ceetm_drain_class(cl);
6392 +
6393 + if (cl->wbfs.lfq && qman_ceetm_lfq_release(cl->wbfs.lfq))
6394 + pr_err(KBUILD_BASENAME
6395 + " : %s : error releasing the LFQ %d\n",
6396 + __func__, cl->wbfs.lfq->idx);
6397 +
6398 + if (cl->wbfs.cq && qman_ceetm_cq_release(cl->wbfs.cq))
6399 + pr_err(KBUILD_BASENAME
6400 + " : %s : error releasing the CQ %d\n",
6401 + __func__, cl->wbfs.cq->idx);
6402 +
6403 + if (cl->wbfs.ccg && qman_ceetm_ccg_release(cl->wbfs.ccg))
6404 + pr_err(KBUILD_BASENAME
6405 + " : %s : error releasing the CCG %d\n",
6406 + __func__, cl->wbfs.ccg->idx);
6407 +
6408 + kfree(cl->wbfs.fq);
6409 +
6410 + if (cl->wbfs.cstats)
6411 + free_percpu(cl->wbfs.cstats);
6412 +
6413 + netif_tx_wake_all_queues(dev);
6414 + }
6415 +
6416 + tcf_block_put(cl->block);
6417 + kfree(cl);
6418 +}
6419 +
6420 +/* Destroy a ceetm qdisc */
6421 +static void ceetm_destroy(struct Qdisc *sch)
6422 +{
6423 + unsigned int ntx, i;
6424 + struct hlist_node *next;
6425 + struct ceetm_class *cl;
6426 + struct ceetm_qdisc *priv = qdisc_priv(sch);
6427 + struct net_device *dev = qdisc_dev(sch);
6428 +
6429 + pr_debug(KBUILD_BASENAME " : %s : destroy qdisc %X\n",
6430 + __func__, sch->handle);
6431 +
6432 + /* All filters need to be removed before destroying the classes */
6433 + tcf_block_put(priv->block);
6434 +
6435 + for (i = 0; i < priv->clhash.hashsize; i++) {
6436 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
6437 + tcf_block_put(cl->block);
6438 + cl->block = NULL;
6439 + }
6440 + }
6441 +
6442 + for (i = 0; i < priv->clhash.hashsize; i++) {
6443 + hlist_for_each_entry_safe(cl, next, &priv->clhash.hash[i],
6444 + common.hnode)
6445 + ceetm_cls_destroy(sch, cl);
6446 + }
6447 +
6448 + qdisc_class_hash_destroy(&priv->clhash);
6449 +
6450 + switch (priv->type) {
6451 + case CEETM_ROOT:
6452 + dpa_disable_ceetm(dev);
6453 +
6454 + if (priv->root.lni && qman_ceetm_lni_release(priv->root.lni))
6455 + pr_err(KBUILD_BASENAME
6456 + " : %s : error releasing the LNI %d\n",
6457 + __func__, priv->root.lni->idx);
6458 +
6459 + if (priv->root.sp && qman_ceetm_sp_release(priv->root.sp))
6460 + pr_err(KBUILD_BASENAME
6461 + " : %s : error releasing the SP %d\n",
6462 + __func__, priv->root.sp->idx);
6463 +
6464 + if (priv->root.qstats)
6465 + free_percpu(priv->root.qstats);
6466 +
6467 + if (!priv->root.qdiscs)
6468 + break;
6469 +
6470 + /* Destroy the pfifo qdiscs in case they haven't been attached
6471 + * to the netdev queues yet.
6472 + */
6473 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++)
6474 + if (priv->root.qdiscs[ntx])
6475 + qdisc_destroy(priv->root.qdiscs[ntx]);
6476 +
6477 + kfree(priv->root.qdiscs);
6478 + break;
6479 +
6480 + case CEETM_PRIO:
6481 + if (priv->prio.parent)
6482 + priv->prio.parent->root.child = NULL;
6483 + break;
6484 +
6485 + case CEETM_WBFS:
6486 + /* Reset the WBFS groups and priorities */
6487 + if (priv->wbfs.ch)
6488 + qman_ceetm_channel_set_group(priv->wbfs.ch, 1, 0, 0);
6489 +
6490 + if (priv->wbfs.parent)
6491 + priv->wbfs.parent->prio.child = NULL;
6492 + break;
6493 + }
6494 +}
6495 +
6496 +static int ceetm_dump(struct Qdisc *sch, struct sk_buff *skb)
6497 +{
6498 + struct Qdisc *qdisc;
6499 + unsigned int ntx, i;
6500 + struct nlattr *nest;
6501 + struct tc_ceetm_qopt qopt;
6502 + struct ceetm_qdisc_stats *qstats;
6503 + struct net_device *dev = qdisc_dev(sch);
6504 + struct ceetm_qdisc *priv = qdisc_priv(sch);
6505 +
6506 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6507 +
6508 + sch_tree_lock(sch);
6509 + memset(&qopt, 0, sizeof(qopt));
6510 + qopt.type = priv->type;
6511 + qopt.shaped = priv->shaped;
6512 +
6513 + switch (priv->type) {
6514 + case CEETM_ROOT:
6515 + /* Gather statistics from the underlying pfifo qdiscs */
6516 + sch->q.qlen = 0;
6517 + memset(&sch->bstats, 0, sizeof(sch->bstats));
6518 + memset(&sch->qstats, 0, sizeof(sch->qstats));
6519 +
6520 + for (ntx = 0; ntx < dev->num_tx_queues; ntx++) {
6521 + qdisc = netdev_get_tx_queue(dev, ntx)->qdisc_sleeping;
6522 + sch->q.qlen += qdisc->q.qlen;
6523 + sch->bstats.bytes += qdisc->bstats.bytes;
6524 + sch->bstats.packets += qdisc->bstats.packets;
6525 + sch->qstats.qlen += qdisc->qstats.qlen;
6526 + sch->qstats.backlog += qdisc->qstats.backlog;
6527 + sch->qstats.drops += qdisc->qstats.drops;
6528 + sch->qstats.requeues += qdisc->qstats.requeues;
6529 + sch->qstats.overlimits += qdisc->qstats.overlimits;
6530 + }
6531 +
6532 + for_each_online_cpu(i) {
6533 + qstats = per_cpu_ptr(priv->root.qstats, i);
6534 + sch->qstats.drops += qstats->drops;
6535 + }
6536 +
6537 + qopt.rate = priv->root.rate;
6538 + qopt.ceil = priv->root.ceil;
6539 + qopt.overhead = priv->root.overhead;
6540 + break;
6541 +
6542 + case CEETM_PRIO:
6543 + qopt.qcount = priv->prio.qcount;
6544 + break;
6545 +
6546 + case CEETM_WBFS:
6547 + qopt.qcount = priv->wbfs.qcount;
6548 + qopt.cr = priv->wbfs.cr;
6549 + qopt.er = priv->wbfs.er;
6550 + break;
6551 +
6552 + default:
6553 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
6554 + sch_tree_unlock(sch);
6555 + return -EINVAL;
6556 + }
6557 +
6558 + nest = nla_nest_start(skb, TCA_OPTIONS);
6559 + if (!nest)
6560 + goto nla_put_failure;
6561 + if (nla_put(skb, TCA_CEETM_QOPS, sizeof(qopt), &qopt))
6562 + goto nla_put_failure;
6563 + nla_nest_end(skb, nest);
6564 +
6565 + sch_tree_unlock(sch);
6566 + return skb->len;
6567 +
6568 +nla_put_failure:
6569 + sch_tree_unlock(sch);
6570 + nla_nest_cancel(skb, nest);
6571 + return -EMSGSIZE;
6572 +}
6573 +
6574 +/* Configure a root ceetm qdisc */
6575 +static int ceetm_init_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
6576 + struct tc_ceetm_qopt *qopt)
6577 +{
6578 + struct netdev_queue *dev_queue;
6579 + struct Qdisc *qdisc;
6580 + enum qm_dc_portal dcp_id;
6581 + unsigned int i, sp_id, parent_id;
6582 + int err;
6583 + u64 bps;
6584 + struct qm_ceetm_sp *sp;
6585 + struct qm_ceetm_lni *lni;
6586 + struct net_device *dev = qdisc_dev(sch);
6587 + struct dpa_priv_s *dpa_priv = netdev_priv(dev);
6588 + struct mac_device *mac_dev = dpa_priv->mac_dev;
6589 +
6590 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6591 +
6592 + /* Validate inputs */
6593 + if (sch->parent != TC_H_ROOT) {
6594 + pr_err("CEETM: a root ceetm qdisc must be root\n");
6595 + return -EINVAL;
6596 + }
6597 +
6598 + if (!mac_dev) {
6599 + pr_err("CEETM: the interface is lacking a mac\n");
6600 + return -EINVAL;
6601 + }
6602 +
6603 + /* Pre-allocate underlying pfifo qdiscs.
6604 + *
6605 + * We want to offload shaping and scheduling decisions to the hardware.
6606 + * The pfifo qdiscs will be attached to the netdev queues and will
6607 + * guide the traffic from the IP stack down to the driver with minimum
6608 + * interference.
6609 + *
6610 + * The CEETM qdiscs and classes will be crossed when the traffic
6611 + * reaches the driver.
6612 + */
6613 + priv->root.qdiscs = kcalloc(dev->num_tx_queues,
6614 + sizeof(priv->root.qdiscs[0]),
6615 + GFP_KERNEL);
6616 + if (!priv->root.qdiscs) {
6617 + return -ENOMEM;
6618 + }
6619 +
6620 + for (i = 0; i < dev->num_tx_queues; i++) {
6621 + dev_queue = netdev_get_tx_queue(dev, i);
6622 + parent_id = TC_H_MAKE(TC_H_MAJ(sch->handle),
6623 + TC_H_MIN(i + PFIFO_MIN_OFFSET));
6624 +
6625 + qdisc = qdisc_create_dflt(dev_queue, &pfifo_qdisc_ops,
6626 + parent_id);
6627 + if (!qdisc)
6628 + return -ENOMEM;
6629 +
6630 + priv->root.qdiscs[i] = qdisc;
6631 + qdisc->flags |= TCQ_F_ONETXQUEUE;
6632 + }
6633 +
6634 + sch->flags |= TCQ_F_MQROOT;
6635 +
6636 + priv->root.qstats = alloc_percpu(struct ceetm_qdisc_stats);
6637 + if (!priv->root.qstats) {
6638 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
6639 + __func__);
6640 + return -ENOMEM;
6641 + }
6642 +
6643 + priv->shaped = qopt->shaped;
6644 + priv->root.rate = qopt->rate;
6645 + priv->root.ceil = qopt->ceil;
6646 + priv->root.overhead = qopt->overhead;
6647 +
6648 + /* Claim the SP */
6649 + get_dcp_and_sp(dev, &dcp_id, &sp_id);
6650 + err = qman_ceetm_sp_claim(&sp, dcp_id, sp_id);
6651 + if (err) {
6652 + pr_err(KBUILD_BASENAME " : %s : failed to claim the SP\n",
6653 + __func__);
6654 + return err;
6655 + }
6656 +
6657 + priv->root.sp = sp;
6658 +
6659 + /* Claim the LNI - will use the same id as the SP id since SPs 0-7
6660 + * are connected to the TX FMan ports
6661 + */
6662 + err = qman_ceetm_lni_claim(&lni, dcp_id, sp_id);
6663 + if (err) {
6664 + pr_err(KBUILD_BASENAME " : %s : failed to claim the LNI\n",
6665 + __func__);
6666 + return err;
6667 + }
6668 +
6669 + priv->root.lni = lni;
6670 +
6671 + err = qman_ceetm_sp_set_lni(sp, lni);
6672 + if (err) {
6673 + pr_err(KBUILD_BASENAME " : %s : failed to link the SP and LNI\n",
6674 + __func__);
6675 + return err;
6676 + }
6677 +
6678 + lni->sp = sp;
6679 +
6680 + /* Configure the LNI shaper */
6681 + if (priv->shaped) {
6682 + err = qman_ceetm_lni_enable_shaper(lni, 1, priv->root.overhead);
6683 + if (err) {
6684 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
6685 + __func__);
6686 + return err;
6687 + }
6688 +
6689 + bps = priv->root.rate << 3; /* Bps -> bps */
6690 + err = qman_ceetm_lni_set_commit_rate_bps(lni, bps, dev->mtu);
6691 + if (err) {
6692 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
6693 + __func__);
6694 + return err;
6695 + }
6696 +
6697 + bps = priv->root.ceil << 3; /* Bps -> bps */
6698 + err = qman_ceetm_lni_set_excess_rate_bps(lni, bps, dev->mtu);
6699 + if (err) {
6700 + pr_err(KBUILD_BASENAME " : %s : failed to configure the LNI shaper\n",
6701 + __func__);
6702 + return err;
6703 + }
6704 + }
6705 +
6706 + /* TODO default configuration */
6707 +
6708 + dpa_enable_ceetm(dev);
6709 + return 0;
6710 +}
6711 +
6712 +/* Configure a prio ceetm qdisc */
6713 +static int ceetm_init_prio(struct Qdisc *sch, struct ceetm_qdisc *priv,
6714 + struct tc_ceetm_qopt *qopt)
6715 +{
6716 + int err;
6717 + unsigned int i;
6718 + struct ceetm_class *parent_cl, *child_cl;
6719 + struct Qdisc *parent_qdisc;
6720 + struct net_device *dev = qdisc_dev(sch);
6721 +
6722 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6723 +
6724 + if (sch->parent == TC_H_ROOT) {
6725 + pr_err("CEETM: a prio ceetm qdisc can not be root\n");
6726 + return -EINVAL;
6727 + }
6728 +
6729 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
6730 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
6731 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
6732 + return -EINVAL;
6733 + }
6734 +
6735 + /* Obtain the parent root ceetm_class */
6736 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
6737 +
6738 + if (!parent_cl || parent_cl->type != CEETM_ROOT) {
6739 + pr_err("CEETM: a prio ceetm qdiscs can be added only under a root ceetm class\n");
6740 + return -EINVAL;
6741 + }
6742 +
6743 + priv->prio.parent = parent_cl;
6744 + parent_cl->root.child = sch;
6745 +
6746 + priv->shaped = parent_cl->shaped;
6747 + priv->prio.qcount = qopt->qcount;
6748 + priv->prio.ch = parent_cl->ch;
6749 +
6750 + /* Create and configure qcount child classes */
6751 + for (i = 0; i < priv->prio.qcount; i++) {
6752 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
6753 + if (!child_cl) {
6754 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
6755 + __func__);
6756 + return -ENOMEM;
6757 + }
6758 +
6759 + child_cl->prio.cstats = alloc_percpu(struct ceetm_class_stats);
6760 + if (!child_cl->prio.cstats) {
6761 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
6762 + __func__);
6763 + err = -ENOMEM;
6764 + goto err_init_prio_cls;
6765 + }
6766 +
6767 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
6768 + child_cl->parent = sch;
6769 + child_cl->type = CEETM_PRIO;
6770 + child_cl->shaped = priv->shaped;
6771 + child_cl->prio.child = NULL;
6772 + child_cl->ch = priv->prio.ch;
6773 +
6774 + /* All shaped CQs have CR and ER enabled by default */
6775 + child_cl->prio.cr = child_cl->shaped;
6776 + child_cl->prio.er = child_cl->shaped;
6777 + child_cl->prio.fq = NULL;
6778 + child_cl->prio.cq = NULL;
6779 +
6780 + /* Configure the corresponding hardware CQ */
6781 + err = ceetm_config_prio_cls(child_cl, dev, i);
6782 + if (err) {
6783 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
6784 + __func__, child_cl->common.classid);
6785 + goto err_init_prio_cls;
6786 + }
6787 +
6788 + /* Add class handle in Qdisc */
6789 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
6790 + pr_debug(KBUILD_BASENAME " : %s : added ceetm prio class %X associated with CQ %d and CCG %d\n",
6791 + __func__, child_cl->common.classid,
6792 + child_cl->prio.cq->idx, child_cl->prio.ccg->idx);
6793 + }
6794 +
6795 + return 0;
6796 +
6797 +err_init_prio_cls:
6798 + ceetm_cls_destroy(sch, child_cl);
6799 + /* Note: ceetm_destroy() will be called by our caller */
6800 + return err;
6801 +}
6802 +
6803 +/* Configure a wbfs ceetm qdisc */
6804 +static int ceetm_init_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
6805 + struct tc_ceetm_qopt *qopt)
6806 +{
6807 + int err, group_b, small_group;
6808 + unsigned int i, id, prio_a, prio_b;
6809 + struct ceetm_class *parent_cl, *child_cl, *root_cl;
6810 + struct Qdisc *parent_qdisc;
6811 + struct ceetm_qdisc *parent_priv;
6812 + struct net_device *dev = qdisc_dev(sch);
6813 +
6814 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
6815 +
6816 + /* Validate inputs */
6817 + if (sch->parent == TC_H_ROOT) {
6818 + pr_err("CEETM: a wbfs ceetm qdiscs can not be root\n");
6819 + return -EINVAL;
6820 + }
6821 +
6822 + /* Obtain the parent prio ceetm qdisc */
6823 + parent_qdisc = qdisc_lookup(dev, TC_H_MAJ(sch->parent));
6824 + if (strcmp(parent_qdisc->ops->id, ceetm_qdisc_ops.id)) {
6825 + pr_err("CEETM: a ceetm qdisc can not be attached to other qdisc/class types\n");
6826 + return -EINVAL;
6827 + }
6828 +
6829 + /* Obtain the parent prio ceetm class */
6830 + parent_cl = ceetm_find(sch->parent, parent_qdisc);
6831 + parent_priv = qdisc_priv(parent_qdisc);
6832 +
6833 + if (!parent_cl || parent_cl->type != CEETM_PRIO) {
6834 + pr_err("CEETM: a wbfs ceetm qdiscs can be added only under a prio ceetm class\n");
6835 + return -EINVAL;
6836 + }
6837 +
6838 + if (!qopt->qcount || !qopt->qweight[0]) {
6839 + pr_err("CEETM: qcount and qweight are mandatory for a wbfs ceetm qdisc\n");
6840 + return -EINVAL;
6841 + }
6842 +
6843 + priv->shaped = parent_cl->shaped;
6844 +
6845 + if (!priv->shaped && (qopt->cr || qopt->er)) {
6846 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
6847 + return -EINVAL;
6848 + }
6849 +
6850 + if (priv->shaped && !(qopt->cr || qopt->er)) {
6851 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
6852 + return -EINVAL;
6853 + }
6854 +
6855 + /* Obtain the parent root ceetm class */
6856 + root_cl = parent_priv->prio.parent;
6857 + if ((root_cl->root.wbfs_grp_a && root_cl->root.wbfs_grp_b) ||
6858 + root_cl->root.wbfs_grp_large) {
6859 + pr_err("CEETM: no more wbfs classes are available\n");
6860 + return -EINVAL;
6861 + }
6862 +
6863 + if ((root_cl->root.wbfs_grp_a || root_cl->root.wbfs_grp_b) &&
6864 + qopt->qcount == CEETM_MAX_WBFS_QCOUNT) {
6865 + pr_err("CEETM: only %d wbfs classes are available\n",
6866 + CEETM_MIN_WBFS_QCOUNT);
6867 + return -EINVAL;
6868 + }
6869 +
6870 + priv->wbfs.parent = parent_cl;
6871 + parent_cl->prio.child = sch;
6872 +
6873 + priv->wbfs.qcount = qopt->qcount;
6874 + priv->wbfs.cr = qopt->cr;
6875 + priv->wbfs.er = qopt->er;
6876 + priv->wbfs.ch = parent_cl->ch;
6877 +
6878 + /* Configure the hardware wbfs channel groups */
6879 + if (priv->wbfs.qcount == CEETM_MAX_WBFS_QCOUNT) {
6880 + /* Configure the large group A */
6881 + priv->wbfs.group_type = WBFS_GRP_LARGE;
6882 + small_group = false;
6883 + group_b = false;
6884 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
6885 + prio_b = prio_a;
6886 +
6887 + } else if (root_cl->root.wbfs_grp_a) {
6888 + /* Configure the group B */
6889 + priv->wbfs.group_type = WBFS_GRP_B;
6890 +
6891 + err = qman_ceetm_channel_get_group(priv->wbfs.ch, &small_group,
6892 + &prio_a, &prio_b);
6893 + if (err) {
6894 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
6895 + __func__);
6896 + return err;
6897 + }
6898 +
6899 + small_group = true;
6900 + group_b = true;
6901 + prio_b = TC_H_MIN(parent_cl->common.classid) - 1;
6902 + /* If group A isn't configured, configure it as group B */
6903 + prio_a = prio_a ? : prio_b;
6904 +
6905 + } else {
6906 + /* Configure the small group A */
6907 + priv->wbfs.group_type = WBFS_GRP_A;
6908 +
6909 + err = qman_ceetm_channel_get_group(priv->wbfs.ch, &small_group,
6910 + &prio_a, &prio_b);
6911 + if (err) {
6912 + pr_err(KBUILD_BASENAME " : %s : failed to get group details\n",
6913 + __func__);
6914 + return err;
6915 + }
6916 +
6917 + small_group = true;
6918 + group_b = false;
6919 + prio_a = TC_H_MIN(parent_cl->common.classid) - 1;
6920 + /* If group B isn't configured, configure it as group A */
6921 + prio_b = prio_b ? : prio_a;
6922 + }
6923 +
6924 + err = qman_ceetm_channel_set_group(priv->wbfs.ch, small_group, prio_a,
6925 + prio_b);
6926 + if (err)
6927 + return err;
6928 +
6929 + if (priv->shaped) {
6930 + err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch,
6931 + group_b,
6932 + priv->wbfs.cr);
6933 + if (err) {
6934 + pr_err(KBUILD_BASENAME " : %s : failed to set group CR eligibility\n",
6935 + __func__);
6936 + return err;
6937 + }
6938 +
6939 + err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch,
6940 + group_b,
6941 + priv->wbfs.er);
6942 + if (err) {
6943 + pr_err(KBUILD_BASENAME " : %s : failed to set group ER eligibility\n",
6944 + __func__);
6945 + return err;
6946 + }
6947 + }
6948 +
6949 + /* Create qcount child classes */
6950 + for (i = 0; i < priv->wbfs.qcount; i++) {
6951 + child_cl = kzalloc(sizeof(*child_cl), GFP_KERNEL);
6952 + if (!child_cl) {
6953 + pr_err(KBUILD_BASENAME " : %s : kzalloc() failed\n",
6954 + __func__);
6955 + return -ENOMEM;
6956 + }
6957 +
6958 + child_cl->wbfs.cstats = alloc_percpu(struct ceetm_class_stats);
6959 + if (!child_cl->wbfs.cstats) {
6960 + pr_err(KBUILD_BASENAME " : %s : alloc_percpu() failed\n",
6961 + __func__);
6962 + err = -ENOMEM;
6963 + goto err_init_wbfs_cls;
6964 + }
6965 +
6966 + child_cl->common.classid = TC_H_MAKE(sch->handle, (i + 1));
6967 + child_cl->parent = sch;
6968 + child_cl->type = CEETM_WBFS;
6969 + child_cl->shaped = priv->shaped;
6970 + child_cl->wbfs.fq = NULL;
6971 + child_cl->wbfs.cq = NULL;
6972 + child_cl->wbfs.weight = qopt->qweight[i];
6973 + child_cl->ch = priv->wbfs.ch;
6974 +
6975 + if (priv->wbfs.group_type == WBFS_GRP_B)
6976 + id = WBFS_GRP_B_OFFSET + i;
6977 + else
6978 + id = WBFS_GRP_A_OFFSET + i;
6979 +
6980 + err = ceetm_config_wbfs_cls(child_cl, dev, id,
6981 + priv->wbfs.group_type);
6982 + if (err) {
6983 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
6984 + __func__, child_cl->common.classid);
6985 + goto err_init_wbfs_cls;
6986 + }
6987 +
6988 + /* Add class handle in Qdisc */
6989 + ceetm_link_class(sch, &priv->clhash, &child_cl->common);
6990 + pr_debug(KBUILD_BASENAME " : %s : added ceetm wbfs class %X associated with CQ %d and CCG %d\n",
6991 + __func__, child_cl->common.classid,
6992 + child_cl->wbfs.cq->idx, child_cl->wbfs.ccg->idx);
6993 + }
6994 +
6995 + /* Signal the root class that a group has been configured */
6996 + switch (priv->wbfs.group_type) {
6997 + case WBFS_GRP_LARGE:
6998 + root_cl->root.wbfs_grp_large = true;
6999 + break;
7000 + case WBFS_GRP_A:
7001 + root_cl->root.wbfs_grp_a = true;
7002 + break;
7003 + case WBFS_GRP_B:
7004 + root_cl->root.wbfs_grp_b = true;
7005 + break;
7006 + }
7007 +
7008 + return 0;
7009 +
7010 +err_init_wbfs_cls:
7011 + ceetm_cls_destroy(sch, child_cl);
7012 + /* Note: ceetm_destroy() will be called by our caller */
7013 + return err;
7014 +}
7015 +
7016 +/* Configure a generic ceetm qdisc */
7017 +static int ceetm_init(struct Qdisc *sch, struct nlattr *opt)
7018 +{
7019 + struct tc_ceetm_qopt *qopt;
7020 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
7021 + int ret;
7022 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7023 + struct net_device *dev = qdisc_dev(sch);
7024 +
7025 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
7026 +
7027 + if (!netif_is_multiqueue(dev))
7028 + return -EOPNOTSUPP;
7029 +
7030 + if (!opt) {
7031 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
7032 + return -EINVAL;
7033 + }
7034 +
7035 + ret = tcf_block_get(&priv->block, &priv->filter_list);
7036 + if (ret)
7037 + return ret;
7038 +
7039 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL);
7040 + if (ret < 0) {
7041 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
7042 + return ret;
7043 + }
7044 +
7045 + if (!tb[TCA_CEETM_QOPS]) {
7046 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
7047 + return -EINVAL;
7048 + }
7049 +
7050 + if (TC_H_MIN(sch->handle)) {
7051 + pr_err("CEETM: a qdisc should not have a minor\n");
7052 + return -EINVAL;
7053 + }
7054 +
7055 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
7056 +
7057 + /* Initialize the class hash list. Each qdisc has its own class hash */
7058 + ret = qdisc_class_hash_init(&priv->clhash);
7059 + if (ret < 0) {
7060 + pr_err(KBUILD_BASENAME " : %s : qdisc_class_hash_init failed\n",
7061 + __func__);
7062 + return ret;
7063 + }
7064 +
7065 + priv->type = qopt->type;
7066 +
7067 + switch (priv->type) {
7068 + case CEETM_ROOT:
7069 + netif_tx_stop_all_queues(dev);
7070 + dpaa_drain_fqs(dev);
7071 + ret = ceetm_init_root(sch, priv, qopt);
7072 + netif_tx_wake_all_queues(dev);
7073 + break;
7074 + case CEETM_PRIO:
7075 + ret = ceetm_init_prio(sch, priv, qopt);
7076 + break;
7077 + case CEETM_WBFS:
7078 + ret = ceetm_init_wbfs(sch, priv, qopt);
7079 + break;
7080 + default:
7081 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
7082 + /* Note: ceetm_destroy() will be called by our caller */
7083 + ret = -EINVAL;
7084 + }
7085 +
7086 + return ret;
7087 +}
7088 +
7089 +/* Edit a root ceetm qdisc */
7090 +static int ceetm_change_root(struct Qdisc *sch, struct ceetm_qdisc *priv,
7091 + struct net_device *dev,
7092 + struct tc_ceetm_qopt *qopt)
7093 +{
7094 + int err = 0;
7095 + u64 bps;
7096 +
7097 + if (priv->shaped != (bool)qopt->shaped) {
7098 + pr_err("CEETM: qdisc %X is %s\n", sch->handle,
7099 + priv->shaped ? "shaped" : "unshaped");
7100 + return -EINVAL;
7101 + }
7102 +
7103 + /* Nothing to modify for unshaped qdiscs */
7104 + if (!priv->shaped)
7105 + return 0;
7106 +
7107 + /* Configure the LNI shaper */
7108 + if (priv->root.overhead != qopt->overhead) {
7109 + err = qman_ceetm_lni_enable_shaper(priv->root.lni, 1,
7110 + qopt->overhead);
7111 + if (err)
7112 + goto change_err;
7113 + priv->root.overhead = qopt->overhead;
7114 + }
7115 +
7116 + if (priv->root.rate != qopt->rate) {
7117 + bps = qopt->rate << 3; /* Bps -> bps */
7118 + err = qman_ceetm_lni_set_commit_rate_bps(priv->root.lni, bps,
7119 + dev->mtu);
7120 + if (err)
7121 + goto change_err;
7122 + priv->root.rate = qopt->rate;
7123 + }
7124 +
7125 + if (priv->root.ceil != qopt->ceil) {
7126 + bps = qopt->ceil << 3; /* Bps -> bps */
7127 + err = qman_ceetm_lni_set_excess_rate_bps(priv->root.lni, bps,
7128 + dev->mtu);
7129 + if (err)
7130 + goto change_err;
7131 + priv->root.ceil = qopt->ceil;
7132 + }
7133 +
7134 + return 0;
7135 +
7136 +change_err:
7137 + pr_err(KBUILD_BASENAME " : %s : failed to configure the root ceetm qdisc %X\n",
7138 + __func__, sch->handle);
7139 + return err;
7140 +}
7141 +
7142 +/* Edit a wbfs ceetm qdisc */
7143 +static int ceetm_change_wbfs(struct Qdisc *sch, struct ceetm_qdisc *priv,
7144 + struct tc_ceetm_qopt *qopt)
7145 +{
7146 + int err;
7147 + bool group_b;
7148 +
7149 + if (qopt->qcount) {
7150 + pr_err("CEETM: the qcount can not be modified\n");
7151 + return -EINVAL;
7152 + }
7153 +
7154 + if (qopt->qweight[0]) {
7155 + pr_err("CEETM: the qweight can be modified through the wbfs classes\n");
7156 + return -EINVAL;
7157 + }
7158 +
7159 + if (!priv->shaped && (qopt->cr || qopt->er)) {
7160 + pr_err("CEETM: CR/ER can be enabled only for shaped wbfs ceetm qdiscs\n");
7161 + return -EINVAL;
7162 + }
7163 +
7164 + if (priv->shaped && !(qopt->cr || qopt->er)) {
7165 + pr_err("CEETM: either CR or ER must be enabled for shaped wbfs ceetm qdiscs\n");
7166 + return -EINVAL;
7167 + }
7168 +
7169 + /* Nothing to modify for unshaped qdiscs */
7170 + if (!priv->shaped)
7171 + return 0;
7172 +
7173 + group_b = priv->wbfs.group_type == WBFS_GRP_B;
7174 +
7175 + if (qopt->cr != priv->wbfs.cr) {
7176 + err = qman_ceetm_channel_set_group_cr_eligibility(priv->wbfs.ch,
7177 + group_b,
7178 + qopt->cr);
7179 + if (err)
7180 + goto change_err;
7181 + priv->wbfs.cr = qopt->cr;
7182 + }
7183 +
7184 + if (qopt->er != priv->wbfs.er) {
7185 + err = qman_ceetm_channel_set_group_er_eligibility(priv->wbfs.ch,
7186 + group_b,
7187 + qopt->er);
7188 + if (err)
7189 + goto change_err;
7190 + priv->wbfs.er = qopt->er;
7191 + }
7192 +
7193 + return 0;
7194 +
7195 +change_err:
7196 + pr_err(KBUILD_BASENAME " : %s : failed to configure the wbfs ceetm qdisc %X\n",
7197 + __func__, sch->handle);
7198 + return err;
7199 +}
7200 +
7201 +/* Edit a ceetm qdisc */
7202 +static int ceetm_change(struct Qdisc *sch, struct nlattr *opt)
7203 +{
7204 + struct tc_ceetm_qopt *qopt;
7205 + struct nlattr *tb[TCA_CEETM_QOPS + 1];
7206 + int ret;
7207 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7208 + struct net_device *dev = qdisc_dev(sch);
7209 +
7210 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
7211 +
7212 + ret = nla_parse_nested(tb, TCA_CEETM_QOPS, opt, ceetm_policy, NULL);
7213 + if (ret < 0) {
7214 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
7215 + return ret;
7216 + }
7217 +
7218 + if (!tb[TCA_CEETM_QOPS]) {
7219 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
7220 + return -EINVAL;
7221 + }
7222 +
7223 + if (TC_H_MIN(sch->handle)) {
7224 + pr_err("CEETM: a qdisc should not have a minor\n");
7225 + return -EINVAL;
7226 + }
7227 +
7228 + qopt = nla_data(tb[TCA_CEETM_QOPS]);
7229 +
7230 + if (priv->type != qopt->type) {
7231 + pr_err("CEETM: qdisc %X is not of the provided type\n",
7232 + sch->handle);
7233 + return -EINVAL;
7234 + }
7235 +
7236 + switch (priv->type) {
7237 + case CEETM_ROOT:
7238 + ret = ceetm_change_root(sch, priv, dev, qopt);
7239 + break;
7240 + case CEETM_PRIO:
7241 + pr_err("CEETM: prio qdiscs can not be modified\n");
7242 + ret = -EINVAL;
7243 + break;
7244 + case CEETM_WBFS:
7245 + ret = ceetm_change_wbfs(sch, priv, qopt);
7246 + break;
7247 + default:
7248 + pr_err(KBUILD_BASENAME " : %s : invalid qdisc\n", __func__);
7249 + ret = -EINVAL;
7250 + }
7251 +
7252 + return ret;
7253 +}
7254 +
7255 +/* Graft the underlying pfifo qdiscs to the netdev queues.
7256 + * It's safe to remove our references at this point, since the kernel will
7257 + * destroy the qdiscs on its own and no cleanup from our part is required.
7258 + */
7259 +static void ceetm_attach(struct Qdisc *sch)
7260 +{
7261 + struct net_device *dev = qdisc_dev(sch);
7262 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7263 + struct Qdisc *qdisc, *old_qdisc;
7264 + unsigned int i;
7265 +
7266 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
7267 +
7268 + for (i = 0; i < dev->num_tx_queues; i++) {
7269 + qdisc = priv->root.qdiscs[i];
7270 + old_qdisc = dev_graft_qdisc(qdisc->dev_queue, qdisc);
7271 + if (old_qdisc)
7272 + qdisc_destroy(old_qdisc);
7273 + }
7274 +
7275 + kfree(priv->root.qdiscs);
7276 + priv->root.qdiscs = NULL;
7277 +}
7278 +
7279 +static unsigned long ceetm_cls_search(struct Qdisc *sch, u32 handle)
7280 +{
7281 + return (unsigned long)ceetm_find(handle, sch);
7282 +}
7283 +
7284 +static int ceetm_cls_change_root(struct ceetm_class *cl,
7285 + struct tc_ceetm_copt *copt,
7286 + struct net_device *dev)
7287 +{
7288 + int err;
7289 + u64 bps;
7290 +
7291 + if ((bool)copt->shaped != cl->shaped) {
7292 + pr_err("CEETM: class %X is %s\n", cl->common.classid,
7293 + cl->shaped ? "shaped" : "unshaped");
7294 + return -EINVAL;
7295 + }
7296 +
7297 + if (cl->shaped && cl->root.rate != copt->rate) {
7298 + bps = copt->rate << 3; /* Bps -> bps */
7299 + err = qman_ceetm_channel_set_commit_rate_bps(cl->ch, bps,
7300 + dev->mtu);
7301 + if (err)
7302 + goto change_cls_err;
7303 + cl->root.rate = copt->rate;
7304 + }
7305 +
7306 + if (cl->shaped && cl->root.ceil != copt->ceil) {
7307 + bps = copt->ceil << 3; /* Bps -> bps */
7308 + err = qman_ceetm_channel_set_excess_rate_bps(cl->ch, bps,
7309 + dev->mtu);
7310 + if (err)
7311 + goto change_cls_err;
7312 + cl->root.ceil = copt->ceil;
7313 + }
7314 +
7315 + if (!cl->shaped && cl->root.tbl != copt->tbl) {
7316 + err = qman_ceetm_channel_set_weight(cl->ch, copt->tbl);
7317 + if (err)
7318 + goto change_cls_err;
7319 + cl->root.tbl = copt->tbl;
7320 + }
7321 +
7322 + return 0;
7323 +
7324 +change_cls_err:
7325 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm root class %X\n",
7326 + __func__, cl->common.classid);
7327 + return err;
7328 +}
7329 +
7330 +static int ceetm_cls_change_prio(struct ceetm_class *cl,
7331 + struct tc_ceetm_copt *copt)
7332 +{
7333 + int err;
7334 +
7335 + if (!cl->shaped && (copt->cr || copt->er)) {
7336 + pr_err("CEETM: only shaped classes can have CR and ER enabled\n");
7337 + return -EINVAL;
7338 + }
7339 +
7340 + if (cl->prio.cr != (bool)copt->cr) {
7341 + err = qman_ceetm_channel_set_cq_cr_eligibility(
7342 + cl->prio.cq->parent,
7343 + cl->prio.cq->idx,
7344 + copt->cr);
7345 + if (err)
7346 + goto change_cls_err;
7347 + cl->prio.cr = copt->cr;
7348 + }
7349 +
7350 + if (cl->prio.er != (bool)copt->er) {
7351 + err = qman_ceetm_channel_set_cq_er_eligibility(
7352 + cl->prio.cq->parent,
7353 + cl->prio.cq->idx,
7354 + copt->er);
7355 + if (err)
7356 + goto change_cls_err;
7357 + cl->prio.er = copt->er;
7358 + }
7359 +
7360 + return 0;
7361 +
7362 +change_cls_err:
7363 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm prio class %X\n",
7364 + __func__, cl->common.classid);
7365 + return err;
7366 +}
7367 +
7368 +static int ceetm_cls_change_wbfs(struct ceetm_class *cl,
7369 + struct tc_ceetm_copt *copt)
7370 +{
7371 + int err;
7372 +
7373 + if (copt->weight != cl->wbfs.weight) {
7374 + /* Configure the CQ weight: real number multiplied by 100 to
7375 + * get rid of the fraction
7376 + */
7377 + err = qman_ceetm_set_queue_weight_in_ratio(cl->wbfs.cq,
7378 + copt->weight * 100);
7379 +
7380 + if (err) {
7381 + pr_err(KBUILD_BASENAME " : %s : failed to configure the ceetm wbfs class %X\n",
7382 + __func__, cl->common.classid);
7383 + return err;
7384 + }
7385 +
7386 + cl->wbfs.weight = copt->weight;
7387 + }
7388 +
7389 + return 0;
7390 +}
7391 +
7392 +/* Add a ceetm root class or configure a ceetm root/prio/wbfs class */
7393 +static int ceetm_cls_change(struct Qdisc *sch, u32 classid, u32 parentid,
7394 + struct nlattr **tca, unsigned long *arg)
7395 +{
7396 + int err;
7397 + u64 bps;
7398 + struct ceetm_qdisc *priv;
7399 + struct ceetm_class *cl = (struct ceetm_class *)*arg;
7400 + struct nlattr *opt = tca[TCA_OPTIONS];
7401 + struct nlattr *tb[__TCA_CEETM_MAX];
7402 + struct tc_ceetm_copt *copt;
7403 + struct qm_ceetm_channel *channel;
7404 + struct net_device *dev = qdisc_dev(sch);
7405 +
7406 + pr_debug(KBUILD_BASENAME " : %s : classid %X under qdisc %X\n",
7407 + __func__, classid, sch->handle);
7408 +
7409 + if (strcmp(sch->ops->id, ceetm_qdisc_ops.id)) {
7410 + pr_err("CEETM: a ceetm class can not be attached to other qdisc/class types\n");
7411 + return -EINVAL;
7412 + }
7413 +
7414 + priv = qdisc_priv(sch);
7415 +
7416 + if (!opt) {
7417 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
7418 + return -EINVAL;
7419 + }
7420 +
7421 + if (!cl && sch->handle != parentid) {
7422 + pr_err("CEETM: classes can be attached to the root ceetm qdisc only\n");
7423 + return -EINVAL;
7424 + }
7425 +
7426 + if (!cl && priv->type != CEETM_ROOT) {
7427 + pr_err("CEETM: root ceetm classes can be attached to the root ceetm qdisc only\n");
7428 + return -EINVAL;
7429 + }
7430 +
7431 + err = nla_parse_nested(tb, TCA_CEETM_COPT, opt, ceetm_policy, NULL);
7432 + if (err < 0) {
7433 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
7434 + return -EINVAL;
7435 + }
7436 +
7437 + if (!tb[TCA_CEETM_COPT]) {
7438 + pr_err(KBUILD_BASENAME " : %s : tc error\n", __func__);
7439 + return -EINVAL;
7440 + }
7441 +
7442 + if (TC_H_MIN(classid) >= PFIFO_MIN_OFFSET) {
7443 + pr_err("CEETM: only minors 0x01 to 0x20 can be used for ceetm root classes\n");
7444 + return -EINVAL;
7445 + }
7446 +
7447 + copt = nla_data(tb[TCA_CEETM_COPT]);
7448 +
7449 + /* Configure an existing ceetm class */
7450 + if (cl) {
7451 + if (copt->type != cl->type) {
7452 + pr_err("CEETM: class %X is not of the provided type\n",
7453 + cl->common.classid);
7454 + return -EINVAL;
7455 + }
7456 +
7457 + switch (copt->type) {
7458 + case CEETM_ROOT:
7459 + return ceetm_cls_change_root(cl, copt, dev);
7460 +
7461 + case CEETM_PRIO:
7462 + return ceetm_cls_change_prio(cl, copt);
7463 +
7464 + case CEETM_WBFS:
7465 + return ceetm_cls_change_wbfs(cl, copt);
7466 +
7467 + default:
7468 + pr_err(KBUILD_BASENAME " : %s : invalid class\n",
7469 + __func__);
7470 + return -EINVAL;
7471 + }
7472 + }
7473 +
7474 + /* Add a new root ceetm class */
7475 + if (copt->type != CEETM_ROOT) {
7476 + pr_err("CEETM: only root ceetm classes can be attached to the root ceetm qdisc\n");
7477 + return -EINVAL;
7478 + }
7479 +
7480 + if (copt->shaped && !priv->shaped) {
7481 + pr_err("CEETM: can not add a shaped ceetm root class under an unshaped ceetm root qdisc\n");
7482 + return -EINVAL;
7483 + }
7484 +
7485 + cl = kzalloc(sizeof(*cl), GFP_KERNEL);
7486 + if (!cl)
7487 + return -ENOMEM;
7488 +
7489 + err = tcf_block_get(&cl->block, &cl->filter_list);
7490 + if (err) {
7491 + kfree(cl);
7492 + return err;
7493 + }
7494 +
7495 + cl->type = copt->type;
7496 + cl->shaped = copt->shaped;
7497 + cl->root.rate = copt->rate;
7498 + cl->root.ceil = copt->ceil;
7499 + cl->root.tbl = copt->tbl;
7500 +
7501 + cl->common.classid = classid;
7502 + cl->parent = sch;
7503 + cl->root.child = NULL;
7504 + cl->root.wbfs_grp_a = false;
7505 + cl->root.wbfs_grp_b = false;
7506 + cl->root.wbfs_grp_large = false;
7507 +
7508 + /* Claim a CEETM channel */
7509 + err = qman_ceetm_channel_claim(&channel, priv->root.lni);
7510 + if (err) {
7511 + pr_err(KBUILD_BASENAME " : %s : failed to claim a channel\n",
7512 + __func__);
7513 + goto claim_err;
7514 + }
7515 +
7516 + cl->ch = channel;
7517 +
7518 + if (cl->shaped) {
7519 + /* Configure the channel shaper */
7520 + err = qman_ceetm_channel_enable_shaper(channel, 1);
7521 + if (err)
7522 + goto channel_err;
7523 +
7524 + bps = cl->root.rate << 3; /* Bps -> bps */
7525 + err = qman_ceetm_channel_set_commit_rate_bps(channel, bps,
7526 + dev->mtu);
7527 + if (err)
7528 + goto channel_err;
7529 +
7530 + bps = cl->root.ceil << 3; /* Bps -> bps */
7531 + err = qman_ceetm_channel_set_excess_rate_bps(channel, bps,
7532 + dev->mtu);
7533 + if (err)
7534 + goto channel_err;
7535 +
7536 + } else {
7537 + /* Configure the uFQ algorithm */
7538 + err = qman_ceetm_channel_set_weight(channel, cl->root.tbl);
7539 + if (err)
7540 + goto channel_err;
7541 + }
7542 +
7543 + /* Add class handle in Qdisc */
7544 + ceetm_link_class(sch, &priv->clhash, &cl->common);
7545 +
7546 + pr_debug(KBUILD_BASENAME " : %s : configured class %X associated with channel %d\n",
7547 + __func__, classid, channel->idx);
7548 + *arg = (unsigned long)cl;
7549 + return 0;
7550 +
7551 +channel_err:
7552 + pr_err(KBUILD_BASENAME " : %s : failed to configure the channel %d\n",
7553 + __func__, channel->idx);
7554 + if (qman_ceetm_channel_release(channel))
7555 + pr_err(KBUILD_BASENAME " : %s : failed to release the channel %d\n",
7556 + __func__, channel->idx);
7557 +claim_err:
7558 + tcf_block_put(cl->block);
7559 + kfree(cl);
7560 + return err;
7561 +}
7562 +
7563 +static void ceetm_cls_walk(struct Qdisc *sch, struct qdisc_walker *arg)
7564 +{
7565 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7566 + struct ceetm_class *cl;
7567 + unsigned int i;
7568 +
7569 + pr_debug(KBUILD_BASENAME " : %s : qdisc %X\n", __func__, sch->handle);
7570 +
7571 + if (arg->stop)
7572 + return;
7573 +
7574 + for (i = 0; i < priv->clhash.hashsize; i++) {
7575 + hlist_for_each_entry(cl, &priv->clhash.hash[i], common.hnode) {
7576 + if (arg->count < arg->skip) {
7577 + arg->count++;
7578 + continue;
7579 + }
7580 + if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
7581 + arg->stop = 1;
7582 + return;
7583 + }
7584 + arg->count++;
7585 + }
7586 + }
7587 +}
7588 +
7589 +static int ceetm_cls_dump(struct Qdisc *sch, unsigned long arg,
7590 + struct sk_buff *skb, struct tcmsg *tcm)
7591 +{
7592 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7593 + struct nlattr *nest;
7594 + struct tc_ceetm_copt copt;
7595 +
7596 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
7597 + __func__, cl->common.classid, sch->handle);
7598 +
7599 + sch_tree_lock(sch);
7600 +
7601 + tcm->tcm_parent = ((struct Qdisc *)cl->parent)->handle;
7602 + tcm->tcm_handle = cl->common.classid;
7603 +
7604 + memset(&copt, 0, sizeof(copt));
7605 +
7606 + copt.shaped = cl->shaped;
7607 + copt.type = cl->type;
7608 +
7609 + switch (cl->type) {
7610 + case CEETM_ROOT:
7611 + if (cl->root.child)
7612 + tcm->tcm_info = cl->root.child->handle;
7613 +
7614 + copt.rate = cl->root.rate;
7615 + copt.ceil = cl->root.ceil;
7616 + copt.tbl = cl->root.tbl;
7617 + break;
7618 +
7619 + case CEETM_PRIO:
7620 + if (cl->prio.child)
7621 + tcm->tcm_info = cl->prio.child->handle;
7622 +
7623 + copt.cr = cl->prio.cr;
7624 + copt.er = cl->prio.er;
7625 + break;
7626 +
7627 + case CEETM_WBFS:
7628 + copt.weight = cl->wbfs.weight;
7629 + break;
7630 + }
7631 +
7632 + nest = nla_nest_start(skb, TCA_OPTIONS);
7633 + if (!nest)
7634 + goto nla_put_failure;
7635 + if (nla_put(skb, TCA_CEETM_COPT, sizeof(copt), &copt))
7636 + goto nla_put_failure;
7637 + nla_nest_end(skb, nest);
7638 + sch_tree_unlock(sch);
7639 + return skb->len;
7640 +
7641 +nla_put_failure:
7642 + sch_tree_unlock(sch);
7643 + nla_nest_cancel(skb, nest);
7644 + return -EMSGSIZE;
7645 +}
7646 +
7647 +static int ceetm_cls_delete(struct Qdisc *sch, unsigned long arg)
7648 +{
7649 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7650 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7651 +
7652 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
7653 + __func__, cl->common.classid, sch->handle);
7654 +
7655 + sch_tree_lock(sch);
7656 + qdisc_class_hash_remove(&priv->clhash, &cl->common);
7657 +
7658 + sch_tree_unlock(sch);
7659 + ceetm_cls_destroy(sch, cl);
7660 + return 0;
7661 +}
7662 +
7663 +/* Get the class' child qdisc, if any */
7664 +static struct Qdisc *ceetm_cls_leaf(struct Qdisc *sch, unsigned long arg)
7665 +{
7666 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7667 +
7668 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n",
7669 + __func__, cl->common.classid, sch->handle);
7670 +
7671 + switch (cl->type) {
7672 + case CEETM_ROOT:
7673 + return cl->root.child;
7674 +
7675 + case CEETM_PRIO:
7676 + return cl->prio.child;
7677 + }
7678 +
7679 + return NULL;
7680 +}
7681 +
7682 +static int ceetm_cls_graft(struct Qdisc *sch, unsigned long arg,
7683 + struct Qdisc *new, struct Qdisc **old)
7684 +{
7685 + if (new && strcmp(new->ops->id, ceetm_qdisc_ops.id)) {
7686 + pr_err("CEETM: only ceetm qdiscs can be attached to ceetm classes\n");
7687 + return -EOPNOTSUPP;
7688 + }
7689 +
7690 + return 0;
7691 +}
7692 +
7693 +static int ceetm_cls_dump_stats(struct Qdisc *sch, unsigned long arg,
7694 + struct gnet_dump *d)
7695 +{
7696 + unsigned int i;
7697 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7698 + struct gnet_stats_basic_packed tmp_bstats;
7699 + struct ceetm_class_stats *cstats = NULL;
7700 + struct qm_ceetm_cq *cq = NULL;
7701 + struct tc_ceetm_xstats xstats;
7702 +
7703 + memset(&xstats, 0, sizeof(xstats));
7704 + memset(&tmp_bstats, 0, sizeof(tmp_bstats));
7705 +
7706 + switch (cl->type) {
7707 + case CEETM_ROOT:
7708 + return 0;
7709 + case CEETM_PRIO:
7710 + cq = cl->prio.cq;
7711 + break;
7712 + case CEETM_WBFS:
7713 + cq = cl->wbfs.cq;
7714 + break;
7715 + }
7716 +
7717 + for_each_online_cpu(i) {
7718 + switch (cl->type) {
7719 + case CEETM_PRIO:
7720 + cstats = per_cpu_ptr(cl->prio.cstats, i);
7721 + break;
7722 + case CEETM_WBFS:
7723 + cstats = per_cpu_ptr(cl->wbfs.cstats, i);
7724 + break;
7725 + }
7726 +
7727 + if (cstats) {
7728 + xstats.ern_drop_count += cstats->ern_drop_count;
7729 + xstats.congested_count += cstats->congested_count;
7730 + tmp_bstats.bytes += cstats->bstats.bytes;
7731 + tmp_bstats.packets += cstats->bstats.packets;
7732 + }
7733 + }
7734 +
7735 + if (gnet_stats_copy_basic(qdisc_root_sleeping_running(sch),
7736 + d, NULL, &tmp_bstats) < 0)
7737 + return -1;
7738 +
7739 + if (cq && qman_ceetm_cq_get_dequeue_statistics(cq, 0,
7740 + &xstats.frame_count,
7741 + &xstats.byte_count))
7742 + return -1;
7743 +
7744 + return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
7745 +}
7746 +
7747 +static struct tcf_block *ceetm_tcf_block(struct Qdisc *sch, unsigned long arg)
7748 +{
7749 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7750 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7751 + struct tcf_block *block = cl ? cl->block : priv->block;
7752 +
7753 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
7754 + cl ? cl->common.classid : 0, sch->handle);
7755 + return block;
7756 +}
7757 +
7758 +static unsigned long ceetm_tcf_bind(struct Qdisc *sch, unsigned long parent,
7759 + u32 classid)
7760 +{
7761 + struct ceetm_class *cl = ceetm_find(classid, sch);
7762 +
7763 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
7764 + cl ? cl->common.classid : 0, sch->handle);
7765 + return (unsigned long)cl;
7766 +}
7767 +
7768 +static void ceetm_tcf_unbind(struct Qdisc *sch, unsigned long arg)
7769 +{
7770 + struct ceetm_class *cl = (struct ceetm_class *)arg;
7771 +
7772 + pr_debug(KBUILD_BASENAME " : %s : class %X under qdisc %X\n", __func__,
7773 + cl ? cl->common.classid : 0, sch->handle);
7774 +}
7775 +
7776 +const struct Qdisc_class_ops ceetm_cls_ops = {
7777 + .graft = ceetm_cls_graft,
7778 + .leaf = ceetm_cls_leaf,
7779 + .find = ceetm_cls_search,
7780 + .change = ceetm_cls_change,
7781 + .delete = ceetm_cls_delete,
7782 + .walk = ceetm_cls_walk,
7783 + .tcf_block = ceetm_tcf_block,
7784 + .bind_tcf = ceetm_tcf_bind,
7785 + .unbind_tcf = ceetm_tcf_unbind,
7786 + .dump = ceetm_cls_dump,
7787 + .dump_stats = ceetm_cls_dump_stats,
7788 +};
7789 +
7790 +struct Qdisc_ops ceetm_qdisc_ops __read_mostly = {
7791 + .id = "ceetm",
7792 + .priv_size = sizeof(struct ceetm_qdisc),
7793 + .cl_ops = &ceetm_cls_ops,
7794 + .init = ceetm_init,
7795 + .destroy = ceetm_destroy,
7796 + .change = ceetm_change,
7797 + .dump = ceetm_dump,
7798 + .attach = ceetm_attach,
7799 + .owner = THIS_MODULE,
7800 +};
7801 +
7802 +/* Run the filters and classifiers attached to the qdisc on the provided skb */
7803 +static struct ceetm_class *ceetm_classify(struct sk_buff *skb,
7804 + struct Qdisc *sch, int *qerr,
7805 + bool *act_drop)
7806 +{
7807 + struct ceetm_qdisc *priv = qdisc_priv(sch);
7808 + struct ceetm_class *cl = NULL, *wbfs_cl;
7809 + struct tcf_result res;
7810 + struct tcf_proto *tcf;
7811 + int result;
7812 +
7813 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
7814 + tcf = priv->filter_list;
7815 + while (tcf && (result = tcf_classify(skb, tcf, &res, false)) >= 0) {
7816 +#ifdef CONFIG_NET_CLS_ACT
7817 + switch (result) {
7818 + case TC_ACT_QUEUED:
7819 + case TC_ACT_STOLEN:
7820 + case TC_ACT_TRAP:
7821 + *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
7822 + case TC_ACT_SHOT:
7823 + /* No valid class found due to action */
7824 + *act_drop = true;
7825 + return NULL;
7826 + }
7827 +#endif
7828 + cl = (void *)res.class;
7829 + if (!cl) {
7830 + if (res.classid == sch->handle) {
7831 + /* The filter leads to the qdisc */
7832 + /* TODO default qdisc */
7833 + return NULL;
7834 + }
7835 +
7836 + cl = ceetm_find(res.classid, sch);
7837 + if (!cl)
7838 + /* The filter leads to an invalid class */
7839 + break;
7840 + }
7841 +
7842 + /* The class might have its own filters attached */
7843 + tcf = cl->filter_list;
7844 + }
7845 +
7846 + if (!cl) {
7847 + /* No valid class found */
7848 + /* TODO default qdisc */
7849 + return NULL;
7850 + }
7851 +
7852 + switch (cl->type) {
7853 + case CEETM_ROOT:
7854 + if (cl->root.child) {
7855 + /* Run the prio qdisc classifiers */
7856 + return ceetm_classify(skb, cl->root.child, qerr,
7857 + act_drop);
7858 + } else {
7859 + /* The root class does not have a child prio qdisc */
7860 + /* TODO default qdisc */
7861 + return NULL;
7862 + }
7863 + case CEETM_PRIO:
7864 + if (cl->prio.child) {
7865 + /* If filters lead to a wbfs class, return it.
7866 + * Otherwise, return the prio class
7867 + */
7868 + wbfs_cl = ceetm_classify(skb, cl->prio.child, qerr,
7869 + act_drop);
7870 + /* A NULL result might indicate either an erroneous
7871 + * filter, or no filters at all. We will assume the
7872 + * latter
7873 + */
7874 + return wbfs_cl ? : cl;
7875 + }
7876 + }
7877 +
7878 + /* For wbfs and childless prio classes, return the class directly */
7879 + return cl;
7880 +}
7881 +
7882 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev)
7883 +{
7884 + int queue_mapping = dpa_get_queue_mapping(skb);
7885 + struct Qdisc *sch = net_dev->qdisc;
7886 + struct ceetm_class_stats *cstats;
7887 + struct ceetm_qdisc_stats *qstats;
7888 + struct dpa_priv_s *priv_dpa;
7889 + struct ceetm_fq *ceetm_fq;
7890 + struct ceetm_qdisc *priv;
7891 + struct qman_fq *conf_fq;
7892 + struct ceetm_class *cl;
7893 + spinlock_t *root_lock;
7894 + bool act_drop = false;
7895 + int ret;
7896 +
7897 + root_lock = qdisc_lock(sch);
7898 + priv = qdisc_priv(sch);
7899 + qstats = this_cpu_ptr(priv->root.qstats);
7900 +
7901 + spin_lock(root_lock);
7902 + cl = ceetm_classify(skb, sch, &ret, &act_drop);
7903 + spin_unlock(root_lock);
7904 +
7905 +#ifdef CONFIG_NET_CLS_ACT
7906 + if (act_drop) {
7907 + if (ret & __NET_XMIT_BYPASS)
7908 + qstats->drops++;
7909 + goto drop;
7910 + }
7911 +#endif
7912 + /* TODO default class */
7913 + if (unlikely(!cl)) {
7914 + qstats->drops++;
7915 + goto drop;
7916 + }
7917 +
7918 + if (unlikely(queue_mapping >= DPAA_ETH_TX_QUEUES))
7919 + queue_mapping = queue_mapping % DPAA_ETH_TX_QUEUES;
7920 +
7921 + priv_dpa = netdev_priv(net_dev);
7922 + conf_fq = priv_dpa->conf_fqs[queue_mapping];
7923 +
7924 + /* Choose the proper tx fq and update the basic stats (bytes and
7925 + * packets sent by the class)
7926 + */
7927 + switch (cl->type) {
7928 + case CEETM_PRIO:
7929 + ceetm_fq = cl->prio.fq;
7930 + cstats = this_cpu_ptr(cl->prio.cstats);
7931 + break;
7932 + case CEETM_WBFS:
7933 + ceetm_fq = cl->wbfs.fq;
7934 + cstats = this_cpu_ptr(cl->wbfs.cstats);
7935 + break;
7936 + default:
7937 + qstats->drops++;
7938 + goto drop;
7939 + }
7940 +
7941 + /* If the FQ is congested, avoid enqueuing the frame and dropping it
7942 + * when it returns on the ERN path. Drop it here directly instead.
7943 + */
7944 + if (unlikely(ceetm_fq->congested)) {
7945 + qstats->drops++;
7946 + goto drop;
7947 + }
7948 +
7949 + bstats_update(&cstats->bstats, skb);
7950 + return dpa_tx_extended(skb, net_dev, &ceetm_fq->fq, conf_fq);
7951 +
7952 +drop:
7953 + dev_kfree_skb_any(skb);
7954 + return NET_XMIT_SUCCESS;
7955 +}
7956 +
7957 +static int __init ceetm_register(void)
7958 +{
7959 + int _errno = 0;
7960 +
7961 + pr_info(KBUILD_MODNAME ": " DPA_CEETM_DESCRIPTION "\n");
7962 +
7963 + _errno = register_qdisc(&ceetm_qdisc_ops);
7964 + if (unlikely(_errno))
7965 + pr_err(KBUILD_MODNAME
7966 + ": %s:%hu:%s(): register_qdisc() = %d\n",
7967 + KBUILD_BASENAME ".c", __LINE__, __func__, _errno);
7968 +
7969 + return _errno;
7970 +}
7971 +
7972 +static void __exit ceetm_unregister(void)
7973 +{
7974 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
7975 + KBUILD_BASENAME ".c", __func__);
7976 +
7977 + unregister_qdisc(&ceetm_qdisc_ops);
7978 +}
7979 +
7980 +module_init(ceetm_register);
7981 +module_exit(ceetm_unregister);
7982 --- /dev/null
7983 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_ceetm.h
7984 @@ -0,0 +1,241 @@
7985 +/* Copyright 2008-2016 Freescale Semiconductor Inc.
7986 + *
7987 + * Redistribution and use in source and binary forms, with or without
7988 + * modification, are permitted provided that the following conditions are met:
7989 + * * Redistributions of source code must retain the above copyright
7990 + * notice, this list of conditions and the following disclaimer.
7991 + * * Redistributions in binary form must reproduce the above copyright
7992 + * notice, this list of conditions and the following disclaimer in the
7993 + * documentation and/or other materials provided with the distribution.
7994 + * * Neither the name of Freescale Semiconductor nor the
7995 + * names of its contributors may be used to endorse or promote products
7996 + * derived from this software without specific prior written permission.
7997 + *
7998 + *
7999 + * ALTERNATIVELY, this software may be distributed under the terms of the
8000 + * GNU General Public License ("GPL") as published by the Free Software
8001 + * Foundation, either version 2 of that License or (at your option) any
8002 + * later version.
8003 + *
8004 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8005 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8006 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8007 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8008 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8009 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8010 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8011 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8012 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8013 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8014 + */
8015 +
8016 +#ifndef __DPAA_ETH_CEETM_H
8017 +#define __DPAA_ETH_CEETM_H
8018 +
8019 +#include <net/pkt_sched.h>
8020 +#include <net/pkt_cls.h>
8021 +#include <net/netlink.h>
8022 +#include <lnxwrp_fm.h>
8023 +
8024 +#include "mac.h"
8025 +#include "dpaa_eth_common.h"
8026 +
8027 +/* Mask to determine the sub-portal id from a channel number */
8028 +#define CHANNEL_SP_MASK 0x1f
8029 +/* The number of the last channel that services DCP0, connected to FMan 0.
8030 + * Value validated for B4 and T series platforms.
8031 + */
8032 +#define DCP0_MAX_CHANNEL 0x80f
8033 +/* A2V=1 - field A2 is valid
8034 + * A0V=1 - field A0 is valid - enables frame confirmation
8035 + * OVOM=1 - override operation mode bits with values from A2
8036 + * EBD=1 - external buffers are deallocated at the end of the FMan flow
8037 + * NL=0 - the BMI releases all the internal buffers
8038 + */
8039 +#define CEETM_CONTEXT_A 0x1a00000080000000
8040 +/* The ratio between the superior and inferior congestion state thresholds. The
8041 + * lower threshold is set to 7/8 of the superior one (as the default for WQ
8042 + * scheduling).
8043 + */
8044 +#define CEETM_CCGR_RATIO 0.875
8045 +/* For functional purposes, there are num_tx_queues pfifo qdiscs through which
8046 + * frames reach the driver. Their handles start from 1:21. Handles 1:1 to 1:20
8047 + * are reserved for the maximum 32 CEETM channels (majors and minors are in
8048 + * hex).
8049 + */
8050 +#define PFIFO_MIN_OFFSET 0x21
8051 +
8052 +/* A maximum of 8 CQs can be linked to a CQ channel or to a WBFS scheduler. */
8053 +#define CEETM_MAX_PRIO_QCOUNT 8
8054 +#define CEETM_MAX_WBFS_QCOUNT 8
8055 +#define CEETM_MIN_WBFS_QCOUNT 4
8056 +
8057 +/* The id offsets of the CQs belonging to WBFS groups (ids 8-11/15 for group A
8058 + * and/or 12-15 for group B).
8059 + */
8060 +#define WBFS_GRP_A_OFFSET 8
8061 +#define WBFS_GRP_B_OFFSET 12
8062 +
8063 +#define WBFS_GRP_A 1
8064 +#define WBFS_GRP_B 2
8065 +#define WBFS_GRP_LARGE 3
8066 +
8067 +enum {
8068 + TCA_CEETM_UNSPEC,
8069 + TCA_CEETM_COPT,
8070 + TCA_CEETM_QOPS,
8071 + __TCA_CEETM_MAX,
8072 +};
8073 +
8074 +/* CEETM configuration types */
8075 +enum {
8076 + CEETM_ROOT = 1,
8077 + CEETM_PRIO,
8078 + CEETM_WBFS
8079 +};
8080 +
8081 +#define TCA_CEETM_MAX (__TCA_CEETM_MAX - 1)
8082 +extern const struct nla_policy ceetm_policy[TCA_CEETM_MAX + 1];
8083 +
8084 +struct ceetm_class;
8085 +struct ceetm_qdisc_stats;
8086 +struct ceetm_class_stats;
8087 +
8088 +struct ceetm_fq {
8089 + struct qman_fq fq;
8090 + struct net_device *net_dev;
8091 + struct ceetm_class *ceetm_cls;
8092 + int congested; /* Congestion status */
8093 +};
8094 +
8095 +struct root_q {
8096 + struct Qdisc **qdiscs;
8097 + __u16 overhead;
8098 + __u32 rate;
8099 + __u32 ceil;
8100 + struct qm_ceetm_sp *sp;
8101 + struct qm_ceetm_lni *lni;
8102 + struct ceetm_qdisc_stats __percpu *qstats;
8103 +};
8104 +
8105 +struct prio_q {
8106 + __u16 qcount;
8107 + struct ceetm_class *parent;
8108 + struct qm_ceetm_channel *ch;
8109 +};
8110 +
8111 +struct wbfs_q {
8112 + __u16 qcount;
8113 + int group_type;
8114 + struct ceetm_class *parent;
8115 + struct qm_ceetm_channel *ch;
8116 + __u16 cr;
8117 + __u16 er;
8118 +};
8119 +
8120 +struct ceetm_qdisc {
8121 + int type; /* LNI/CHNL/WBFS */
8122 + bool shaped;
8123 + union {
8124 + struct root_q root;
8125 + struct prio_q prio;
8126 + struct wbfs_q wbfs;
8127 + };
8128 + struct Qdisc_class_hash clhash;
8129 + struct tcf_proto *filter_list; /* qdisc attached filters */
8130 + struct tcf_block *block;
8131 +};
8132 +
8133 +/* CEETM Qdisc configuration parameters */
8134 +struct tc_ceetm_qopt {
8135 + __u32 type;
8136 + __u16 shaped;
8137 + __u16 qcount;
8138 + __u16 overhead;
8139 + __u32 rate;
8140 + __u32 ceil;
8141 + __u16 cr;
8142 + __u16 er;
8143 + __u8 qweight[CEETM_MAX_WBFS_QCOUNT];
8144 +};
8145 +
8146 +struct root_c {
8147 + unsigned int rate;
8148 + unsigned int ceil;
8149 + unsigned int tbl;
8150 + bool wbfs_grp_a;
8151 + bool wbfs_grp_b;
8152 + bool wbfs_grp_large;
8153 + struct Qdisc *child;
8154 +};
8155 +
8156 +struct prio_c {
8157 + bool cr;
8158 + bool er;
8159 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
8160 + struct qm_ceetm_lfq *lfq;
8161 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
8162 + struct qm_ceetm_ccg *ccg;
8163 + /* only one wbfs can be linked to one priority CQ */
8164 + struct Qdisc *child;
8165 + struct ceetm_class_stats __percpu *cstats;
8166 +};
8167 +
8168 +struct wbfs_c {
8169 + __u8 weight; /* The weight of the class between 1 and 248 */
8170 + struct ceetm_fq *fq; /* Hardware FQ instance Handle */
8171 + struct qm_ceetm_lfq *lfq;
8172 + struct qm_ceetm_cq *cq; /* Hardware Class Queue instance Handle */
8173 + struct qm_ceetm_ccg *ccg;
8174 + struct ceetm_class_stats __percpu *cstats;
8175 +};
8176 +
8177 +struct ceetm_class {
8178 + struct Qdisc_class_common common;
8179 + struct tcf_proto *filter_list; /* class attached filters */
8180 + struct tcf_block *block;
8181 + struct Qdisc *parent;
8182 + struct qm_ceetm_channel *ch;
8183 + bool shaped;
8184 + int type; /* ROOT/PRIO/WBFS */
8185 + union {
8186 + struct root_c root;
8187 + struct prio_c prio;
8188 + struct wbfs_c wbfs;
8189 + };
8190 +};
8191 +
8192 +/* CEETM Class configuration parameters */
8193 +struct tc_ceetm_copt {
8194 + __u32 type;
8195 + __u16 shaped;
8196 + __u32 rate;
8197 + __u32 ceil;
8198 + __u16 tbl;
8199 + __u16 cr;
8200 + __u16 er;
8201 + __u8 weight;
8202 +};
8203 +
8204 +/* CEETM stats */
8205 +struct ceetm_qdisc_stats {
8206 + __u32 drops;
8207 +};
8208 +
8209 +struct ceetm_class_stats {
8210 + /* Software counters */
8211 + struct gnet_stats_basic_packed bstats;
8212 + __u32 ern_drop_count;
8213 + __u32 congested_count;
8214 +};
8215 +
8216 +struct tc_ceetm_xstats {
8217 + __u32 ern_drop_count;
8218 + __u32 congested_count;
8219 + /* Hardware counters */
8220 + __u64 frame_count;
8221 + __u64 byte_count;
8222 +};
8223 +
8224 +int __hot ceetm_tx(struct sk_buff *skb, struct net_device *net_dev);
8225 +#endif
8226 --- /dev/null
8227 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
8228 @@ -0,0 +1,1745 @@
8229 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
8230 + *
8231 + * Redistribution and use in source and binary forms, with or without
8232 + * modification, are permitted provided that the following conditions are met:
8233 + * * Redistributions of source code must retain the above copyright
8234 + * notice, this list of conditions and the following disclaimer.
8235 + * * Redistributions in binary form must reproduce the above copyright
8236 + * notice, this list of conditions and the following disclaimer in the
8237 + * documentation and/or other materials provided with the distribution.
8238 + * * Neither the name of Freescale Semiconductor nor the
8239 + * names of its contributors may be used to endorse or promote products
8240 + * derived from this software without specific prior written permission.
8241 + *
8242 + *
8243 + * ALTERNATIVELY, this software may be distributed under the terms of the
8244 + * GNU General Public License ("GPL") as published by the Free Software
8245 + * Foundation, either version 2 of that License or (at your option) any
8246 + * later version.
8247 + *
8248 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
8249 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
8250 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
8251 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
8252 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
8253 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8254 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
8255 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8256 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
8257 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8258 + */
8259 +
8260 +#include <linux/init.h>
8261 +#include <linux/module.h>
8262 +#include <linux/of_platform.h>
8263 +#include <linux/of_net.h>
8264 +#include <linux/etherdevice.h>
8265 +#include <linux/kthread.h>
8266 +#include <linux/percpu.h>
8267 +#include <linux/highmem.h>
8268 +#include <linux/sort.h>
8269 +#include <linux/fsl_qman.h>
8270 +#include <linux/ip.h>
8271 +#include <linux/ipv6.h>
8272 +#include <linux/if_vlan.h> /* vlan_eth_hdr */
8273 +#include "dpaa_eth.h"
8274 +#include "dpaa_eth_common.h"
8275 +#ifdef CONFIG_FSL_DPAA_1588
8276 +#include "dpaa_1588.h"
8277 +#endif
8278 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
8279 +#include "dpaa_debugfs.h"
8280 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
8281 +#include "mac.h"
8282 +
8283 +/* Size in bytes of the FQ taildrop threshold */
8284 +#define DPA_FQ_TD 0x200000
8285 +
8286 +static struct dpa_bp *dpa_bp_array[64];
8287 +
8288 +int dpa_max_frm;
8289 +EXPORT_SYMBOL(dpa_max_frm);
8290 +
8291 +int dpa_rx_extra_headroom;
8292 +EXPORT_SYMBOL(dpa_rx_extra_headroom);
8293 +
8294 +int dpa_num_cpus = NR_CPUS;
8295 +
8296 +static const struct fqid_cell tx_confirm_fqids[] = {
8297 + {0, DPAA_ETH_TX_QUEUES}
8298 +};
8299 +
8300 +static struct fqid_cell default_fqids[][3] = {
8301 + [RX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_RX_QUEUES} },
8302 + [TX] = { {0, 1}, {0, 1}, {0, DPAA_ETH_TX_QUEUES} }
8303 +};
8304 +
8305 +static const char fsl_qman_frame_queues[][25] = {
8306 + [RX] = "fsl,qman-frame-queues-rx",
8307 + [TX] = "fsl,qman-frame-queues-tx"
8308 +};
8309 +#ifdef CONFIG_FSL_DPAA_HOOKS
8310 +/* A set of callbacks for hooking into the fastpath at different points. */
8311 +struct dpaa_eth_hooks_s dpaa_eth_hooks;
8312 +EXPORT_SYMBOL(dpaa_eth_hooks);
8313 +/* This function should only be called on the probe paths, since it makes no
8314 + * effort to guarantee consistency of the destination hooks structure.
8315 + */
8316 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks)
8317 +{
8318 + if (hooks)
8319 + dpaa_eth_hooks = *hooks;
8320 + else
8321 + pr_err("NULL pointer to hooks!\n");
8322 +}
8323 +EXPORT_SYMBOL(fsl_dpaa_eth_set_hooks);
8324 +#endif
8325 +
8326 +int dpa_netdev_init(struct net_device *net_dev,
8327 + const uint8_t *mac_addr,
8328 + uint16_t tx_timeout)
8329 +{
8330 + int err;
8331 + struct dpa_priv_s *priv = netdev_priv(net_dev);
8332 + struct device *dev = net_dev->dev.parent;
8333 +
8334 + net_dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
8335 +
8336 + net_dev->features |= net_dev->hw_features;
8337 + net_dev->vlan_features = net_dev->features;
8338 +
8339 + memcpy(net_dev->perm_addr, mac_addr, net_dev->addr_len);
8340 + memcpy(net_dev->dev_addr, mac_addr, net_dev->addr_len);
8341 +
8342 + net_dev->ethtool_ops = &dpa_ethtool_ops;
8343 +
8344 + net_dev->needed_headroom = priv->tx_headroom;
8345 + net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
8346 +
8347 + err = register_netdev(net_dev);
8348 + if (err < 0) {
8349 + dev_err(dev, "register_netdev() = %d\n", err);
8350 + return err;
8351 + }
8352 +
8353 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
8354 + /* create debugfs entry for this net_device */
8355 + err = dpa_netdev_debugfs_create(net_dev);
8356 + if (err) {
8357 + unregister_netdev(net_dev);
8358 + return err;
8359 + }
8360 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
8361 +
8362 + return 0;
8363 +}
8364 +EXPORT_SYMBOL(dpa_netdev_init);
8365 +
8366 +int __cold dpa_start(struct net_device *net_dev)
8367 +{
8368 + int err, i;
8369 + struct dpa_priv_s *priv;
8370 + struct mac_device *mac_dev;
8371 +
8372 + priv = netdev_priv(net_dev);
8373 + mac_dev = priv->mac_dev;
8374 +
8375 + err = mac_dev->init_phy(net_dev, priv->mac_dev);
8376 + if (err < 0) {
8377 + if (netif_msg_ifup(priv))
8378 + netdev_err(net_dev, "init_phy() = %d\n", err);
8379 + return err;
8380 + }
8381 +
8382 + for_each_port_device(i, mac_dev->port_dev) {
8383 + err = fm_port_enable(mac_dev->port_dev[i]);
8384 + if (err)
8385 + goto mac_start_failed;
8386 + }
8387 +
8388 + err = priv->mac_dev->start(mac_dev);
8389 + if (err < 0) {
8390 + if (netif_msg_ifup(priv))
8391 + netdev_err(net_dev, "mac_dev->start() = %d\n", err);
8392 + goto mac_start_failed;
8393 + }
8394 +
8395 + netif_tx_start_all_queues(net_dev);
8396 +
8397 + return 0;
8398 +
8399 +mac_start_failed:
8400 + for_each_port_device(i, mac_dev->port_dev)
8401 + fm_port_disable(mac_dev->port_dev[i]);
8402 +
8403 + return err;
8404 +}
8405 +EXPORT_SYMBOL(dpa_start);
8406 +
8407 +int __cold dpa_stop(struct net_device *net_dev)
8408 +{
8409 + int _errno, i, err;
8410 + struct dpa_priv_s *priv;
8411 + struct mac_device *mac_dev;
8412 +
8413 + priv = netdev_priv(net_dev);
8414 + mac_dev = priv->mac_dev;
8415 +
8416 + netif_tx_stop_all_queues(net_dev);
8417 + /* Allow the Fman (Tx) port to process in-flight frames before we
8418 + * try switching it off.
8419 + */
8420 + usleep_range(5000, 10000);
8421 +
8422 + _errno = mac_dev->stop(mac_dev);
8423 + if (unlikely(_errno < 0))
8424 + if (netif_msg_ifdown(priv))
8425 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
8426 + _errno);
8427 +
8428 + for_each_port_device(i, mac_dev->port_dev) {
8429 + err = fm_port_disable(mac_dev->port_dev[i]);
8430 + _errno = err ? err : _errno;
8431 + }
8432 +
8433 + if (mac_dev->phy_dev)
8434 + phy_disconnect(mac_dev->phy_dev);
8435 + mac_dev->phy_dev = NULL;
8436 +
8437 + return _errno;
8438 +}
8439 +EXPORT_SYMBOL(dpa_stop);
8440 +
8441 +void __cold dpa_timeout(struct net_device *net_dev)
8442 +{
8443 + const struct dpa_priv_s *priv;
8444 + struct dpa_percpu_priv_s *percpu_priv;
8445 +
8446 + priv = netdev_priv(net_dev);
8447 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
8448 +
8449 + if (netif_msg_timer(priv))
8450 + netdev_crit(net_dev, "Transmit timeout!\n");
8451 +
8452 + percpu_priv->stats.tx_errors++;
8453 +}
8454 +EXPORT_SYMBOL(dpa_timeout);
8455 +
8456 +/* net_device */
8457 +
8458 +/**
8459 + * @param net_dev the device for which statistics are calculated
8460 + * @param stats the function fills this structure with the device's statistics
8461 + * @return the address of the structure containing the statistics
8462 + *
8463 + * Calculates the statistics for the given device by adding the statistics
8464 + * collected by each CPU.
8465 + */
8466 +void __cold
8467 +dpa_get_stats64(struct net_device *net_dev,
8468 + struct rtnl_link_stats64 *stats)
8469 +{
8470 + struct dpa_priv_s *priv = netdev_priv(net_dev);
8471 + u64 *cpustats;
8472 + u64 *netstats = (u64 *)stats;
8473 + int i, j;
8474 + struct dpa_percpu_priv_s *percpu_priv;
8475 + int numstats = sizeof(struct rtnl_link_stats64) / sizeof(u64);
8476 +
8477 + for_each_possible_cpu(i) {
8478 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
8479 +
8480 + cpustats = (u64 *)&percpu_priv->stats;
8481 +
8482 + for (j = 0; j < numstats; j++)
8483 + netstats[j] += cpustats[j];
8484 + }
8485 +}
8486 +EXPORT_SYMBOL(dpa_get_stats64);
8487 +
8488 +/* .ndo_init callback */
8489 +int dpa_ndo_init(struct net_device *net_dev)
8490 +{
8491 + /* If fsl_fm_max_frm is set to a higher value than the all-common 1500,
8492 + * we choose conservatively and let the user explicitly set a higher
8493 + * MTU via ifconfig. Otherwise, the user may end up with different MTUs
8494 + * in the same LAN.
8495 + * If on the other hand fsl_fm_max_frm has been chosen below 1500,
8496 + * start with the maximum allowed.
8497 + */
8498 + int init_mtu = min(dpa_get_max_mtu(), ETH_DATA_LEN);
8499 +
8500 + pr_debug("Setting initial MTU on net device: %d\n", init_mtu);
8501 + net_dev->mtu = init_mtu;
8502 +
8503 + return 0;
8504 +}
8505 +EXPORT_SYMBOL(dpa_ndo_init);
8506 +
8507 +int dpa_set_features(struct net_device *dev, netdev_features_t features)
8508 +{
8509 + /* Not much to do here for now */
8510 + dev->features = features;
8511 + return 0;
8512 +}
8513 +EXPORT_SYMBOL(dpa_set_features);
8514 +
8515 +netdev_features_t dpa_fix_features(struct net_device *dev,
8516 + netdev_features_t features)
8517 +{
8518 + netdev_features_t unsupported_features = 0;
8519 +
8520 + /* In theory we should never be requested to enable features that
8521 + * we didn't set in netdev->features and netdev->hw_features at probe
8522 + * time, but double check just to be on the safe side.
8523 + * We don't support enabling Rx csum through ethtool yet
8524 + */
8525 + unsupported_features |= NETIF_F_RXCSUM;
8526 +
8527 + features &= ~unsupported_features;
8528 +
8529 + return features;
8530 +}
8531 +EXPORT_SYMBOL(dpa_fix_features);
8532 +
8533 +#ifdef CONFIG_FSL_DPAA_TS
8534 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv, enum port_type rx_tx,
8535 + const void *data)
8536 +{
8537 + u64 *ts;
8538 +
8539 + ts = fm_port_get_buffer_time_stamp(priv->mac_dev->port_dev[rx_tx],
8540 + data);
8541 +
8542 + if (!ts || *ts == 0)
8543 + return 0;
8544 +
8545 + be64_to_cpus(ts);
8546 +
8547 + return *ts;
8548 +}
8549 +
8550 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
8551 + struct skb_shared_hwtstamps *shhwtstamps, const void *data)
8552 +{
8553 + u64 ns;
8554 +
8555 + ns = dpa_get_timestamp_ns(priv, rx_tx, data);
8556 +
8557 + if (ns == 0)
8558 + return -EINVAL;
8559 +
8560 + memset(shhwtstamps, 0, sizeof(*shhwtstamps));
8561 + shhwtstamps->hwtstamp = ns_to_ktime(ns);
8562 +
8563 + return 0;
8564 +}
8565 +
8566 +static void dpa_ts_tx_enable(struct net_device *dev)
8567 +{
8568 + struct dpa_priv_s *priv = netdev_priv(dev);
8569 + struct mac_device *mac_dev = priv->mac_dev;
8570 +
8571 + if (mac_dev->ptp_enable)
8572 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
8573 +
8574 + priv->ts_tx_en = true;
8575 +}
8576 +
8577 +static void dpa_ts_tx_disable(struct net_device *dev)
8578 +{
8579 + struct dpa_priv_s *priv = netdev_priv(dev);
8580 +
8581 +#if 0
8582 +/* the RTC might be needed by the Rx Ts, cannot disable here
8583 + * no separate ptp_disable API for Rx/Tx, cannot disable here
8584 + */
8585 + struct mac_device *mac_dev = priv->mac_dev;
8586 +
8587 + if (mac_dev->fm_rtc_disable)
8588 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
8589 +
8590 + if (mac_dev->ptp_disable)
8591 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
8592 +#endif
8593 +
8594 + priv->ts_tx_en = false;
8595 +}
8596 +
8597 +static void dpa_ts_rx_enable(struct net_device *dev)
8598 +{
8599 + struct dpa_priv_s *priv = netdev_priv(dev);
8600 + struct mac_device *mac_dev = priv->mac_dev;
8601 +
8602 + if (mac_dev->ptp_enable)
8603 + mac_dev->ptp_enable(mac_dev->get_mac_handle(mac_dev));
8604 +
8605 + priv->ts_rx_en = true;
8606 +}
8607 +
8608 +static void dpa_ts_rx_disable(struct net_device *dev)
8609 +{
8610 + struct dpa_priv_s *priv = netdev_priv(dev);
8611 +
8612 +#if 0
8613 +/* the RTC might be needed by the Tx Ts, cannot disable here
8614 + * no separate ptp_disable API for Rx/Tx, cannot disable here
8615 + */
8616 + struct mac_device *mac_dev = priv->mac_dev;
8617 +
8618 + if (mac_dev->fm_rtc_disable)
8619 + mac_dev->fm_rtc_disable(get_fm_handle(dev));
8620 +
8621 + if (mac_dev->ptp_disable)
8622 + mac_dev->ptp_disable(mac_dev->get_mac_handle(mac_dev));
8623 +#endif
8624 +
8625 + priv->ts_rx_en = false;
8626 +}
8627 +
8628 +static int dpa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
8629 +{
8630 + struct hwtstamp_config config;
8631 +
8632 + if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
8633 + return -EFAULT;
8634 +
8635 + switch (config.tx_type) {
8636 + case HWTSTAMP_TX_OFF:
8637 + dpa_ts_tx_disable(dev);
8638 + break;
8639 + case HWTSTAMP_TX_ON:
8640 + dpa_ts_tx_enable(dev);
8641 + break;
8642 + default:
8643 + return -ERANGE;
8644 + }
8645 +
8646 + if (config.rx_filter == HWTSTAMP_FILTER_NONE)
8647 + dpa_ts_rx_disable(dev);
8648 + else {
8649 + dpa_ts_rx_enable(dev);
8650 + /* TS is set for all frame types, not only those requested */
8651 + config.rx_filter = HWTSTAMP_FILTER_ALL;
8652 + }
8653 +
8654 + return copy_to_user(rq->ifr_data, &config, sizeof(config)) ?
8655 + -EFAULT : 0;
8656 +}
8657 +#endif /* CONFIG_FSL_DPAA_TS */
8658 +
8659 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
8660 +{
8661 +#ifdef CONFIG_FSL_DPAA_1588
8662 + struct dpa_priv_s *priv = netdev_priv(dev);
8663 +#endif
8664 + int ret = -EINVAL;
8665 +
8666 + if (!netif_running(dev))
8667 + return -EINVAL;
8668 +
8669 + if (cmd == SIOCGMIIREG) {
8670 + if (!dev->phydev)
8671 + ret = -EINVAL;
8672 + else
8673 + ret = phy_mii_ioctl(dev->phydev, rq, cmd);
8674 + }
8675 +
8676 +#ifdef CONFIG_FSL_DPAA_TS
8677 + if (cmd == SIOCSHWTSTAMP)
8678 + return dpa_ts_ioctl(dev, rq, cmd);
8679 +#endif /* CONFIG_FSL_DPAA_TS */
8680 +
8681 +#ifdef CONFIG_FSL_DPAA_1588
8682 + if ((cmd >= PTP_ENBL_TXTS_IOCTL) && (cmd <= PTP_CLEANUP_TS)) {
8683 + if (priv->tsu && priv->tsu->valid)
8684 + ret = dpa_ioctl_1588(dev, rq, cmd);
8685 + else
8686 + ret = -ENODEV;
8687 + }
8688 +#endif
8689 +
8690 + return ret;
8691 +}
8692 +EXPORT_SYMBOL(dpa_ioctl);
8693 +
8694 +int __cold dpa_remove(struct platform_device *of_dev)
8695 +{
8696 + int err;
8697 + struct device *dev;
8698 + struct net_device *net_dev;
8699 + struct dpa_priv_s *priv;
8700 +
8701 + dev = &of_dev->dev;
8702 + net_dev = dev_get_drvdata(dev);
8703 +
8704 + priv = netdev_priv(net_dev);
8705 +
8706 + dpaa_eth_sysfs_remove(dev);
8707 +
8708 + dev_set_drvdata(dev, NULL);
8709 + unregister_netdev(net_dev);
8710 +
8711 + err = dpa_fq_free(dev, &priv->dpa_fq_list);
8712 +
8713 + qman_delete_cgr_safe(&priv->ingress_cgr);
8714 + qman_release_cgrid(priv->ingress_cgr.cgrid);
8715 + qman_delete_cgr_safe(&priv->cgr_data.cgr);
8716 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
8717 +
8718 + dpa_private_napi_del(net_dev);
8719 +
8720 + dpa_bp_free(priv);
8721 +
8722 + if (priv->buf_layout)
8723 + devm_kfree(dev, priv->buf_layout);
8724 +
8725 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
8726 + /* remove debugfs entry for this net_device */
8727 + dpa_netdev_debugfs_remove(net_dev);
8728 +#endif /* CONFIG_FSL_DPAA_DBG_LOOP */
8729 +
8730 +#ifdef CONFIG_FSL_DPAA_1588
8731 + if (priv->tsu && priv->tsu->valid)
8732 + dpa_ptp_cleanup(priv);
8733 +#endif
8734 +
8735 + free_netdev(net_dev);
8736 +
8737 + return err;
8738 +}
8739 +EXPORT_SYMBOL(dpa_remove);
8740 +
8741 +struct mac_device * __cold __must_check
8742 +__attribute__((nonnull))
8743 +dpa_mac_probe(struct platform_device *_of_dev)
8744 +{
8745 + struct device *dpa_dev, *dev;
8746 + struct device_node *mac_node;
8747 + struct platform_device *of_dev;
8748 + struct mac_device *mac_dev;
8749 +#ifdef CONFIG_FSL_DPAA_1588
8750 + int lenp;
8751 + const phandle *phandle_prop;
8752 + struct net_device *net_dev = NULL;
8753 + struct dpa_priv_s *priv = NULL;
8754 + struct device_node *timer_node;
8755 +#endif
8756 + dpa_dev = &_of_dev->dev;
8757 +
8758 + mac_node = of_parse_phandle(_of_dev->dev.of_node, "fsl,fman-mac", 0);
8759 + if (unlikely(mac_node == NULL)) {
8760 + dev_err(dpa_dev, "Cannot find MAC device device tree node\n");
8761 + return ERR_PTR(-EFAULT);
8762 + }
8763 +
8764 + of_dev = of_find_device_by_node(mac_node);
8765 + if (unlikely(of_dev == NULL)) {
8766 + dev_err(dpa_dev, "of_find_device_by_node(%s) failed\n",
8767 + mac_node->full_name);
8768 + of_node_put(mac_node);
8769 + return ERR_PTR(-EINVAL);
8770 + }
8771 + of_node_put(mac_node);
8772 +
8773 + dev = &of_dev->dev;
8774 +
8775 + mac_dev = dev_get_drvdata(dev);
8776 + if (unlikely(mac_dev == NULL)) {
8777 + dev_err(dpa_dev, "dev_get_drvdata(%s) failed\n",
8778 + dev_name(dev));
8779 + return ERR_PTR(-EINVAL);
8780 + }
8781 +
8782 +#ifdef CONFIG_FSL_DPAA_1588
8783 + phandle_prop = of_get_property(mac_node, "ptp-timer", &lenp);
8784 + if (phandle_prop && ((mac_dev->phy_if != PHY_INTERFACE_MODE_SGMII) ||
8785 + ((mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII) &&
8786 + (mac_dev->speed == SPEED_1000)))) {
8787 + timer_node = of_find_node_by_phandle(*phandle_prop);
8788 + if (timer_node)
8789 + net_dev = dev_get_drvdata(dpa_dev);
8790 + if (timer_node && net_dev) {
8791 + priv = netdev_priv(net_dev);
8792 + if (!dpa_ptp_init(priv))
8793 + dev_info(dev, "%s: ptp 1588 is initialized.\n",
8794 + mac_node->full_name);
8795 + }
8796 + }
8797 +#endif
8798 +
8799 + return mac_dev;
8800 +}
8801 +EXPORT_SYMBOL(dpa_mac_probe);
8802 +
8803 +int dpa_set_mac_address(struct net_device *net_dev, void *addr)
8804 +{
8805 + const struct dpa_priv_s *priv;
8806 + int _errno;
8807 + struct mac_device *mac_dev;
8808 +
8809 + priv = netdev_priv(net_dev);
8810 +
8811 + _errno = eth_mac_addr(net_dev, addr);
8812 + if (_errno < 0) {
8813 + if (netif_msg_drv(priv))
8814 + netdev_err(net_dev,
8815 + "eth_mac_addr() = %d\n",
8816 + _errno);
8817 + return _errno;
8818 + }
8819 +
8820 + mac_dev = priv->mac_dev;
8821 +
8822 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
8823 + net_dev->dev_addr);
8824 + if (_errno < 0) {
8825 + if (netif_msg_drv(priv))
8826 + netdev_err(net_dev,
8827 + "mac_dev->change_addr() = %d\n",
8828 + _errno);
8829 + return _errno;
8830 + }
8831 +
8832 + return 0;
8833 +}
8834 +EXPORT_SYMBOL(dpa_set_mac_address);
8835 +
8836 +void dpa_set_rx_mode(struct net_device *net_dev)
8837 +{
8838 + int _errno;
8839 + const struct dpa_priv_s *priv;
8840 +
8841 + priv = netdev_priv(net_dev);
8842 +
8843 + if (!!(net_dev->flags & IFF_PROMISC) != priv->mac_dev->promisc) {
8844 + priv->mac_dev->promisc = !priv->mac_dev->promisc;
8845 + _errno = priv->mac_dev->set_promisc(
8846 + priv->mac_dev->get_mac_handle(priv->mac_dev),
8847 + priv->mac_dev->promisc);
8848 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
8849 + netdev_err(net_dev,
8850 + "mac_dev->set_promisc() = %d\n",
8851 + _errno);
8852 + }
8853 +
8854 + _errno = priv->mac_dev->set_multi(net_dev, priv->mac_dev);
8855 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
8856 + netdev_err(net_dev, "mac_dev->set_multi() = %d\n", _errno);
8857 +}
8858 +EXPORT_SYMBOL(dpa_set_rx_mode);
8859 +
8860 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
8861 + struct dpa_buffer_layout_s *layout)
8862 +{
8863 + struct fm_port_params params;
8864 +
8865 + /* Rx */
8866 + layout[RX].priv_data_size = (uint16_t)DPA_RX_PRIV_DATA_SIZE;
8867 + layout[RX].parse_results = true;
8868 + layout[RX].hash_results = true;
8869 +#ifdef CONFIG_FSL_DPAA_TS
8870 + layout[RX].time_stamp = true;
8871 +#endif
8872 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[RX], &params);
8873 + layout[RX].manip_extra_space = params.manip_extra_space;
8874 + /* a value of zero for data alignment means "don't care", so align to
8875 + * a non-zero value to prevent FMD from using its own default
8876 + */
8877 + layout[RX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
8878 +
8879 + /* Tx */
8880 + layout[TX].priv_data_size = DPA_TX_PRIV_DATA_SIZE;
8881 + layout[TX].parse_results = true;
8882 + layout[TX].hash_results = true;
8883 +#ifdef CONFIG_FSL_DPAA_TS
8884 + layout[TX].time_stamp = true;
8885 +#endif
8886 + fm_port_get_buff_layout_ext_params(mac_dev->port_dev[TX], &params);
8887 + layout[TX].manip_extra_space = params.manip_extra_space;
8888 + layout[TX].data_align = params.data_align ? : DPA_FD_DATA_ALIGNMENT;
8889 +}
8890 +EXPORT_SYMBOL(dpa_set_buffers_layout);
8891 +
8892 +int __attribute__((nonnull))
8893 +dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev)
8894 +{
8895 + int err;
8896 + struct bman_pool_params bp_params;
8897 +
8898 + if (dpa_bp->size == 0 || dpa_bp->config_count == 0) {
8899 + pr_err("Buffer pool is not properly initialized! Missing size or initial number of buffers");
8900 + return -EINVAL;
8901 + }
8902 +
8903 + memset(&bp_params, 0, sizeof(struct bman_pool_params));
8904 +#ifdef CONFIG_FMAN_PFC
8905 + bp_params.flags = BMAN_POOL_FLAG_THRESH;
8906 + bp_params.thresholds[0] = bp_params.thresholds[2] =
8907 + CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD;
8908 + bp_params.thresholds[1] = bp_params.thresholds[3] =
8909 + CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT;
8910 +#endif
8911 +
8912 + /* If the pool is already specified, we only create one per bpid */
8913 + if (dpa_bpid2pool_use(dpa_bp->bpid))
8914 + return 0;
8915 +
8916 + if (dpa_bp->bpid == 0)
8917 + bp_params.flags |= BMAN_POOL_FLAG_DYNAMIC_BPID;
8918 + else
8919 + bp_params.bpid = dpa_bp->bpid;
8920 +
8921 + dpa_bp->pool = bman_new_pool(&bp_params);
8922 + if (unlikely(dpa_bp->pool == NULL)) {
8923 + pr_err("bman_new_pool() failed\n");
8924 + return -ENODEV;
8925 + }
8926 +
8927 + dpa_bp->bpid = (uint8_t)bman_get_params(dpa_bp->pool)->bpid;
8928 +
8929 + err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(40));
8930 + if (err) {
8931 + pr_err("dma_coerce_mask_and_coherent() failed\n");
8932 + goto bman_free_pool;
8933 + }
8934 +
8935 + dpa_bp->dev = dev;
8936 +
8937 + if (dpa_bp->seed_cb) {
8938 + err = dpa_bp->seed_cb(dpa_bp);
8939 + if (err)
8940 + goto bman_free_pool;
8941 + }
8942 +
8943 + dpa_bpid2pool_map(dpa_bp->bpid, dpa_bp);
8944 +
8945 + return 0;
8946 +
8947 +bman_free_pool:
8948 + bman_free_pool(dpa_bp->pool);
8949 +
8950 + return err;
8951 +}
8952 +EXPORT_SYMBOL(dpa_bp_alloc);
8953 +
8954 +void dpa_bp_drain(struct dpa_bp *bp)
8955 +{
8956 + int ret, num = 8;
8957 +
8958 + do {
8959 + struct bm_buffer bmb[8];
8960 + int i;
8961 +
8962 + ret = bman_acquire(bp->pool, bmb, num, 0);
8963 + if (ret < 0) {
8964 + if (num == 8) {
8965 + /* we have less than 8 buffers left;
8966 + * drain them one by one
8967 + */
8968 + num = 1;
8969 + ret = 1;
8970 + continue;
8971 + } else {
8972 + /* Pool is fully drained */
8973 + break;
8974 + }
8975 + }
8976 +
8977 + for (i = 0; i < num; i++) {
8978 + dma_addr_t addr = bm_buf_addr(&bmb[i]);
8979 +
8980 + dma_unmap_single(bp->dev, addr, bp->size,
8981 + DMA_BIDIRECTIONAL);
8982 +
8983 + bp->free_buf_cb(phys_to_virt(addr));
8984 + }
8985 + } while (ret > 0);
8986 +}
8987 +EXPORT_SYMBOL(dpa_bp_drain);
8988 +
8989 +static void __cold __attribute__((nonnull))
8990 +_dpa_bp_free(struct dpa_bp *dpa_bp)
8991 +{
8992 + struct dpa_bp *bp = dpa_bpid2pool(dpa_bp->bpid);
8993 +
8994 + /* the mapping between bpid and dpa_bp is done very late in the
8995 + * allocation procedure; if something failed before the mapping, the bp
8996 + * was not configured, therefore we don't need the below instructions
8997 + */
8998 + if (!bp)
8999 + return;
9000 +
9001 + if (!atomic_dec_and_test(&bp->refs))
9002 + return;
9003 +
9004 + if (bp->free_buf_cb)
9005 + dpa_bp_drain(bp);
9006 +
9007 + dpa_bp_array[bp->bpid] = NULL;
9008 + bman_free_pool(bp->pool);
9009 +}
9010 +
9011 +void __cold __attribute__((nonnull))
9012 +dpa_bp_free(struct dpa_priv_s *priv)
9013 +{
9014 + int i;
9015 +
9016 + if (priv->dpa_bp)
9017 + for (i = 0; i < priv->bp_count; i++)
9018 + _dpa_bp_free(&priv->dpa_bp[i]);
9019 +}
9020 +EXPORT_SYMBOL(dpa_bp_free);
9021 +
9022 +struct dpa_bp *dpa_bpid2pool(int bpid)
9023 +{
9024 + return dpa_bp_array[bpid];
9025 +}
9026 +EXPORT_SYMBOL(dpa_bpid2pool);
9027 +
9028 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp)
9029 +{
9030 + dpa_bp_array[bpid] = dpa_bp;
9031 + atomic_set(&dpa_bp->refs, 1);
9032 +}
9033 +
9034 +bool dpa_bpid2pool_use(int bpid)
9035 +{
9036 + if (dpa_bpid2pool(bpid)) {
9037 + atomic_inc(&dpa_bp_array[bpid]->refs);
9038 + return true;
9039 + }
9040 +
9041 + return false;
9042 +}
9043 +
9044 +#ifdef CONFIG_FMAN_PFC
9045 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
9046 + void *accel_priv, select_queue_fallback_t fallback)
9047 +{
9048 + return dpa_get_queue_mapping(skb);
9049 +}
9050 +#endif
9051 +
9052 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
9053 + u32 fq_start,
9054 + u32 fq_count,
9055 + struct list_head *list,
9056 + enum dpa_fq_type fq_type)
9057 +{
9058 + int i;
9059 + struct dpa_fq *dpa_fq;
9060 +
9061 + dpa_fq = devm_kzalloc(dev, sizeof(*dpa_fq) * fq_count, GFP_KERNEL);
9062 + if (dpa_fq == NULL)
9063 + return NULL;
9064 +
9065 + for (i = 0; i < fq_count; i++) {
9066 + dpa_fq[i].fq_type = fq_type;
9067 + if (fq_type == FQ_TYPE_RX_PCD_HI_PRIO)
9068 + dpa_fq[i].fqid = fq_start ?
9069 + DPAA_ETH_FQ_DELTA + fq_start + i : 0;
9070 + else
9071 + dpa_fq[i].fqid = fq_start ? fq_start + i : 0;
9072 +
9073 + list_add_tail(&dpa_fq[i].list, list);
9074 + }
9075 +
9076 +#ifdef CONFIG_FMAN_PFC
9077 + if (fq_type == FQ_TYPE_TX)
9078 + for (i = 0; i < fq_count; i++)
9079 + dpa_fq[i].wq = i / dpa_num_cpus;
9080 + else
9081 +#endif
9082 + for (i = 0; i < fq_count; i++)
9083 + _dpa_assign_wq(dpa_fq + i);
9084 +
9085 + return dpa_fq;
9086 +}
9087 +EXPORT_SYMBOL(dpa_fq_alloc);
9088 +
9089 +/* Probing of FQs for MACful ports */
9090 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
9091 + struct fm_port_fqs *port_fqs,
9092 + bool alloc_tx_conf_fqs,
9093 + enum port_type ptype)
9094 +{
9095 + struct fqid_cell *fqids = NULL;
9096 + const void *fqids_off = NULL;
9097 + struct dpa_fq *dpa_fq = NULL;
9098 + struct device_node *np = dev->of_node;
9099 + int num_ranges;
9100 + int i, lenp;
9101 +
9102 + if (ptype == TX && alloc_tx_conf_fqs) {
9103 + if (!dpa_fq_alloc(dev, tx_confirm_fqids->start,
9104 + tx_confirm_fqids->count, list,
9105 + FQ_TYPE_TX_CONF_MQ))
9106 + goto fq_alloc_failed;
9107 + }
9108 +
9109 + fqids_off = of_get_property(np, fsl_qman_frame_queues[ptype], &lenp);
9110 + if (fqids_off == NULL) {
9111 + /* No dts definition, so use the defaults. */
9112 + fqids = default_fqids[ptype];
9113 + num_ranges = 3;
9114 + } else {
9115 + num_ranges = lenp / sizeof(*fqids);
9116 +
9117 + fqids = devm_kzalloc(dev, sizeof(*fqids) * num_ranges,
9118 + GFP_KERNEL);
9119 + if (fqids == NULL)
9120 + goto fqids_alloc_failed;
9121 +
9122 + /* convert to CPU endianess */
9123 + for (i = 0; i < num_ranges; i++) {
9124 + fqids[i].start = be32_to_cpup(fqids_off +
9125 + i * sizeof(*fqids));
9126 + fqids[i].count = be32_to_cpup(fqids_off +
9127 + i * sizeof(*fqids) + sizeof(__be32));
9128 + }
9129 + }
9130 +
9131 + for (i = 0; i < num_ranges; i++) {
9132 + switch (i) {
9133 + case 0:
9134 + /* The first queue is the error queue */
9135 + if (fqids[i].count != 1)
9136 + goto invalid_error_queue;
9137 +
9138 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
9139 + fqids[i].count, list,
9140 + ptype == RX ?
9141 + FQ_TYPE_RX_ERROR :
9142 + FQ_TYPE_TX_ERROR);
9143 + if (dpa_fq == NULL)
9144 + goto fq_alloc_failed;
9145 +
9146 + if (ptype == RX)
9147 + port_fqs->rx_errq = &dpa_fq[0];
9148 + else
9149 + port_fqs->tx_errq = &dpa_fq[0];
9150 + break;
9151 + case 1:
9152 + /* the second queue is the default queue */
9153 + if (fqids[i].count != 1)
9154 + goto invalid_default_queue;
9155 +
9156 + dpa_fq = dpa_fq_alloc(dev, fqids[i].start,
9157 + fqids[i].count, list,
9158 + ptype == RX ?
9159 + FQ_TYPE_RX_DEFAULT :
9160 + FQ_TYPE_TX_CONFIRM);
9161 + if (dpa_fq == NULL)
9162 + goto fq_alloc_failed;
9163 +
9164 + if (ptype == RX)
9165 + port_fqs->rx_defq = &dpa_fq[0];
9166 + else
9167 + port_fqs->tx_defq = &dpa_fq[0];
9168 + break;
9169 + default:
9170 + /* all subsequent queues are either RX* PCD or Tx */
9171 + if (ptype == RX) {
9172 + if (!dpa_fq_alloc(dev, fqids[i].start,
9173 + fqids[i].count, list,
9174 + FQ_TYPE_RX_PCD) ||
9175 + !dpa_fq_alloc(dev, fqids[i].start,
9176 + fqids[i].count, list,
9177 + FQ_TYPE_RX_PCD_HI_PRIO))
9178 + goto fq_alloc_failed;
9179 + } else {
9180 + if (!dpa_fq_alloc(dev, fqids[i].start,
9181 + fqids[i].count, list,
9182 + FQ_TYPE_TX))
9183 + goto fq_alloc_failed;
9184 + }
9185 + break;
9186 + }
9187 + }
9188 +
9189 + return 0;
9190 +
9191 +fq_alloc_failed:
9192 +fqids_alloc_failed:
9193 + dev_err(dev, "Cannot allocate memory for frame queues\n");
9194 + return -ENOMEM;
9195 +
9196 +invalid_default_queue:
9197 +invalid_error_queue:
9198 + dev_err(dev, "Too many default or error queues\n");
9199 + return -EINVAL;
9200 +}
9201 +EXPORT_SYMBOL(dpa_fq_probe_mac);
9202 +
9203 +static u32 rx_pool_channel;
9204 +static DEFINE_SPINLOCK(rx_pool_channel_init);
9205 +
9206 +int dpa_get_channel(void)
9207 +{
9208 + spin_lock(&rx_pool_channel_init);
9209 + if (!rx_pool_channel) {
9210 + u32 pool;
9211 + int ret = qman_alloc_pool(&pool);
9212 + if (!ret)
9213 + rx_pool_channel = pool;
9214 + }
9215 + spin_unlock(&rx_pool_channel_init);
9216 + if (!rx_pool_channel)
9217 + return -ENOMEM;
9218 + return rx_pool_channel;
9219 +}
9220 +EXPORT_SYMBOL(dpa_get_channel);
9221 +
9222 +void dpa_release_channel(void)
9223 +{
9224 + qman_release_pool(rx_pool_channel);
9225 +}
9226 +EXPORT_SYMBOL(dpa_release_channel);
9227 +
9228 +void dpaa_eth_add_channel(u16 channel)
9229 +{
9230 + const cpumask_t *cpus = qman_affine_cpus();
9231 + u32 pool = QM_SDQCR_CHANNELS_POOL_CONV(channel);
9232 + int cpu;
9233 + struct qman_portal *portal;
9234 +
9235 + for_each_cpu(cpu, cpus) {
9236 + portal = (struct qman_portal *)qman_get_affine_portal(cpu);
9237 + qman_p_static_dequeue_add(portal, pool);
9238 + }
9239 +}
9240 +EXPORT_SYMBOL(dpaa_eth_add_channel);
9241 +
9242 +/**
9243 + * Congestion group state change notification callback.
9244 + * Stops the device's egress queues while they are congested and
9245 + * wakes them upon exiting congested state.
9246 + * Also updates some CGR-related stats.
9247 + */
9248 +static void dpaa_eth_cgscn(struct qman_portal *qm, struct qman_cgr *cgr,
9249 +
9250 + int congested)
9251 +{
9252 + struct dpa_priv_s *priv = (struct dpa_priv_s *)container_of(cgr,
9253 + struct dpa_priv_s, cgr_data.cgr);
9254 +
9255 + if (congested) {
9256 + priv->cgr_data.congestion_start_jiffies = jiffies;
9257 + netif_tx_stop_all_queues(priv->net_dev);
9258 + priv->cgr_data.cgr_congested_count++;
9259 + } else {
9260 + priv->cgr_data.congested_jiffies +=
9261 + (jiffies - priv->cgr_data.congestion_start_jiffies);
9262 + netif_tx_wake_all_queues(priv->net_dev);
9263 + }
9264 +}
9265 +
9266 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv)
9267 +{
9268 + struct qm_mcc_initcgr initcgr;
9269 + u32 cs_th;
9270 + int err;
9271 +
9272 + err = qman_alloc_cgrid(&priv->cgr_data.cgr.cgrid);
9273 + if (err < 0) {
9274 + pr_err("Error %d allocating CGR ID\n", err);
9275 + goto out_error;
9276 + }
9277 + priv->cgr_data.cgr.cb = dpaa_eth_cgscn;
9278 +
9279 + /* Enable Congestion State Change Notifications and CS taildrop */
9280 + initcgr.we_mask = QM_CGR_WE_CSCN_EN | QM_CGR_WE_CS_THRES;
9281 + initcgr.cgr.cscn_en = QM_CGR_EN;
9282 +
9283 + /* Set different thresholds based on the MAC speed.
9284 + * TODO: this may turn suboptimal if the MAC is reconfigured at a speed
9285 + * lower than its max, e.g. if a dTSEC later negotiates a 100Mbps link.
9286 + * In such cases, we ought to reconfigure the threshold, too.
9287 + */
9288 + if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
9289 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_10G;
9290 + else
9291 + cs_th = CONFIG_FSL_DPAA_CS_THRESHOLD_1G;
9292 + qm_cgr_cs_thres_set64(&initcgr.cgr.cs_thres, cs_th, 1);
9293 +
9294 + initcgr.we_mask |= QM_CGR_WE_CSTD_EN;
9295 + initcgr.cgr.cstd_en = QM_CGR_EN;
9296 +
9297 + err = qman_create_cgr(&priv->cgr_data.cgr, QMAN_CGR_FLAG_USE_INIT,
9298 + &initcgr);
9299 + if (err < 0) {
9300 + pr_err("Error %d creating CGR with ID %d\n", err,
9301 + priv->cgr_data.cgr.cgrid);
9302 + qman_release_cgrid(priv->cgr_data.cgr.cgrid);
9303 + goto out_error;
9304 + }
9305 + pr_debug("Created CGR %d for netdev with hwaddr %pM on QMan channel %d\n",
9306 + priv->cgr_data.cgr.cgrid, priv->mac_dev->addr,
9307 + priv->cgr_data.cgr.chan);
9308 +
9309 +out_error:
9310 + return err;
9311 +}
9312 +EXPORT_SYMBOL(dpaa_eth_cgr_init);
9313 +
9314 +static inline void dpa_setup_ingress(const struct dpa_priv_s *priv,
9315 + struct dpa_fq *fq,
9316 + const struct qman_fq *template)
9317 +{
9318 + fq->fq_base = *template;
9319 + fq->net_dev = priv->net_dev;
9320 +
9321 + fq->flags = QMAN_FQ_FLAG_NO_ENQUEUE;
9322 + fq->channel = priv->channel;
9323 +}
9324 +
9325 +static inline void dpa_setup_egress(const struct dpa_priv_s *priv,
9326 + struct dpa_fq *fq,
9327 + struct fm_port *port,
9328 + const struct qman_fq *template)
9329 +{
9330 + fq->fq_base = *template;
9331 + fq->net_dev = priv->net_dev;
9332 +
9333 + if (port) {
9334 + fq->flags = QMAN_FQ_FLAG_TO_DCPORTAL;
9335 + fq->channel = (uint16_t)fm_get_tx_port_channel(port);
9336 + } else {
9337 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
9338 + }
9339 +}
9340 +
9341 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
9342 + struct fm_port *tx_port)
9343 +{
9344 + struct dpa_fq *fq;
9345 + uint16_t portals[NR_CPUS];
9346 + int cpu, portal_cnt = 0, num_portals = 0;
9347 + uint32_t pcd_fqid, pcd_fqid_hi_prio;
9348 + const cpumask_t *affine_cpus = qman_affine_cpus();
9349 + int egress_cnt = 0, conf_cnt = 0;
9350 +
9351 + /* Prepare for PCD FQs init */
9352 + for_each_cpu(cpu, affine_cpus)
9353 + portals[num_portals++] = qman_affine_channel(cpu);
9354 + if (num_portals == 0)
9355 + dev_err(priv->net_dev->dev.parent,
9356 + "No Qman software (affine) channels found");
9357 +
9358 + pcd_fqid = (priv->mac_dev) ?
9359 + DPAA_ETH_PCD_FQ_BASE(priv->mac_dev->res->start) : 0;
9360 + pcd_fqid_hi_prio = (priv->mac_dev) ?
9361 + DPAA_ETH_PCD_FQ_HI_PRIO_BASE(priv->mac_dev->res->start) : 0;
9362 +
9363 + /* Initialize each FQ in the list */
9364 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
9365 + switch (fq->fq_type) {
9366 + case FQ_TYPE_RX_DEFAULT:
9367 + BUG_ON(!priv->mac_dev);
9368 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
9369 + break;
9370 + case FQ_TYPE_RX_ERROR:
9371 + BUG_ON(!priv->mac_dev);
9372 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_errq);
9373 + break;
9374 + case FQ_TYPE_RX_PCD:
9375 + /* For MACless we can't have dynamic Rx queues */
9376 + BUG_ON(!priv->mac_dev && !fq->fqid);
9377 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
9378 + if (!fq->fqid)
9379 + fq->fqid = pcd_fqid++;
9380 + fq->channel = portals[portal_cnt];
9381 + portal_cnt = (portal_cnt + 1) % num_portals;
9382 + break;
9383 + case FQ_TYPE_RX_PCD_HI_PRIO:
9384 + /* For MACless we can't have dynamic Hi Pri Rx queues */
9385 + BUG_ON(!priv->mac_dev && !fq->fqid);
9386 + dpa_setup_ingress(priv, fq, &fq_cbs->rx_defq);
9387 + if (!fq->fqid)
9388 + fq->fqid = pcd_fqid_hi_prio++;
9389 + fq->channel = portals[portal_cnt];
9390 + portal_cnt = (portal_cnt + 1) % num_portals;
9391 + break;
9392 + case FQ_TYPE_TX:
9393 + dpa_setup_egress(priv, fq, tx_port,
9394 + &fq_cbs->egress_ern);
9395 + /* If we have more Tx queues than the number of cores,
9396 + * just ignore the extra ones.
9397 + */
9398 + if (egress_cnt < DPAA_ETH_TX_QUEUES)
9399 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
9400 + break;
9401 + case FQ_TYPE_TX_CONFIRM:
9402 + BUG_ON(!priv->mac_dev);
9403 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
9404 + break;
9405 + case FQ_TYPE_TX_CONF_MQ:
9406 + BUG_ON(!priv->mac_dev);
9407 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_defq);
9408 + priv->conf_fqs[conf_cnt++] = &fq->fq_base;
9409 + break;
9410 + case FQ_TYPE_TX_ERROR:
9411 + BUG_ON(!priv->mac_dev);
9412 + dpa_setup_ingress(priv, fq, &fq_cbs->tx_errq);
9413 + break;
9414 + default:
9415 + dev_warn(priv->net_dev->dev.parent,
9416 + "Unknown FQ type detected!\n");
9417 + break;
9418 + }
9419 + }
9420 +
9421 + /* The number of Tx queues may be smaller than the number of cores, if
9422 + * the Tx queue range is specified in the device tree instead of being
9423 + * dynamically allocated.
9424 + * Make sure all CPUs receive a corresponding Tx queue.
9425 + */
9426 + while (egress_cnt < DPAA_ETH_TX_QUEUES) {
9427 + list_for_each_entry(fq, &priv->dpa_fq_list, list) {
9428 + if (fq->fq_type != FQ_TYPE_TX)
9429 + continue;
9430 + priv->egress_fqs[egress_cnt++] = &fq->fq_base;
9431 + if (egress_cnt == DPAA_ETH_TX_QUEUES)
9432 + break;
9433 + }
9434 + }
9435 +}
9436 +EXPORT_SYMBOL(dpa_fq_setup);
9437 +
9438 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable)
9439 +{
9440 + int _errno;
9441 + const struct dpa_priv_s *priv;
9442 + struct device *dev;
9443 + struct qman_fq *fq;
9444 + struct qm_mcc_initfq initfq;
9445 + struct qman_fq *confq;
9446 + int queue_id;
9447 +
9448 + priv = netdev_priv(dpa_fq->net_dev);
9449 + dev = dpa_fq->net_dev->dev.parent;
9450 +
9451 + if (dpa_fq->fqid == 0)
9452 + dpa_fq->flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
9453 +
9454 + dpa_fq->init = !(dpa_fq->flags & QMAN_FQ_FLAG_NO_MODIFY);
9455 +
9456 + _errno = qman_create_fq(dpa_fq->fqid, dpa_fq->flags, &dpa_fq->fq_base);
9457 + if (_errno) {
9458 + dev_err(dev, "qman_create_fq() failed\n");
9459 + return _errno;
9460 + }
9461 + fq = &dpa_fq->fq_base;
9462 +
9463 + if (dpa_fq->init) {
9464 + memset(&initfq, 0, sizeof(initfq));
9465 +
9466 + initfq.we_mask = QM_INITFQ_WE_FQCTRL;
9467 +
9468 + /* Try to reduce the number of portal interrupts for
9469 + * Tx Confirmation FQs.
9470 + */
9471 + if (dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM)
9472 + initfq.fqd.fq_ctrl |= QM_FQCTRL_HOLDACTIVE;
9473 +
9474 + /* FQ placement */
9475 + initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
9476 +
9477 + initfq.fqd.dest.channel = dpa_fq->channel;
9478 + initfq.fqd.dest.wq = dpa_fq->wq;
9479 +
9480 + /* Put all egress queues in a congestion group of their own.
9481 + * Sensu stricto, the Tx confirmation queues are Rx FQs,
9482 + * rather than Tx - but they nonetheless account for the
9483 + * memory footprint on behalf of egress traffic. We therefore
9484 + * place them in the netdev's CGR, along with the Tx FQs.
9485 + */
9486 + if (dpa_fq->fq_type == FQ_TYPE_TX ||
9487 + dpa_fq->fq_type == FQ_TYPE_TX_CONFIRM ||
9488 + dpa_fq->fq_type == FQ_TYPE_TX_CONF_MQ) {
9489 + initfq.we_mask |= QM_INITFQ_WE_CGID;
9490 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
9491 + initfq.fqd.cgid = (uint8_t)priv->cgr_data.cgr.cgrid;
9492 + /* Set a fixed overhead accounting, in an attempt to
9493 + * reduce the impact of fixed-size skb shells and the
9494 + * driver's needed headroom on system memory. This is
9495 + * especially the case when the egress traffic is
9496 + * composed of small datagrams.
9497 + * Unfortunately, QMan's OAL value is capped to an
9498 + * insufficient value, but even that is better than
9499 + * no overhead accounting at all.
9500 + */
9501 + initfq.we_mask |= QM_INITFQ_WE_OAC;
9502 + initfq.fqd.oac_init.oac = QM_OAC_CG;
9503 + initfq.fqd.oac_init.oal =
9504 + (signed char)(min(sizeof(struct sk_buff) +
9505 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
9506 + }
9507 +
9508 + if (td_enable) {
9509 + initfq.we_mask |= QM_INITFQ_WE_TDTHRESH;
9510 + qm_fqd_taildrop_set(&initfq.fqd.td,
9511 + DPA_FQ_TD, 1);
9512 + initfq.fqd.fq_ctrl = QM_FQCTRL_TDE;
9513 + }
9514 +
9515 + /* Configure the Tx confirmation queue, now that we know
9516 + * which Tx queue it pairs with.
9517 + */
9518 + if (dpa_fq->fq_type == FQ_TYPE_TX) {
9519 + queue_id = _dpa_tx_fq_to_id(priv, &dpa_fq->fq_base);
9520 + if (queue_id >= 0) {
9521 + confq = priv->conf_fqs[queue_id];
9522 + if (confq) {
9523 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
9524 + /* ContextA: OVOM=1 (use contextA2 bits instead of ICAD)
9525 + * A2V=1 (contextA A2 field is valid)
9526 + * A0V=1 (contextA A0 field is valid)
9527 + * B0V=1 (contextB field is valid)
9528 + * ContextA A2: EBD=1 (deallocate buffers inside FMan)
9529 + * ContextB B0(ASPID): 0 (absolute Virtual Storage ID)
9530 + */
9531 + initfq.fqd.context_a.hi = 0x1e000000;
9532 + initfq.fqd.context_a.lo = 0x80000000;
9533 + }
9534 + }
9535 + }
9536 +
9537 + /* Put all *private* ingress queues in our "ingress CGR". */
9538 + if (priv->use_ingress_cgr &&
9539 + (dpa_fq->fq_type == FQ_TYPE_RX_DEFAULT ||
9540 + dpa_fq->fq_type == FQ_TYPE_RX_ERROR ||
9541 + dpa_fq->fq_type == FQ_TYPE_RX_PCD ||
9542 + dpa_fq->fq_type == FQ_TYPE_RX_PCD_HI_PRIO)) {
9543 + initfq.we_mask |= QM_INITFQ_WE_CGID;
9544 + initfq.fqd.fq_ctrl |= QM_FQCTRL_CGE;
9545 + initfq.fqd.cgid = (uint8_t)priv->ingress_cgr.cgrid;
9546 + /* Set a fixed overhead accounting, just like for the
9547 + * egress CGR.
9548 + */
9549 + initfq.we_mask |= QM_INITFQ_WE_OAC;
9550 + initfq.fqd.oac_init.oac = QM_OAC_CG;
9551 + initfq.fqd.oac_init.oal =
9552 + (signed char)(min(sizeof(struct sk_buff) +
9553 + priv->tx_headroom, (size_t)FSL_QMAN_MAX_OAL));
9554 + }
9555 +
9556 + /* Initialization common to all ingress queues */
9557 + if (dpa_fq->flags & QMAN_FQ_FLAG_NO_ENQUEUE) {
9558 + initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
9559 + initfq.fqd.fq_ctrl |=
9560 + QM_FQCTRL_CTXASTASHING | QM_FQCTRL_AVOIDBLOCK;
9561 + initfq.fqd.context_a.stashing.exclusive =
9562 + QM_STASHING_EXCL_DATA | QM_STASHING_EXCL_CTX |
9563 + QM_STASHING_EXCL_ANNOTATION;
9564 + initfq.fqd.context_a.stashing.data_cl = 2;
9565 + initfq.fqd.context_a.stashing.annotation_cl = 1;
9566 + initfq.fqd.context_a.stashing.context_cl =
9567 + DIV_ROUND_UP(sizeof(struct qman_fq), 64);
9568 + }
9569 +
9570 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
9571 + if (_errno < 0) {
9572 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno)) {
9573 + dpa_fq->init = 0;
9574 + } else {
9575 + dev_err(dev, "qman_init_fq(%u) = %d\n",
9576 + qman_fq_fqid(fq), _errno);
9577 + qman_destroy_fq(fq, 0);
9578 + }
9579 + return _errno;
9580 + }
9581 + }
9582 +
9583 + dpa_fq->fqid = qman_fq_fqid(fq);
9584 +
9585 + return 0;
9586 +}
9587 +EXPORT_SYMBOL(dpa_fq_init);
9588 +
9589 +int __cold __attribute__((nonnull))
9590 +_dpa_fq_free(struct device *dev, struct qman_fq *fq)
9591 +{
9592 + int _errno, __errno;
9593 + struct dpa_fq *dpa_fq;
9594 + const struct dpa_priv_s *priv;
9595 +
9596 + _errno = 0;
9597 +
9598 + dpa_fq = container_of(fq, struct dpa_fq, fq_base);
9599 + priv = netdev_priv(dpa_fq->net_dev);
9600 +
9601 + if (dpa_fq->init) {
9602 + _errno = qman_retire_fq(fq, NULL);
9603 + if (unlikely(_errno < 0) && netif_msg_drv(priv))
9604 + dev_err(dev, "qman_retire_fq(%u) = %d\n",
9605 + qman_fq_fqid(fq), _errno);
9606 +
9607 + __errno = qman_oos_fq(fq);
9608 + if (unlikely(__errno < 0) && netif_msg_drv(priv)) {
9609 + dev_err(dev, "qman_oos_fq(%u) = %d\n",
9610 + qman_fq_fqid(fq), __errno);
9611 + if (_errno >= 0)
9612 + _errno = __errno;
9613 + }
9614 + }
9615 +
9616 + qman_destroy_fq(fq, 0);
9617 + list_del(&dpa_fq->list);
9618 +
9619 + return _errno;
9620 +}
9621 +EXPORT_SYMBOL(_dpa_fq_free);
9622 +
9623 +int __cold __attribute__((nonnull))
9624 +dpa_fq_free(struct device *dev, struct list_head *list)
9625 +{
9626 + int _errno, __errno;
9627 + struct dpa_fq *dpa_fq, *tmp;
9628 +
9629 + _errno = 0;
9630 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
9631 + __errno = _dpa_fq_free(dev, (struct qman_fq *)dpa_fq);
9632 + if (unlikely(__errno < 0) && _errno >= 0)
9633 + _errno = __errno;
9634 + }
9635 +
9636 + return _errno;
9637 +}
9638 +EXPORT_SYMBOL(dpa_fq_free);
9639 +
9640 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable)
9641 +{
9642 + int _errno, __errno;
9643 + struct dpa_fq *dpa_fq, *tmp;
9644 + static bool print_msg __read_mostly;
9645 +
9646 + _errno = 0;
9647 + print_msg = true;
9648 + list_for_each_entry_safe(dpa_fq, tmp, list, list) {
9649 + __errno = dpa_fq_init(dpa_fq, td_enable);
9650 + if (unlikely(__errno < 0) && _errno >= 0) {
9651 + if (DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, __errno)) {
9652 + if (print_msg) {
9653 + dev_warn(dev,
9654 + "Skip RX PCD High Priority FQs initialization\n");
9655 + print_msg = false;
9656 + }
9657 + if (_dpa_fq_free(dev, (struct qman_fq *)dpa_fq))
9658 + dev_warn(dev,
9659 + "Error freeing frame queues\n");
9660 + } else {
9661 + _errno = __errno;
9662 + break;
9663 + }
9664 + }
9665 + }
9666 +
9667 + return _errno;
9668 +}
9669 +EXPORT_SYMBOL(dpa_fqs_init);
9670 +static void
9671 +dpaa_eth_init_tx_port(struct fm_port *port, struct dpa_fq *errq,
9672 + struct dpa_fq *defq, struct dpa_buffer_layout_s *buf_layout)
9673 +{
9674 + struct fm_port_params tx_port_param;
9675 + bool frag_enabled = false;
9676 +
9677 + memset(&tx_port_param, 0, sizeof(tx_port_param));
9678 + dpaa_eth_init_port(tx, port, tx_port_param, errq->fqid, defq->fqid,
9679 + buf_layout, frag_enabled);
9680 +}
9681 +
9682 +static void
9683 +dpaa_eth_init_rx_port(struct fm_port *port, struct dpa_bp *bp, size_t count,
9684 + struct dpa_fq *errq, struct dpa_fq *defq,
9685 + struct dpa_buffer_layout_s *buf_layout)
9686 +{
9687 + struct fm_port_params rx_port_param;
9688 + int i;
9689 + bool frag_enabled = false;
9690 +
9691 + memset(&rx_port_param, 0, sizeof(rx_port_param));
9692 + count = min(ARRAY_SIZE(rx_port_param.pool_param), count);
9693 + rx_port_param.num_pools = (uint8_t)count;
9694 + for (i = 0; i < count; i++) {
9695 + if (i >= rx_port_param.num_pools)
9696 + break;
9697 + rx_port_param.pool_param[i].id = bp[i].bpid;
9698 + rx_port_param.pool_param[i].size = (uint16_t)bp[i].size;
9699 + }
9700 +
9701 + dpaa_eth_init_port(rx, port, rx_port_param, errq->fqid, defq->fqid,
9702 + buf_layout, frag_enabled);
9703 +}
9704 +
9705 +#if defined(CONFIG_FSL_SDK_FMAN_TEST)
9706 +/* Defined as weak, to be implemented by fman pcd tester. */
9707 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *)
9708 +__attribute__((weak));
9709 +
9710 +int dpa_free_pcd_fqids(struct device *, uint32_t) __attribute__((weak));
9711 +#else
9712 +int dpa_alloc_pcd_fqids(struct device *, uint32_t, uint8_t, uint32_t *);
9713 +
9714 +int dpa_free_pcd_fqids(struct device *, uint32_t);
9715 +
9716 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
9717 +
9718 +
9719 +int dpa_alloc_pcd_fqids(struct device *dev, uint32_t num,
9720 + uint8_t alignment, uint32_t *base_fqid)
9721 +{
9722 + dev_crit(dev, "callback not implemented!\n");
9723 +
9724 + return 0;
9725 +}
9726 +
9727 +int dpa_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
9728 +{
9729 +
9730 + dev_crit(dev, "callback not implemented!\n");
9731 +
9732 + return 0;
9733 +}
9734 +
9735 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
9736 + struct dpa_bp *bp, size_t count,
9737 + struct fm_port_fqs *port_fqs,
9738 + struct dpa_buffer_layout_s *buf_layout,
9739 + struct device *dev)
9740 +{
9741 + struct fm_port_pcd_param rx_port_pcd_param;
9742 + struct fm_port *rxport = mac_dev->port_dev[RX];
9743 + struct fm_port *txport = mac_dev->port_dev[TX];
9744 +
9745 + dpaa_eth_init_tx_port(txport, port_fqs->tx_errq,
9746 + port_fqs->tx_defq, &buf_layout[TX]);
9747 + dpaa_eth_init_rx_port(rxport, bp, count, port_fqs->rx_errq,
9748 + port_fqs->rx_defq, &buf_layout[RX]);
9749 +
9750 + rx_port_pcd_param.cba = dpa_alloc_pcd_fqids;
9751 + rx_port_pcd_param.cbf = dpa_free_pcd_fqids;
9752 + rx_port_pcd_param.dev = dev;
9753 + fm_port_pcd_bind(rxport, &rx_port_pcd_param);
9754 +}
9755 +EXPORT_SYMBOL(dpaa_eth_init_ports);
9756 +
9757 +void dpa_release_sgt(struct qm_sg_entry *sgt)
9758 +{
9759 + struct dpa_bp *dpa_bp;
9760 + struct bm_buffer bmb[DPA_BUFF_RELEASE_MAX];
9761 + uint8_t i = 0, j;
9762 +
9763 + memset(bmb, 0, DPA_BUFF_RELEASE_MAX * sizeof(struct bm_buffer));
9764 +
9765 + do {
9766 + dpa_bp = dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i]));
9767 + DPA_BUG_ON(!dpa_bp);
9768 +
9769 + j = 0;
9770 + do {
9771 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
9772 + bm_buffer_set64(&bmb[j], qm_sg_addr(&sgt[i]));
9773 +
9774 + j++; i++;
9775 + } while (j < ARRAY_SIZE(bmb) &&
9776 + !qm_sg_entry_get_final(&sgt[i-1]) &&
9777 + qm_sg_entry_get_bpid(&sgt[i-1]) ==
9778 + qm_sg_entry_get_bpid(&sgt[i]));
9779 +
9780 + while (bman_release(dpa_bp->pool, bmb, j, 0))
9781 + cpu_relax();
9782 + } while (!qm_sg_entry_get_final(&sgt[i-1]));
9783 +}
9784 +EXPORT_SYMBOL(dpa_release_sgt);
9785 +
9786 +void __attribute__((nonnull))
9787 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd)
9788 +{
9789 + struct qm_sg_entry *sgt;
9790 + struct dpa_bp *dpa_bp;
9791 + struct bm_buffer bmb;
9792 + dma_addr_t addr;
9793 + void *vaddr;
9794 +
9795 + bmb.opaque = 0;
9796 + bm_buffer_set64(&bmb, qm_fd_addr(fd));
9797 +
9798 + dpa_bp = dpa_bpid2pool(fd->bpid);
9799 + DPA_BUG_ON(!dpa_bp);
9800 +
9801 + if (fd->format == qm_fd_sg) {
9802 + vaddr = phys_to_virt(qm_fd_addr(fd));
9803 + sgt = vaddr + dpa_fd_offset(fd);
9804 +
9805 + dma_unmap_single(dpa_bp->dev, qm_fd_addr(fd), dpa_bp->size,
9806 + DMA_BIDIRECTIONAL);
9807 +
9808 + dpa_release_sgt(sgt);
9809 + addr = dma_map_single(dpa_bp->dev, vaddr, dpa_bp->size,
9810 + DMA_BIDIRECTIONAL);
9811 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
9812 + dev_err(dpa_bp->dev, "DMA mapping failed");
9813 + return;
9814 + }
9815 + bm_buffer_set64(&bmb, addr);
9816 + }
9817 +
9818 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
9819 + cpu_relax();
9820 +}
9821 +EXPORT_SYMBOL(dpa_fd_release);
9822 +
9823 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
9824 + const struct qm_mr_entry *msg)
9825 +{
9826 + switch (msg->ern.rc & QM_MR_RC_MASK) {
9827 + case QM_MR_RC_CGR_TAILDROP:
9828 + percpu_priv->ern_cnt.cg_tdrop++;
9829 + break;
9830 + case QM_MR_RC_WRED:
9831 + percpu_priv->ern_cnt.wred++;
9832 + break;
9833 + case QM_MR_RC_ERROR:
9834 + percpu_priv->ern_cnt.err_cond++;
9835 + break;
9836 + case QM_MR_RC_ORPWINDOW_EARLY:
9837 + percpu_priv->ern_cnt.early_window++;
9838 + break;
9839 + case QM_MR_RC_ORPWINDOW_LATE:
9840 + percpu_priv->ern_cnt.late_window++;
9841 + break;
9842 + case QM_MR_RC_FQ_TAILDROP:
9843 + percpu_priv->ern_cnt.fq_tdrop++;
9844 + break;
9845 + case QM_MR_RC_ORPWINDOW_RETIRED:
9846 + percpu_priv->ern_cnt.fq_retired++;
9847 + break;
9848 + case QM_MR_RC_ORP_ZERO:
9849 + percpu_priv->ern_cnt.orp_zero++;
9850 + break;
9851 + }
9852 +}
9853 +EXPORT_SYMBOL(count_ern);
9854 +
9855 +/**
9856 + * Turn on HW checksum computation for this outgoing frame.
9857 + * If the current protocol is not something we support in this regard
9858 + * (or if the stack has already computed the SW checksum), we do nothing.
9859 + *
9860 + * Returns 0 if all goes well (or HW csum doesn't apply), and a negative value
9861 + * otherwise.
9862 + *
9863 + * Note that this function may modify the fd->cmd field and the skb data buffer
9864 + * (the Parse Results area).
9865 + */
9866 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
9867 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results)
9868 +{
9869 + fm_prs_result_t *parse_result;
9870 + struct iphdr *iph;
9871 + struct ipv6hdr *ipv6h = NULL;
9872 + u8 l4_proto;
9873 + u16 ethertype = ntohs(skb->protocol);
9874 + int retval = 0;
9875 +
9876 + if (skb->ip_summed != CHECKSUM_PARTIAL)
9877 + return 0;
9878 +
9879 + /* Note: L3 csum seems to be already computed in sw, but we can't choose
9880 + * L4 alone from the FM configuration anyway.
9881 + */
9882 +
9883 + /* Fill in some fields of the Parse Results array, so the FMan
9884 + * can find them as if they came from the FMan Parser.
9885 + */
9886 + parse_result = (fm_prs_result_t *)parse_results;
9887 +
9888 + /* If we're dealing with VLAN, get the real Ethernet type */
9889 + if (ethertype == ETH_P_8021Q) {
9890 + /* We can't always assume the MAC header is set correctly
9891 + * by the stack, so reset to beginning of skb->data
9892 + */
9893 + skb_reset_mac_header(skb);
9894 + ethertype = ntohs(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto);
9895 + }
9896 +
9897 + /* Fill in the relevant L3 parse result fields
9898 + * and read the L4 protocol type
9899 + */
9900 + switch (ethertype) {
9901 + case ETH_P_IP:
9902 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV4);
9903 + iph = ip_hdr(skb);
9904 + DPA_BUG_ON(iph == NULL);
9905 + l4_proto = iph->protocol;
9906 + break;
9907 + case ETH_P_IPV6:
9908 + parse_result->l3r = cpu_to_be16(FM_L3_PARSE_RESULT_IPV6);
9909 + ipv6h = ipv6_hdr(skb);
9910 + DPA_BUG_ON(ipv6h == NULL);
9911 + l4_proto = ipv6h->nexthdr;
9912 + break;
9913 + default:
9914 + /* We shouldn't even be here */
9915 + if (netif_msg_tx_err(priv) && net_ratelimit())
9916 + netdev_alert(priv->net_dev,
9917 + "Can't compute HW csum for L3 proto 0x%x\n",
9918 + ntohs(skb->protocol));
9919 + retval = -EIO;
9920 + goto return_error;
9921 + }
9922 +
9923 + /* Fill in the relevant L4 parse result fields */
9924 + switch (l4_proto) {
9925 + case IPPROTO_UDP:
9926 + parse_result->l4r = FM_L4_PARSE_RESULT_UDP;
9927 + break;
9928 + case IPPROTO_TCP:
9929 + parse_result->l4r = FM_L4_PARSE_RESULT_TCP;
9930 + break;
9931 + default:
9932 + /* This can as well be a BUG() */
9933 + if (netif_msg_tx_err(priv) && net_ratelimit())
9934 + netdev_alert(priv->net_dev,
9935 + "Can't compute HW csum for L4 proto 0x%x\n",
9936 + l4_proto);
9937 + retval = -EIO;
9938 + goto return_error;
9939 + }
9940 +
9941 + /* At index 0 is IPOffset_1 as defined in the Parse Results */
9942 + parse_result->ip_off[0] = (uint8_t)skb_network_offset(skb);
9943 + parse_result->l4_off = (uint8_t)skb_transport_offset(skb);
9944 +
9945 + /* Enable L3 (and L4, if TCP or UDP) HW checksum. */
9946 + fd->cmd |= FM_FD_CMD_RPD | FM_FD_CMD_DTC;
9947 +
9948 + /* On P1023 and similar platforms fd->cmd interpretation could
9949 + * be disabled by setting CONTEXT_A bit ICMD; currently this bit
9950 + * is not set so we do not need to check; in the future, if/when
9951 + * using context_a we need to check this bit
9952 + */
9953 +
9954 +return_error:
9955 + return retval;
9956 +}
9957 +EXPORT_SYMBOL(dpa_enable_tx_csum);
9958 +
9959 +#ifdef CONFIG_FSL_DPAA_CEETM
9960 +void dpa_enable_ceetm(struct net_device *dev)
9961 +{
9962 + struct dpa_priv_s *priv = netdev_priv(dev);
9963 + priv->ceetm_en = true;
9964 +}
9965 +EXPORT_SYMBOL(dpa_enable_ceetm);
9966 +
9967 +void dpa_disable_ceetm(struct net_device *dev)
9968 +{
9969 + struct dpa_priv_s *priv = netdev_priv(dev);
9970 + priv->ceetm_en = false;
9971 +}
9972 +EXPORT_SYMBOL(dpa_disable_ceetm);
9973 +#endif
9974 --- /dev/null
9975 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h
9976 @@ -0,0 +1,226 @@
9977 +/* Copyright 2008-2013 Freescale Semiconductor, Inc.
9978 + *
9979 + * Redistribution and use in source and binary forms, with or without
9980 + * modification, are permitted provided that the following conditions are met:
9981 + * * Redistributions of source code must retain the above copyright
9982 + * notice, this list of conditions and the following disclaimer.
9983 + * * Redistributions in binary form must reproduce the above copyright
9984 + * notice, this list of conditions and the following disclaimer in the
9985 + * documentation and/or other materials provided with the distribution.
9986 + * * Neither the name of Freescale Semiconductor nor the
9987 + * names of its contributors may be used to endorse or promote products
9988 + * derived from this software without specific prior written permission.
9989 + *
9990 + *
9991 + * ALTERNATIVELY, this software may be distributed under the terms of the
9992 + * GNU General Public License ("GPL") as published by the Free Software
9993 + * Foundation, either version 2 of that License or (at your option) any
9994 + * later version.
9995 + *
9996 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
9997 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9998 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
9999 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10000 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10001 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10002 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10003 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10004 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10005 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10006 + */
10007 +
10008 +#ifndef __DPAA_ETH_COMMON_H
10009 +#define __DPAA_ETH_COMMON_H
10010 +
10011 +#include <linux/etherdevice.h> /* struct net_device */
10012 +#include <linux/fsl_bman.h> /* struct bm_buffer */
10013 +#include <linux/of_platform.h> /* struct platform_device */
10014 +#include <linux/net_tstamp.h> /* struct hwtstamp_config */
10015 +
10016 +#include "dpaa_eth.h"
10017 +#include "lnxwrp_fsl_fman.h"
10018 +
10019 +#define dpaa_eth_init_port(type, port, param, errq_id, defq_id, buf_layout,\
10020 + frag_enabled) \
10021 +{ \
10022 + param.errq = errq_id; \
10023 + param.defq = defq_id; \
10024 + param.priv_data_size = buf_layout->priv_data_size; \
10025 + param.parse_results = buf_layout->parse_results; \
10026 + param.hash_results = buf_layout->hash_results; \
10027 + param.frag_enable = frag_enabled; \
10028 + param.time_stamp = buf_layout->time_stamp; \
10029 + param.manip_extra_space = buf_layout->manip_extra_space; \
10030 + param.data_align = buf_layout->data_align; \
10031 + fm_set_##type##_port_params(port, &param); \
10032 +}
10033 +
10034 +/* The SGT needs to be 256 bytes long. Even if the table has only one entry,
10035 + * the FMan will read 256 bytes from its start.
10036 + */
10037 +#define DPA_SGT_SIZE 256
10038 +#define DPA_SGT_MAX_ENTRIES 16 /* maximum number of entries in SG Table */
10039 +
10040 +#define DPA_BUFF_RELEASE_MAX 8 /* maximum number of buffers released at once */
10041 +
10042 +#define DPA_RX_PCD_HI_PRIO_FQ_INIT_FAIL(dpa_fq, _errno) \
10043 + (((dpa_fq)->fq_type == FQ_TYPE_RX_PCD_HI_PRIO) && \
10044 + (_errno == -EIO))
10045 +/* return codes for the dpaa-eth hooks */
10046 +enum dpaa_eth_hook_result {
10047 + /* fd/skb was retained by the hook.
10048 + *
10049 + * On the Rx path, this means the Ethernet driver will _not_
10050 + * deliver the skb to the stack. Instead, the hook implementation
10051 + * is expected to properly dispose of the skb.
10052 + *
10053 + * On the Tx path, the Ethernet driver's dpa_tx() function will
10054 + * immediately return NETDEV_TX_OK. The hook implementation is expected
10055 + * to free the skb. *DO*NOT* release it to BMan, or enqueue it to FMan,
10056 + * unless you know exactly what you're doing!
10057 + *
10058 + * On the confirmation/error paths, the Ethernet driver will _not_
10059 + * perform any fd cleanup, nor update the interface statistics.
10060 + */
10061 + DPAA_ETH_STOLEN,
10062 + /* fd/skb was returned to the Ethernet driver for regular processing.
10063 + * The hook is not allowed to, for instance, reallocate the skb (as if
10064 + * by linearizing, copying, cloning or reallocating the headroom).
10065 + */
10066 + DPAA_ETH_CONTINUE
10067 +};
10068 +
10069 +typedef enum dpaa_eth_hook_result (*dpaa_eth_ingress_hook_t)(
10070 + struct sk_buff *skb, struct net_device *net_dev, u32 fqid);
10071 +typedef enum dpaa_eth_hook_result (*dpaa_eth_egress_hook_t)(
10072 + struct sk_buff *skb, struct net_device *net_dev);
10073 +typedef enum dpaa_eth_hook_result (*dpaa_eth_confirm_hook_t)(
10074 + struct net_device *net_dev, const struct qm_fd *fd, u32 fqid);
10075 +
10076 +/* used in napi related functions */
10077 +extern u16 qman_portal_max;
10078 +
10079 +/* from dpa_ethtool.c */
10080 +extern const struct ethtool_ops dpa_ethtool_ops;
10081 +
10082 +#ifdef CONFIG_FSL_DPAA_HOOKS
10083 +/* Various hooks used for unit-testing and/or fastpath optimizations.
10084 + * Currently only one set of such hooks is supported.
10085 + */
10086 +struct dpaa_eth_hooks_s {
10087 + /* Invoked on the Tx private path, immediately after receiving the skb
10088 + * from the stack.
10089 + */
10090 + dpaa_eth_egress_hook_t tx;
10091 +
10092 + /* Invoked on the Rx private path, right before passing the skb
10093 + * up the stack. At that point, the packet's protocol id has already
10094 + * been set. The skb's data pointer is now at the L3 header, and
10095 + * skb->mac_header points to the L2 header. skb->len has been adjusted
10096 + * to be the length of L3+payload (i.e., the length of the
10097 + * original frame minus the L2 header len).
10098 + * For more details on what the skb looks like, see eth_type_trans().
10099 + */
10100 + dpaa_eth_ingress_hook_t rx_default;
10101 +
10102 + /* Driver hook for the Rx error private path. */
10103 + dpaa_eth_confirm_hook_t rx_error;
10104 + /* Driver hook for the Tx confirmation private path. */
10105 + dpaa_eth_confirm_hook_t tx_confirm;
10106 + /* Driver hook for the Tx error private path. */
10107 + dpaa_eth_confirm_hook_t tx_error;
10108 +};
10109 +
10110 +void fsl_dpaa_eth_set_hooks(struct dpaa_eth_hooks_s *hooks);
10111 +
10112 +extern struct dpaa_eth_hooks_s dpaa_eth_hooks;
10113 +#endif
10114 +
10115 +int dpa_netdev_init(struct net_device *net_dev,
10116 + const uint8_t *mac_addr,
10117 + uint16_t tx_timeout);
10118 +int __cold dpa_start(struct net_device *net_dev);
10119 +int __cold dpa_stop(struct net_device *net_dev);
10120 +void __cold dpa_timeout(struct net_device *net_dev);
10121 +void __cold
10122 +dpa_get_stats64(struct net_device *net_dev,
10123 + struct rtnl_link_stats64 *stats);
10124 +int dpa_ndo_init(struct net_device *net_dev);
10125 +int dpa_set_features(struct net_device *dev, netdev_features_t features);
10126 +netdev_features_t dpa_fix_features(struct net_device *dev,
10127 + netdev_features_t features);
10128 +#ifdef CONFIG_FSL_DPAA_TS
10129 +u64 dpa_get_timestamp_ns(const struct dpa_priv_s *priv,
10130 + enum port_type rx_tx, const void *data);
10131 +/* Updates the skb shared hw timestamp from the hardware timestamp */
10132 +int dpa_get_ts(const struct dpa_priv_s *priv, enum port_type rx_tx,
10133 + struct skb_shared_hwtstamps *shhwtstamps, const void *data);
10134 +#endif /* CONFIG_FSL_DPAA_TS */
10135 +int dpa_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
10136 +int __cold dpa_remove(struct platform_device *of_dev);
10137 +struct mac_device * __cold __must_check
10138 +__attribute__((nonnull)) dpa_mac_probe(struct platform_device *_of_dev);
10139 +int dpa_set_mac_address(struct net_device *net_dev, void *addr);
10140 +void dpa_set_rx_mode(struct net_device *net_dev);
10141 +void dpa_set_buffers_layout(struct mac_device *mac_dev,
10142 + struct dpa_buffer_layout_s *layout);
10143 +int __attribute__((nonnull))
10144 +dpa_bp_alloc(struct dpa_bp *dpa_bp, struct device *dev);
10145 +void __cold __attribute__((nonnull))
10146 +dpa_bp_free(struct dpa_priv_s *priv);
10147 +struct dpa_bp *dpa_bpid2pool(int bpid);
10148 +void dpa_bpid2pool_map(int bpid, struct dpa_bp *dpa_bp);
10149 +bool dpa_bpid2pool_use(int bpid);
10150 +void dpa_bp_drain(struct dpa_bp *bp);
10151 +#ifdef CONFIG_FMAN_PFC
10152 +u16 dpa_select_queue(struct net_device *net_dev, struct sk_buff *skb,
10153 + void *accel_priv, select_queue_fallback_t fallback);
10154 +#endif
10155 +struct dpa_fq *dpa_fq_alloc(struct device *dev,
10156 + u32 fq_start,
10157 + u32 fq_count,
10158 + struct list_head *list,
10159 + enum dpa_fq_type fq_type);
10160 +int dpa_fq_probe_mac(struct device *dev, struct list_head *list,
10161 + struct fm_port_fqs *port_fqs,
10162 + bool tx_conf_fqs_per_core,
10163 + enum port_type ptype);
10164 +int dpa_get_channel(void);
10165 +void dpa_release_channel(void);
10166 +void dpaa_eth_add_channel(u16 channel);
10167 +int dpaa_eth_cgr_init(struct dpa_priv_s *priv);
10168 +void dpa_fq_setup(struct dpa_priv_s *priv, const struct dpa_fq_cbs_t *fq_cbs,
10169 + struct fm_port *tx_port);
10170 +int dpa_fq_init(struct dpa_fq *dpa_fq, bool td_enable);
10171 +int dpa_fqs_init(struct device *dev, struct list_head *list, bool td_enable);
10172 +int __cold __attribute__((nonnull))
10173 +dpa_fq_free(struct device *dev, struct list_head *list);
10174 +void dpaa_eth_init_ports(struct mac_device *mac_dev,
10175 + struct dpa_bp *bp, size_t count,
10176 + struct fm_port_fqs *port_fqs,
10177 + struct dpa_buffer_layout_s *buf_layout,
10178 + struct device *dev);
10179 +void dpa_release_sgt(struct qm_sg_entry *sgt);
10180 +void __attribute__((nonnull))
10181 +dpa_fd_release(const struct net_device *net_dev, const struct qm_fd *fd);
10182 +void count_ern(struct dpa_percpu_priv_s *percpu_priv,
10183 + const struct qm_mr_entry *msg);
10184 +int dpa_enable_tx_csum(struct dpa_priv_s *priv,
10185 + struct sk_buff *skb, struct qm_fd *fd, char *parse_results);
10186 +#ifdef CONFIG_FSL_DPAA_CEETM
10187 +void dpa_enable_ceetm(struct net_device *dev);
10188 +void dpa_disable_ceetm(struct net_device *dev);
10189 +#endif
10190 +struct proxy_device {
10191 + struct mac_device *mac_dev;
10192 +};
10193 +
10194 +/* mac device control functions exposed by proxy interface*/
10195 +int dpa_proxy_start(struct net_device *net_dev);
10196 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev);
10197 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
10198 + struct net_device *net_dev);
10199 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
10200 + struct net_device *net_dev);
10201 +
10202 +#endif /* __DPAA_ETH_COMMON_H */
10203 --- /dev/null
10204 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_proxy.c
10205 @@ -0,0 +1,381 @@
10206 +/* Copyright 2008-2013 Freescale Semiconductor Inc.
10207 + *
10208 + * Redistribution and use in source and binary forms, with or without
10209 + * modification, are permitted provided that the following conditions are met:
10210 + * * Redistributions of source code must retain the above copyright
10211 + * notice, this list of conditions and the following disclaimer.
10212 + * * Redistributions in binary form must reproduce the above copyright
10213 + * notice, this list of conditions and the following disclaimer in the
10214 + * documentation and/or other materials provided with the distribution.
10215 + * * Neither the name of Freescale Semiconductor nor the
10216 + * names of its contributors may be used to endorse or promote products
10217 + * derived from this software without specific prior written permission.
10218 + *
10219 + *
10220 + * ALTERNATIVELY, this software may be distributed under the terms of the
10221 + * GNU General Public License ("GPL") as published by the Free Software
10222 + * Foundation, either version 2 of that License or (at your option) any
10223 + * later version.
10224 + *
10225 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10226 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10227 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10228 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10229 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10230 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10231 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10232 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10233 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10234 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10235 + */
10236 +
10237 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10238 +#define pr_fmt(fmt) \
10239 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10240 + KBUILD_BASENAME".c", __LINE__, __func__
10241 +#else
10242 +#define pr_fmt(fmt) \
10243 + KBUILD_MODNAME ": " fmt
10244 +#endif
10245 +
10246 +#include <linux/init.h>
10247 +#include <linux/module.h>
10248 +#include <linux/of_platform.h>
10249 +#include "dpaa_eth.h"
10250 +#include "dpaa_eth_common.h"
10251 +#include "dpaa_eth_base.h"
10252 +#include "lnxwrp_fsl_fman.h" /* fm_get_rx_extra_headroom(), fm_get_max_frm() */
10253 +#include "mac.h"
10254 +
10255 +#define DPA_DESCRIPTION "FSL DPAA Proxy initialization driver"
10256 +
10257 +MODULE_LICENSE("Dual BSD/GPL");
10258 +
10259 +MODULE_DESCRIPTION(DPA_DESCRIPTION);
10260 +
10261 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev);
10262 +#ifdef CONFIG_PM
10263 +
10264 +static int proxy_suspend(struct device *dev)
10265 +{
10266 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
10267 + struct mac_device *mac_dev = proxy_dev->mac_dev;
10268 + int err = 0;
10269 +
10270 + err = fm_port_suspend(mac_dev->port_dev[RX]);
10271 + if (err)
10272 + goto port_suspend_failed;
10273 +
10274 + err = fm_port_suspend(mac_dev->port_dev[TX]);
10275 + if (err)
10276 + err = fm_port_resume(mac_dev->port_dev[RX]);
10277 +
10278 +port_suspend_failed:
10279 + return err;
10280 +}
10281 +
10282 +static int proxy_resume(struct device *dev)
10283 +{
10284 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
10285 + struct mac_device *mac_dev = proxy_dev->mac_dev;
10286 + int err = 0;
10287 +
10288 + err = fm_port_resume(mac_dev->port_dev[TX]);
10289 + if (err)
10290 + goto port_resume_failed;
10291 +
10292 + err = fm_port_resume(mac_dev->port_dev[RX]);
10293 + if (err)
10294 + err = fm_port_suspend(mac_dev->port_dev[TX]);
10295 +
10296 +port_resume_failed:
10297 + return err;
10298 +}
10299 +
10300 +static const struct dev_pm_ops proxy_pm_ops = {
10301 + .suspend = proxy_suspend,
10302 + .resume = proxy_resume,
10303 +};
10304 +
10305 +#define PROXY_PM_OPS (&proxy_pm_ops)
10306 +
10307 +#else /* CONFIG_PM */
10308 +
10309 +#define PROXY_PM_OPS NULL
10310 +
10311 +#endif /* CONFIG_PM */
10312 +
10313 +static int dpaa_eth_proxy_probe(struct platform_device *_of_dev)
10314 +{
10315 + int err = 0, i;
10316 + struct device *dev;
10317 + struct device_node *dpa_node;
10318 + struct dpa_bp *dpa_bp;
10319 + struct list_head proxy_fq_list;
10320 + size_t count;
10321 + struct fm_port_fqs port_fqs;
10322 + struct dpa_buffer_layout_s *buf_layout = NULL;
10323 + struct mac_device *mac_dev;
10324 + struct proxy_device *proxy_dev;
10325 +
10326 + dev = &_of_dev->dev;
10327 +
10328 + dpa_node = dev->of_node;
10329 +
10330 + if (!of_device_is_available(dpa_node))
10331 + return -ENODEV;
10332 +
10333 + /* Get the buffer pools assigned to this interface */
10334 + dpa_bp = dpa_bp_probe(_of_dev, &count);
10335 + if (IS_ERR(dpa_bp))
10336 + return PTR_ERR(dpa_bp);
10337 +
10338 + mac_dev = dpa_mac_probe(_of_dev);
10339 + if (IS_ERR(mac_dev))
10340 + return PTR_ERR(mac_dev);
10341 +
10342 + proxy_dev = devm_kzalloc(dev, sizeof(*proxy_dev), GFP_KERNEL);
10343 + if (!proxy_dev) {
10344 + dev_err(dev, "devm_kzalloc() failed\n");
10345 + return -ENOMEM;
10346 + }
10347 +
10348 + proxy_dev->mac_dev = mac_dev;
10349 + dev_set_drvdata(dev, proxy_dev);
10350 +
10351 + /* We have physical ports, so we need to establish
10352 + * the buffer layout.
10353 + */
10354 + buf_layout = devm_kzalloc(dev, 2 * sizeof(*buf_layout),
10355 + GFP_KERNEL);
10356 + if (!buf_layout) {
10357 + dev_err(dev, "devm_kzalloc() failed\n");
10358 + return -ENOMEM;
10359 + }
10360 + dpa_set_buffers_layout(mac_dev, buf_layout);
10361 +
10362 + INIT_LIST_HEAD(&proxy_fq_list);
10363 +
10364 + memset(&port_fqs, 0, sizeof(port_fqs));
10365 +
10366 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true, RX);
10367 + if (!err)
10368 + err = dpa_fq_probe_mac(dev, &proxy_fq_list, &port_fqs, true,
10369 + TX);
10370 + if (err < 0) {
10371 + devm_kfree(dev, buf_layout);
10372 + return err;
10373 + }
10374 +
10375 + /* Proxy initializer - Just configures the MAC on behalf of
10376 + * another partition.
10377 + */
10378 + dpaa_eth_init_ports(mac_dev, dpa_bp, count, &port_fqs,
10379 + buf_layout, dev);
10380 +
10381 + /* Proxy interfaces need to be started, and the allocated
10382 + * memory freed
10383 + */
10384 + devm_kfree(dev, buf_layout);
10385 + devm_kfree(dev, dpa_bp);
10386 +
10387 + /* Free FQ structures */
10388 + devm_kfree(dev, port_fqs.rx_defq);
10389 + devm_kfree(dev, port_fqs.rx_errq);
10390 + devm_kfree(dev, port_fqs.tx_defq);
10391 + devm_kfree(dev, port_fqs.tx_errq);
10392 +
10393 + for_each_port_device(i, mac_dev->port_dev) {
10394 + err = fm_port_enable(mac_dev->port_dev[i]);
10395 + if (err)
10396 + goto port_enable_fail;
10397 + }
10398 +
10399 + dev_info(dev, "probed MAC device with MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
10400 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
10401 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
10402 +
10403 + return 0; /* Proxy interface initialization ended */
10404 +
10405 +port_enable_fail:
10406 + for_each_port_device(i, mac_dev->port_dev)
10407 + fm_port_disable(mac_dev->port_dev[i]);
10408 + dpa_eth_proxy_remove(_of_dev);
10409 +
10410 + return err;
10411 +}
10412 +
10413 +int dpa_proxy_set_mac_address(struct proxy_device *proxy_dev,
10414 + struct net_device *net_dev)
10415 +{
10416 + struct mac_device *mac_dev;
10417 + int _errno;
10418 +
10419 + mac_dev = proxy_dev->mac_dev;
10420 +
10421 + _errno = mac_dev->change_addr(mac_dev->get_mac_handle(mac_dev),
10422 + net_dev->dev_addr);
10423 + if (_errno < 0)
10424 + return _errno;
10425 +
10426 + return 0;
10427 +}
10428 +EXPORT_SYMBOL(dpa_proxy_set_mac_address);
10429 +
10430 +int dpa_proxy_set_rx_mode(struct proxy_device *proxy_dev,
10431 + struct net_device *net_dev)
10432 +{
10433 + struct mac_device *mac_dev = proxy_dev->mac_dev;
10434 + int _errno;
10435 +
10436 + if (!!(net_dev->flags & IFF_PROMISC) != mac_dev->promisc) {
10437 + mac_dev->promisc = !mac_dev->promisc;
10438 + _errno = mac_dev->set_promisc(mac_dev->get_mac_handle(mac_dev),
10439 + mac_dev->promisc);
10440 + if (unlikely(_errno < 0))
10441 + netdev_err(net_dev, "mac_dev->set_promisc() = %d\n",
10442 + _errno);
10443 + }
10444 +
10445 + _errno = mac_dev->set_multi(net_dev, mac_dev);
10446 + if (unlikely(_errno < 0))
10447 + return _errno;
10448 +
10449 + return 0;
10450 +}
10451 +EXPORT_SYMBOL(dpa_proxy_set_rx_mode);
10452 +
10453 +int dpa_proxy_start(struct net_device *net_dev)
10454 +{
10455 + struct mac_device *mac_dev;
10456 + const struct dpa_priv_s *priv;
10457 + struct proxy_device *proxy_dev;
10458 + int _errno;
10459 + int i;
10460 +
10461 + priv = netdev_priv(net_dev);
10462 + proxy_dev = (struct proxy_device *)priv->peer;
10463 + mac_dev = proxy_dev->mac_dev;
10464 +
10465 + _errno = mac_dev->init_phy(net_dev, mac_dev);
10466 + if (_errno < 0) {
10467 + if (netif_msg_drv(priv))
10468 + netdev_err(net_dev, "init_phy() = %d\n",
10469 + _errno);
10470 + return _errno;
10471 + }
10472 +
10473 + for_each_port_device(i, mac_dev->port_dev) {
10474 + _errno = fm_port_enable(mac_dev->port_dev[i]);
10475 + if (_errno)
10476 + goto port_enable_fail;
10477 + }
10478 +
10479 + _errno = mac_dev->start(mac_dev);
10480 + if (_errno < 0) {
10481 + if (netif_msg_drv(priv))
10482 + netdev_err(net_dev, "mac_dev->start() = %d\n",
10483 + _errno);
10484 + goto port_enable_fail;
10485 + }
10486 +
10487 + return _errno;
10488 +
10489 +port_enable_fail:
10490 + for_each_port_device(i, mac_dev->port_dev)
10491 + fm_port_disable(mac_dev->port_dev[i]);
10492 +
10493 + return _errno;
10494 +}
10495 +EXPORT_SYMBOL(dpa_proxy_start);
10496 +
10497 +int dpa_proxy_stop(struct proxy_device *proxy_dev, struct net_device *net_dev)
10498 +{
10499 + struct mac_device *mac_dev = proxy_dev->mac_dev;
10500 + const struct dpa_priv_s *priv = netdev_priv(net_dev);
10501 + int _errno, i, err;
10502 +
10503 + _errno = mac_dev->stop(mac_dev);
10504 + if (_errno < 0) {
10505 + if (netif_msg_drv(priv))
10506 + netdev_err(net_dev, "mac_dev->stop() = %d\n",
10507 + _errno);
10508 + return _errno;
10509 + }
10510 +
10511 + for_each_port_device(i, mac_dev->port_dev) {
10512 + err = fm_port_disable(mac_dev->port_dev[i]);
10513 + _errno = err ? err : _errno;
10514 + }
10515 +
10516 + if (mac_dev->phy_dev)
10517 + phy_disconnect(mac_dev->phy_dev);
10518 + mac_dev->phy_dev = NULL;
10519 +
10520 + return _errno;
10521 +}
10522 +EXPORT_SYMBOL(dpa_proxy_stop);
10523 +
10524 +static int __cold dpa_eth_proxy_remove(struct platform_device *of_dev)
10525 +{
10526 + struct device *dev = &of_dev->dev;
10527 + struct proxy_device *proxy_dev = dev_get_drvdata(dev);
10528 +
10529 + kfree(proxy_dev);
10530 +
10531 + dev_set_drvdata(dev, NULL);
10532 +
10533 + return 0;
10534 +}
10535 +
10536 +static const struct of_device_id dpa_proxy_match[] = {
10537 + {
10538 + .compatible = "fsl,dpa-ethernet-init"
10539 + },
10540 + {}
10541 +};
10542 +MODULE_DEVICE_TABLE(of, dpa_proxy_match);
10543 +
10544 +static struct platform_driver dpa_proxy_driver = {
10545 + .driver = {
10546 + .name = KBUILD_MODNAME "-proxy",
10547 + .of_match_table = dpa_proxy_match,
10548 + .owner = THIS_MODULE,
10549 + .pm = PROXY_PM_OPS,
10550 + },
10551 + .probe = dpaa_eth_proxy_probe,
10552 + .remove = dpa_eth_proxy_remove
10553 +};
10554 +
10555 +static int __init __cold dpa_proxy_load(void)
10556 +{
10557 + int _errno;
10558 +
10559 + pr_info(DPA_DESCRIPTION "\n");
10560 +
10561 + /* Initialize dpaa_eth mirror values */
10562 + dpa_rx_extra_headroom = fm_get_rx_extra_headroom();
10563 + dpa_max_frm = fm_get_max_frm();
10564 +
10565 + _errno = platform_driver_register(&dpa_proxy_driver);
10566 + if (unlikely(_errno < 0)) {
10567 + pr_err(KBUILD_MODNAME
10568 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
10569 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
10570 + }
10571 +
10572 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
10573 + KBUILD_BASENAME".c", __func__);
10574 +
10575 + return _errno;
10576 +}
10577 +module_init(dpa_proxy_load);
10578 +
10579 +static void __exit __cold dpa_proxy_unload(void)
10580 +{
10581 + platform_driver_unregister(&dpa_proxy_driver);
10582 +
10583 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
10584 + KBUILD_BASENAME".c", __func__);
10585 +}
10586 +module_exit(dpa_proxy_unload);
10587 --- /dev/null
10588 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sg.c
10589 @@ -0,0 +1,1195 @@
10590 +/* Copyright 2012 Freescale Semiconductor Inc.
10591 + *
10592 + * Redistribution and use in source and binary forms, with or without
10593 + * modification, are permitted provided that the following conditions are met:
10594 + * * Redistributions of source code must retain the above copyright
10595 + * notice, this list of conditions and the following disclaimer.
10596 + * * Redistributions in binary form must reproduce the above copyright
10597 + * notice, this list of conditions and the following disclaimer in the
10598 + * documentation and/or other materials provided with the distribution.
10599 + * * Neither the name of Freescale Semiconductor nor the
10600 + * names of its contributors may be used to endorse or promote products
10601 + * derived from this software without specific prior written permission.
10602 + *
10603 + *
10604 + * ALTERNATIVELY, this software may be distributed under the terms of the
10605 + * GNU General Public License ("GPL") as published by the Free Software
10606 + * Foundation, either version 2 of that License or (at your option) any
10607 + * later version.
10608 + *
10609 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
10610 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10611 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
10612 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
10613 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10614 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10615 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
10616 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
10617 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
10618 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10619 + */
10620 +
10621 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
10622 +#define pr_fmt(fmt) \
10623 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
10624 + KBUILD_BASENAME".c", __LINE__, __func__
10625 +#else
10626 +#define pr_fmt(fmt) \
10627 + KBUILD_MODNAME ": " fmt
10628 +#endif
10629 +
10630 +#include <linux/init.h>
10631 +#include <linux/skbuff.h>
10632 +#include <linux/highmem.h>
10633 +#include <linux/fsl_bman.h>
10634 +#include <net/sock.h>
10635 +
10636 +#include "dpaa_eth.h"
10637 +#include "dpaa_eth_common.h"
10638 +#ifdef CONFIG_FSL_DPAA_1588
10639 +#include "dpaa_1588.h"
10640 +#endif
10641 +#ifdef CONFIG_FSL_DPAA_CEETM
10642 +#include "dpaa_eth_ceetm.h"
10643 +#endif
10644 +
10645 +/* DMA map and add a page frag back into the bpool.
10646 + * @vaddr fragment must have been allocated with netdev_alloc_frag(),
10647 + * specifically for fitting into @dpa_bp.
10648 + */
10649 +static void dpa_bp_recycle_frag(struct dpa_bp *dpa_bp, unsigned long vaddr,
10650 + int *count_ptr)
10651 +{
10652 + struct bm_buffer bmb;
10653 + dma_addr_t addr;
10654 +
10655 + bmb.opaque = 0;
10656 +
10657 + addr = dma_map_single(dpa_bp->dev, (void *)vaddr, dpa_bp->size,
10658 + DMA_BIDIRECTIONAL);
10659 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
10660 + dev_err(dpa_bp->dev, "DMA mapping failed");
10661 + return;
10662 + }
10663 +
10664 + bm_buffer_set64(&bmb, addr);
10665 +
10666 + while (bman_release(dpa_bp->pool, &bmb, 1, 0))
10667 + cpu_relax();
10668 +
10669 + (*count_ptr)++;
10670 +}
10671 +
10672 +static int _dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp)
10673 +{
10674 + void *new_buf, *fman_buf;
10675 + struct bm_buffer bmb[8];
10676 + dma_addr_t addr;
10677 + uint8_t i;
10678 + struct device *dev = dpa_bp->dev;
10679 + struct sk_buff *skb, **skbh;
10680 +
10681 + memset(bmb, 0, sizeof(struct bm_buffer) * 8);
10682 +
10683 + for (i = 0; i < 8; i++) {
10684 + /* We'll prepend the skb back-pointer; can't use the DPA
10685 + * priv space, because FMan will overwrite it (from offset 0)
10686 + * if it ends up being the second, third, etc. fragment
10687 + * in a S/G frame.
10688 + *
10689 + * We only need enough space to store a pointer, but allocate
10690 + * an entire cacheline for performance reasons.
10691 + */
10692 +#ifndef CONFIG_PPC
10693 + if (unlikely(dpaa_errata_a010022)) {
10694 + struct page *new_page = alloc_page(GFP_ATOMIC);
10695 + if (unlikely(!new_page))
10696 + goto netdev_alloc_failed;
10697 + new_buf = page_address(new_page);
10698 + }
10699 + else
10700 +#endif
10701 + new_buf = netdev_alloc_frag(SMP_CACHE_BYTES + DPA_BP_RAW_SIZE);
10702 +
10703 + if (unlikely(!new_buf))
10704 + goto netdev_alloc_failed;
10705 + new_buf = PTR_ALIGN(new_buf, SMP_CACHE_BYTES);
10706 +
10707 + /* Apart from the buffer that will be used by the FMan, the
10708 + * skb also guarantees enough space to hold the backpointer
10709 + * in the headroom and the shared info at the end.
10710 + */
10711 + skb = build_skb(new_buf,
10712 + SMP_CACHE_BYTES + DPA_SKB_SIZE(dpa_bp->size) +
10713 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
10714 + if (unlikely(!skb)) {
10715 + put_page(virt_to_head_page(new_buf));
10716 + goto build_skb_failed;
10717 + }
10718 +
10719 + /* Reserve SMP_CACHE_BYTES in the skb's headroom to store the
10720 + * backpointer. This area will not be synced to, or
10721 + * overwritten by, the FMan.
10722 + */
10723 + skb_reserve(skb, SMP_CACHE_BYTES);
10724 +
10725 + /* We don't sync the first SMP_CACHE_BYTES of the buffer to
10726 + * the FMan. The skb backpointer is stored at the end of the
10727 + * reserved headroom. Otherwise it will be overwritten by the
10728 + * FMan.
10729 + * The buffer synced with the FMan starts right after the
10730 + * reserved headroom.
10731 + */
10732 + fman_buf = new_buf + SMP_CACHE_BYTES;
10733 + DPA_WRITE_SKB_PTR(skb, skbh, fman_buf, -1);
10734 +
10735 + addr = dma_map_single(dev, fman_buf,
10736 + dpa_bp->size, DMA_BIDIRECTIONAL);
10737 + if (unlikely(dma_mapping_error(dev, addr)))
10738 + goto dma_map_failed;
10739 +
10740 + bm_buffer_set64(&bmb[i], addr);
10741 + }
10742 +
10743 +release_bufs:
10744 + /* Release the buffers. In case bman is busy, keep trying
10745 + * until successful. bman_release() is guaranteed to succeed
10746 + * in a reasonable amount of time
10747 + */
10748 + while (unlikely(bman_release(dpa_bp->pool, bmb, i, 0)))
10749 + cpu_relax();
10750 + return i;
10751 +
10752 +dma_map_failed:
10753 + kfree_skb(skb);
10754 +
10755 +build_skb_failed:
10756 +netdev_alloc_failed:
10757 + net_err_ratelimited("dpa_bp_add_8_bufs() failed\n");
10758 + WARN_ONCE(1, "Memory allocation failure on Rx\n");
10759 +
10760 + bm_buffer_set64(&bmb[i], 0);
10761 + /* Avoid releasing a completely null buffer; bman_release() requires
10762 + * at least one buffer.
10763 + */
10764 + if (likely(i))
10765 + goto release_bufs;
10766 +
10767 + return 0;
10768 +}
10769 +
10770 +/* Cold path wrapper over _dpa_bp_add_8_bufs(). */
10771 +static void dpa_bp_add_8_bufs(const struct dpa_bp *dpa_bp, int cpu)
10772 +{
10773 + int *count_ptr = per_cpu_ptr(dpa_bp->percpu_count, cpu);
10774 + *count_ptr += _dpa_bp_add_8_bufs(dpa_bp);
10775 +}
10776 +
10777 +int dpa_bp_priv_seed(struct dpa_bp *dpa_bp)
10778 +{
10779 + int i;
10780 +
10781 + /* Give each CPU an allotment of "config_count" buffers */
10782 + for_each_possible_cpu(i) {
10783 + int j;
10784 +
10785 + /* Although we access another CPU's counters here
10786 + * we do it at boot time so it is safe
10787 + */
10788 + for (j = 0; j < dpa_bp->config_count; j += 8)
10789 + dpa_bp_add_8_bufs(dpa_bp, i);
10790 + }
10791 + return 0;
10792 +}
10793 +EXPORT_SYMBOL(dpa_bp_priv_seed);
10794 +
10795 +/* Add buffers/(pages) for Rx processing whenever bpool count falls below
10796 + * REFILL_THRESHOLD.
10797 + */
10798 +int dpaa_eth_refill_bpools(struct dpa_bp *dpa_bp, int *countptr)
10799 +{
10800 + int count = *countptr;
10801 + int new_bufs;
10802 +
10803 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_REFILL_THRESHOLD)) {
10804 + do {
10805 + new_bufs = _dpa_bp_add_8_bufs(dpa_bp);
10806 + if (unlikely(!new_bufs)) {
10807 + /* Avoid looping forever if we've temporarily
10808 + * run out of memory. We'll try again at the
10809 + * next NAPI cycle.
10810 + */
10811 + break;
10812 + }
10813 + count += new_bufs;
10814 + } while (count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT);
10815 +
10816 + *countptr = count;
10817 + if (unlikely(count < CONFIG_FSL_DPAA_ETH_MAX_BUF_COUNT))
10818 + return -ENOMEM;
10819 + }
10820 +
10821 + return 0;
10822 +}
10823 +EXPORT_SYMBOL(dpaa_eth_refill_bpools);
10824 +
10825 +/* Cleanup function for outgoing frame descriptors that were built on Tx path,
10826 + * either contiguous frames or scatter/gather ones.
10827 + * Skb freeing is not handled here.
10828 + *
10829 + * This function may be called on error paths in the Tx function, so guard
10830 + * against cases when not all fd relevant fields were filled in.
10831 + *
10832 + * Return the skb backpointer, since for S/G frames the buffer containing it
10833 + * gets freed here.
10834 + */
10835 +struct sk_buff *_dpa_cleanup_tx_fd(const struct dpa_priv_s *priv,
10836 + const struct qm_fd *fd)
10837 +{
10838 + const struct qm_sg_entry *sgt;
10839 + int i;
10840 + struct dpa_bp *dpa_bp = priv->dpa_bp;
10841 + dma_addr_t addr = qm_fd_addr(fd);
10842 + dma_addr_t sg_addr;
10843 + struct sk_buff **skbh;
10844 + struct sk_buff *skb = NULL;
10845 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
10846 + int nr_frags;
10847 + int sg_len;
10848 +
10849 + /* retrieve skb back pointer */
10850 + DPA_READ_SKB_PTR(skb, skbh, phys_to_virt(addr), 0);
10851 +
10852 + if (unlikely(fd->format == qm_fd_sg)) {
10853 + nr_frags = skb_shinfo(skb)->nr_frags;
10854 + dma_unmap_single(dpa_bp->dev, addr,
10855 + dpa_fd_offset(fd) + DPA_SGT_SIZE,
10856 + dma_dir);
10857 +
10858 + /* The sgt buffer has been allocated with netdev_alloc_frag(),
10859 + * it's from lowmem.
10860 + */
10861 + sgt = phys_to_virt(addr + dpa_fd_offset(fd));
10862 +#ifdef CONFIG_FSL_DPAA_1588
10863 + if (priv->tsu && priv->tsu->valid &&
10864 + priv->tsu->hwts_tx_en_ioctl)
10865 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
10866 +#endif
10867 +#ifdef CONFIG_FSL_DPAA_TS
10868 + if (unlikely(priv->ts_tx_en &&
10869 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
10870 + struct skb_shared_hwtstamps shhwtstamps;
10871 +
10872 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
10873 + skb_tstamp_tx(skb, &shhwtstamps);
10874 + }
10875 +#endif /* CONFIG_FSL_DPAA_TS */
10876 +
10877 + /* sgt[0] is from lowmem, was dma_map_single()-ed */
10878 + sg_addr = qm_sg_addr(&sgt[0]);
10879 + sg_len = qm_sg_entry_get_len(&sgt[0]);
10880 + dma_unmap_single(dpa_bp->dev, sg_addr, sg_len, dma_dir);
10881 +
10882 + /* remaining pages were mapped with dma_map_page() */
10883 + for (i = 1; i <= nr_frags; i++) {
10884 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
10885 + sg_addr = qm_sg_addr(&sgt[i]);
10886 + sg_len = qm_sg_entry_get_len(&sgt[i]);
10887 + dma_unmap_page(dpa_bp->dev, sg_addr, sg_len, dma_dir);
10888 + }
10889 +
10890 + /* Free the page frag that we allocated on Tx */
10891 + put_page(virt_to_head_page(sgt));
10892 + } else {
10893 + dma_unmap_single(dpa_bp->dev, addr,
10894 + skb_tail_pointer(skb) - (u8 *)skbh, dma_dir);
10895 +#ifdef CONFIG_FSL_DPAA_TS
10896 + /* get the timestamp for non-SG frames */
10897 +#ifdef CONFIG_FSL_DPAA_1588
10898 + if (priv->tsu && priv->tsu->valid &&
10899 + priv->tsu->hwts_tx_en_ioctl)
10900 + dpa_ptp_store_txstamp(priv, skb, (void *)skbh);
10901 +#endif
10902 + if (unlikely(priv->ts_tx_en &&
10903 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
10904 + struct skb_shared_hwtstamps shhwtstamps;
10905 +
10906 + dpa_get_ts(priv, TX, &shhwtstamps, (void *)skbh);
10907 + skb_tstamp_tx(skb, &shhwtstamps);
10908 + }
10909 +#endif
10910 + }
10911 +
10912 + return skb;
10913 +}
10914 +EXPORT_SYMBOL(_dpa_cleanup_tx_fd);
10915 +
10916 +#ifndef CONFIG_FSL_DPAA_TS
10917 +bool dpa_skb_is_recyclable(struct sk_buff *skb)
10918 +{
10919 +#ifndef CONFIG_PPC
10920 + /* Do no recycle skbs realigned by the errata workaround */
10921 + if (unlikely(dpaa_errata_a010022) && skb->mark == NONREC_MARK)
10922 + return false;
10923 +#endif
10924 +
10925 + /* No recycling possible if skb buffer is kmalloc'ed */
10926 + if (skb->head_frag == 0)
10927 + return false;
10928 +
10929 + /* or if it's an userspace buffer */
10930 + if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
10931 + return false;
10932 +
10933 + /* or if it's cloned or shared */
10934 + if (skb_shared(skb) || skb_cloned(skb) ||
10935 + skb->fclone != SKB_FCLONE_UNAVAILABLE)
10936 + return false;
10937 +
10938 + return true;
10939 +}
10940 +EXPORT_SYMBOL(dpa_skb_is_recyclable);
10941 +
10942 +bool dpa_buf_is_recyclable(struct sk_buff *skb,
10943 + uint32_t min_size,
10944 + uint16_t min_offset,
10945 + unsigned char **new_buf_start)
10946 +{
10947 + unsigned char *new;
10948 +
10949 + /* In order to recycle a buffer, the following conditions must be met:
10950 + * - buffer size no less than the buffer pool size
10951 + * - buffer size no higher than an upper limit (to avoid moving too much
10952 + * system memory to the buffer pools)
10953 + * - buffer address aligned to cacheline bytes
10954 + * - offset of data from start of buffer no lower than a minimum value
10955 + * - offset of data from start of buffer no higher than a maximum value
10956 + * - the skb back-pointer is stored safely
10957 + */
10958 +
10959 + /* guarantee both the minimum size and the minimum data offset */
10960 + new = min(skb_end_pointer(skb) - min_size, skb->data - min_offset);
10961 +
10962 + /* left align to the nearest cacheline */
10963 + new = (unsigned char *)((unsigned long)new & ~(SMP_CACHE_BYTES - 1));
10964 +
10965 + /* Make sure there is enough space to store the skb back-pointer in
10966 + * the headroom, right before the start of the buffer.
10967 + *
10968 + * Guarantee that both maximum size and maximum data offsets aren't
10969 + * crossed.
10970 + */
10971 + if (likely(new >= (skb->head + sizeof(void *)) &&
10972 + new >= (skb->data - DPA_MAX_FD_OFFSET) &&
10973 + skb_end_pointer(skb) - new <= DPA_RECYCLE_MAX_SIZE)) {
10974 + *new_buf_start = new;
10975 + return true;
10976 + }
10977 +
10978 + return false;
10979 +}
10980 +EXPORT_SYMBOL(dpa_buf_is_recyclable);
10981 +#endif
10982 +
10983 +/* Build a linear skb around the received buffer.
10984 + * We are guaranteed there is enough room at the end of the data buffer to
10985 + * accommodate the shared info area of the skb.
10986 + */
10987 +static struct sk_buff *__hot contig_fd_to_skb(const struct dpa_priv_s *priv,
10988 + const struct qm_fd *fd, int *use_gro)
10989 +{
10990 + dma_addr_t addr = qm_fd_addr(fd);
10991 + ssize_t fd_off = dpa_fd_offset(fd);
10992 + void *vaddr;
10993 + const fm_prs_result_t *parse_results;
10994 + struct sk_buff *skb = NULL, **skbh;
10995 +
10996 + vaddr = phys_to_virt(addr);
10997 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
10998 +
10999 + /* Retrieve the skb and adjust data and tail pointers, to make sure
11000 + * forwarded skbs will have enough space on Tx if extra headers
11001 + * are added.
11002 + */
11003 + DPA_READ_SKB_PTR(skb, skbh, vaddr, -1);
11004 +
11005 +#ifdef CONFIG_FSL_DPAA_ETH_JUMBO_FRAME
11006 + /* When using jumbo Rx buffers, we risk having frames dropped due to
11007 + * the socket backlog reaching its maximum allowed size.
11008 + * Use the frame length for the skb truesize instead of the buffer
11009 + * size, as this is the size of the data that actually gets copied to
11010 + * userspace.
11011 + * The stack may increase the payload. In this case, it will want to
11012 + * warn us that the frame length is larger than the truesize. We
11013 + * bypass the warning.
11014 + */
11015 + skb->truesize = SKB_TRUESIZE(dpa_fd_length(fd));
11016 +#endif
11017 +
11018 + DPA_BUG_ON(fd_off != priv->rx_headroom);
11019 + skb_reserve(skb, fd_off);
11020 + skb_put(skb, dpa_fd_length(fd));
11021 +
11022 + /* Peek at the parse results for csum validation */
11023 + parse_results = (const fm_prs_result_t *)(vaddr +
11024 + DPA_RX_PRIV_DATA_SIZE);
11025 + _dpa_process_parse_results(parse_results, fd, skb, use_gro);
11026 +
11027 +#ifdef CONFIG_FSL_DPAA_1588
11028 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_rx_en_ioctl)
11029 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
11030 +#endif
11031 +#ifdef CONFIG_FSL_DPAA_TS
11032 + if (priv->ts_rx_en)
11033 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
11034 +#endif /* CONFIG_FSL_DPAA_TS */
11035 +
11036 + return skb;
11037 +}
11038 +
11039 +
11040 +/* Build an skb with the data of the first S/G entry in the linear portion and
11041 + * the rest of the frame as skb fragments.
11042 + *
11043 + * The page fragment holding the S/G Table is recycled here.
11044 + */
11045 +static struct sk_buff *__hot sg_fd_to_skb(const struct dpa_priv_s *priv,
11046 + const struct qm_fd *fd, int *use_gro,
11047 + int *count_ptr)
11048 +{
11049 + const struct qm_sg_entry *sgt;
11050 + dma_addr_t addr = qm_fd_addr(fd);
11051 + ssize_t fd_off = dpa_fd_offset(fd);
11052 + dma_addr_t sg_addr;
11053 + void *vaddr, *sg_vaddr;
11054 + struct dpa_bp *dpa_bp;
11055 + struct page *page, *head_page;
11056 + int frag_offset, frag_len;
11057 + int page_offset;
11058 + int i;
11059 + const fm_prs_result_t *parse_results;
11060 + struct sk_buff *skb = NULL, *skb_tmp, **skbh;
11061 +
11062 + vaddr = phys_to_virt(addr);
11063 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)vaddr, SMP_CACHE_BYTES));
11064 +
11065 + dpa_bp = priv->dpa_bp;
11066 + /* Iterate through the SGT entries and add data buffers to the skb */
11067 + sgt = vaddr + fd_off;
11068 + for (i = 0; i < DPA_SGT_MAX_ENTRIES; i++) {
11069 + /* Extension bit is not supported */
11070 + DPA_BUG_ON(qm_sg_entry_get_ext(&sgt[i]));
11071 +
11072 + /* We use a single global Rx pool */
11073 + DPA_BUG_ON(dpa_bp !=
11074 + dpa_bpid2pool(qm_sg_entry_get_bpid(&sgt[i])));
11075 +
11076 + sg_addr = qm_sg_addr(&sgt[i]);
11077 + sg_vaddr = phys_to_virt(sg_addr);
11078 + DPA_BUG_ON(!IS_ALIGNED((unsigned long)sg_vaddr,
11079 + SMP_CACHE_BYTES));
11080 +
11081 + dma_unmap_single(dpa_bp->dev, sg_addr, dpa_bp->size,
11082 + DMA_BIDIRECTIONAL);
11083 + if (i == 0) {
11084 + DPA_READ_SKB_PTR(skb, skbh, sg_vaddr, -1);
11085 +#ifdef CONFIG_FSL_DPAA_1588
11086 + if (priv->tsu && priv->tsu->valid &&
11087 + priv->tsu->hwts_rx_en_ioctl)
11088 + dpa_ptp_store_rxstamp(priv, skb, vaddr);
11089 +#endif
11090 +#ifdef CONFIG_FSL_DPAA_TS
11091 + if (priv->ts_rx_en)
11092 + dpa_get_ts(priv, RX, skb_hwtstamps(skb), vaddr);
11093 +#endif /* CONFIG_FSL_DPAA_TS */
11094 +
11095 + /* In the case of a SG frame, FMan stores the Internal
11096 + * Context in the buffer containing the sgt.
11097 + * Inspect the parse results before anything else.
11098 + */
11099 + parse_results = (const fm_prs_result_t *)(vaddr +
11100 + DPA_RX_PRIV_DATA_SIZE);
11101 + _dpa_process_parse_results(parse_results, fd, skb,
11102 + use_gro);
11103 +
11104 + /* Make sure forwarded skbs will have enough space
11105 + * on Tx, if extra headers are added.
11106 + */
11107 + DPA_BUG_ON(fd_off != priv->rx_headroom);
11108 + skb_reserve(skb, fd_off);
11109 + skb_put(skb, qm_sg_entry_get_len(&sgt[i]));
11110 + } else {
11111 + /* Not the first S/G entry; all data from buffer will
11112 + * be added in an skb fragment; fragment index is offset
11113 + * by one since first S/G entry was incorporated in the
11114 + * linear part of the skb.
11115 + *
11116 + * Caution: 'page' may be a tail page.
11117 + */
11118 + DPA_READ_SKB_PTR(skb_tmp, skbh, sg_vaddr, -1);
11119 + page = virt_to_page(sg_vaddr);
11120 + head_page = virt_to_head_page(sg_vaddr);
11121 +
11122 + /* Free (only) the skbuff shell because its data buffer
11123 + * is already a frag in the main skb.
11124 + */
11125 + get_page(head_page);
11126 + dev_kfree_skb(skb_tmp);
11127 +
11128 + /* Compute offset in (possibly tail) page */
11129 + page_offset = ((unsigned long)sg_vaddr &
11130 + (PAGE_SIZE - 1)) +
11131 + (page_address(page) - page_address(head_page));
11132 + /* page_offset only refers to the beginning of sgt[i];
11133 + * but the buffer itself may have an internal offset.
11134 + */
11135 + frag_offset = qm_sg_entry_get_offset(&sgt[i]) +
11136 + page_offset;
11137 + frag_len = qm_sg_entry_get_len(&sgt[i]);
11138 + /* skb_add_rx_frag() does no checking on the page; if
11139 + * we pass it a tail page, we'll end up with
11140 + * bad page accounting and eventually with segafults.
11141 + */
11142 + skb_add_rx_frag(skb, i - 1, head_page, frag_offset,
11143 + frag_len, dpa_bp->size);
11144 + }
11145 + /* Update the pool count for the current {cpu x bpool} */
11146 + (*count_ptr)--;
11147 +
11148 + if (qm_sg_entry_get_final(&sgt[i]))
11149 + break;
11150 + }
11151 + WARN_ONCE(i == DPA_SGT_MAX_ENTRIES, "No final bit on SGT\n");
11152 +
11153 + /* recycle the SGT fragment */
11154 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
11155 + dpa_bp_recycle_frag(dpa_bp, (unsigned long)vaddr, count_ptr);
11156 + return skb;
11157 +}
11158 +
11159 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
11160 +static inline int dpa_skb_loop(const struct dpa_priv_s *priv,
11161 + struct sk_buff *skb)
11162 +{
11163 + if (unlikely(priv->loop_to < 0))
11164 + return 0; /* loop disabled by default */
11165 +
11166 + skb_push(skb, ETH_HLEN); /* compensate for eth_type_trans */
11167 + /* Save the current CPU ID in order to maintain core affinity */
11168 + skb_set_queue_mapping(skb, raw_smp_processor_id());
11169 + dpa_tx(skb, dpa_loop_netdevs[priv->loop_to]);
11170 +
11171 + return 1; /* Frame Tx on the selected interface */
11172 +}
11173 +#endif
11174 +
11175 +void __hot _dpa_rx(struct net_device *net_dev,
11176 + struct qman_portal *portal,
11177 + const struct dpa_priv_s *priv,
11178 + struct dpa_percpu_priv_s *percpu_priv,
11179 + const struct qm_fd *fd,
11180 + u32 fqid,
11181 + int *count_ptr)
11182 +{
11183 + struct dpa_bp *dpa_bp;
11184 + struct sk_buff *skb;
11185 + dma_addr_t addr = qm_fd_addr(fd);
11186 + u32 fd_status = fd->status;
11187 + unsigned int skb_len;
11188 + struct rtnl_link_stats64 *percpu_stats = &percpu_priv->stats;
11189 + int use_gro = net_dev->features & NETIF_F_GRO;
11190 +
11191 + if (unlikely(fd_status & FM_FD_STAT_RX_ERRORS) != 0) {
11192 + if (netif_msg_hw(priv) && net_ratelimit())
11193 + netdev_warn(net_dev, "FD status = 0x%08x\n",
11194 + fd_status & FM_FD_STAT_RX_ERRORS);
11195 +
11196 + percpu_stats->rx_errors++;
11197 + goto _release_frame;
11198 + }
11199 +
11200 + dpa_bp = priv->dpa_bp;
11201 + DPA_BUG_ON(dpa_bp != dpa_bpid2pool(fd->bpid));
11202 +
11203 + /* prefetch the first 64 bytes of the frame or the SGT start */
11204 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
11205 + prefetch(phys_to_virt(addr) + dpa_fd_offset(fd));
11206 +
11207 + /* The only FD types that we may receive are contig and S/G */
11208 + DPA_BUG_ON((fd->format != qm_fd_contig) && (fd->format != qm_fd_sg));
11209 +
11210 + if (likely(fd->format == qm_fd_contig)) {
11211 +#ifdef CONFIG_FSL_DPAA_HOOKS
11212 + /* Execute the Rx processing hook, if it exists. */
11213 + if (dpaa_eth_hooks.rx_default &&
11214 + dpaa_eth_hooks.rx_default((void *)fd, net_dev,
11215 + fqid) == DPAA_ETH_STOLEN) {
11216 + /* won't count the rx bytes in */
11217 + return;
11218 + }
11219 +#endif
11220 + skb = contig_fd_to_skb(priv, fd, &use_gro);
11221 + } else {
11222 + skb = sg_fd_to_skb(priv, fd, &use_gro, count_ptr);
11223 + percpu_priv->rx_sg++;
11224 + }
11225 +
11226 + /* Account for either the contig buffer or the SGT buffer (depending on
11227 + * which case we were in) having been removed from the pool.
11228 + */
11229 + (*count_ptr)--;
11230 + skb->protocol = eth_type_trans(skb, net_dev);
11231 +
11232 + skb_len = skb->len;
11233 +
11234 +#ifdef CONFIG_FSL_DPAA_DBG_LOOP
11235 + if (dpa_skb_loop(priv, skb)) {
11236 + percpu_stats->rx_packets++;
11237 + percpu_stats->rx_bytes += skb_len;
11238 + return;
11239 + }
11240 +#endif
11241 +
11242 + skb_record_rx_queue(skb, raw_smp_processor_id());
11243 +
11244 + if (use_gro) {
11245 + gro_result_t gro_result;
11246 + const struct qman_portal_config *pc =
11247 + qman_p_get_portal_config(portal);
11248 + struct dpa_napi_portal *np = &percpu_priv->np[pc->index];
11249 +
11250 + np->p = portal;
11251 + gro_result = napi_gro_receive(&np->napi, skb);
11252 + /* If frame is dropped by the stack, rx_dropped counter is
11253 + * incremented automatically, so no need for us to update it
11254 + */
11255 + if (unlikely(gro_result == GRO_DROP))
11256 + goto packet_dropped;
11257 + } else if (unlikely(netif_receive_skb(skb) == NET_RX_DROP))
11258 + goto packet_dropped;
11259 +
11260 + percpu_stats->rx_packets++;
11261 + percpu_stats->rx_bytes += skb_len;
11262 +
11263 +packet_dropped:
11264 + return;
11265 +
11266 +_release_frame:
11267 + dpa_fd_release(net_dev, fd);
11268 +}
11269 +
11270 +int __hot skb_to_contig_fd(struct dpa_priv_s *priv,
11271 + struct sk_buff *skb, struct qm_fd *fd,
11272 + int *count_ptr, int *offset)
11273 +{
11274 + struct sk_buff **skbh;
11275 + dma_addr_t addr;
11276 + struct dpa_bp *dpa_bp = priv->dpa_bp;
11277 + struct net_device *net_dev = priv->net_dev;
11278 + int err;
11279 + enum dma_data_direction dma_dir;
11280 + unsigned char *buffer_start;
11281 + int dma_map_size;
11282 +
11283 +#ifndef CONFIG_FSL_DPAA_TS
11284 + /* Check recycling conditions; only if timestamp support is not
11285 + * enabled, otherwise we need the fd back on tx confirmation
11286 + */
11287 +
11288 + /* We can recycle the buffer if:
11289 + * - the pool is not full
11290 + * - the buffer meets the skb recycling conditions
11291 + * - the buffer meets our own (size, offset, align) conditions
11292 + */
11293 + if (likely((*count_ptr < dpa_bp->target_count) &&
11294 + dpa_skb_is_recyclable(skb) &&
11295 + dpa_buf_is_recyclable(skb, dpa_bp->size,
11296 + priv->tx_headroom, &buffer_start))) {
11297 + /* Buffer is recyclable; use the new start address
11298 + * and set fd parameters and DMA mapping direction
11299 + */
11300 + fd->bpid = dpa_bp->bpid;
11301 + DPA_BUG_ON(skb->data - buffer_start > DPA_MAX_FD_OFFSET);
11302 + fd->offset = (uint16_t)(skb->data - buffer_start);
11303 + dma_dir = DMA_BIDIRECTIONAL;
11304 + dma_map_size = dpa_bp->size;
11305 +
11306 + /* Store the skb back-pointer before the start of the buffer.
11307 + * Otherwise it will be overwritten by the FMan.
11308 + */
11309 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, -1);
11310 + *offset = skb_headroom(skb) - fd->offset;
11311 + } else
11312 +#endif
11313 + {
11314 + /* Not recyclable.
11315 + * We are guaranteed to have at least tx_headroom bytes
11316 + * available, so just use that for offset.
11317 + */
11318 + fd->bpid = 0xff;
11319 + buffer_start = skb->data - priv->tx_headroom;
11320 + fd->offset = priv->tx_headroom;
11321 + dma_dir = DMA_TO_DEVICE;
11322 + dma_map_size = skb_tail_pointer(skb) - buffer_start;
11323 +
11324 + /* The buffer will be Tx-confirmed, but the TxConf cb must
11325 + * necessarily look at our Tx private data to retrieve the
11326 + * skbuff. Store the back-pointer inside the buffer.
11327 + */
11328 + DPA_WRITE_SKB_PTR(skb, skbh, buffer_start, 0);
11329 + }
11330 +
11331 + /* Enable L3/L4 hardware checksum computation.
11332 + *
11333 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
11334 + * need to write into the skb.
11335 + */
11336 + err = dpa_enable_tx_csum(priv, skb, fd,
11337 + ((char *)skbh) + DPA_TX_PRIV_DATA_SIZE);
11338 + if (unlikely(err < 0)) {
11339 + if (netif_msg_tx_err(priv) && net_ratelimit())
11340 + netdev_err(net_dev, "HW csum error: %d\n", err);
11341 + return err;
11342 + }
11343 +
11344 + /* Fill in the rest of the FD fields */
11345 + fd->format = qm_fd_contig;
11346 + fd->length20 = skb->len;
11347 + fd->cmd |= FM_FD_CMD_FCO;
11348 +
11349 + /* Map the entire buffer size that may be seen by FMan, but no more */
11350 + addr = dma_map_single(dpa_bp->dev, skbh, dma_map_size, dma_dir);
11351 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
11352 + if (netif_msg_tx_err(priv) && net_ratelimit())
11353 + netdev_err(net_dev, "dma_map_single() failed\n");
11354 + return -EINVAL;
11355 + }
11356 + qm_fd_addr_set64(fd, addr);
11357 +
11358 + return 0;
11359 +}
11360 +EXPORT_SYMBOL(skb_to_contig_fd);
11361 +
11362 +#ifndef CONFIG_PPC
11363 +/* Verify the conditions that trigger the A010022 errata: data unaligned to
11364 + * 16 bytes, 4K memory address crossings and S/G fragments.
11365 + */
11366 +static bool a010022_check_skb(struct sk_buff *skb, struct dpa_priv_s *priv)
11367 +{
11368 + /* Check if the headroom is aligned */
11369 + if (((uintptr_t)skb->data - priv->tx_headroom) %
11370 + priv->buf_layout[TX].data_align != 0)
11371 + return true;
11372 +
11373 + /* Check for paged data in the skb. We do not support S/G fragments */
11374 + if (skb_is_nonlinear(skb))
11375 + return true;
11376 +
11377 + /* Check if the headroom crosses a boundary */
11378 + if (HAS_DMA_ISSUE(skb->head, skb_headroom(skb)))
11379 + return true;
11380 +
11381 + /* Check if the non-paged data crosses a boundary */
11382 + if (HAS_DMA_ISSUE(skb->data, skb_headlen(skb)))
11383 + return true;
11384 +
11385 + /* Check if the entire linear skb crosses a boundary */
11386 + if (HAS_DMA_ISSUE(skb->head, skb_end_offset(skb)))
11387 + return true;
11388 +
11389 + return false;
11390 +}
11391 +
11392 +/* Realign the skb by copying its contents at the start of a newly allocated
11393 + * page. Build a new skb around the new buffer and release the old one.
11394 + * A performance drop should be expected.
11395 + */
11396 +static struct sk_buff *a010022_realign_skb(struct sk_buff *skb,
11397 + struct dpa_priv_s *priv)
11398 +{
11399 + int trans_offset = skb_transport_offset(skb);
11400 + int net_offset = skb_network_offset(skb);
11401 + int nsize, headroom, npage_order;
11402 + struct sk_buff *nskb = NULL;
11403 + struct page *npage;
11404 + void *npage_addr;
11405 +
11406 + headroom = DPAA_A010022_HEADROOM;
11407 +
11408 + /* For the new skb we only need the old one's data (both non-paged and
11409 + * paged). We can skip the old tailroom.
11410 + *
11411 + * Make sure the skb_shinfo is cache-line aligned.
11412 + */
11413 + nsize = SMP_CACHE_BYTES + DPA_SKB_SIZE(headroom + skb->len) +
11414 + SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
11415 +
11416 + /* Reserve enough memory to accommodate Jumbo frames */
11417 + npage_order = (nsize - 1) / PAGE_SIZE;
11418 + npage = alloc_pages(GFP_ATOMIC | __GFP_COMP, npage_order);
11419 + if (unlikely(!npage)) {
11420 + WARN_ONCE(1, "Memory allocation failure\n");
11421 + return NULL;
11422 + }
11423 + npage_addr = page_address(npage);
11424 +
11425 + nskb = build_skb(npage_addr, nsize);
11426 + if (unlikely(!nskb))
11427 + goto err;
11428 +
11429 + /* Reserve only the needed headroom in order to guarantee the data's
11430 + * alignment.
11431 + * Code borrowed and adapted from skb_copy().
11432 + */
11433 + skb_reserve(nskb, headroom);
11434 + skb_put(nskb, skb->len);
11435 + if (skb_copy_bits(skb, 0, nskb->data, skb->len)) {
11436 + WARN_ONCE(1, "skb parsing failure\n");
11437 + goto err;
11438 + }
11439 + copy_skb_header(nskb, skb);
11440 +
11441 +#ifdef CONFIG_FSL_DPAA_TS
11442 + /* Copy relevant timestamp info from the old skb to the new */
11443 + if (priv->ts_tx_en) {
11444 + skb_shinfo(nskb)->tx_flags = skb_shinfo(skb)->tx_flags;
11445 + skb_shinfo(nskb)->hwtstamps = skb_shinfo(skb)->hwtstamps;
11446 + skb_shinfo(nskb)->tskey = skb_shinfo(skb)->tskey;
11447 + if (skb->sk)
11448 + skb_set_owner_w(nskb, skb->sk);
11449 + }
11450 +#endif
11451 + /* We move the headroom when we align it so we have to reset the
11452 + * network and transport header offsets relative to the new data
11453 + * pointer. The checksum offload relies on these offsets.
11454 + */
11455 + skb_set_network_header(nskb, net_offset);
11456 + skb_set_transport_header(nskb, trans_offset);
11457 +
11458 + /* We don't want the buffer to be recycled so we mark it accordingly */
11459 + nskb->mark = NONREC_MARK;
11460 +
11461 + dev_kfree_skb(skb);
11462 + return nskb;
11463 +
11464 +err:
11465 + if (nskb)
11466 + dev_kfree_skb(nskb);
11467 + put_page(npage);
11468 + return NULL;
11469 +}
11470 +#endif
11471 +
11472 +int __hot skb_to_sg_fd(struct dpa_priv_s *priv,
11473 + struct sk_buff *skb, struct qm_fd *fd)
11474 +{
11475 + struct dpa_bp *dpa_bp = priv->dpa_bp;
11476 + dma_addr_t addr;
11477 + dma_addr_t sg_addr;
11478 + struct sk_buff **skbh;
11479 + struct net_device *net_dev = priv->net_dev;
11480 + int sg_len, sgt_size;
11481 + int err;
11482 +
11483 + struct qm_sg_entry *sgt;
11484 + void *sgt_buf;
11485 + skb_frag_t *frag;
11486 + int i = 0, j = 0;
11487 + int nr_frags;
11488 + const enum dma_data_direction dma_dir = DMA_TO_DEVICE;
11489 +
11490 + nr_frags = skb_shinfo(skb)->nr_frags;
11491 + fd->format = qm_fd_sg;
11492 +
11493 + /* The FMan reads 256 bytes from the start of the SGT regardless of
11494 + * its size. In accordance, we reserve the same amount of memory as
11495 + * well.
11496 + */
11497 + sgt_size = DPA_SGT_SIZE;
11498 +
11499 + /* Get a page frag to store the SGTable, or a full page if the errata
11500 + * is in place and we need to avoid crossing a 4k boundary.
11501 + */
11502 +#ifndef CONFIG_PPC
11503 + if (unlikely(dpaa_errata_a010022))
11504 + sgt_buf = page_address(alloc_page(GFP_ATOMIC));
11505 + else
11506 +#endif
11507 + sgt_buf = netdev_alloc_frag(priv->tx_headroom + sgt_size);
11508 + if (unlikely(!sgt_buf)) {
11509 + dev_err(dpa_bp->dev, "netdev_alloc_frag() failed\n");
11510 + return -ENOMEM;
11511 + }
11512 +
11513 + /* it seems that the memory allocator does not zero the allocated mem */
11514 + memset(sgt_buf, 0, priv->tx_headroom + sgt_size);
11515 +
11516 + /* Enable L3/L4 hardware checksum computation.
11517 + *
11518 + * We must do this before dma_map_single(DMA_TO_DEVICE), because we may
11519 + * need to write into the skb.
11520 + */
11521 + err = dpa_enable_tx_csum(priv, skb, fd,
11522 + sgt_buf + DPA_TX_PRIV_DATA_SIZE);
11523 + if (unlikely(err < 0)) {
11524 + if (netif_msg_tx_err(priv) && net_ratelimit())
11525 + netdev_err(net_dev, "HW csum error: %d\n", err);
11526 + goto csum_failed;
11527 + }
11528 +
11529 + /* Assign the data from skb->data to the first SG list entry */
11530 + sgt = (struct qm_sg_entry *)(sgt_buf + priv->tx_headroom);
11531 + sg_len = skb_headlen(skb);
11532 + qm_sg_entry_set_bpid(&sgt[0], 0xff);
11533 + qm_sg_entry_set_offset(&sgt[0], 0);
11534 + qm_sg_entry_set_len(&sgt[0], sg_len);
11535 + qm_sg_entry_set_ext(&sgt[0], 0);
11536 + qm_sg_entry_set_final(&sgt[0], 0);
11537 +
11538 + addr = dma_map_single(dpa_bp->dev, skb->data, sg_len, dma_dir);
11539 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
11540 + dev_err(dpa_bp->dev, "DMA mapping failed");
11541 + err = -EINVAL;
11542 + goto sg0_map_failed;
11543 + }
11544 +
11545 + qm_sg_entry_set64(&sgt[0], addr);
11546 +
11547 + /* populate the rest of SGT entries */
11548 + for (i = 1; i <= nr_frags; i++) {
11549 + frag = &skb_shinfo(skb)->frags[i - 1];
11550 + qm_sg_entry_set_bpid(&sgt[i], 0xff);
11551 + qm_sg_entry_set_offset(&sgt[i], 0);
11552 + qm_sg_entry_set_len(&sgt[i], frag->size);
11553 + qm_sg_entry_set_ext(&sgt[i], 0);
11554 +
11555 + if (i == nr_frags)
11556 + qm_sg_entry_set_final(&sgt[i], 1);
11557 + else
11558 + qm_sg_entry_set_final(&sgt[i], 0);
11559 +
11560 + DPA_BUG_ON(!skb_frag_page(frag));
11561 + addr = skb_frag_dma_map(dpa_bp->dev, frag, 0, frag->size,
11562 + dma_dir);
11563 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
11564 + dev_err(dpa_bp->dev, "DMA mapping failed");
11565 + err = -EINVAL;
11566 + goto sg_map_failed;
11567 + }
11568 +
11569 + /* keep the offset in the address */
11570 + qm_sg_entry_set64(&sgt[i], addr);
11571 + }
11572 +
11573 + fd->length20 = skb->len;
11574 + fd->offset = priv->tx_headroom;
11575 +
11576 + /* DMA map the SGT page
11577 + *
11578 + * It's safe to store the skb back-pointer inside the buffer since
11579 + * S/G frames are non-recyclable.
11580 + */
11581 + DPA_WRITE_SKB_PTR(skb, skbh, sgt_buf, 0);
11582 + addr = dma_map_single(dpa_bp->dev, sgt_buf,
11583 + priv->tx_headroom + sgt_size,
11584 + dma_dir);
11585 +
11586 + if (unlikely(dma_mapping_error(dpa_bp->dev, addr))) {
11587 + dev_err(dpa_bp->dev, "DMA mapping failed");
11588 + err = -EINVAL;
11589 + goto sgt_map_failed;
11590 + }
11591 +
11592 + qm_fd_addr_set64(fd, addr);
11593 + fd->bpid = 0xff;
11594 + fd->cmd |= FM_FD_CMD_FCO;
11595 +
11596 + return 0;
11597 +
11598 +sgt_map_failed:
11599 +sg_map_failed:
11600 + for (j = 0; j < i; j++) {
11601 + sg_addr = qm_sg_addr(&sgt[j]);
11602 + dma_unmap_page(dpa_bp->dev, sg_addr,
11603 + qm_sg_entry_get_len(&sgt[j]), dma_dir);
11604 + }
11605 +sg0_map_failed:
11606 +csum_failed:
11607 + put_page(virt_to_head_page(sgt_buf));
11608 +
11609 + return err;
11610 +}
11611 +EXPORT_SYMBOL(skb_to_sg_fd);
11612 +
11613 +int __hot dpa_tx(struct sk_buff *skb, struct net_device *net_dev)
11614 +{
11615 + struct dpa_priv_s *priv;
11616 + int queue_mapping = dpa_get_queue_mapping(skb);
11617 + struct qman_fq *egress_fq, *conf_fq;
11618 +
11619 +#ifdef CONFIG_FSL_DPAA_HOOKS
11620 + /* If there is a Tx hook, run it. */
11621 + if (dpaa_eth_hooks.tx &&
11622 + dpaa_eth_hooks.tx(skb, net_dev) == DPAA_ETH_STOLEN)
11623 + /* won't update any Tx stats */
11624 + return NETDEV_TX_OK;
11625 +#endif
11626 +
11627 + priv = netdev_priv(net_dev);
11628 +
11629 +#ifdef CONFIG_FSL_DPAA_CEETM
11630 + if (priv->ceetm_en)
11631 + return ceetm_tx(skb, net_dev);
11632 +#endif
11633 +
11634 + if (unlikely(queue_mapping >= DPAA_ETH_TX_QUEUES))
11635 + queue_mapping = queue_mapping % DPAA_ETH_TX_QUEUES;
11636 +
11637 + egress_fq = priv->egress_fqs[queue_mapping];
11638 + conf_fq = priv->conf_fqs[queue_mapping];
11639 +
11640 + return dpa_tx_extended(skb, net_dev, egress_fq, conf_fq);
11641 +}
11642 +
11643 +int __hot dpa_tx_extended(struct sk_buff *skb, struct net_device *net_dev,
11644 + struct qman_fq *egress_fq, struct qman_fq *conf_fq)
11645 +{
11646 + struct dpa_priv_s *priv;
11647 + struct qm_fd fd;
11648 + struct dpa_percpu_priv_s *percpu_priv;
11649 + struct rtnl_link_stats64 *percpu_stats;
11650 + int err = 0;
11651 + bool nonlinear;
11652 + int *countptr, offset = 0;
11653 +
11654 + priv = netdev_priv(net_dev);
11655 + /* Non-migratable context, safe to use raw_cpu_ptr */
11656 + percpu_priv = raw_cpu_ptr(priv->percpu_priv);
11657 + percpu_stats = &percpu_priv->stats;
11658 + countptr = raw_cpu_ptr(priv->dpa_bp->percpu_count);
11659 +
11660 + clear_fd(&fd);
11661 +
11662 +#ifndef CONFIG_PPC
11663 + if (unlikely(dpaa_errata_a010022) && a010022_check_skb(skb, priv)) {
11664 + skb = a010022_realign_skb(skb, priv);
11665 + if (!skb)
11666 + goto skb_to_fd_failed;
11667 + }
11668 +#endif
11669 +
11670 + nonlinear = skb_is_nonlinear(skb);
11671 +
11672 +#ifdef CONFIG_FSL_DPAA_1588
11673 + if (priv->tsu && priv->tsu->valid && priv->tsu->hwts_tx_en_ioctl)
11674 + fd.cmd |= FM_FD_CMD_UPD;
11675 +#endif
11676 +#ifdef CONFIG_FSL_DPAA_TS
11677 + if (unlikely(priv->ts_tx_en &&
11678 + skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
11679 + fd.cmd |= FM_FD_CMD_UPD;
11680 + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
11681 +#endif /* CONFIG_FSL_DPAA_TS */
11682 +
11683 + /* MAX_SKB_FRAGS is larger than our DPA_SGT_MAX_ENTRIES; make sure
11684 + * we don't feed FMan with more fragments than it supports.
11685 + * Btw, we're using the first sgt entry to store the linear part of
11686 + * the skb, so we're one extra frag short.
11687 + */
11688 + if (nonlinear &&
11689 + likely(skb_shinfo(skb)->nr_frags < DPA_SGT_MAX_ENTRIES)) {
11690 + /* Just create a S/G fd based on the skb */
11691 + err = skb_to_sg_fd(priv, skb, &fd);
11692 + percpu_priv->tx_frag_skbuffs++;
11693 + } else {
11694 + /* Make sure we have enough headroom to accommodate private
11695 + * data, parse results, etc. Normally this shouldn't happen if
11696 + * we're here via the standard kernel stack.
11697 + */
11698 + if (unlikely(skb_headroom(skb) < priv->tx_headroom)) {
11699 + struct sk_buff *skb_new;
11700 +
11701 + skb_new = skb_realloc_headroom(skb, priv->tx_headroom);
11702 + if (unlikely(!skb_new)) {
11703 + dev_kfree_skb(skb);
11704 + percpu_stats->tx_errors++;
11705 + return NETDEV_TX_OK;
11706 + }
11707 +
11708 + /* propagate the skb ownership information */
11709 + if (skb->sk)
11710 + skb_set_owner_w(skb_new, skb->sk);
11711 +
11712 + dev_kfree_skb(skb);
11713 + skb = skb_new;
11714 + }
11715 +
11716 + /* We're going to store the skb backpointer at the beginning
11717 + * of the data buffer, so we need a privately owned skb
11718 + */
11719 +
11720 + /* Code borrowed from skb_unshare(). */
11721 + if (skb_cloned(skb)) {
11722 + struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
11723 + kfree_skb(skb);
11724 + skb = nskb;
11725 +#ifndef CONFIG_PPC
11726 + if (unlikely(dpaa_errata_a010022) &&
11727 + a010022_check_skb(skb, priv)) {
11728 + skb = a010022_realign_skb(skb, priv);
11729 + if (!skb)
11730 + goto skb_to_fd_failed;
11731 + }
11732 +#endif
11733 + /* skb_copy() has now linearized the skbuff. */
11734 + } else if (unlikely(nonlinear)) {
11735 + /* We are here because the egress skb contains
11736 + * more fragments than we support. In this case,
11737 + * we have no choice but to linearize it ourselves.
11738 + */
11739 + err = __skb_linearize(skb);
11740 + }
11741 + if (unlikely(!skb || err < 0))
11742 + /* Common out-of-memory error path */
11743 + goto enomem;
11744 +
11745 + err = skb_to_contig_fd(priv, skb, &fd, countptr, &offset);
11746 + }
11747 + if (unlikely(err < 0))
11748 + goto skb_to_fd_failed;
11749 +
11750 + if (fd.bpid != 0xff) {
11751 + skb_recycle(skb);
11752 + /* skb_recycle() reserves NET_SKB_PAD as skb headroom,
11753 + * but we need the skb to look as if returned by build_skb().
11754 + * We need to manually adjust the tailptr as well.
11755 + */
11756 + skb->data = skb->head + offset;
11757 + skb_reset_tail_pointer(skb);
11758 +
11759 + (*countptr)++;
11760 + percpu_priv->tx_returned++;
11761 + }
11762 +
11763 + if (unlikely(dpa_xmit(priv, percpu_stats, &fd, egress_fq, conf_fq) < 0))
11764 + goto xmit_failed;
11765 +
11766 + netif_trans_update(net_dev);
11767 + return NETDEV_TX_OK;
11768 +
11769 +xmit_failed:
11770 + if (fd.bpid != 0xff) {
11771 + (*countptr)--;
11772 + percpu_priv->tx_returned--;
11773 + dpa_fd_release(net_dev, &fd);
11774 + percpu_stats->tx_errors++;
11775 + return NETDEV_TX_OK;
11776 + }
11777 + _dpa_cleanup_tx_fd(priv, &fd);
11778 +skb_to_fd_failed:
11779 +enomem:
11780 + percpu_stats->tx_errors++;
11781 + dev_kfree_skb(skb);
11782 + return NETDEV_TX_OK;
11783 +}
11784 +EXPORT_SYMBOL(dpa_tx_extended);
11785 --- /dev/null
11786 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_sysfs.c
11787 @@ -0,0 +1,278 @@
11788 +/* Copyright 2008-2012 Freescale Semiconductor Inc.
11789 + *
11790 + * Redistribution and use in source and binary forms, with or without
11791 + * modification, are permitted provided that the following conditions are met:
11792 + * * Redistributions of source code must retain the above copyright
11793 + * notice, this list of conditions and the following disclaimer.
11794 + * * Redistributions in binary form must reproduce the above copyright
11795 + * notice, this list of conditions and the following disclaimer in the
11796 + * documentation and/or other materials provided with the distribution.
11797 + * * Neither the name of Freescale Semiconductor nor the
11798 + * names of its contributors may be used to endorse or promote products
11799 + * derived from this software without specific prior written permission.
11800 + *
11801 + *
11802 + * ALTERNATIVELY, this software may be distributed under the terms of the
11803 + * GNU General Public License ("GPL") as published by the Free Software
11804 + * Foundation, either version 2 of that License or (at your option) any
11805 + * later version.
11806 + *
11807 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
11808 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
11809 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11810 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
11811 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
11812 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11813 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
11814 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
11815 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11816 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11817 + */
11818 +
11819 +#include <linux/init.h>
11820 +#include <linux/module.h>
11821 +#include <linux/kthread.h>
11822 +#include <linux/io.h>
11823 +#include <linux/of_net.h>
11824 +#include "dpaa_eth.h"
11825 +#include "mac.h" /* struct mac_device */
11826 +#ifdef CONFIG_FSL_DPAA_1588
11827 +#include "dpaa_1588.h"
11828 +#endif
11829 +
11830 +static ssize_t dpaa_eth_show_addr(struct device *dev,
11831 + struct device_attribute *attr, char *buf)
11832 +{
11833 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11834 + struct mac_device *mac_dev = priv->mac_dev;
11835 +
11836 + if (mac_dev)
11837 + return sprintf(buf, "%llx",
11838 + (unsigned long long)mac_dev->res->start);
11839 + else
11840 + return sprintf(buf, "none");
11841 +}
11842 +
11843 +static ssize_t dpaa_eth_show_type(struct device *dev,
11844 + struct device_attribute *attr, char *buf)
11845 +{
11846 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11847 + ssize_t res = 0;
11848 +
11849 + if (priv)
11850 + res = sprintf(buf, "%s", priv->if_type);
11851 +
11852 + return res;
11853 +}
11854 +
11855 +static ssize_t dpaa_eth_show_fqids(struct device *dev,
11856 + struct device_attribute *attr, char *buf)
11857 +{
11858 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11859 + ssize_t bytes = 0;
11860 + int i = 0;
11861 + char *str;
11862 + struct dpa_fq *fq;
11863 + struct dpa_fq *tmp;
11864 + struct dpa_fq *prev = NULL;
11865 + u32 first_fqid = 0;
11866 + u32 last_fqid = 0;
11867 + char *prevstr = NULL;
11868 +
11869 + list_for_each_entry_safe(fq, tmp, &priv->dpa_fq_list, list) {
11870 + switch (fq->fq_type) {
11871 + case FQ_TYPE_RX_DEFAULT:
11872 + str = "Rx default";
11873 + break;
11874 + case FQ_TYPE_RX_ERROR:
11875 + str = "Rx error";
11876 + break;
11877 + case FQ_TYPE_RX_PCD:
11878 + str = "Rx PCD";
11879 + break;
11880 + case FQ_TYPE_TX_CONFIRM:
11881 + str = "Tx default confirmation";
11882 + break;
11883 + case FQ_TYPE_TX_CONF_MQ:
11884 + str = "Tx confirmation (mq)";
11885 + break;
11886 + case FQ_TYPE_TX_ERROR:
11887 + str = "Tx error";
11888 + break;
11889 + case FQ_TYPE_TX:
11890 + str = "Tx";
11891 + break;
11892 + case FQ_TYPE_RX_PCD_HI_PRIO:
11893 + str ="Rx PCD High Priority";
11894 + break;
11895 + default:
11896 + str = "Unknown";
11897 + }
11898 +
11899 + if (prev && (abs(fq->fqid - prev->fqid) != 1 ||
11900 + str != prevstr)) {
11901 + if (last_fqid == first_fqid)
11902 + bytes += sprintf(buf + bytes,
11903 + "%s: %d\n", prevstr, prev->fqid);
11904 + else
11905 + bytes += sprintf(buf + bytes,
11906 + "%s: %d - %d\n", prevstr,
11907 + first_fqid, last_fqid);
11908 + }
11909 +
11910 + if (prev && abs(fq->fqid - prev->fqid) == 1 && str == prevstr)
11911 + last_fqid = fq->fqid;
11912 + else
11913 + first_fqid = last_fqid = fq->fqid;
11914 +
11915 + prev = fq;
11916 + prevstr = str;
11917 + i++;
11918 + }
11919 +
11920 + if (prev) {
11921 + if (last_fqid == first_fqid)
11922 + bytes += sprintf(buf + bytes, "%s: %d\n", prevstr,
11923 + prev->fqid);
11924 + else
11925 + bytes += sprintf(buf + bytes, "%s: %d - %d\n", prevstr,
11926 + first_fqid, last_fqid);
11927 + }
11928 +
11929 + return bytes;
11930 +}
11931 +
11932 +static ssize_t dpaa_eth_show_bpids(struct device *dev,
11933 + struct device_attribute *attr, char *buf)
11934 +{
11935 + ssize_t bytes = 0;
11936 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11937 + struct dpa_bp *dpa_bp = priv->dpa_bp;
11938 + int i = 0;
11939 +
11940 + for (i = 0; i < priv->bp_count; i++)
11941 + bytes += snprintf(buf + bytes, PAGE_SIZE, "%u\n",
11942 + dpa_bp[i].bpid);
11943 +
11944 + return bytes;
11945 +}
11946 +
11947 +static ssize_t dpaa_eth_show_mac_regs(struct device *dev,
11948 + struct device_attribute *attr, char *buf)
11949 +{
11950 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11951 + struct mac_device *mac_dev = priv->mac_dev;
11952 + int n = 0;
11953 +
11954 + if (mac_dev)
11955 + n = fm_mac_dump_regs(mac_dev, buf, n);
11956 + else
11957 + return sprintf(buf, "no mac registers\n");
11958 +
11959 + return n;
11960 +}
11961 +
11962 +static ssize_t dpaa_eth_show_mac_rx_stats(struct device *dev,
11963 + struct device_attribute *attr, char *buf)
11964 +{
11965 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11966 + struct mac_device *mac_dev = priv->mac_dev;
11967 + int n = 0;
11968 +
11969 + if (mac_dev)
11970 + n = fm_mac_dump_rx_stats(mac_dev, buf, n);
11971 + else
11972 + return sprintf(buf, "no mac rx stats\n");
11973 +
11974 + return n;
11975 +}
11976 +
11977 +static ssize_t dpaa_eth_show_mac_tx_stats(struct device *dev,
11978 + struct device_attribute *attr, char *buf)
11979 +{
11980 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11981 + struct mac_device *mac_dev = priv->mac_dev;
11982 + int n = 0;
11983 +
11984 + if (mac_dev)
11985 + n = fm_mac_dump_tx_stats(mac_dev, buf, n);
11986 + else
11987 + return sprintf(buf, "no mac tx stats\n");
11988 +
11989 + return n;
11990 +}
11991 +
11992 +#ifdef CONFIG_FSL_DPAA_1588
11993 +static ssize_t dpaa_eth_show_ptp_1588(struct device *dev,
11994 + struct device_attribute *attr, char *buf)
11995 +{
11996 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
11997 +
11998 + if (priv->tsu && priv->tsu->valid)
11999 + return sprintf(buf, "1\n");
12000 + else
12001 + return sprintf(buf, "0\n");
12002 +}
12003 +
12004 +static ssize_t dpaa_eth_set_ptp_1588(struct device *dev,
12005 + struct device_attribute *attr,
12006 + const char *buf, size_t count)
12007 +{
12008 + struct dpa_priv_s *priv = netdev_priv(to_net_dev(dev));
12009 + unsigned int num;
12010 + unsigned long flags;
12011 +
12012 + if (kstrtouint(buf, 0, &num) < 0)
12013 + return -EINVAL;
12014 +
12015 + local_irq_save(flags);
12016 +
12017 + if (num) {
12018 + if (priv->tsu)
12019 + priv->tsu->valid = TRUE;
12020 + } else {
12021 + if (priv->tsu)
12022 + priv->tsu->valid = FALSE;
12023 + }
12024 +
12025 + local_irq_restore(flags);
12026 +
12027 + return count;
12028 +}
12029 +#endif
12030 +
12031 +static struct device_attribute dpaa_eth_attrs[] = {
12032 + __ATTR(device_addr, S_IRUGO, dpaa_eth_show_addr, NULL),
12033 + __ATTR(device_type, S_IRUGO, dpaa_eth_show_type, NULL),
12034 + __ATTR(fqids, S_IRUGO, dpaa_eth_show_fqids, NULL),
12035 + __ATTR(bpids, S_IRUGO, dpaa_eth_show_bpids, NULL),
12036 + __ATTR(mac_regs, S_IRUGO, dpaa_eth_show_mac_regs, NULL),
12037 + __ATTR(mac_rx_stats, S_IRUGO, dpaa_eth_show_mac_rx_stats, NULL),
12038 + __ATTR(mac_tx_stats, S_IRUGO, dpaa_eth_show_mac_tx_stats, NULL),
12039 +#ifdef CONFIG_FSL_DPAA_1588
12040 + __ATTR(ptp_1588, S_IRUGO | S_IWUSR, dpaa_eth_show_ptp_1588,
12041 + dpaa_eth_set_ptp_1588),
12042 +#endif
12043 +};
12044 +
12045 +void dpaa_eth_sysfs_init(struct device *dev)
12046 +{
12047 + int i;
12048 +
12049 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
12050 + if (device_create_file(dev, &dpaa_eth_attrs[i])) {
12051 + dev_err(dev, "Error creating sysfs file\n");
12052 + while (i > 0)
12053 + device_remove_file(dev, &dpaa_eth_attrs[--i]);
12054 + return;
12055 + }
12056 +}
12057 +EXPORT_SYMBOL(dpaa_eth_sysfs_init);
12058 +
12059 +void dpaa_eth_sysfs_remove(struct device *dev)
12060 +{
12061 + int i;
12062 +
12063 + for (i = 0; i < ARRAY_SIZE(dpaa_eth_attrs); i++)
12064 + device_remove_file(dev, &dpaa_eth_attrs[i]);
12065 +}
12066 --- /dev/null
12067 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_trace.h
12068 @@ -0,0 +1,144 @@
12069 +/* Copyright 2013 Freescale Semiconductor Inc.
12070 + *
12071 + * Redistribution and use in source and binary forms, with or without
12072 + * modification, are permitted provided that the following conditions are met:
12073 + * * Redistributions of source code must retain the above copyright
12074 + * notice, this list of conditions and the following disclaimer.
12075 + * * Redistributions in binary form must reproduce the above copyright
12076 + * notice, this list of conditions and the following disclaimer in the
12077 + * documentation and/or other materials provided with the distribution.
12078 + * * Neither the name of Freescale Semiconductor nor the
12079 + * names of its contributors may be used to endorse or promote products
12080 + * derived from this software without specific prior written permission.
12081 + *
12082 + *
12083 + * ALTERNATIVELY, this software may be distributed under the terms of the
12084 + * GNU General Public License ("GPL") as published by the Free Software
12085 + * Foundation, either version 2 of that License or (at your option) any
12086 + * later version.
12087 + *
12088 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12089 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12090 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12091 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12092 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12093 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12094 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12095 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12096 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12097 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12098 + */
12099 +
12100 +#undef TRACE_SYSTEM
12101 +#define TRACE_SYSTEM dpaa_eth
12102 +
12103 +#if !defined(_DPAA_ETH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
12104 +#define _DPAA_ETH_TRACE_H
12105 +
12106 +#include <linux/skbuff.h>
12107 +#include <linux/netdevice.h>
12108 +#include "dpaa_eth.h"
12109 +#include <linux/tracepoint.h>
12110 +
12111 +#define fd_format_name(format) { qm_fd_##format, #format }
12112 +#define fd_format_list \
12113 + fd_format_name(contig), \
12114 + fd_format_name(sg)
12115 +#define TR_FMT "[%s] fqid=%d, fd: addr=0x%llx, format=%s, off=%u, len=%u," \
12116 + " status=0x%08x"
12117 +
12118 +/* This is used to declare a class of events.
12119 + * individual events of this type will be defined below.
12120 + */
12121 +
12122 +/* Store details about a frame descriptor and the FQ on which it was
12123 + * transmitted/received.
12124 + */
12125 +DECLARE_EVENT_CLASS(dpaa_eth_fd,
12126 + /* Trace function prototype */
12127 + TP_PROTO(struct net_device *netdev,
12128 + struct qman_fq *fq,
12129 + const struct qm_fd *fd),
12130 +
12131 + /* Repeat argument list here */
12132 + TP_ARGS(netdev, fq, fd),
12133 +
12134 + /* A structure containing the relevant information we want to record.
12135 + * Declare name and type for each normal element, name, type and size
12136 + * for arrays. Use __string for variable length strings.
12137 + */
12138 + TP_STRUCT__entry(
12139 + __field(u32, fqid)
12140 + __field(u64, fd_addr)
12141 + __field(u8, fd_format)
12142 + __field(u16, fd_offset)
12143 + __field(u32, fd_length)
12144 + __field(u32, fd_status)
12145 + __string(name, netdev->name)
12146 + ),
12147 +
12148 + /* The function that assigns values to the above declared fields */
12149 + TP_fast_assign(
12150 + __entry->fqid = fq->fqid;
12151 + __entry->fd_addr = qm_fd_addr_get64(fd);
12152 + __entry->fd_format = fd->format;
12153 + __entry->fd_offset = dpa_fd_offset(fd);
12154 + __entry->fd_length = dpa_fd_length(fd);
12155 + __entry->fd_status = fd->status;
12156 + __assign_str(name, netdev->name);
12157 + ),
12158 +
12159 + /* This is what gets printed when the trace event is triggered */
12160 + /* TODO: print the status using __print_flags() */
12161 + TP_printk(TR_FMT,
12162 + __get_str(name), __entry->fqid, __entry->fd_addr,
12163 + __print_symbolic(__entry->fd_format, fd_format_list),
12164 + __entry->fd_offset, __entry->fd_length, __entry->fd_status)
12165 +);
12166 +
12167 +/* Now declare events of the above type. Format is:
12168 + * DEFINE_EVENT(class, name, proto, args), with proto and args same as for class
12169 + */
12170 +
12171 +/* Tx (egress) fd */
12172 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_fd,
12173 +
12174 + TP_PROTO(struct net_device *netdev,
12175 + struct qman_fq *fq,
12176 + const struct qm_fd *fd),
12177 +
12178 + TP_ARGS(netdev, fq, fd)
12179 +);
12180 +
12181 +/* Rx fd */
12182 +DEFINE_EVENT(dpaa_eth_fd, dpa_rx_fd,
12183 +
12184 + TP_PROTO(struct net_device *netdev,
12185 + struct qman_fq *fq,
12186 + const struct qm_fd *fd),
12187 +
12188 + TP_ARGS(netdev, fq, fd)
12189 +);
12190 +
12191 +/* Tx confirmation fd */
12192 +DEFINE_EVENT(dpaa_eth_fd, dpa_tx_conf_fd,
12193 +
12194 + TP_PROTO(struct net_device *netdev,
12195 + struct qman_fq *fq,
12196 + const struct qm_fd *fd),
12197 +
12198 + TP_ARGS(netdev, fq, fd)
12199 +);
12200 +
12201 +/* If only one event of a certain type needs to be declared, use TRACE_EVENT().
12202 + * The syntax is the same as for DECLARE_EVENT_CLASS().
12203 + */
12204 +
12205 +#endif /* _DPAA_ETH_TRACE_H */
12206 +
12207 +/* This must be outside ifdef _DPAA_ETH_TRACE_H */
12208 +#undef TRACE_INCLUDE_PATH
12209 +#define TRACE_INCLUDE_PATH .
12210 +#undef TRACE_INCLUDE_FILE
12211 +#define TRACE_INCLUDE_FILE dpaa_eth_trace
12212 +#include <trace/define_trace.h>
12213 --- /dev/null
12214 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_ethtool.c
12215 @@ -0,0 +1,587 @@
12216 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
12217 + *
12218 + * Redistribution and use in source and binary forms, with or without
12219 + * modification, are permitted provided that the following conditions are met:
12220 + * * Redistributions of source code must retain the above copyright
12221 + * notice, this list of conditions and the following disclaimer.
12222 + * * Redistributions in binary form must reproduce the above copyright
12223 + * notice, this list of conditions and the following disclaimer in the
12224 + * documentation and/or other materials provided with the distribution.
12225 + * * Neither the name of Freescale Semiconductor nor the
12226 + * names of its contributors may be used to endorse or promote products
12227 + * derived from this software without specific prior written permission.
12228 + *
12229 + *
12230 + * ALTERNATIVELY, this software may be distributed under the terms of the
12231 + * GNU General Public License ("GPL") as published by the Free Software
12232 + * Foundation, either version 2 of that License or (at your option) any
12233 + * later version.
12234 + *
12235 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12236 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12237 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12238 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12239 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12240 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12241 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12242 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12243 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12244 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12245 + */
12246 +
12247 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12248 +#define pr_fmt(fmt) \
12249 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12250 + KBUILD_BASENAME".c", __LINE__, __func__
12251 +#else
12252 +#define pr_fmt(fmt) \
12253 + KBUILD_MODNAME ": " fmt
12254 +#endif
12255 +
12256 +#include <linux/string.h>
12257 +#include <linux/of_platform.h>
12258 +#include <linux/net_tstamp.h>
12259 +#include <linux/fsl/ptp_qoriq.h>
12260 +
12261 +#include "dpaa_eth.h"
12262 +#include "mac.h" /* struct mac_device */
12263 +#include "dpaa_eth_common.h"
12264 +
12265 +static const char dpa_stats_percpu[][ETH_GSTRING_LEN] = {
12266 + "interrupts",
12267 + "rx packets",
12268 + "tx packets",
12269 + "tx recycled",
12270 + "tx confirm",
12271 + "tx S/G",
12272 + "rx S/G",
12273 + "tx error",
12274 + "rx error",
12275 + "bp count"
12276 +};
12277 +
12278 +static char dpa_stats_global[][ETH_GSTRING_LEN] = {
12279 + /* dpa rx errors */
12280 + "rx dma error",
12281 + "rx frame physical error",
12282 + "rx frame size error",
12283 + "rx header error",
12284 + "rx csum error",
12285 +
12286 + /* demultiplexing errors */
12287 + "qman cg_tdrop",
12288 + "qman wred",
12289 + "qman error cond",
12290 + "qman early window",
12291 + "qman late window",
12292 + "qman fq tdrop",
12293 + "qman fq retired",
12294 + "qman orp disabled",
12295 +
12296 + /* congestion related stats */
12297 + "congestion time (ms)",
12298 + "entered congestion",
12299 + "congested (0/1)"
12300 +};
12301 +
12302 +#define DPA_STATS_PERCPU_LEN ARRAY_SIZE(dpa_stats_percpu)
12303 +#define DPA_STATS_GLOBAL_LEN ARRAY_SIZE(dpa_stats_global)
12304 +
12305 +static int __cold dpa_get_ksettings(struct net_device *net_dev,
12306 + struct ethtool_link_ksettings *cmd)
12307 +{
12308 + int _errno;
12309 + struct dpa_priv_s *priv;
12310 +
12311 + priv = netdev_priv(net_dev);
12312 +
12313 + if (priv->mac_dev == NULL) {
12314 + netdev_info(net_dev, "This is a MAC-less interface\n");
12315 + return -ENODEV;
12316 + }
12317 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
12318 + netdev_dbg(net_dev, "phy device not initialized\n");
12319 + return 0;
12320 + }
12321 +
12322 + phy_ethtool_ksettings_get(priv->mac_dev->phy_dev, cmd);
12323 +
12324 + return _errno;
12325 +}
12326 +
12327 +static int __cold dpa_set_ksettings(struct net_device *net_dev,
12328 + const struct ethtool_link_ksettings *cmd)
12329 +{
12330 + int _errno;
12331 + struct dpa_priv_s *priv;
12332 +
12333 + priv = netdev_priv(net_dev);
12334 +
12335 + if (priv->mac_dev == NULL) {
12336 + netdev_info(net_dev, "This is a MAC-less interface\n");
12337 + return -ENODEV;
12338 + }
12339 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
12340 + netdev_err(net_dev, "phy device not initialized\n");
12341 + return -ENODEV;
12342 + }
12343 +
12344 + _errno = phy_ethtool_ksettings_set(priv->mac_dev->phy_dev, cmd);
12345 + if (unlikely(_errno < 0))
12346 + netdev_err(net_dev, "phy_ethtool_ksettings_set() = %d\n", _errno);
12347 +
12348 + return _errno;
12349 +}
12350 +
12351 +static void __cold dpa_get_drvinfo(struct net_device *net_dev,
12352 + struct ethtool_drvinfo *drvinfo)
12353 +{
12354 + int _errno;
12355 +
12356 + strncpy(drvinfo->driver, KBUILD_MODNAME,
12357 + sizeof(drvinfo->driver) - 1)[sizeof(drvinfo->driver)-1] = 0;
12358 + _errno = snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
12359 + "%X", 0);
12360 +
12361 + if (unlikely(_errno >= sizeof(drvinfo->fw_version))) {
12362 + /* Truncated output */
12363 + netdev_notice(net_dev, "snprintf() = %d\n", _errno);
12364 + } else if (unlikely(_errno < 0)) {
12365 + netdev_warn(net_dev, "snprintf() = %d\n", _errno);
12366 + memset(drvinfo->fw_version, 0, sizeof(drvinfo->fw_version));
12367 + }
12368 + strncpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
12369 + sizeof(drvinfo->bus_info)-1)[sizeof(drvinfo->bus_info)-1] = 0;
12370 +}
12371 +
12372 +static uint32_t __cold dpa_get_msglevel(struct net_device *net_dev)
12373 +{
12374 + return ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable;
12375 +}
12376 +
12377 +static void __cold dpa_set_msglevel(struct net_device *net_dev,
12378 + uint32_t msg_enable)
12379 +{
12380 + ((struct dpa_priv_s *)netdev_priv(net_dev))->msg_enable = msg_enable;
12381 +}
12382 +
12383 +static int __cold dpa_nway_reset(struct net_device *net_dev)
12384 +{
12385 + int _errno;
12386 + struct dpa_priv_s *priv;
12387 +
12388 + priv = netdev_priv(net_dev);
12389 +
12390 + if (priv->mac_dev == NULL) {
12391 + netdev_info(net_dev, "This is a MAC-less interface\n");
12392 + return -ENODEV;
12393 + }
12394 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
12395 + netdev_err(net_dev, "phy device not initialized\n");
12396 + return -ENODEV;
12397 + }
12398 +
12399 + _errno = 0;
12400 + if (priv->mac_dev->phy_dev->autoneg) {
12401 + _errno = phy_start_aneg(priv->mac_dev->phy_dev);
12402 + if (unlikely(_errno < 0))
12403 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
12404 + _errno);
12405 + }
12406 +
12407 + return _errno;
12408 +}
12409 +
12410 +static void __cold dpa_get_pauseparam(struct net_device *net_dev,
12411 + struct ethtool_pauseparam *epause)
12412 +{
12413 + struct dpa_priv_s *priv;
12414 + struct mac_device *mac_dev;
12415 + struct phy_device *phy_dev;
12416 +
12417 + priv = netdev_priv(net_dev);
12418 + mac_dev = priv->mac_dev;
12419 +
12420 + if (mac_dev == NULL) {
12421 + netdev_info(net_dev, "This is a MAC-less interface\n");
12422 + return;
12423 + }
12424 +
12425 + phy_dev = mac_dev->phy_dev;
12426 + if (unlikely(phy_dev == NULL)) {
12427 + netdev_err(net_dev, "phy device not initialized\n");
12428 + return;
12429 + }
12430 +
12431 + epause->autoneg = mac_dev->autoneg_pause;
12432 + epause->rx_pause = mac_dev->rx_pause_active;
12433 + epause->tx_pause = mac_dev->tx_pause_active;
12434 +}
12435 +
12436 +static int __cold dpa_set_pauseparam(struct net_device *net_dev,
12437 + struct ethtool_pauseparam *epause)
12438 +{
12439 + struct dpa_priv_s *priv;
12440 + struct mac_device *mac_dev;
12441 + struct phy_device *phy_dev;
12442 + int _errno;
12443 + u32 newadv, oldadv;
12444 + bool rx_pause, tx_pause;
12445 +
12446 + priv = netdev_priv(net_dev);
12447 + mac_dev = priv->mac_dev;
12448 +
12449 + if (mac_dev == NULL) {
12450 + netdev_info(net_dev, "This is a MAC-less interface\n");
12451 + return -ENODEV;
12452 + }
12453 +
12454 + phy_dev = mac_dev->phy_dev;
12455 + if (unlikely(phy_dev == NULL)) {
12456 + netdev_err(net_dev, "phy device not initialized\n");
12457 + return -ENODEV;
12458 + }
12459 +
12460 + if (!(phy_dev->supported & SUPPORTED_Pause) ||
12461 + (!(phy_dev->supported & SUPPORTED_Asym_Pause) &&
12462 + (epause->rx_pause != epause->tx_pause)))
12463 + return -EINVAL;
12464 +
12465 + /* The MAC should know how to handle PAUSE frame autonegotiation before
12466 + * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
12467 + * settings.
12468 + */
12469 + mac_dev->autoneg_pause = !!epause->autoneg;
12470 + mac_dev->rx_pause_req = !!epause->rx_pause;
12471 + mac_dev->tx_pause_req = !!epause->tx_pause;
12472 +
12473 + /* Determine the sym/asym advertised PAUSE capabilities from the desired
12474 + * rx/tx pause settings.
12475 + */
12476 + newadv = 0;
12477 + if (epause->rx_pause)
12478 + newadv = ADVERTISED_Pause | ADVERTISED_Asym_Pause;
12479 + if (epause->tx_pause)
12480 + newadv |= ADVERTISED_Asym_Pause;
12481 +
12482 + oldadv = phy_dev->advertising &
12483 + (ADVERTISED_Pause | ADVERTISED_Asym_Pause);
12484 +
12485 + /* If there are differences between the old and the new advertised
12486 + * values, restart PHY autonegotiation and advertise the new values.
12487 + */
12488 + if (oldadv != newadv) {
12489 + phy_dev->advertising &= ~(ADVERTISED_Pause
12490 + | ADVERTISED_Asym_Pause);
12491 + phy_dev->advertising |= newadv;
12492 + if (phy_dev->autoneg) {
12493 + _errno = phy_start_aneg(phy_dev);
12494 + if (unlikely(_errno < 0))
12495 + netdev_err(net_dev, "phy_start_aneg() = %d\n",
12496 + _errno);
12497 + }
12498 + }
12499 +
12500 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
12501 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
12502 + if (unlikely(_errno < 0))
12503 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
12504 +
12505 + return _errno;
12506 +}
12507 +
12508 +#ifdef CONFIG_PM
12509 +static void dpa_get_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
12510 +{
12511 + struct dpa_priv_s *priv = netdev_priv(net_dev);
12512 +
12513 + wol->supported = 0;
12514 + wol->wolopts = 0;
12515 +
12516 + if (!priv->wol || !device_can_wakeup(net_dev->dev.parent))
12517 + return;
12518 +
12519 + if (priv->wol & DPAA_WOL_MAGIC) {
12520 + wol->supported = WAKE_MAGIC;
12521 + wol->wolopts = WAKE_MAGIC;
12522 + }
12523 +}
12524 +
12525 +static int dpa_set_wol(struct net_device *net_dev, struct ethtool_wolinfo *wol)
12526 +{
12527 + struct dpa_priv_s *priv = netdev_priv(net_dev);
12528 +
12529 + if (priv->mac_dev == NULL) {
12530 + netdev_info(net_dev, "This is a MAC-less interface\n");
12531 + return -ENODEV;
12532 + }
12533 +
12534 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
12535 + netdev_dbg(net_dev, "phy device not initialized\n");
12536 + return -ENODEV;
12537 + }
12538 +
12539 + if (!device_can_wakeup(net_dev->dev.parent) ||
12540 + (wol->wolopts & ~WAKE_MAGIC))
12541 + return -EOPNOTSUPP;
12542 +
12543 + priv->wol = 0;
12544 +
12545 + if (wol->wolopts & WAKE_MAGIC) {
12546 + priv->wol = DPAA_WOL_MAGIC;
12547 + device_set_wakeup_enable(net_dev->dev.parent, 1);
12548 + } else {
12549 + device_set_wakeup_enable(net_dev->dev.parent, 0);
12550 + }
12551 +
12552 + return 0;
12553 +}
12554 +#endif
12555 +
12556 +static int dpa_get_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
12557 +{
12558 + struct dpa_priv_s *priv;
12559 +
12560 + priv = netdev_priv(net_dev);
12561 + if (priv->mac_dev == NULL) {
12562 + netdev_info(net_dev, "This is a MAC-less interface\n");
12563 + return -ENODEV;
12564 + }
12565 +
12566 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
12567 + netdev_err(net_dev, "phy device not initialized\n");
12568 + return -ENODEV;
12569 + }
12570 +
12571 + return phy_ethtool_get_eee(priv->mac_dev->phy_dev, et_eee);
12572 +}
12573 +
12574 +static int dpa_set_eee(struct net_device *net_dev, struct ethtool_eee *et_eee)
12575 +{
12576 + struct dpa_priv_s *priv;
12577 +
12578 + priv = netdev_priv(net_dev);
12579 + if (priv->mac_dev == NULL) {
12580 + netdev_info(net_dev, "This is a MAC-less interface\n");
12581 + return -ENODEV;
12582 + }
12583 +
12584 + if (unlikely(priv->mac_dev->phy_dev == NULL)) {
12585 + netdev_err(net_dev, "phy device not initialized\n");
12586 + return -ENODEV;
12587 + }
12588 +
12589 + return phy_ethtool_set_eee(priv->mac_dev->phy_dev, et_eee);
12590 +}
12591 +
12592 +static int dpa_get_sset_count(struct net_device *net_dev, int type)
12593 +{
12594 + unsigned int total_stats, num_stats;
12595 +
12596 + num_stats = num_online_cpus() + 1;
12597 + total_stats = num_stats * DPA_STATS_PERCPU_LEN + DPA_STATS_GLOBAL_LEN;
12598 +
12599 + switch (type) {
12600 + case ETH_SS_STATS:
12601 + return total_stats;
12602 + default:
12603 + return -EOPNOTSUPP;
12604 + }
12605 +}
12606 +
12607 +static void copy_stats(struct dpa_percpu_priv_s *percpu_priv, int num_cpus,
12608 + int crr_cpu, u64 bp_count, u64 *data)
12609 +{
12610 + int num_stat_values = num_cpus + 1;
12611 + int crr_stat = 0;
12612 +
12613 + /* update current CPU's stats and also add them to the total values */
12614 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->in_interrupt;
12615 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->in_interrupt;
12616 +
12617 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_packets;
12618 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_packets;
12619 +
12620 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_packets;
12621 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_packets;
12622 +
12623 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_returned;
12624 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_returned;
12625 +
12626 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_confirm;
12627 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_confirm;
12628 +
12629 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->tx_frag_skbuffs;
12630 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->tx_frag_skbuffs;
12631 +
12632 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->rx_sg;
12633 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->rx_sg;
12634 +
12635 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.tx_errors;
12636 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.tx_errors;
12637 +
12638 + data[crr_stat * num_stat_values + crr_cpu] = percpu_priv->stats.rx_errors;
12639 + data[crr_stat++ * num_stat_values + num_cpus] += percpu_priv->stats.rx_errors;
12640 +
12641 + data[crr_stat * num_stat_values + crr_cpu] = bp_count;
12642 + data[crr_stat++ * num_stat_values + num_cpus] += bp_count;
12643 +}
12644 +
12645 +static void dpa_get_ethtool_stats(struct net_device *net_dev,
12646 + struct ethtool_stats *stats, u64 *data)
12647 +{
12648 + u64 bp_count, cg_time, cg_num, cg_status;
12649 + struct dpa_percpu_priv_s *percpu_priv;
12650 + struct qm_mcr_querycgr query_cgr;
12651 + struct dpa_rx_errors rx_errors;
12652 + struct dpa_ern_cnt ern_cnt;
12653 + struct dpa_priv_s *priv;
12654 + unsigned int num_cpus, offset;
12655 + struct dpa_bp *dpa_bp;
12656 + int total_stats, i;
12657 +
12658 + total_stats = dpa_get_sset_count(net_dev, ETH_SS_STATS);
12659 + priv = netdev_priv(net_dev);
12660 + dpa_bp = priv->dpa_bp;
12661 + num_cpus = num_online_cpus();
12662 + bp_count = 0;
12663 +
12664 + memset(&rx_errors, 0, sizeof(struct dpa_rx_errors));
12665 + memset(&ern_cnt, 0, sizeof(struct dpa_ern_cnt));
12666 + memset(data, 0, total_stats * sizeof(u64));
12667 +
12668 + for_each_online_cpu(i) {
12669 + percpu_priv = per_cpu_ptr(priv->percpu_priv, i);
12670 +
12671 + if (dpa_bp->percpu_count)
12672 + bp_count = *(per_cpu_ptr(dpa_bp->percpu_count, i));
12673 +
12674 + rx_errors.dme += percpu_priv->rx_errors.dme;
12675 + rx_errors.fpe += percpu_priv->rx_errors.fpe;
12676 + rx_errors.fse += percpu_priv->rx_errors.fse;
12677 + rx_errors.phe += percpu_priv->rx_errors.phe;
12678 + rx_errors.cse += percpu_priv->rx_errors.cse;
12679 +
12680 + ern_cnt.cg_tdrop += percpu_priv->ern_cnt.cg_tdrop;
12681 + ern_cnt.wred += percpu_priv->ern_cnt.wred;
12682 + ern_cnt.err_cond += percpu_priv->ern_cnt.err_cond;
12683 + ern_cnt.early_window += percpu_priv->ern_cnt.early_window;
12684 + ern_cnt.late_window += percpu_priv->ern_cnt.late_window;
12685 + ern_cnt.fq_tdrop += percpu_priv->ern_cnt.fq_tdrop;
12686 + ern_cnt.fq_retired += percpu_priv->ern_cnt.fq_retired;
12687 + ern_cnt.orp_zero += percpu_priv->ern_cnt.orp_zero;
12688 +
12689 + copy_stats(percpu_priv, num_cpus, i, bp_count, data);
12690 + }
12691 +
12692 + offset = (num_cpus + 1) * DPA_STATS_PERCPU_LEN;
12693 + memcpy(data + offset, &rx_errors, sizeof(struct dpa_rx_errors));
12694 +
12695 + offset += sizeof(struct dpa_rx_errors) / sizeof(u64);
12696 + memcpy(data + offset, &ern_cnt, sizeof(struct dpa_ern_cnt));
12697 +
12698 + /* gather congestion related counters */
12699 + cg_num = 0;
12700 + cg_status = 0;
12701 + cg_time = jiffies_to_msecs(priv->cgr_data.congested_jiffies);
12702 + if (qman_query_cgr(&priv->cgr_data.cgr, &query_cgr) == 0) {
12703 + cg_num = priv->cgr_data.cgr_congested_count;
12704 + cg_status = query_cgr.cgr.cs;
12705 +
12706 + /* reset congestion stats (like QMan API does */
12707 + priv->cgr_data.congested_jiffies = 0;
12708 + priv->cgr_data.cgr_congested_count = 0;
12709 + }
12710 +
12711 + offset += sizeof(struct dpa_ern_cnt) / sizeof(u64);
12712 + data[offset++] = cg_time;
12713 + data[offset++] = cg_num;
12714 + data[offset++] = cg_status;
12715 +}
12716 +
12717 +static void dpa_get_strings(struct net_device *net_dev, u32 stringset, u8 *data)
12718 +{
12719 + unsigned int i, j, num_cpus, size;
12720 + char stat_string_cpu[ETH_GSTRING_LEN];
12721 + u8 *strings;
12722 +
12723 + strings = data;
12724 + num_cpus = num_online_cpus();
12725 + size = DPA_STATS_GLOBAL_LEN * ETH_GSTRING_LEN;
12726 +
12727 + for (i = 0; i < DPA_STATS_PERCPU_LEN; i++) {
12728 + for (j = 0; j < num_cpus; j++) {
12729 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [CPU %d]", dpa_stats_percpu[i], j);
12730 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
12731 + strings += ETH_GSTRING_LEN;
12732 + }
12733 + snprintf(stat_string_cpu, ETH_GSTRING_LEN, "%s [TOTAL]", dpa_stats_percpu[i]);
12734 + memcpy(strings, stat_string_cpu, ETH_GSTRING_LEN);
12735 + strings += ETH_GSTRING_LEN;
12736 + }
12737 + memcpy(strings, dpa_stats_global, size);
12738 +}
12739 +
12740 +static int dpaa_get_ts_info(struct net_device *net_dev,
12741 + struct ethtool_ts_info *info)
12742 +{
12743 + struct dpa_priv_s *priv = netdev_priv(net_dev);
12744 + struct device *dev = priv->mac_dev->dev;
12745 + struct device_node *mac_node = dev->of_node;
12746 + struct device_node *fman_node = NULL, *ptp_node = NULL;
12747 + struct platform_device *ptp_dev = NULL;
12748 + struct qoriq_ptp *ptp = NULL;
12749 +
12750 + info->phc_index = -1;
12751 +
12752 + fman_node = of_get_parent(mac_node);
12753 + if (fman_node)
12754 + ptp_node = of_parse_phandle(fman_node, "ptimer-handle", 0);
12755 +
12756 + if (ptp_node)
12757 + ptp_dev = of_find_device_by_node(ptp_node);
12758 +
12759 + if (ptp_dev)
12760 + ptp = platform_get_drvdata(ptp_dev);
12761 +
12762 + if (ptp)
12763 + info->phc_index = ptp->phc_index;
12764 +
12765 +#ifdef CONFIG_FSL_DPAA_TS
12766 + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
12767 + SOF_TIMESTAMPING_RX_HARDWARE |
12768 + SOF_TIMESTAMPING_RAW_HARDWARE;
12769 + info->tx_types = (1 << HWTSTAMP_TX_OFF) |
12770 + (1 << HWTSTAMP_TX_ON);
12771 + info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
12772 + (1 << HWTSTAMP_FILTER_ALL);
12773 +#else
12774 + info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
12775 + SOF_TIMESTAMPING_SOFTWARE;
12776 +#endif
12777 +
12778 + return 0;
12779 +}
12780 +
12781 +const struct ethtool_ops dpa_ethtool_ops = {
12782 + .get_link_ksettings = dpa_get_ksettings,
12783 + .set_link_ksettings = dpa_set_ksettings,
12784 + .get_drvinfo = dpa_get_drvinfo,
12785 + .get_msglevel = dpa_get_msglevel,
12786 + .set_msglevel = dpa_set_msglevel,
12787 + .nway_reset = dpa_nway_reset,
12788 + .get_pauseparam = dpa_get_pauseparam,
12789 + .set_pauseparam = dpa_set_pauseparam,
12790 + .self_test = NULL, /* TODO invoke the cold-boot unit-test? */
12791 + .get_link = ethtool_op_get_link,
12792 + .get_eee = dpa_get_eee,
12793 + .set_eee = dpa_set_eee,
12794 + .get_sset_count = dpa_get_sset_count,
12795 + .get_ethtool_stats = dpa_get_ethtool_stats,
12796 + .get_strings = dpa_get_strings,
12797 +#ifdef CONFIG_PM
12798 + .get_wol = dpa_get_wol,
12799 + .set_wol = dpa_set_wol,
12800 +#endif
12801 + .get_ts_info = dpaa_get_ts_info,
12802 +};
12803 --- /dev/null
12804 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac-api.c
12805 @@ -0,0 +1,931 @@
12806 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
12807 + *
12808 + * Redistribution and use in source and binary forms, with or without
12809 + * modification, are permitted provided that the following conditions are met:
12810 + * * Redistributions of source code must retain the above copyright
12811 + * notice, this list of conditions and the following disclaimer.
12812 + * * Redistributions in binary form must reproduce the above copyright
12813 + * notice, this list of conditions and the following disclaimer in the
12814 + * documentation and/or other materials provided with the distribution.
12815 + * * Neither the name of Freescale Semiconductor nor the
12816 + * names of its contributors may be used to endorse or promote products
12817 + * derived from this software without specific prior written permission.
12818 + *
12819 + *
12820 + * ALTERNATIVELY, this software may be distributed under the terms of the
12821 + * GNU General Public License ("GPL") as published by the Free Software
12822 + * Foundation, either version 2 of that License or (at your option) any
12823 + * later version.
12824 + *
12825 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
12826 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
12827 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
12828 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
12829 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
12830 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
12831 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
12832 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12833 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
12834 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12835 + */
12836 +
12837 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
12838 +#define pr_fmt(fmt) \
12839 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
12840 + KBUILD_BASENAME".c", __LINE__, __func__
12841 +#else
12842 +#define pr_fmt(fmt) \
12843 + KBUILD_MODNAME ": " fmt
12844 +#endif
12845 +
12846 +#include <linux/init.h>
12847 +#include <linux/module.h>
12848 +#include <linux/io.h>
12849 +#include <linux/of_platform.h>
12850 +#include <linux/of_mdio.h>
12851 +#include <linux/phy.h>
12852 +#include <linux/netdevice.h>
12853 +
12854 +#include "dpaa_eth.h"
12855 +#include "mac.h"
12856 +#include "lnxwrp_fsl_fman.h"
12857 +
12858 +#include "error_ext.h" /* GET_ERROR_TYPE, E_OK */
12859 +
12860 +#include "fsl_fman_dtsec.h"
12861 +#include "fsl_fman_tgec.h"
12862 +#include "fsl_fman_memac.h"
12863 +#include "../sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h"
12864 +
12865 +#define MAC_DESCRIPTION "FSL FMan MAC API based driver"
12866 +
12867 +MODULE_LICENSE("Dual BSD/GPL");
12868 +
12869 +MODULE_AUTHOR("Emil Medve <Emilian.Medve@Freescale.com>");
12870 +
12871 +MODULE_DESCRIPTION(MAC_DESCRIPTION);
12872 +
12873 +struct mac_priv_s {
12874 + struct fm_mac_dev *fm_mac;
12875 +};
12876 +
12877 +const char *mac_driver_description __initconst = MAC_DESCRIPTION;
12878 +const size_t mac_sizeof_priv[] = {
12879 + [DTSEC] = sizeof(struct mac_priv_s),
12880 + [XGMAC] = sizeof(struct mac_priv_s),
12881 + [MEMAC] = sizeof(struct mac_priv_s)
12882 +};
12883 +
12884 +static const enet_mode_t _100[] = {
12885 + [PHY_INTERFACE_MODE_MII] = e_ENET_MODE_MII_100,
12886 + [PHY_INTERFACE_MODE_RMII] = e_ENET_MODE_RMII_100
12887 +};
12888 +
12889 +static const enet_mode_t _1000[] = {
12890 + [PHY_INTERFACE_MODE_GMII] = e_ENET_MODE_GMII_1000,
12891 + [PHY_INTERFACE_MODE_SGMII] = e_ENET_MODE_SGMII_1000,
12892 + [PHY_INTERFACE_MODE_QSGMII] = e_ENET_MODE_QSGMII_1000,
12893 + [PHY_INTERFACE_MODE_TBI] = e_ENET_MODE_TBI_1000,
12894 + [PHY_INTERFACE_MODE_RGMII] = e_ENET_MODE_RGMII_1000,
12895 + [PHY_INTERFACE_MODE_RGMII_ID] = e_ENET_MODE_RGMII_1000,
12896 + [PHY_INTERFACE_MODE_RGMII_RXID] = e_ENET_MODE_RGMII_1000,
12897 + [PHY_INTERFACE_MODE_RGMII_TXID] = e_ENET_MODE_RGMII_1000,
12898 + [PHY_INTERFACE_MODE_RTBI] = e_ENET_MODE_RTBI_1000
12899 +};
12900 +
12901 +static enet_mode_t __cold __attribute__((nonnull))
12902 +macdev2enetinterface(const struct mac_device *mac_dev)
12903 +{
12904 + switch (mac_dev->max_speed) {
12905 + case SPEED_100:
12906 + return _100[mac_dev->phy_if];
12907 + case SPEED_1000:
12908 + return _1000[mac_dev->phy_if];
12909 + case SPEED_2500:
12910 + return e_ENET_MODE_SGMII_2500;
12911 + case SPEED_10000:
12912 + return e_ENET_MODE_XGMII_10000;
12913 + default:
12914 + return e_ENET_MODE_MII_100;
12915 + }
12916 +}
12917 +
12918 +static void mac_exception(handle_t _mac_dev, e_FmMacExceptions exception)
12919 +{
12920 + struct mac_device *mac_dev;
12921 +
12922 + mac_dev = (struct mac_device *)_mac_dev;
12923 +
12924 + if (e_FM_MAC_EX_10G_RX_FIFO_OVFL == exception) {
12925 + /* don't flag RX FIFO after the first */
12926 + fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
12927 + e_FM_MAC_EX_10G_RX_FIFO_OVFL, false);
12928 + dev_err(mac_dev->dev, "10G MAC got RX FIFO Error = %x\n",
12929 + exception);
12930 + }
12931 +
12932 + dev_dbg(mac_dev->dev, "%s:%s() -> %d\n", KBUILD_BASENAME".c", __func__,
12933 + exception);
12934 +}
12935 +
12936 +static int __cold init(struct mac_device *mac_dev)
12937 +{
12938 + int _errno;
12939 + struct mac_priv_s *priv;
12940 + t_FmMacParams param;
12941 + uint32_t version;
12942 +
12943 + priv = macdev_priv(mac_dev);
12944 +
12945 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
12946 + mac_dev->dev, mac_dev->res->start, 0x2000);
12947 + param.enetMode = macdev2enetinterface(mac_dev);
12948 + memcpy(&param.addr, mac_dev->addr, min(sizeof(param.addr),
12949 + sizeof(mac_dev->addr)));
12950 + param.macId = mac_dev->cell_index;
12951 + param.h_Fm = (handle_t)mac_dev->fm;
12952 + param.mdioIrq = NO_IRQ;
12953 + param.f_Exception = mac_exception;
12954 + param.f_Event = mac_exception;
12955 + param.h_App = mac_dev;
12956 +
12957 + priv->fm_mac = fm_mac_config(&param);
12958 + if (unlikely(priv->fm_mac == NULL)) {
12959 + _errno = -EINVAL;
12960 + goto _return;
12961 + }
12962 +
12963 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
12964 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
12965 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
12966 +
12967 + _errno = fm_mac_config_max_frame_length(priv->fm_mac,
12968 + fm_get_max_frm());
12969 + if (unlikely(_errno < 0))
12970 + goto _return_fm_mac_free;
12971 +
12972 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
12973 + /* 10G always works with pad and CRC */
12974 + _errno = fm_mac_config_pad_and_crc(priv->fm_mac, true);
12975 + if (unlikely(_errno < 0))
12976 + goto _return_fm_mac_free;
12977 +
12978 + _errno = fm_mac_config_half_duplex(priv->fm_mac,
12979 + mac_dev->half_duplex);
12980 + if (unlikely(_errno < 0))
12981 + goto _return_fm_mac_free;
12982 + } else {
12983 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
12984 + if (unlikely(_errno < 0))
12985 + goto _return_fm_mac_free;
12986 + }
12987 +
12988 + _errno = fm_mac_init(priv->fm_mac);
12989 + if (unlikely(_errno < 0))
12990 + goto _return_fm_mac_free;
12991 +
12992 +#ifndef CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN
12993 + /* For 1G MAC, disable by default the MIB counters overflow interrupt */
12994 + if (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) {
12995 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
12996 + e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL, FALSE);
12997 + if (unlikely(_errno < 0))
12998 + goto _return_fm_mac_free;
12999 + }
13000 +#endif /* !CONFIG_FMAN_MIB_CNT_OVF_IRQ_EN */
13001 +
13002 + /* For 10G MAC, disable Tx ECC exception */
13003 + if (macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) {
13004 + _errno = fm_mac_set_exception(mac_dev->get_mac_handle(mac_dev),
13005 + e_FM_MAC_EX_10G_1TX_ECC_ER, FALSE);
13006 + if (unlikely(_errno < 0))
13007 + goto _return_fm_mac_free;
13008 + }
13009 +
13010 + _errno = fm_mac_get_version(priv->fm_mac, &version);
13011 + if (unlikely(_errno < 0))
13012 + goto _return_fm_mac_free;
13013 +
13014 + dev_info(mac_dev->dev, "FMan %s version: 0x%08x\n",
13015 + ((macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
13016 + "dTSEC" : "XGEC"), version);
13017 +
13018 + goto _return;
13019 +
13020 +
13021 +_return_fm_mac_free:
13022 + fm_mac_free(mac_dev->get_mac_handle(mac_dev));
13023 +
13024 +_return:
13025 + return _errno;
13026 +}
13027 +
13028 +static int __cold memac_init(struct mac_device *mac_dev)
13029 +{
13030 + int _errno;
13031 + struct mac_priv_s *priv;
13032 + t_FmMacParams param;
13033 +
13034 + priv = macdev_priv(mac_dev);
13035 +
13036 + param.baseAddr = (typeof(param.baseAddr))(uintptr_t)devm_ioremap(
13037 + mac_dev->dev, mac_dev->res->start, 0x2000);
13038 + param.enetMode = macdev2enetinterface(mac_dev);
13039 + memcpy(&param.addr, mac_dev->addr, sizeof(mac_dev->addr));
13040 + param.macId = mac_dev->cell_index;
13041 + param.h_Fm = (handle_t)mac_dev->fm;
13042 + param.mdioIrq = NO_IRQ;
13043 + param.f_Exception = mac_exception;
13044 + param.f_Event = mac_exception;
13045 + param.h_App = mac_dev;
13046 +
13047 + priv->fm_mac = fm_mac_config(&param);
13048 + if (unlikely(priv->fm_mac == NULL)) {
13049 + _errno = -EINVAL;
13050 + goto _return;
13051 + }
13052 +
13053 + fm_mac_set_handle(mac_dev->fm_dev, priv->fm_mac,
13054 + (macdev2enetinterface(mac_dev) != e_ENET_MODE_XGMII_10000) ?
13055 + param.macId : param.macId + FM_MAX_NUM_OF_1G_MACS);
13056 +
13057 + _errno = fm_mac_config_max_frame_length(priv->fm_mac, fm_get_max_frm());
13058 + if (unlikely(_errno < 0))
13059 + goto _return_fm_mac_free;
13060 +
13061 + _errno = fm_mac_config_reset_on_init(priv->fm_mac, true);
13062 + if (unlikely(_errno < 0))
13063 + goto _return_fm_mac_free;
13064 +
13065 + _errno = fm_mac_init(priv->fm_mac);
13066 + if (unlikely(_errno < 0))
13067 + goto _return_fm_mac_free;
13068 +
13069 + dev_info(mac_dev->dev, "FMan MEMAC\n");
13070 +
13071 + goto _return;
13072 +
13073 +_return_fm_mac_free:
13074 + fm_mac_free(priv->fm_mac);
13075 +
13076 +_return:
13077 + return _errno;
13078 +}
13079 +
13080 +static int __cold start(struct mac_device *mac_dev)
13081 +{
13082 + int _errno;
13083 + struct phy_device *phy_dev = mac_dev->phy_dev;
13084 +
13085 + _errno = fm_mac_enable(mac_dev->get_mac_handle(mac_dev));
13086 +
13087 + if (!_errno && phy_dev)
13088 + phy_start(phy_dev);
13089 +
13090 + return _errno;
13091 +}
13092 +
13093 +static int __cold stop(struct mac_device *mac_dev)
13094 +{
13095 + if (mac_dev->phy_dev)
13096 + phy_stop(mac_dev->phy_dev);
13097 +
13098 + return fm_mac_disable(mac_dev->get_mac_handle(mac_dev));
13099 +}
13100 +
13101 +static int __cold set_multi(struct net_device *net_dev,
13102 + struct mac_device *mac_dev)
13103 +{
13104 + struct mac_priv_s *mac_priv;
13105 + struct mac_address *old_addr, *tmp;
13106 + struct netdev_hw_addr *ha;
13107 + int _errno;
13108 +
13109 + mac_priv = macdev_priv(mac_dev);
13110 +
13111 + /* Clear previous address list */
13112 + list_for_each_entry_safe(old_addr, tmp, &mac_dev->mc_addr_list, list) {
13113 + _errno = fm_mac_remove_hash_mac_addr(mac_priv->fm_mac,
13114 + (t_EnetAddr *)old_addr->addr);
13115 + if (_errno < 0)
13116 + return _errno;
13117 +
13118 + list_del(&old_addr->list);
13119 + kfree(old_addr);
13120 + }
13121 +
13122 + /* Add all the addresses from the new list */
13123 + netdev_for_each_mc_addr(ha, net_dev) {
13124 + _errno = fm_mac_add_hash_mac_addr(mac_priv->fm_mac,
13125 + (t_EnetAddr *)ha->addr);
13126 + if (_errno < 0)
13127 + return _errno;
13128 +
13129 + tmp = kmalloc(sizeof(struct mac_address), GFP_ATOMIC);
13130 + if (!tmp) {
13131 + dev_err(mac_dev->dev, "Out of memory\n");
13132 + return -ENOMEM;
13133 + }
13134 + memcpy(tmp->addr, ha->addr, ETH_ALEN);
13135 + list_add(&tmp->list, &mac_dev->mc_addr_list);
13136 + }
13137 + return 0;
13138 +}
13139 +
13140 +/* Avoid redundant calls to FMD, if the MAC driver already contains the desired
13141 + * active PAUSE settings. Otherwise, the new active settings should be reflected
13142 + * in FMan.
13143 + */
13144 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
13145 +{
13146 + struct fm_mac_dev *fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
13147 + int _errno = 0;
13148 +
13149 + if (unlikely(rx != mac_dev->rx_pause_active)) {
13150 + _errno = fm_mac_set_rx_pause_frames(fm_mac_dev, rx);
13151 + if (likely(_errno == 0))
13152 + mac_dev->rx_pause_active = rx;
13153 + }
13154 +
13155 + if (unlikely(tx != mac_dev->tx_pause_active)) {
13156 + _errno = fm_mac_set_tx_pause_frames(fm_mac_dev, tx);
13157 + if (likely(_errno == 0))
13158 + mac_dev->tx_pause_active = tx;
13159 + }
13160 +
13161 + return _errno;
13162 +}
13163 +EXPORT_SYMBOL(set_mac_active_pause);
13164 +
13165 +/* Determine the MAC RX/TX PAUSE frames settings based on PHY
13166 + * autonegotiation or values set by eththool.
13167 + */
13168 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause)
13169 +{
13170 + struct phy_device *phy_dev = mac_dev->phy_dev;
13171 + u16 lcl_adv, rmt_adv;
13172 + u8 flowctrl;
13173 +
13174 + *rx_pause = *tx_pause = false;
13175 +
13176 + if (!phy_dev->duplex)
13177 + return;
13178 +
13179 + /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
13180 + * are those set by ethtool.
13181 + */
13182 + if (!mac_dev->autoneg_pause) {
13183 + *rx_pause = mac_dev->rx_pause_req;
13184 + *tx_pause = mac_dev->tx_pause_req;
13185 + return;
13186 + }
13187 +
13188 + /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
13189 + * settings depend on the result of the link negotiation.
13190 + */
13191 +
13192 + /* get local capabilities */
13193 + lcl_adv = 0;
13194 + if (phy_dev->advertising & ADVERTISED_Pause)
13195 + lcl_adv |= ADVERTISE_PAUSE_CAP;
13196 + if (phy_dev->advertising & ADVERTISED_Asym_Pause)
13197 + lcl_adv |= ADVERTISE_PAUSE_ASYM;
13198 +
13199 + /* get link partner capabilities */
13200 + rmt_adv = 0;
13201 + if (phy_dev->pause)
13202 + rmt_adv |= LPA_PAUSE_CAP;
13203 + if (phy_dev->asym_pause)
13204 + rmt_adv |= LPA_PAUSE_ASYM;
13205 +
13206 + /* Calculate TX/RX settings based on local and peer advertised
13207 + * symmetric/asymmetric PAUSE capabilities.
13208 + */
13209 + flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
13210 + if (flowctrl & FLOW_CTRL_RX)
13211 + *rx_pause = true;
13212 + if (flowctrl & FLOW_CTRL_TX)
13213 + *tx_pause = true;
13214 +}
13215 +EXPORT_SYMBOL(get_pause_cfg);
13216 +
13217 +static void adjust_link_void(struct net_device *net_dev)
13218 +{
13219 +}
13220 +
13221 +static void adjust_link(struct net_device *net_dev)
13222 +{
13223 + struct dpa_priv_s *priv = netdev_priv(net_dev);
13224 + struct mac_device *mac_dev = priv->mac_dev;
13225 + struct phy_device *phy_dev = mac_dev->phy_dev;
13226 + struct fm_mac_dev *fm_mac_dev;
13227 + bool rx_pause, tx_pause;
13228 + int _errno;
13229 +
13230 + fm_mac_dev = mac_dev->get_mac_handle(mac_dev);
13231 + fm_mac_adjust_link(fm_mac_dev, phy_dev->link, phy_dev->speed,
13232 + phy_dev->duplex);
13233 +
13234 + get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
13235 + _errno = set_mac_active_pause(mac_dev, rx_pause, tx_pause);
13236 + if (unlikely(_errno < 0))
13237 + netdev_err(net_dev, "set_mac_active_pause() = %d\n", _errno);
13238 +}
13239 +
13240 +/* Initializes driver's PHY state, and attaches to the PHY.
13241 + * Returns 0 on success.
13242 + */
13243 +static int dtsec_init_phy(struct net_device *net_dev,
13244 + struct mac_device *mac_dev)
13245 +{
13246 + struct phy_device *phy_dev;
13247 +
13248 + if (of_phy_is_fixed_link(mac_dev->phy_node))
13249 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
13250 + 0, mac_dev->phy_if);
13251 + else
13252 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
13253 + &adjust_link, 0, mac_dev->phy_if);
13254 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
13255 + netdev_err(net_dev, "Could not connect to PHY %s\n",
13256 + mac_dev->phy_node ?
13257 + mac_dev->phy_node->full_name :
13258 + mac_dev->fixed_bus_id);
13259 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
13260 + }
13261 +
13262 + /* Remove any features not supported by the controller */
13263 + phy_dev->supported &= mac_dev->if_support;
13264 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
13265 + * as most of the PHY drivers do not enable them by default.
13266 + */
13267 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
13268 + phy_dev->advertising = phy_dev->supported;
13269 +
13270 + mac_dev->phy_dev = phy_dev;
13271 +
13272 + return 0;
13273 +}
13274 +
13275 +static int xgmac_init_phy(struct net_device *net_dev,
13276 + struct mac_device *mac_dev)
13277 +{
13278 + struct phy_device *phy_dev;
13279 +
13280 + if (of_phy_is_fixed_link(mac_dev->phy_node))
13281 + phy_dev = of_phy_attach(net_dev, mac_dev->phy_node,
13282 + 0, mac_dev->phy_if);
13283 + else
13284 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
13285 + &adjust_link_void, 0, mac_dev->phy_if);
13286 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
13287 + netdev_err(net_dev, "Could not attach to PHY %s\n",
13288 + mac_dev->phy_node ?
13289 + mac_dev->phy_node->full_name :
13290 + mac_dev->fixed_bus_id);
13291 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
13292 + }
13293 +
13294 + phy_dev->supported &= mac_dev->if_support;
13295 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
13296 + * as most of the PHY drivers do not enable them by default.
13297 + */
13298 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
13299 + phy_dev->advertising = phy_dev->supported;
13300 +
13301 + mac_dev->phy_dev = phy_dev;
13302 +
13303 + return 0;
13304 +}
13305 +
13306 +static int memac_init_phy(struct net_device *net_dev,
13307 + struct mac_device *mac_dev)
13308 +{
13309 + struct phy_device *phy_dev;
13310 + void (*adjust_link_handler)(struct net_device *);
13311 +
13312 + if ((macdev2enetinterface(mac_dev) == e_ENET_MODE_XGMII_10000) ||
13313 + (macdev2enetinterface(mac_dev) == e_ENET_MODE_SGMII_2500)) {
13314 + /* Pass a void link state handler to the PHY state machine
13315 + * for XGMII (10G) and SGMII 2.5G, as the hardware does not
13316 + * permit dynamic link speed adjustments. */
13317 + adjust_link_handler = adjust_link_void;
13318 + } else if (macdev2enetinterface(mac_dev) & e_ENET_IF_RGMII) {
13319 + /* Regular RGMII ports connected to a PHY, as well as
13320 + * ports that are marked as "fixed-link" in the DTS,
13321 + * will have the adjust_link callback. This calls
13322 + * fman_memac_adjust_link in order to configure the
13323 + * IF_MODE register, which is needed in both cases.
13324 + */
13325 + adjust_link_handler = adjust_link;
13326 + } else if (of_phy_is_fixed_link(mac_dev->phy_node)) {
13327 + /* Pass a void link state handler for fixed-link
13328 + * interfaces that are not RGMII. Only RGMII has been
13329 + * tested and confirmed to work with fixed-link. Other
13330 + * MII interfaces may need further work.
13331 + * TODO: Change this as needed.
13332 + */
13333 + adjust_link_handler = adjust_link_void;
13334 + } else {
13335 + /* MII, RMII, SMII, GMII, SGMII, BASEX ports,
13336 + * that are NOT fixed-link.
13337 + * TODO: May not be needed for interfaces that
13338 + * pass through the SerDes block (*SGMII, XFI).
13339 + */
13340 + adjust_link_handler = adjust_link;
13341 + }
13342 + phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
13343 + adjust_link_handler, 0,
13344 + mac_dev->phy_if);
13345 +
13346 + if (unlikely(phy_dev == NULL) || IS_ERR(phy_dev)) {
13347 + netdev_err(net_dev, "Could not connect to PHY %s\n",
13348 + mac_dev->phy_node ?
13349 + mac_dev->phy_node->full_name :
13350 + mac_dev->fixed_bus_id);
13351 + return phy_dev == NULL ? -ENODEV : PTR_ERR(phy_dev);
13352 + }
13353 +
13354 + /* Remove any features not supported by the controller */
13355 + phy_dev->supported &= mac_dev->if_support;
13356 + /* Enable the symmetric and asymmetric PAUSE frame advertisements,
13357 + * as most of the PHY drivers do not enable them by default.
13358 + */
13359 + phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
13360 + phy_dev->advertising = phy_dev->supported;
13361 +
13362 + mac_dev->phy_dev = phy_dev;
13363 +
13364 + return 0;
13365 +}
13366 +
13367 +static int __cold uninit(struct fm_mac_dev *fm_mac_dev)
13368 +{
13369 + int _errno, __errno;
13370 +
13371 + _errno = fm_mac_disable(fm_mac_dev);
13372 + __errno = fm_mac_free(fm_mac_dev);
13373 +
13374 + if (unlikely(__errno < 0))
13375 + _errno = __errno;
13376 +
13377 + return _errno;
13378 +}
13379 +
13380 +static struct fm_mac_dev *get_mac_handle(struct mac_device *mac_dev)
13381 +{
13382 + const struct mac_priv_s *priv;
13383 + priv = macdev_priv(mac_dev);
13384 + return priv->fm_mac;
13385 +}
13386 +
13387 +static int dtsec_dump_regs(struct mac_device *h_mac, char *buf, int nn)
13388 +{
13389 + struct dtsec_regs *p_mm = (struct dtsec_regs *) h_mac->vaddr;
13390 + int i = 0, n = nn;
13391 +
13392 + FM_DMP_SUBTITLE(buf, n, "\n");
13393 +
13394 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - DTSEC-%d", h_mac->cell_index);
13395 +
13396 + FM_DMP_V32(buf, n, p_mm, tsec_id);
13397 + FM_DMP_V32(buf, n, p_mm, tsec_id2);
13398 + FM_DMP_V32(buf, n, p_mm, ievent);
13399 + FM_DMP_V32(buf, n, p_mm, imask);
13400 + FM_DMP_V32(buf, n, p_mm, ecntrl);
13401 + FM_DMP_V32(buf, n, p_mm, ptv);
13402 + FM_DMP_V32(buf, n, p_mm, tmr_ctrl);
13403 + FM_DMP_V32(buf, n, p_mm, tmr_pevent);
13404 + FM_DMP_V32(buf, n, p_mm, tmr_pemask);
13405 + FM_DMP_V32(buf, n, p_mm, tctrl);
13406 + FM_DMP_V32(buf, n, p_mm, rctrl);
13407 + FM_DMP_V32(buf, n, p_mm, maccfg1);
13408 + FM_DMP_V32(buf, n, p_mm, maccfg2);
13409 + FM_DMP_V32(buf, n, p_mm, ipgifg);
13410 + FM_DMP_V32(buf, n, p_mm, hafdup);
13411 + FM_DMP_V32(buf, n, p_mm, maxfrm);
13412 +
13413 + FM_DMP_V32(buf, n, p_mm, macstnaddr1);
13414 + FM_DMP_V32(buf, n, p_mm, macstnaddr2);
13415 +
13416 + for (i = 0; i < 7; ++i) {
13417 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match1);
13418 + FM_DMP_V32(buf, n, p_mm, macaddr[i].exact_match2);
13419 + }
13420 +
13421 + FM_DMP_V32(buf, n, p_mm, car1);
13422 + FM_DMP_V32(buf, n, p_mm, car2);
13423 +
13424 + return n;
13425 +}
13426 +
13427 +static int xgmac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
13428 +{
13429 + struct tgec_regs *p_mm = (struct tgec_regs *) h_mac->vaddr;
13430 + int n = nn;
13431 +
13432 + FM_DMP_SUBTITLE(buf, n, "\n");
13433 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - TGEC -%d", h_mac->cell_index);
13434 +
13435 + FM_DMP_V32(buf, n, p_mm, tgec_id);
13436 + FM_DMP_V32(buf, n, p_mm, command_config);
13437 + FM_DMP_V32(buf, n, p_mm, mac_addr_0);
13438 + FM_DMP_V32(buf, n, p_mm, mac_addr_1);
13439 + FM_DMP_V32(buf, n, p_mm, maxfrm);
13440 + FM_DMP_V32(buf, n, p_mm, pause_quant);
13441 + FM_DMP_V32(buf, n, p_mm, rx_fifo_sections);
13442 + FM_DMP_V32(buf, n, p_mm, tx_fifo_sections);
13443 + FM_DMP_V32(buf, n, p_mm, rx_fifo_almost_f_e);
13444 + FM_DMP_V32(buf, n, p_mm, tx_fifo_almost_f_e);
13445 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
13446 + FM_DMP_V32(buf, n, p_mm, mdio_cfg_status);
13447 + FM_DMP_V32(buf, n, p_mm, mdio_command);
13448 + FM_DMP_V32(buf, n, p_mm, mdio_data);
13449 + FM_DMP_V32(buf, n, p_mm, mdio_regaddr);
13450 + FM_DMP_V32(buf, n, p_mm, status);
13451 + FM_DMP_V32(buf, n, p_mm, tx_ipg_len);
13452 + FM_DMP_V32(buf, n, p_mm, mac_addr_2);
13453 + FM_DMP_V32(buf, n, p_mm, mac_addr_3);
13454 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_rd);
13455 + FM_DMP_V32(buf, n, p_mm, rx_fifo_ptr_wr);
13456 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_rd);
13457 + FM_DMP_V32(buf, n, p_mm, tx_fifo_ptr_wr);
13458 + FM_DMP_V32(buf, n, p_mm, imask);
13459 + FM_DMP_V32(buf, n, p_mm, ievent);
13460 +
13461 + return n;
13462 +}
13463 +
13464 +static int memac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
13465 +{
13466 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
13467 + int i = 0, n = nn;
13468 +
13469 + FM_DMP_SUBTITLE(buf, n, "\n");
13470 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d", h_mac->cell_index);
13471 +
13472 + FM_DMP_V32(buf, n, p_mm, command_config);
13473 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_l);
13474 + FM_DMP_V32(buf, n, p_mm, mac_addr0.mac_addr_u);
13475 + FM_DMP_V32(buf, n, p_mm, maxfrm);
13476 + FM_DMP_V32(buf, n, p_mm, hashtable_ctrl);
13477 + FM_DMP_V32(buf, n, p_mm, ievent);
13478 + FM_DMP_V32(buf, n, p_mm, tx_ipg_length);
13479 + FM_DMP_V32(buf, n, p_mm, imask);
13480 +
13481 + for (i = 0; i < 4; ++i)
13482 + FM_DMP_V32(buf, n, p_mm, pause_quanta[i]);
13483 +
13484 + for (i = 0; i < 4; ++i)
13485 + FM_DMP_V32(buf, n, p_mm, pause_thresh[i]);
13486 +
13487 + FM_DMP_V32(buf, n, p_mm, rx_pause_status);
13488 +
13489 + for (i = 0; i < MEMAC_NUM_OF_PADDRS; ++i) {
13490 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_l);
13491 + FM_DMP_V32(buf, n, p_mm, mac_addr[i].mac_addr_u);
13492 + }
13493 +
13494 + FM_DMP_V32(buf, n, p_mm, lpwake_timer);
13495 + FM_DMP_V32(buf, n, p_mm, sleep_timer);
13496 + FM_DMP_V32(buf, n, p_mm, statn_config);
13497 + FM_DMP_V32(buf, n, p_mm, if_mode);
13498 + FM_DMP_V32(buf, n, p_mm, if_status);
13499 + FM_DMP_V32(buf, n, p_mm, hg_config);
13500 + FM_DMP_V32(buf, n, p_mm, hg_pause_quanta);
13501 + FM_DMP_V32(buf, n, p_mm, hg_pause_thresh);
13502 + FM_DMP_V32(buf, n, p_mm, hgrx_pause_status);
13503 + FM_DMP_V32(buf, n, p_mm, hg_fifos_status);
13504 + FM_DMP_V32(buf, n, p_mm, rhm);
13505 + FM_DMP_V32(buf, n, p_mm, thm);
13506 +
13507 + return n;
13508 +}
13509 +
13510 +static int memac_dump_regs_rx(struct mac_device *h_mac, char *buf, int nn)
13511 +{
13512 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
13513 + int n = nn;
13514 +
13515 + FM_DMP_SUBTITLE(buf, n, "\n");
13516 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Rx stats", h_mac->cell_index);
13517 +
13518 + /* Rx Statistics Counter */
13519 + FM_DMP_V32(buf, n, p_mm, reoct_l);
13520 + FM_DMP_V32(buf, n, p_mm, reoct_u);
13521 + FM_DMP_V32(buf, n, p_mm, roct_l);
13522 + FM_DMP_V32(buf, n, p_mm, roct_u);
13523 + FM_DMP_V32(buf, n, p_mm, raln_l);
13524 + FM_DMP_V32(buf, n, p_mm, raln_u);
13525 + FM_DMP_V32(buf, n, p_mm, rxpf_l);
13526 + FM_DMP_V32(buf, n, p_mm, rxpf_u);
13527 + FM_DMP_V32(buf, n, p_mm, rfrm_l);
13528 + FM_DMP_V32(buf, n, p_mm, rfrm_u);
13529 + FM_DMP_V32(buf, n, p_mm, rfcs_l);
13530 + FM_DMP_V32(buf, n, p_mm, rfcs_u);
13531 + FM_DMP_V32(buf, n, p_mm, rvlan_l);
13532 + FM_DMP_V32(buf, n, p_mm, rvlan_u);
13533 + FM_DMP_V32(buf, n, p_mm, rerr_l);
13534 + FM_DMP_V32(buf, n, p_mm, rerr_u);
13535 + FM_DMP_V32(buf, n, p_mm, ruca_l);
13536 + FM_DMP_V32(buf, n, p_mm, ruca_u);
13537 + FM_DMP_V32(buf, n, p_mm, rmca_l);
13538 + FM_DMP_V32(buf, n, p_mm, rmca_u);
13539 + FM_DMP_V32(buf, n, p_mm, rbca_l);
13540 + FM_DMP_V32(buf, n, p_mm, rbca_u);
13541 + FM_DMP_V32(buf, n, p_mm, rdrp_l);
13542 + FM_DMP_V32(buf, n, p_mm, rdrp_u);
13543 + FM_DMP_V32(buf, n, p_mm, rpkt_l);
13544 + FM_DMP_V32(buf, n, p_mm, rpkt_u);
13545 + FM_DMP_V32(buf, n, p_mm, rund_l);
13546 + FM_DMP_V32(buf, n, p_mm, rund_u);
13547 + FM_DMP_V32(buf, n, p_mm, r64_l);
13548 + FM_DMP_V32(buf, n, p_mm, r64_u);
13549 + FM_DMP_V32(buf, n, p_mm, r127_l);
13550 + FM_DMP_V32(buf, n, p_mm, r127_u);
13551 + FM_DMP_V32(buf, n, p_mm, r255_l);
13552 + FM_DMP_V32(buf, n, p_mm, r255_u);
13553 + FM_DMP_V32(buf, n, p_mm, r511_l);
13554 + FM_DMP_V32(buf, n, p_mm, r511_u);
13555 + FM_DMP_V32(buf, n, p_mm, r1023_l);
13556 + FM_DMP_V32(buf, n, p_mm, r1023_u);
13557 + FM_DMP_V32(buf, n, p_mm, r1518_l);
13558 + FM_DMP_V32(buf, n, p_mm, r1518_u);
13559 + FM_DMP_V32(buf, n, p_mm, r1519x_l);
13560 + FM_DMP_V32(buf, n, p_mm, r1519x_u);
13561 + FM_DMP_V32(buf, n, p_mm, rovr_l);
13562 + FM_DMP_V32(buf, n, p_mm, rovr_u);
13563 + FM_DMP_V32(buf, n, p_mm, rjbr_l);
13564 + FM_DMP_V32(buf, n, p_mm, rjbr_u);
13565 + FM_DMP_V32(buf, n, p_mm, rfrg_l);
13566 + FM_DMP_V32(buf, n, p_mm, rfrg_u);
13567 + FM_DMP_V32(buf, n, p_mm, rcnp_l);
13568 + FM_DMP_V32(buf, n, p_mm, rcnp_u);
13569 + FM_DMP_V32(buf, n, p_mm, rdrntp_l);
13570 + FM_DMP_V32(buf, n, p_mm, rdrntp_u);
13571 +
13572 + return n;
13573 +}
13574 +
13575 +static int memac_dump_regs_tx(struct mac_device *h_mac, char *buf, int nn)
13576 +{
13577 + struct memac_regs *p_mm = (struct memac_regs *) h_mac->vaddr;
13578 + int n = nn;
13579 +
13580 + FM_DMP_SUBTITLE(buf, n, "\n");
13581 + FM_DMP_TITLE(buf, n, p_mm, "FM MAC - MEMAC -%d Tx stats", h_mac->cell_index);
13582 +
13583 +
13584 + /* Tx Statistics Counter */
13585 + FM_DMP_V32(buf, n, p_mm, teoct_l);
13586 + FM_DMP_V32(buf, n, p_mm, teoct_u);
13587 + FM_DMP_V32(buf, n, p_mm, toct_l);
13588 + FM_DMP_V32(buf, n, p_mm, toct_u);
13589 + FM_DMP_V32(buf, n, p_mm, txpf_l);
13590 + FM_DMP_V32(buf, n, p_mm, txpf_u);
13591 + FM_DMP_V32(buf, n, p_mm, tfrm_l);
13592 + FM_DMP_V32(buf, n, p_mm, tfrm_u);
13593 + FM_DMP_V32(buf, n, p_mm, tfcs_l);
13594 + FM_DMP_V32(buf, n, p_mm, tfcs_u);
13595 + FM_DMP_V32(buf, n, p_mm, tvlan_l);
13596 + FM_DMP_V32(buf, n, p_mm, tvlan_u);
13597 + FM_DMP_V32(buf, n, p_mm, terr_l);
13598 + FM_DMP_V32(buf, n, p_mm, terr_u);
13599 + FM_DMP_V32(buf, n, p_mm, tuca_l);
13600 + FM_DMP_V32(buf, n, p_mm, tuca_u);
13601 + FM_DMP_V32(buf, n, p_mm, tmca_l);
13602 + FM_DMP_V32(buf, n, p_mm, tmca_u);
13603 + FM_DMP_V32(buf, n, p_mm, tbca_l);
13604 + FM_DMP_V32(buf, n, p_mm, tbca_u);
13605 + FM_DMP_V32(buf, n, p_mm, tpkt_l);
13606 + FM_DMP_V32(buf, n, p_mm, tpkt_u);
13607 + FM_DMP_V32(buf, n, p_mm, tund_l);
13608 + FM_DMP_V32(buf, n, p_mm, tund_u);
13609 + FM_DMP_V32(buf, n, p_mm, t64_l);
13610 + FM_DMP_V32(buf, n, p_mm, t64_u);
13611 + FM_DMP_V32(buf, n, p_mm, t127_l);
13612 + FM_DMP_V32(buf, n, p_mm, t127_u);
13613 + FM_DMP_V32(buf, n, p_mm, t255_l);
13614 + FM_DMP_V32(buf, n, p_mm, t255_u);
13615 + FM_DMP_V32(buf, n, p_mm, t511_l);
13616 + FM_DMP_V32(buf, n, p_mm, t511_u);
13617 + FM_DMP_V32(buf, n, p_mm, t1023_l);
13618 + FM_DMP_V32(buf, n, p_mm, t1023_u);
13619 + FM_DMP_V32(buf, n, p_mm, t1518_l);
13620 + FM_DMP_V32(buf, n, p_mm, t1518_u);
13621 + FM_DMP_V32(buf, n, p_mm, t1519x_l);
13622 + FM_DMP_V32(buf, n, p_mm, t1519x_u);
13623 + FM_DMP_V32(buf, n, p_mm, tcnp_l);
13624 + FM_DMP_V32(buf, n, p_mm, tcnp_u);
13625 +
13626 + return n;
13627 +}
13628 +
13629 +int fm_mac_dump_regs(struct mac_device *h_mac, char *buf, int nn)
13630 +{
13631 + int n = nn;
13632 +
13633 + n = h_mac->dump_mac_regs(h_mac, buf, n);
13634 +
13635 + return n;
13636 +}
13637 +EXPORT_SYMBOL(fm_mac_dump_regs);
13638 +
13639 +int fm_mac_dump_rx_stats(struct mac_device *h_mac, char *buf, int nn)
13640 +{
13641 + int n = nn;
13642 +
13643 + if(h_mac->dump_mac_rx_stats)
13644 + n = h_mac->dump_mac_rx_stats(h_mac, buf, n);
13645 +
13646 + return n;
13647 +}
13648 +EXPORT_SYMBOL(fm_mac_dump_rx_stats);
13649 +
13650 +int fm_mac_dump_tx_stats(struct mac_device *h_mac, char *buf, int nn)
13651 +{
13652 + int n = nn;
13653 +
13654 + if(h_mac->dump_mac_tx_stats)
13655 + n = h_mac->dump_mac_tx_stats(h_mac, buf, n);
13656 +
13657 + return n;
13658 +}
13659 +EXPORT_SYMBOL(fm_mac_dump_tx_stats);
13660 +
13661 +static void __cold setup_dtsec(struct mac_device *mac_dev)
13662 +{
13663 + mac_dev->init_phy = dtsec_init_phy;
13664 + mac_dev->init = init;
13665 + mac_dev->start = start;
13666 + mac_dev->stop = stop;
13667 + mac_dev->set_promisc = fm_mac_set_promiscuous;
13668 + mac_dev->change_addr = fm_mac_modify_mac_addr;
13669 + mac_dev->set_multi = set_multi;
13670 + mac_dev->uninit = uninit;
13671 + mac_dev->ptp_enable = fm_mac_enable_1588_time_stamp;
13672 + mac_dev->ptp_disable = fm_mac_disable_1588_time_stamp;
13673 + mac_dev->get_mac_handle = get_mac_handle;
13674 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
13675 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
13676 + mac_dev->fm_rtc_enable = fm_rtc_enable;
13677 + mac_dev->fm_rtc_disable = fm_rtc_disable;
13678 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
13679 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
13680 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
13681 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
13682 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
13683 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
13684 + mac_dev->set_wol = fm_mac_set_wol;
13685 + mac_dev->dump_mac_regs = dtsec_dump_regs;
13686 +}
13687 +
13688 +static void __cold setup_xgmac(struct mac_device *mac_dev)
13689 +{
13690 + mac_dev->init_phy = xgmac_init_phy;
13691 + mac_dev->init = init;
13692 + mac_dev->start = start;
13693 + mac_dev->stop = stop;
13694 + mac_dev->set_promisc = fm_mac_set_promiscuous;
13695 + mac_dev->change_addr = fm_mac_modify_mac_addr;
13696 + mac_dev->set_multi = set_multi;
13697 + mac_dev->uninit = uninit;
13698 + mac_dev->get_mac_handle = get_mac_handle;
13699 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
13700 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
13701 + mac_dev->set_wol = fm_mac_set_wol;
13702 + mac_dev->dump_mac_regs = xgmac_dump_regs;
13703 +}
13704 +
13705 +static void __cold setup_memac(struct mac_device *mac_dev)
13706 +{
13707 + mac_dev->init_phy = memac_init_phy;
13708 + mac_dev->init = memac_init;
13709 + mac_dev->start = start;
13710 + mac_dev->stop = stop;
13711 + mac_dev->set_promisc = fm_mac_set_promiscuous;
13712 + mac_dev->change_addr = fm_mac_modify_mac_addr;
13713 + mac_dev->set_multi = set_multi;
13714 + mac_dev->uninit = uninit;
13715 + mac_dev->get_mac_handle = get_mac_handle;
13716 + mac_dev->set_tx_pause = fm_mac_set_tx_pause_frames;
13717 + mac_dev->set_rx_pause = fm_mac_set_rx_pause_frames;
13718 + mac_dev->fm_rtc_enable = fm_rtc_enable;
13719 + mac_dev->fm_rtc_disable = fm_rtc_disable;
13720 + mac_dev->fm_rtc_get_cnt = fm_rtc_get_cnt;
13721 + mac_dev->fm_rtc_set_cnt = fm_rtc_set_cnt;
13722 + mac_dev->fm_rtc_get_drift = fm_rtc_get_drift;
13723 + mac_dev->fm_rtc_set_drift = fm_rtc_set_drift;
13724 + mac_dev->fm_rtc_set_alarm = fm_rtc_set_alarm;
13725 + mac_dev->fm_rtc_set_fiper = fm_rtc_set_fiper;
13726 + mac_dev->set_wol = fm_mac_set_wol;
13727 + mac_dev->dump_mac_regs = memac_dump_regs;
13728 + mac_dev->dump_mac_rx_stats = memac_dump_regs_rx;
13729 + mac_dev->dump_mac_tx_stats = memac_dump_regs_tx;
13730 +}
13731 +
13732 +void (*const mac_setup[])(struct mac_device *mac_dev) = {
13733 + [DTSEC] = setup_dtsec,
13734 + [XGMAC] = setup_xgmac,
13735 + [MEMAC] = setup_memac
13736 +};
13737 --- /dev/null
13738 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.c
13739 @@ -0,0 +1,490 @@
13740 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
13741 + *
13742 + * Redistribution and use in source and binary forms, with or without
13743 + * modification, are permitted provided that the following conditions are met:
13744 + * * Redistributions of source code must retain the above copyright
13745 + * notice, this list of conditions and the following disclaimer.
13746 + * * Redistributions in binary form must reproduce the above copyright
13747 + * notice, this list of conditions and the following disclaimer in the
13748 + * documentation and/or other materials provided with the distribution.
13749 + * * Neither the name of Freescale Semiconductor nor the
13750 + * names of its contributors may be used to endorse or promote products
13751 + * derived from this software without specific prior written permission.
13752 + *
13753 + *
13754 + * ALTERNATIVELY, this software may be distributed under the terms of the
13755 + * GNU General Public License ("GPL") as published by the Free Software
13756 + * Foundation, either version 2 of that License or (at your option) any
13757 + * later version.
13758 + *
13759 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
13760 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13761 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
13762 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
13763 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13764 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
13765 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
13766 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13767 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
13768 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13769 + */
13770 +
13771 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
13772 +#define pr_fmt(fmt) \
13773 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
13774 + KBUILD_BASENAME".c", __LINE__, __func__
13775 +#else
13776 +#define pr_fmt(fmt) \
13777 + KBUILD_MODNAME ": " fmt
13778 +#endif
13779 +
13780 +#include <linux/init.h>
13781 +#include <linux/module.h>
13782 +#include <linux/of_address.h>
13783 +#include <linux/of_platform.h>
13784 +#include <linux/of_net.h>
13785 +#include <linux/of_mdio.h>
13786 +#include <linux/phy_fixed.h>
13787 +#include <linux/device.h>
13788 +#include <linux/phy.h>
13789 +#include <linux/io.h>
13790 +
13791 +#include "lnxwrp_fm_ext.h"
13792 +
13793 +#include "mac.h"
13794 +
13795 +#define DTSEC_SUPPORTED \
13796 + (SUPPORTED_10baseT_Half \
13797 + | SUPPORTED_10baseT_Full \
13798 + | SUPPORTED_100baseT_Half \
13799 + | SUPPORTED_100baseT_Full \
13800 + | SUPPORTED_Autoneg \
13801 + | SUPPORTED_Pause \
13802 + | SUPPORTED_Asym_Pause \
13803 + | SUPPORTED_MII)
13804 +
13805 +static const char phy_str[][11] = {
13806 + [PHY_INTERFACE_MODE_MII] = "mii",
13807 + [PHY_INTERFACE_MODE_GMII] = "gmii",
13808 + [PHY_INTERFACE_MODE_SGMII] = "sgmii",
13809 + [PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
13810 + [PHY_INTERFACE_MODE_TBI] = "tbi",
13811 + [PHY_INTERFACE_MODE_RMII] = "rmii",
13812 + [PHY_INTERFACE_MODE_RGMII] = "rgmii",
13813 + [PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
13814 + [PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
13815 + [PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
13816 + [PHY_INTERFACE_MODE_RTBI] = "rtbi",
13817 + [PHY_INTERFACE_MODE_XGMII] = "xgmii",
13818 + [PHY_INTERFACE_MODE_2500SGMII] = "sgmii-2500",
13819 +};
13820 +
13821 +static phy_interface_t __pure __attribute__((nonnull)) str2phy(const char *str)
13822 +{
13823 + int i;
13824 +
13825 + for (i = 0; i < ARRAY_SIZE(phy_str); i++)
13826 + if (strcmp(str, phy_str[i]) == 0)
13827 + return (phy_interface_t)i;
13828 +
13829 + return PHY_INTERFACE_MODE_MII;
13830 +}
13831 +
13832 +static const uint16_t phy2speed[] = {
13833 + [PHY_INTERFACE_MODE_MII] = SPEED_100,
13834 + [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
13835 + [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
13836 + [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
13837 + [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
13838 + [PHY_INTERFACE_MODE_RMII] = SPEED_100,
13839 + [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
13840 + [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
13841 + [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
13842 + [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
13843 + [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
13844 + [PHY_INTERFACE_MODE_XGMII] = SPEED_10000,
13845 + [PHY_INTERFACE_MODE_2500SGMII] = SPEED_2500,
13846 +};
13847 +
13848 +static struct mac_device * __cold
13849 +alloc_macdev(struct device *dev, size_t sizeof_priv,
13850 + void (*setup)(struct mac_device *mac_dev))
13851 +{
13852 + struct mac_device *mac_dev;
13853 +
13854 + mac_dev = devm_kzalloc(dev, sizeof(*mac_dev) + sizeof_priv, GFP_KERNEL);
13855 + if (unlikely(mac_dev == NULL))
13856 + mac_dev = ERR_PTR(-ENOMEM);
13857 + else {
13858 + mac_dev->dev = dev;
13859 + dev_set_drvdata(dev, mac_dev);
13860 + setup(mac_dev);
13861 + }
13862 +
13863 + return mac_dev;
13864 +}
13865 +
13866 +static int __cold free_macdev(struct mac_device *mac_dev)
13867 +{
13868 + dev_set_drvdata(mac_dev->dev, NULL);
13869 +
13870 + return mac_dev->uninit(mac_dev->get_mac_handle(mac_dev));
13871 +}
13872 +
13873 +static const struct of_device_id mac_match[] = {
13874 + [DTSEC] = {
13875 + .compatible = "fsl,fman-dtsec"
13876 + },
13877 + [XGMAC] = {
13878 + .compatible = "fsl,fman-xgec"
13879 + },
13880 + [MEMAC] = {
13881 + .compatible = "fsl,fman-memac"
13882 + },
13883 + {}
13884 +};
13885 +MODULE_DEVICE_TABLE(of, mac_match);
13886 +
13887 +static int __cold mac_probe(struct platform_device *_of_dev)
13888 +{
13889 + int _errno, i;
13890 + struct device *dev;
13891 + struct device_node *mac_node, *dev_node;
13892 + struct mac_device *mac_dev;
13893 + struct platform_device *of_dev;
13894 + struct resource res;
13895 + const uint8_t *mac_addr;
13896 + const char *char_prop;
13897 + int nph;
13898 + u32 cell_index;
13899 + const struct of_device_id *match;
13900 +
13901 + dev = &_of_dev->dev;
13902 + mac_node = dev->of_node;
13903 +
13904 + match = of_match_device(mac_match, dev);
13905 + if (!match)
13906 + return -EINVAL;
13907 +
13908 + for (i = 0; i < ARRAY_SIZE(mac_match) - 1 && match != mac_match + i;
13909 + i++)
13910 + ;
13911 + BUG_ON(i >= ARRAY_SIZE(mac_match) - 1);
13912 +
13913 + mac_dev = alloc_macdev(dev, mac_sizeof_priv[i], mac_setup[i]);
13914 + if (IS_ERR(mac_dev)) {
13915 + _errno = PTR_ERR(mac_dev);
13916 + dev_err(dev, "alloc_macdev() = %d\n", _errno);
13917 + goto _return;
13918 + }
13919 +
13920 + INIT_LIST_HEAD(&mac_dev->mc_addr_list);
13921 +
13922 + /* Get the FM node */
13923 + dev_node = of_get_parent(mac_node);
13924 + if (unlikely(dev_node == NULL)) {
13925 + dev_err(dev, "of_get_parent(%s) failed\n",
13926 + mac_node->full_name);
13927 + _errno = -EINVAL;
13928 + goto _return_dev_set_drvdata;
13929 + }
13930 +
13931 + of_dev = of_find_device_by_node(dev_node);
13932 + if (unlikely(of_dev == NULL)) {
13933 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
13934 + dev_node->full_name);
13935 + _errno = -EINVAL;
13936 + goto _return_of_node_put;
13937 + }
13938 +
13939 + mac_dev->fm_dev = fm_bind(&of_dev->dev);
13940 + if (unlikely(mac_dev->fm_dev == NULL)) {
13941 + dev_err(dev, "fm_bind(%s) failed\n", dev_node->full_name);
13942 + _errno = -ENODEV;
13943 + goto _return_of_node_put;
13944 + }
13945 +
13946 + mac_dev->fm = (void *)fm_get_handle(mac_dev->fm_dev);
13947 + of_node_put(dev_node);
13948 +
13949 + /* Get the address of the memory mapped registers */
13950 + _errno = of_address_to_resource(mac_node, 0, &res);
13951 + if (unlikely(_errno < 0)) {
13952 + dev_err(dev, "of_address_to_resource(%s) = %d\n",
13953 + mac_node->full_name, _errno);
13954 + goto _return_dev_set_drvdata;
13955 + }
13956 +
13957 + mac_dev->res = __devm_request_region(
13958 + dev,
13959 + fm_get_mem_region(mac_dev->fm_dev),
13960 + res.start, res.end + 1 - res.start, "mac");
13961 + if (unlikely(mac_dev->res == NULL)) {
13962 + dev_err(dev, "__devm_request_mem_region(mac) failed\n");
13963 + _errno = -EBUSY;
13964 + goto _return_dev_set_drvdata;
13965 + }
13966 +
13967 + mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
13968 + mac_dev->res->end + 1
13969 + - mac_dev->res->start);
13970 + if (unlikely(mac_dev->vaddr == NULL)) {
13971 + dev_err(dev, "devm_ioremap() failed\n");
13972 + _errno = -EIO;
13973 + goto _return_dev_set_drvdata;
13974 + }
13975 +
13976 +#define TBIPA_OFFSET 0x1c
13977 +#define TBIPA_DEFAULT_ADDR 5 /* override if used as external PHY addr. */
13978 + mac_dev->tbi_node = of_parse_phandle(mac_node, "tbi-handle", 0);
13979 + if (mac_dev->tbi_node) {
13980 + u32 tbiaddr = TBIPA_DEFAULT_ADDR;
13981 + const __be32 *tbi_reg;
13982 + void __iomem *addr;
13983 +
13984 + tbi_reg = of_get_property(mac_dev->tbi_node, "reg", NULL);
13985 + if (tbi_reg)
13986 + tbiaddr = be32_to_cpup(tbi_reg);
13987 + addr = mac_dev->vaddr + TBIPA_OFFSET;
13988 + /* TODO: out_be32 does not exist on ARM */
13989 + out_be32(addr, tbiaddr);
13990 + }
13991 +
13992 + if (!of_device_is_available(mac_node)) {
13993 + devm_iounmap(dev, mac_dev->vaddr);
13994 + __devm_release_region(dev, fm_get_mem_region(mac_dev->fm_dev),
13995 + res.start, res.end + 1 - res.start);
13996 + fm_unbind(mac_dev->fm_dev);
13997 + devm_kfree(dev, mac_dev);
13998 + dev_set_drvdata(dev, NULL);
13999 + return -ENODEV;
14000 + }
14001 +
14002 + /* Get the cell-index */
14003 + _errno = of_property_read_u32(mac_node, "cell-index", &cell_index);
14004 + if (unlikely(_errno)) {
14005 + dev_err(dev, "Cannot read cell-index of mac node %s from device tree\n",
14006 + mac_node->full_name);
14007 + goto _return_dev_set_drvdata;
14008 + }
14009 + mac_dev->cell_index = (uint8_t)cell_index;
14010 + if (mac_dev->cell_index >= 8)
14011 + mac_dev->cell_index -= 8;
14012 +
14013 + /* Get the MAC address */
14014 + mac_addr = of_get_mac_address(mac_node);
14015 + if (unlikely(mac_addr == NULL)) {
14016 + dev_err(dev, "of_get_mac_address(%s) failed\n",
14017 + mac_node->full_name);
14018 + _errno = -EINVAL;
14019 + goto _return_dev_set_drvdata;
14020 + }
14021 + memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
14022 +
14023 + /* Verify the number of port handles */
14024 + nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
14025 + if (unlikely(nph < 0)) {
14026 + dev_err(dev, "Cannot read port handles of mac node %s from device tree\n",
14027 + mac_node->full_name);
14028 + _errno = nph;
14029 + goto _return_dev_set_drvdata;
14030 + }
14031 +
14032 + if (nph != ARRAY_SIZE(mac_dev->port_dev)) {
14033 + dev_err(dev, "Not supported number of port handles of mac node %s from device tree\n",
14034 + mac_node->full_name);
14035 + _errno = -EINVAL;
14036 + goto _return_dev_set_drvdata;
14037 + }
14038 +
14039 + for_each_port_device(i, mac_dev->port_dev) {
14040 + dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
14041 + if (unlikely(dev_node == NULL)) {
14042 + dev_err(dev, "Cannot find port node referenced by mac node %s from device tree\n",
14043 + mac_node->full_name);
14044 + _errno = -EINVAL;
14045 + goto _return_of_node_put;
14046 + }
14047 +
14048 + of_dev = of_find_device_by_node(dev_node);
14049 + if (unlikely(of_dev == NULL)) {
14050 + dev_err(dev, "of_find_device_by_node(%s) failed\n",
14051 + dev_node->full_name);
14052 + _errno = -EINVAL;
14053 + goto _return_of_node_put;
14054 + }
14055 +
14056 + mac_dev->port_dev[i] = fm_port_bind(&of_dev->dev);
14057 + if (unlikely(mac_dev->port_dev[i] == NULL)) {
14058 + dev_err(dev, "dev_get_drvdata(%s) failed\n",
14059 + dev_node->full_name);
14060 + _errno = -EINVAL;
14061 + goto _return_of_node_put;
14062 + }
14063 + of_node_put(dev_node);
14064 + }
14065 +
14066 + /* Get the PHY connection type */
14067 + _errno = of_property_read_string(mac_node, "phy-connection-type",
14068 + &char_prop);
14069 + if (unlikely(_errno)) {
14070 + dev_warn(dev,
14071 + "Cannot read PHY connection type of mac node %s from device tree. Defaulting to MII\n",
14072 + mac_node->full_name);
14073 + mac_dev->phy_if = PHY_INTERFACE_MODE_MII;
14074 + } else
14075 + mac_dev->phy_if = str2phy(char_prop);
14076 +
14077 + mac_dev->link = false;
14078 + mac_dev->half_duplex = false;
14079 + mac_dev->speed = phy2speed[mac_dev->phy_if];
14080 + mac_dev->max_speed = mac_dev->speed;
14081 + mac_dev->if_support = DTSEC_SUPPORTED;
14082 + /* We don't support half-duplex in SGMII mode */
14083 + if (strstr(char_prop, "sgmii") || strstr(char_prop, "qsgmii") ||
14084 + strstr(char_prop, "sgmii-2500"))
14085 + mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
14086 + SUPPORTED_100baseT_Half);
14087 +
14088 + /* Gigabit support (no half-duplex) */
14089 + if (mac_dev->max_speed == SPEED_1000 ||
14090 + mac_dev->max_speed == SPEED_2500)
14091 + mac_dev->if_support |= SUPPORTED_1000baseT_Full;
14092 +
14093 + /* The 10G interface only supports one mode */
14094 + if (strstr(char_prop, "xgmii"))
14095 + mac_dev->if_support = SUPPORTED_10000baseT_Full;
14096 +
14097 + /* Get the rest of the PHY information */
14098 + mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
14099 + if (!mac_dev->phy_node) {
14100 + struct phy_device *phy;
14101 +
14102 + if (!of_phy_is_fixed_link(mac_node)) {
14103 + dev_err(dev, "Wrong PHY information of mac node %s\n",
14104 + mac_node->full_name);
14105 + goto _return_dev_set_drvdata;
14106 + }
14107 +
14108 + _errno = of_phy_register_fixed_link(mac_node);
14109 + if (_errno)
14110 + goto _return_dev_set_drvdata;
14111 +
14112 + mac_dev->fixed_link = devm_kzalloc(mac_dev->dev,
14113 + sizeof(*mac_dev->fixed_link),
14114 + GFP_KERNEL);
14115 + if (!mac_dev->fixed_link)
14116 + goto _return_dev_set_drvdata;
14117 +
14118 + mac_dev->phy_node = of_node_get(mac_node);
14119 + phy = of_phy_find_device(mac_dev->phy_node);
14120 + if (!phy)
14121 + goto _return_dev_set_drvdata;
14122 +
14123 + mac_dev->fixed_link->link = phy->link;
14124 + mac_dev->fixed_link->speed = phy->speed;
14125 + mac_dev->fixed_link->duplex = phy->duplex;
14126 + mac_dev->fixed_link->pause = phy->pause;
14127 + mac_dev->fixed_link->asym_pause = phy->asym_pause;
14128 + printk(KERN_INFO "Setting up fixed link, speed %d duplex %d\n", mac_dev->fixed_link->speed, mac_dev->fixed_link->duplex);
14129 + }
14130 +
14131 + _errno = mac_dev->init(mac_dev);
14132 + if (unlikely(_errno < 0)) {
14133 + dev_err(dev, "mac_dev->init() = %d\n", _errno);
14134 + goto _return_dev_set_drvdata;
14135 + }
14136 +
14137 + /* pause frame autonegotiation enabled*/
14138 + mac_dev->autoneg_pause = true;
14139 +
14140 + /* by intializing the values to false, force FMD to enable PAUSE frames
14141 + * on RX and TX
14142 + */
14143 + mac_dev->rx_pause_req = mac_dev->tx_pause_req = true;
14144 + mac_dev->rx_pause_active = mac_dev->tx_pause_active = false;
14145 + _errno = set_mac_active_pause(mac_dev, true, true);
14146 + if (unlikely(_errno < 0))
14147 + dev_err(dev, "set_mac_active_pause() = %d\n", _errno);
14148 +
14149 + dev_info(dev,
14150 + "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
14151 + mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
14152 + mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
14153 +
14154 + goto _return;
14155 +
14156 +_return_of_node_put:
14157 + of_node_put(dev_node);
14158 +_return_dev_set_drvdata:
14159 + dev_set_drvdata(dev, NULL);
14160 +_return:
14161 + return _errno;
14162 +}
14163 +
14164 +static int __cold mac_remove(struct platform_device *of_dev)
14165 +{
14166 + int i, _errno;
14167 + struct device *dev;
14168 + struct mac_device *mac_dev;
14169 +
14170 + dev = &of_dev->dev;
14171 + mac_dev = (struct mac_device *)dev_get_drvdata(dev);
14172 +
14173 + for_each_port_device(i, mac_dev->port_dev)
14174 + fm_port_unbind(mac_dev->port_dev[i]);
14175 +
14176 + fm_unbind(mac_dev->fm_dev);
14177 +
14178 + _errno = free_macdev(mac_dev);
14179 +
14180 + return _errno;
14181 +}
14182 +
14183 +static struct platform_driver mac_driver = {
14184 + .driver = {
14185 + .name = KBUILD_MODNAME,
14186 + .of_match_table = mac_match,
14187 + .owner = THIS_MODULE,
14188 + },
14189 + .probe = mac_probe,
14190 + .remove = mac_remove
14191 +};
14192 +
14193 +static int __init __cold mac_load(void)
14194 +{
14195 + int _errno;
14196 +
14197 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
14198 + KBUILD_BASENAME".c", __func__);
14199 +
14200 + pr_info(KBUILD_MODNAME ": %s\n", mac_driver_description);
14201 +
14202 + _errno = platform_driver_register(&mac_driver);
14203 + if (unlikely(_errno < 0)) {
14204 + pr_err(KBUILD_MODNAME ": %s:%hu:%s(): platform_driver_register() = %d\n",
14205 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
14206 + goto _return;
14207 + }
14208 +
14209 + goto _return;
14210 +
14211 +_return:
14212 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
14213 + KBUILD_BASENAME".c", __func__);
14214 +
14215 + return _errno;
14216 +}
14217 +module_init(mac_load);
14218 +
14219 +static void __exit __cold mac_unload(void)
14220 +{
14221 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
14222 + KBUILD_BASENAME".c", __func__);
14223 +
14224 + platform_driver_unregister(&mac_driver);
14225 +
14226 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
14227 + KBUILD_BASENAME".c", __func__);
14228 +}
14229 +module_exit(mac_unload);
14230 --- /dev/null
14231 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/mac.h
14232 @@ -0,0 +1,134 @@
14233 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
14234 + *
14235 + * Redistribution and use in source and binary forms, with or without
14236 + * modification, are permitted provided that the following conditions are met:
14237 + * * Redistributions of source code must retain the above copyright
14238 + * notice, this list of conditions and the following disclaimer.
14239 + * * Redistributions in binary form must reproduce the above copyright
14240 + * notice, this list of conditions and the following disclaimer in the
14241 + * documentation and/or other materials provided with the distribution.
14242 + * * Neither the name of Freescale Semiconductor nor the
14243 + * names of its contributors may be used to endorse or promote products
14244 + * derived from this software without specific prior written permission.
14245 + *
14246 + *
14247 + * ALTERNATIVELY, this software may be distributed under the terms of the
14248 + * GNU General Public License ("GPL") as published by the Free Software
14249 + * Foundation, either version 2 of that License or (at your option) any
14250 + * later version.
14251 + *
14252 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
14253 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14254 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14255 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
14256 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14257 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14258 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14259 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14260 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14261 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14262 + */
14263 +
14264 +#ifndef __MAC_H
14265 +#define __MAC_H
14266 +
14267 +#include <linux/device.h> /* struct device, BUS_ID_SIZE */
14268 +#include <linux/if_ether.h> /* ETH_ALEN */
14269 +#include <linux/phy.h> /* phy_interface_t, struct phy_device */
14270 +#include <linux/list.h>
14271 +
14272 +#include "lnxwrp_fsl_fman.h" /* struct port_device */
14273 +
14274 +enum {DTSEC, XGMAC, MEMAC};
14275 +
14276 +struct mac_device {
14277 + struct device *dev;
14278 + void *priv;
14279 + uint8_t cell_index;
14280 + struct resource *res;
14281 + void __iomem *vaddr;
14282 + uint8_t addr[ETH_ALEN];
14283 + bool promisc;
14284 +
14285 + struct fm *fm_dev;
14286 + struct fm_port *port_dev[2];
14287 +
14288 + phy_interface_t phy_if;
14289 + u32 if_support;
14290 + bool link;
14291 + bool half_duplex;
14292 + uint16_t speed;
14293 + uint16_t max_speed;
14294 + struct device_node *phy_node;
14295 + char fixed_bus_id[MII_BUS_ID_SIZE + 3];
14296 + struct device_node *tbi_node;
14297 + struct phy_device *phy_dev;
14298 + void *fm;
14299 + /* List of multicast addresses */
14300 + struct list_head mc_addr_list;
14301 + struct fixed_phy_status *fixed_link;
14302 +
14303 + bool autoneg_pause;
14304 + bool rx_pause_req;
14305 + bool tx_pause_req;
14306 + bool rx_pause_active;
14307 + bool tx_pause_active;
14308 +
14309 + struct fm_mac_dev *(*get_mac_handle)(struct mac_device *mac_dev);
14310 + int (*init_phy)(struct net_device *net_dev, struct mac_device *mac_dev);
14311 + int (*init)(struct mac_device *mac_dev);
14312 + int (*start)(struct mac_device *mac_dev);
14313 + int (*stop)(struct mac_device *mac_dev);
14314 + int (*set_promisc)(struct fm_mac_dev *fm_mac_dev, bool enable);
14315 + int (*change_addr)(struct fm_mac_dev *fm_mac_dev, uint8_t *addr);
14316 + int (*set_multi)(struct net_device *net_dev,
14317 + struct mac_device *mac_dev);
14318 + int (*uninit)(struct fm_mac_dev *fm_mac_dev);
14319 + int (*ptp_enable)(struct fm_mac_dev *fm_mac_dev);
14320 + int (*ptp_disable)(struct fm_mac_dev *fm_mac_dev);
14321 + int (*set_rx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
14322 + int (*set_tx_pause)(struct fm_mac_dev *fm_mac_dev, bool en);
14323 + int (*fm_rtc_enable)(struct fm *fm_dev);
14324 + int (*fm_rtc_disable)(struct fm *fm_dev);
14325 + int (*fm_rtc_get_cnt)(struct fm *fm_dev, uint64_t *ts);
14326 + int (*fm_rtc_set_cnt)(struct fm *fm_dev, uint64_t ts);
14327 + int (*fm_rtc_get_drift)(struct fm *fm_dev, uint32_t *drift);
14328 + int (*fm_rtc_set_drift)(struct fm *fm_dev, uint32_t drift);
14329 + int (*fm_rtc_set_alarm)(struct fm *fm_dev, uint32_t id, uint64_t time);
14330 + int (*fm_rtc_set_fiper)(struct fm *fm_dev, uint32_t id,
14331 + uint64_t fiper);
14332 + int (*fm_rtc_enable_interrupt)(struct fm *fm_dev, uint32_t events);
14333 + int (*fm_rtc_disable_interrupt)(struct fm *fm_dev, uint32_t events);
14334 +
14335 + int (*set_wol)(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
14336 + bool en);
14337 + int (*dump_mac_regs)(struct mac_device *h_mac, char *buf, int nn);
14338 + int (*dump_mac_rx_stats)(struct mac_device *h_mac, char *buf, int nn);
14339 + int (*dump_mac_tx_stats)(struct mac_device *h_mac, char *buf, int nn);
14340 +};
14341 +
14342 +struct mac_address {
14343 + uint8_t addr[ETH_ALEN];
14344 + struct list_head list;
14345 +};
14346 +
14347 +#define get_fm_handle(net_dev) \
14348 + (((struct dpa_priv_s *)netdev_priv(net_dev))->mac_dev->fm_dev)
14349 +
14350 +#define for_each_port_device(i, port_dev) \
14351 + for (i = 0; i < ARRAY_SIZE(port_dev); i++)
14352 +
14353 +static inline __attribute((nonnull)) void *macdev_priv(
14354 + const struct mac_device *mac_dev)
14355 +{
14356 + return (void *)mac_dev + sizeof(*mac_dev);
14357 +}
14358 +
14359 +extern const char *mac_driver_description;
14360 +extern const size_t mac_sizeof_priv[];
14361 +extern void (*const mac_setup[])(struct mac_device *mac_dev);
14362 +
14363 +int set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
14364 +void get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, bool *tx_pause);
14365 +
14366 +#endif /* __MAC_H */
14367 --- /dev/null
14368 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.c
14369 @@ -0,0 +1,848 @@
14370 +/* Copyright 2011-2012 Freescale Semiconductor Inc.
14371 + *
14372 + * Redistribution and use in source and binary forms, with or without
14373 + * modification, are permitted provided that the following conditions are met:
14374 + * * Redistributions of source code must retain the above copyright
14375 + * notice, this list of conditions and the following disclaimer.
14376 + * * Redistributions in binary form must reproduce the above copyright
14377 + * notice, this list of conditions and the following disclaimer in the
14378 + * documentation and/or other materials provided with the distribution.
14379 + * * Neither the name of Freescale Semiconductor nor the
14380 + * names of its contributors may be used to endorse or promote products
14381 + * derived from this software without specific prior written permission.
14382 + *
14383 + *
14384 + * ALTERNATIVELY, this software may be distributed under the terms of the
14385 + * GNU General Public License ("GPL") as published by the Free Software
14386 + * Foundation, either version 2 of that License or (at your option) any
14387 + * later version.
14388 + *
14389 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
14390 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14391 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14392 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
14393 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
14394 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
14395 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
14396 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14397 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
14398 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14399 + */
14400 +
14401 +/* Offline Parsing / Host Command port driver for FSL QorIQ FMan.
14402 + * Validates device-tree configuration and sets up the offline ports.
14403 + */
14404 +
14405 +#ifdef CONFIG_FSL_DPAA_ETH_DEBUG
14406 +#define pr_fmt(fmt) \
14407 + KBUILD_MODNAME ": %s:%hu:%s() " fmt, \
14408 + KBUILD_BASENAME".c", __LINE__, __func__
14409 +#else
14410 +#define pr_fmt(fmt) \
14411 + KBUILD_MODNAME ": " fmt
14412 +#endif
14413 +
14414 +
14415 +#include <linux/init.h>
14416 +#include <linux/module.h>
14417 +#include <linux/of_platform.h>
14418 +#include <linux/fsl_qman.h>
14419 +
14420 +#include "offline_port.h"
14421 +#include "dpaa_eth.h"
14422 +#include "dpaa_eth_common.h"
14423 +
14424 +#define OH_MOD_DESCRIPTION "FSL FMan Offline Parsing port driver"
14425 +/* Manip extra space and data alignment for fragmentation */
14426 +#define FRAG_MANIP_SPACE 128
14427 +#define FRAG_DATA_ALIGN 64
14428 +
14429 +
14430 +MODULE_LICENSE("Dual BSD/GPL");
14431 +MODULE_AUTHOR("Bogdan Hamciuc <bogdan.hamciuc@freescale.com>");
14432 +MODULE_DESCRIPTION(OH_MOD_DESCRIPTION);
14433 +
14434 +
14435 +static const struct of_device_id oh_port_match_table[] = {
14436 + {
14437 + .compatible = "fsl,dpa-oh"
14438 + },
14439 + {
14440 + .compatible = "fsl,dpa-oh-shared"
14441 + },
14442 + {}
14443 +};
14444 +MODULE_DEVICE_TABLE(of, oh_port_match_table);
14445 +
14446 +#ifdef CONFIG_PM
14447 +
14448 +static int oh_suspend(struct device *dev)
14449 +{
14450 + struct dpa_oh_config_s *oh_config;
14451 +
14452 + oh_config = dev_get_drvdata(dev);
14453 + return fm_port_suspend(oh_config->oh_port);
14454 +}
14455 +
14456 +static int oh_resume(struct device *dev)
14457 +{
14458 + struct dpa_oh_config_s *oh_config;
14459 +
14460 + oh_config = dev_get_drvdata(dev);
14461 + return fm_port_resume(oh_config->oh_port);
14462 +}
14463 +
14464 +static const struct dev_pm_ops oh_pm_ops = {
14465 + .suspend = oh_suspend,
14466 + .resume = oh_resume,
14467 +};
14468 +
14469 +#define OH_PM_OPS (&oh_pm_ops)
14470 +
14471 +#else /* CONFIG_PM */
14472 +
14473 +#define OH_PM_OPS NULL
14474 +
14475 +#endif /* CONFIG_PM */
14476 +
14477 +/* Creates Frame Queues */
14478 +static uint32_t oh_fq_create(struct qman_fq *fq,
14479 + uint32_t fq_id, uint16_t channel,
14480 + uint16_t wq_id)
14481 +{
14482 + struct qm_mcc_initfq fq_opts;
14483 + uint32_t create_flags, init_flags;
14484 + uint32_t ret = 0;
14485 +
14486 + if (fq == NULL)
14487 + return 1;
14488 +
14489 + /* Set flags for FQ create */
14490 + create_flags = QMAN_FQ_FLAG_LOCKED | QMAN_FQ_FLAG_TO_DCPORTAL;
14491 +
14492 + /* Create frame queue */
14493 + ret = qman_create_fq(fq_id, create_flags, fq);
14494 + if (ret != 0)
14495 + return 1;
14496 +
14497 + /* Set flags for FQ init */
14498 + init_flags = QMAN_INITFQ_FLAG_SCHED;
14499 +
14500 + /* Set FQ init options. Specify destination WQ ID and channel */
14501 + fq_opts.we_mask = QM_INITFQ_WE_DESTWQ;
14502 + fq_opts.fqd.dest.wq = wq_id;
14503 + fq_opts.fqd.dest.channel = channel;
14504 +
14505 + /* Initialize frame queue */
14506 + ret = qman_init_fq(fq, init_flags, &fq_opts);
14507 + if (ret != 0) {
14508 + qman_destroy_fq(fq, 0);
14509 + return 1;
14510 + }
14511 +
14512 + return 0;
14513 +}
14514 +
14515 +static void dump_fq(struct device *dev, int fqid, uint16_t channel)
14516 +{
14517 + if (channel) {
14518 + /* display fqs with a valid (!= 0) destination channel */
14519 + dev_info(dev, "FQ ID:%d Channel ID:%d\n", fqid, channel);
14520 + }
14521 +}
14522 +
14523 +static void dump_fq_duple(struct device *dev, struct qman_fq *fqs,
14524 + int fqs_count, uint16_t channel_id)
14525 +{
14526 + int i;
14527 + for (i = 0; i < fqs_count; i++)
14528 + dump_fq(dev, (fqs + i)->fqid, channel_id);
14529 +}
14530 +
14531 +static void dump_oh_config(struct device *dev, struct dpa_oh_config_s *conf)
14532 +{
14533 + struct list_head *fq_list;
14534 + struct fq_duple *fqd;
14535 + int i;
14536 +
14537 + dev_info(dev, "Default egress frame queue: %d\n", conf->default_fqid);
14538 + dev_info(dev, "Default error frame queue: %d\n", conf->error_fqid);
14539 +
14540 + /* TX queues (old initialization) */
14541 + dev_info(dev, "Initialized queues:");
14542 + for (i = 0; i < conf->egress_cnt; i++)
14543 + dump_fq_duple(dev, conf->egress_fqs, conf->egress_cnt,
14544 + conf->channel);
14545 +
14546 + /* initialized ingress queues */
14547 + list_for_each(fq_list, &conf->fqs_ingress_list) {
14548 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14549 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
14550 + }
14551 +
14552 + /* initialized egress queues */
14553 + list_for_each(fq_list, &conf->fqs_egress_list) {
14554 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14555 + dump_fq_duple(dev, fqd->fqs, fqd->fqs_count, fqd->channel_id);
14556 + }
14557 +}
14558 +
14559 +/* Destroys Frame Queues */
14560 +static void oh_fq_destroy(struct qman_fq *fq)
14561 +{
14562 + int _errno = 0;
14563 +
14564 + _errno = qman_retire_fq(fq, NULL);
14565 + if (unlikely(_errno < 0))
14566 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_retire_fq(%u)=%d\n",
14567 + KBUILD_BASENAME".c", __LINE__, __func__,
14568 + qman_fq_fqid(fq), _errno);
14569 +
14570 + _errno = qman_oos_fq(fq);
14571 + if (unlikely(_errno < 0)) {
14572 + pr_err(KBUILD_MODNAME": %s:%hu:%s(): qman_oos_fq(%u)=%d\n",
14573 + KBUILD_BASENAME".c", __LINE__, __func__,
14574 + qman_fq_fqid(fq), _errno);
14575 + }
14576 +
14577 + qman_destroy_fq(fq, 0);
14578 +}
14579 +
14580 +/* Allocation code for the OH port's PCD frame queues */
14581 +static int __cold oh_alloc_pcd_fqids(struct device *dev,
14582 + uint32_t num,
14583 + uint8_t alignment,
14584 + uint32_t *base_fqid)
14585 +{
14586 + dev_crit(dev, "callback not implemented!\n");
14587 + BUG();
14588 +
14589 + return 0;
14590 +}
14591 +
14592 +static int __cold oh_free_pcd_fqids(struct device *dev, uint32_t base_fqid)
14593 +{
14594 + dev_crit(dev, "callback not implemented!\n");
14595 + BUG();
14596 +
14597 + return 0;
14598 +}
14599 +
14600 +static void oh_set_buffer_layout(struct fm_port *port,
14601 + struct dpa_buffer_layout_s *layout)
14602 +{
14603 + struct fm_port_params params;
14604 +
14605 + layout->priv_data_size = DPA_TX_PRIV_DATA_SIZE;
14606 + layout->parse_results = true;
14607 + layout->hash_results = true;
14608 + layout->time_stamp = false;
14609 +
14610 + fm_port_get_buff_layout_ext_params(port, &params);
14611 + layout->manip_extra_space = params.manip_extra_space;
14612 + layout->data_align = params.data_align;
14613 +}
14614 +
14615 +static int
14616 +oh_port_probe(struct platform_device *_of_dev)
14617 +{
14618 + struct device *dpa_oh_dev;
14619 + struct device_node *dpa_oh_node;
14620 + int lenp, _errno = 0, fq_idx, duple_idx;
14621 + int n_size, i, j, ret, duples_count;
14622 + struct platform_device *oh_of_dev;
14623 + struct device_node *oh_node, *bpool_node = NULL, *root_node;
14624 + struct device *oh_dev;
14625 + struct dpa_oh_config_s *oh_config = NULL;
14626 + const __be32 *oh_all_queues;
14627 + const __be32 *channel_ids;
14628 + const __be32 *oh_tx_queues;
14629 + uint32_t queues_count;
14630 + uint32_t crt_fqid_base;
14631 + uint32_t crt_fq_count;
14632 + bool frag_enabled = false;
14633 + struct fm_port_params oh_port_tx_params;
14634 + struct fm_port_pcd_param oh_port_pcd_params;
14635 + struct dpa_buffer_layout_s buf_layout;
14636 +
14637 + /* True if the current partition owns the OH port. */
14638 + bool init_oh_port;
14639 +
14640 + const struct of_device_id *match;
14641 + int crt_ext_pools_count;
14642 + u32 ext_pool_size;
14643 + u32 port_id;
14644 + u32 channel_id;
14645 +
14646 + int channel_ids_count;
14647 + int channel_idx;
14648 + struct fq_duple *fqd;
14649 + struct list_head *fq_list, *fq_list_tmp;
14650 +
14651 + const __be32 *bpool_cfg;
14652 + uint32_t bpid;
14653 +
14654 + memset(&oh_port_tx_params, 0, sizeof(oh_port_tx_params));
14655 + dpa_oh_dev = &_of_dev->dev;
14656 + dpa_oh_node = dpa_oh_dev->of_node;
14657 + BUG_ON(dpa_oh_node == NULL);
14658 +
14659 + match = of_match_device(oh_port_match_table, dpa_oh_dev);
14660 + if (!match)
14661 + return -EINVAL;
14662 +
14663 + dev_dbg(dpa_oh_dev, "Probing OH port...\n");
14664 +
14665 + /* Find the referenced OH node */
14666 + oh_node = of_parse_phandle(dpa_oh_node, "fsl,fman-oh-port", 0);
14667 + if (oh_node == NULL) {
14668 + dev_err(dpa_oh_dev,
14669 + "Can't find OH node referenced from node %s\n",
14670 + dpa_oh_node->full_name);
14671 + return -EINVAL;
14672 + }
14673 + dev_info(dpa_oh_dev, "Found OH node handle compatible with %s\n",
14674 + match->compatible);
14675 +
14676 + _errno = of_property_read_u32(oh_node, "cell-index", &port_id);
14677 + if (_errno) {
14678 + dev_err(dpa_oh_dev, "No port id found in node %s\n",
14679 + dpa_oh_node->full_name);
14680 + goto return_kfree;
14681 + }
14682 +
14683 + _errno = of_property_read_u32(oh_node, "fsl,qman-channel-id",
14684 + &channel_id);
14685 + if (_errno) {
14686 + dev_err(dpa_oh_dev, "No channel id found in node %s\n",
14687 + dpa_oh_node->full_name);
14688 + goto return_kfree;
14689 + }
14690 +
14691 + oh_of_dev = of_find_device_by_node(oh_node);
14692 + BUG_ON(oh_of_dev == NULL);
14693 + oh_dev = &oh_of_dev->dev;
14694 +
14695 + /* The OH port must be initialized exactly once.
14696 + * The following scenarios are of interest:
14697 + * - the node is Linux-private (will always initialize it);
14698 + * - the node is shared between two Linux partitions
14699 + * (only one of them will initialize it);
14700 + * - the node is shared between a Linux and a LWE partition
14701 + * (Linux will initialize it) - "fsl,dpa-oh-shared"
14702 + */
14703 +
14704 + /* Check if the current partition owns the OH port
14705 + * and ought to initialize it. It may be the case that we leave this
14706 + * to another (also Linux) partition.
14707 + */
14708 + init_oh_port = strcmp(match->compatible, "fsl,dpa-oh-shared");
14709 +
14710 + /* If we aren't the "owner" of the OH node, we're done here. */
14711 + if (!init_oh_port) {
14712 + dev_dbg(dpa_oh_dev,
14713 + "Not owning the shared OH port %s, will not initialize it.\n",
14714 + oh_node->full_name);
14715 + of_node_put(oh_node);
14716 + return 0;
14717 + }
14718 +
14719 + /* Allocate OH dev private data */
14720 + oh_config = devm_kzalloc(dpa_oh_dev, sizeof(*oh_config), GFP_KERNEL);
14721 + if (oh_config == NULL) {
14722 + dev_err(dpa_oh_dev,
14723 + "Can't allocate private data for OH node %s referenced from node %s!\n",
14724 + oh_node->full_name, dpa_oh_node->full_name);
14725 + _errno = -ENOMEM;
14726 + goto return_kfree;
14727 + }
14728 +
14729 + INIT_LIST_HEAD(&oh_config->fqs_ingress_list);
14730 + INIT_LIST_HEAD(&oh_config->fqs_egress_list);
14731 +
14732 + /* FQs that enter OH port */
14733 + lenp = 0;
14734 + oh_all_queues = of_get_property(dpa_oh_node,
14735 + "fsl,qman-frame-queues-ingress", &lenp);
14736 + if (lenp % (2 * sizeof(*oh_all_queues))) {
14737 + dev_warn(dpa_oh_dev,
14738 + "Wrong ingress queues format for OH node %s referenced from node %s!\n",
14739 + oh_node->full_name, dpa_oh_node->full_name);
14740 + /* just ignore the last unpaired value */
14741 + }
14742 +
14743 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
14744 + dev_err(dpa_oh_dev, "Allocating %d ingress frame queues duples\n",
14745 + duples_count);
14746 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
14747 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
14748 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
14749 +
14750 + fqd = devm_kzalloc(dpa_oh_dev,
14751 + sizeof(struct fq_duple), GFP_KERNEL);
14752 + if (!fqd) {
14753 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
14754 + oh_node->full_name,
14755 + dpa_oh_node->full_name);
14756 + _errno = -ENOMEM;
14757 + goto return_kfree;
14758 + }
14759 +
14760 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
14761 + crt_fq_count * sizeof(struct qman_fq),
14762 + GFP_KERNEL);
14763 + if (!fqd->fqs) {
14764 + dev_err(dpa_oh_dev, "Can't allocate structures for ingress frame queues for OH node %s referenced from node %s!\n",
14765 + oh_node->full_name,
14766 + dpa_oh_node->full_name);
14767 + _errno = -ENOMEM;
14768 + goto return_kfree;
14769 + }
14770 +
14771 + for (j = 0; j < crt_fq_count; j++)
14772 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
14773 + fqd->fqs_count = crt_fq_count;
14774 + fqd->channel_id = (uint16_t)channel_id;
14775 + list_add(&fqd->fq_list, &oh_config->fqs_ingress_list);
14776 + }
14777 +
14778 + /* create the ingress queues */
14779 + list_for_each(fq_list, &oh_config->fqs_ingress_list) {
14780 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14781 +
14782 + for (j = 0; j < fqd->fqs_count; j++) {
14783 + ret = oh_fq_create(fqd->fqs + j,
14784 + (fqd->fqs + j)->fqid,
14785 + fqd->channel_id, 3);
14786 + if (ret != 0) {
14787 + dev_err(dpa_oh_dev, "Unable to create ingress frame queue %d for OH node %s referenced from node %s!\n",
14788 + (fqd->fqs + j)->fqid,
14789 + oh_node->full_name,
14790 + dpa_oh_node->full_name);
14791 + _errno = -EINVAL;
14792 + goto return_kfree;
14793 + }
14794 + }
14795 + }
14796 +
14797 + /* FQs that exit OH port */
14798 + lenp = 0;
14799 + oh_all_queues = of_get_property(dpa_oh_node,
14800 + "fsl,qman-frame-queues-egress", &lenp);
14801 + if (lenp % (2 * sizeof(*oh_all_queues))) {
14802 + dev_warn(dpa_oh_dev,
14803 + "Wrong egress queues format for OH node %s referenced from node %s!\n",
14804 + oh_node->full_name, dpa_oh_node->full_name);
14805 + /* just ignore the last unpaired value */
14806 + }
14807 +
14808 + duples_count = lenp / (2 * sizeof(*oh_all_queues));
14809 + dev_dbg(dpa_oh_dev, "Allocating %d egress frame queues duples\n",
14810 + duples_count);
14811 + for (duple_idx = 0; duple_idx < duples_count; duple_idx++) {
14812 + crt_fqid_base = be32_to_cpu(oh_all_queues[2 * duple_idx]);
14813 + crt_fq_count = be32_to_cpu(oh_all_queues[2 * duple_idx + 1]);
14814 +
14815 + fqd = devm_kzalloc(dpa_oh_dev,
14816 + sizeof(struct fq_duple), GFP_KERNEL);
14817 + if (!fqd) {
14818 + dev_err(dpa_oh_dev, "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
14819 + oh_node->full_name,
14820 + dpa_oh_node->full_name);
14821 + _errno = -ENOMEM;
14822 + goto return_kfree;
14823 + }
14824 +
14825 + fqd->fqs = devm_kzalloc(dpa_oh_dev,
14826 + crt_fq_count * sizeof(struct qman_fq),
14827 + GFP_KERNEL);
14828 + if (!fqd->fqs) {
14829 + dev_err(dpa_oh_dev,
14830 + "Can't allocate structures for egress frame queues for OH node %s referenced from node %s!\n",
14831 + oh_node->full_name,
14832 + dpa_oh_node->full_name);
14833 + _errno = -ENOMEM;
14834 + goto return_kfree;
14835 + }
14836 +
14837 + for (j = 0; j < crt_fq_count; j++)
14838 + (fqd->fqs + j)->fqid = crt_fqid_base + j;
14839 + fqd->fqs_count = crt_fq_count;
14840 + /* channel ID is specified in another attribute */
14841 + fqd->channel_id = 0;
14842 + list_add_tail(&fqd->fq_list, &oh_config->fqs_egress_list);
14843 +
14844 + /* allocate the queue */
14845 +
14846 + }
14847 +
14848 + /* channel_ids for FQs that exit OH port */
14849 + lenp = 0;
14850 + channel_ids = of_get_property(dpa_oh_node,
14851 + "fsl,qman-channel-ids-egress", &lenp);
14852 +
14853 + channel_ids_count = lenp / (sizeof(*channel_ids));
14854 + if (channel_ids_count != duples_count) {
14855 + dev_warn(dpa_oh_dev,
14856 + "Not all egress queues have a channel id for OH node %s referenced from node %s!\n",
14857 + oh_node->full_name, dpa_oh_node->full_name);
14858 + /* just ignore the queues that do not have a Channel ID */
14859 + }
14860 +
14861 + channel_idx = 0;
14862 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
14863 + if (channel_idx + 1 > channel_ids_count)
14864 + break;
14865 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14866 + fqd->channel_id =
14867 + (uint16_t)be32_to_cpu(channel_ids[channel_idx++]);
14868 + }
14869 +
14870 + /* create egress queues */
14871 + list_for_each(fq_list, &oh_config->fqs_egress_list) {
14872 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
14873 +
14874 + if (fqd->channel_id == 0) {
14875 + /* missing channel id in dts */
14876 + continue;
14877 + }
14878 +
14879 + for (j = 0; j < fqd->fqs_count; j++) {
14880 + ret = oh_fq_create(fqd->fqs + j,
14881 + (fqd->fqs + j)->fqid,
14882 + fqd->channel_id, 3);
14883 + if (ret != 0) {
14884 + dev_err(dpa_oh_dev, "Unable to create egress frame queue %d for OH node %s referenced from node %s!\n",
14885 + (fqd->fqs + j)->fqid,
14886 + oh_node->full_name,
14887 + dpa_oh_node->full_name);
14888 + _errno = -EINVAL;
14889 + goto return_kfree;
14890 + }
14891 + }
14892 + }
14893 +
14894 + /* Read FQ ids/nums for the DPA OH node */
14895 + oh_all_queues = of_get_property(dpa_oh_node,
14896 + "fsl,qman-frame-queues-oh", &lenp);
14897 + if (oh_all_queues == NULL) {
14898 + dev_err(dpa_oh_dev,
14899 + "No frame queues have been defined for OH node %s referenced from node %s\n",
14900 + oh_node->full_name, dpa_oh_node->full_name);
14901 + _errno = -EINVAL;
14902 + goto return_kfree;
14903 + }
14904 +
14905 + /* Check that the OH error and default FQs are there */
14906 + BUG_ON(lenp % (2 * sizeof(*oh_all_queues)));
14907 + queues_count = lenp / (2 * sizeof(*oh_all_queues));
14908 + if (queues_count != 2) {
14909 + dev_err(dpa_oh_dev,
14910 + "Error and Default queues must be defined for OH node %s referenced from node %s\n",
14911 + oh_node->full_name, dpa_oh_node->full_name);
14912 + _errno = -EINVAL;
14913 + goto return_kfree;
14914 + }
14915 +
14916 + /* Read the FQIDs defined for this OH port */
14917 + dev_dbg(dpa_oh_dev, "Reading %d queues...\n", queues_count);
14918 + fq_idx = 0;
14919 +
14920 + /* Error FQID - must be present */
14921 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
14922 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
14923 + if (crt_fq_count != 1) {
14924 + dev_err(dpa_oh_dev,
14925 + "Only 1 Error FQ allowed in OH node %s referenced from node %s (read: %d FQIDs).\n",
14926 + oh_node->full_name, dpa_oh_node->full_name,
14927 + crt_fq_count);
14928 + _errno = -EINVAL;
14929 + goto return_kfree;
14930 + }
14931 + oh_config->error_fqid = crt_fqid_base;
14932 + dev_dbg(dpa_oh_dev, "Read Error FQID 0x%x for OH port %s.\n",
14933 + oh_config->error_fqid, oh_node->full_name);
14934 +
14935 + /* Default FQID - must be present */
14936 + crt_fqid_base = be32_to_cpu(oh_all_queues[fq_idx++]);
14937 + crt_fq_count = be32_to_cpu(oh_all_queues[fq_idx++]);
14938 + if (crt_fq_count != 1) {
14939 + dev_err(dpa_oh_dev,
14940 + "Only 1 Default FQ allowed in OH node %s referenced from %s (read: %d FQIDs).\n",
14941 + oh_node->full_name, dpa_oh_node->full_name,
14942 + crt_fq_count);
14943 + _errno = -EINVAL;
14944 + goto return_kfree;
14945 + }
14946 + oh_config->default_fqid = crt_fqid_base;
14947 + dev_dbg(dpa_oh_dev, "Read Default FQID 0x%x for OH port %s.\n",
14948 + oh_config->default_fqid, oh_node->full_name);
14949 +
14950 + /* TX FQID - presence is optional */
14951 + oh_tx_queues = of_get_property(dpa_oh_node, "fsl,qman-frame-queues-tx",
14952 + &lenp);
14953 + if (oh_tx_queues == NULL) {
14954 + dev_dbg(dpa_oh_dev,
14955 + "No tx queues have been defined for OH node %s referenced from node %s\n",
14956 + oh_node->full_name, dpa_oh_node->full_name);
14957 + goto config_port;
14958 + }
14959 +
14960 + /* Check that queues-tx has only a base and a count defined */
14961 + BUG_ON(lenp % (2 * sizeof(*oh_tx_queues)));
14962 + queues_count = lenp / (2 * sizeof(*oh_tx_queues));
14963 + if (queues_count != 1) {
14964 + dev_err(dpa_oh_dev,
14965 + "TX queues must be defined in only one <base count> tuple for OH node %s referenced from node %s\n",
14966 + oh_node->full_name, dpa_oh_node->full_name);
14967 + _errno = -EINVAL;
14968 + goto return_kfree;
14969 + }
14970 +
14971 + fq_idx = 0;
14972 + crt_fqid_base = be32_to_cpu(oh_tx_queues[fq_idx++]);
14973 + crt_fq_count = be32_to_cpu(oh_tx_queues[fq_idx++]);
14974 + oh_config->egress_cnt = crt_fq_count;
14975 +
14976 + /* Allocate TX queues */
14977 + dev_dbg(dpa_oh_dev, "Allocating %d queues for TX...\n", crt_fq_count);
14978 + oh_config->egress_fqs = devm_kzalloc(dpa_oh_dev,
14979 + crt_fq_count * sizeof(struct qman_fq), GFP_KERNEL);
14980 + if (oh_config->egress_fqs == NULL) {
14981 + dev_err(dpa_oh_dev,
14982 + "Can't allocate private data for TX queues for OH node %s referenced from node %s!\n",
14983 + oh_node->full_name, dpa_oh_node->full_name);
14984 + _errno = -ENOMEM;
14985 + goto return_kfree;
14986 + }
14987 +
14988 + /* Create TX queues */
14989 + for (i = 0; i < crt_fq_count; i++) {
14990 + ret = oh_fq_create(oh_config->egress_fqs + i,
14991 + crt_fqid_base + i, (uint16_t)channel_id, 3);
14992 + if (ret != 0) {
14993 + dev_err(dpa_oh_dev,
14994 + "Unable to create TX frame queue %d for OH node %s referenced from node %s!\n",
14995 + crt_fqid_base + i, oh_node->full_name,
14996 + dpa_oh_node->full_name);
14997 + _errno = -EINVAL;
14998 + goto return_kfree;
14999 + }
15000 + }
15001 +
15002 +config_port:
15003 + /* Get a handle to the fm_port so we can set
15004 + * its configuration params
15005 + */
15006 + oh_config->oh_port = fm_port_bind(oh_dev);
15007 + if (oh_config->oh_port == NULL) {
15008 + dev_err(dpa_oh_dev, "NULL drvdata from fm port dev %s!\n",
15009 + oh_node->full_name);
15010 + _errno = -EINVAL;
15011 + goto return_kfree;
15012 + }
15013 +
15014 + oh_set_buffer_layout(oh_config->oh_port, &buf_layout);
15015 +
15016 + /* read the pool handlers */
15017 + crt_ext_pools_count = of_count_phandle_with_args(dpa_oh_node,
15018 + "fsl,bman-buffer-pools", NULL);
15019 + if (crt_ext_pools_count <= 0) {
15020 + dev_info(dpa_oh_dev,
15021 + "OH port %s has no buffer pool. Fragmentation will not be enabled\n",
15022 + oh_node->full_name);
15023 + goto init_port;
15024 + }
15025 +
15026 + /* used for reading ext_pool_size*/
15027 + root_node = of_find_node_by_path("/");
15028 + if (root_node == NULL) {
15029 + dev_err(dpa_oh_dev, "of_find_node_by_path(/) failed\n");
15030 + _errno = -EINVAL;
15031 + goto return_kfree;
15032 + }
15033 +
15034 + n_size = of_n_size_cells(root_node);
15035 + of_node_put(root_node);
15036 +
15037 + dev_dbg(dpa_oh_dev, "OH port number of pools = %d\n",
15038 + crt_ext_pools_count);
15039 +
15040 + oh_port_tx_params.num_pools = (uint8_t)crt_ext_pools_count;
15041 +
15042 + for (i = 0; i < crt_ext_pools_count; i++) {
15043 + bpool_node = of_parse_phandle(dpa_oh_node,
15044 + "fsl,bman-buffer-pools", i);
15045 + if (bpool_node == NULL) {
15046 + dev_err(dpa_oh_dev, "Invalid Buffer pool node\n");
15047 + _errno = -EINVAL;
15048 + goto return_kfree;
15049 + }
15050 +
15051 + _errno = of_property_read_u32(bpool_node, "fsl,bpid", &bpid);
15052 + if (_errno) {
15053 + dev_err(dpa_oh_dev, "Invalid Buffer Pool ID\n");
15054 + _errno = -EINVAL;
15055 + goto return_kfree;
15056 + }
15057 +
15058 + oh_port_tx_params.pool_param[i].id = (uint8_t)bpid;
15059 + dev_dbg(dpa_oh_dev, "OH port bpool id = %u\n", bpid);
15060 +
15061 + bpool_cfg = of_get_property(bpool_node,
15062 + "fsl,bpool-ethernet-cfg", &lenp);
15063 + if (bpool_cfg == NULL) {
15064 + dev_err(dpa_oh_dev, "Invalid Buffer pool config params\n");
15065 + _errno = -EINVAL;
15066 + goto return_kfree;
15067 + }
15068 +
15069 + ext_pool_size = of_read_number(bpool_cfg + n_size, n_size);
15070 + oh_port_tx_params.pool_param[i].size = (uint16_t)ext_pool_size;
15071 + dev_dbg(dpa_oh_dev, "OH port bpool size = %u\n",
15072 + ext_pool_size);
15073 + of_node_put(bpool_node);
15074 +
15075 + }
15076 +
15077 + if (buf_layout.data_align != FRAG_DATA_ALIGN ||
15078 + buf_layout.manip_extra_space != FRAG_MANIP_SPACE)
15079 + goto init_port;
15080 +
15081 + frag_enabled = true;
15082 + dev_info(dpa_oh_dev, "IP Fragmentation enabled for OH port %d",
15083 + port_id);
15084 +
15085 +init_port:
15086 + of_node_put(oh_node);
15087 + /* Set Tx params */
15088 + dpaa_eth_init_port(tx, oh_config->oh_port, oh_port_tx_params,
15089 + oh_config->error_fqid, oh_config->default_fqid, (&buf_layout),
15090 + frag_enabled);
15091 + /* Set PCD params */
15092 + oh_port_pcd_params.cba = oh_alloc_pcd_fqids;
15093 + oh_port_pcd_params.cbf = oh_free_pcd_fqids;
15094 + oh_port_pcd_params.dev = dpa_oh_dev;
15095 + fm_port_pcd_bind(oh_config->oh_port, &oh_port_pcd_params);
15096 +
15097 + dev_set_drvdata(dpa_oh_dev, oh_config);
15098 +
15099 + /* Enable the OH port */
15100 + _errno = fm_port_enable(oh_config->oh_port);
15101 + if (_errno)
15102 + goto return_kfree;
15103 +
15104 + dev_info(dpa_oh_dev, "OH port %s enabled.\n", oh_node->full_name);
15105 +
15106 + /* print of all referenced & created queues */
15107 + dump_oh_config(dpa_oh_dev, oh_config);
15108 +
15109 + return 0;
15110 +
15111 +return_kfree:
15112 + if (bpool_node)
15113 + of_node_put(bpool_node);
15114 + if (oh_node)
15115 + of_node_put(oh_node);
15116 + if (oh_config && oh_config->egress_fqs)
15117 + devm_kfree(dpa_oh_dev, oh_config->egress_fqs);
15118 +
15119 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_ingress_list) {
15120 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
15121 + list_del(fq_list);
15122 + devm_kfree(dpa_oh_dev, fqd->fqs);
15123 + devm_kfree(dpa_oh_dev, fqd);
15124 + }
15125 +
15126 + list_for_each_safe(fq_list, fq_list_tmp, &oh_config->fqs_egress_list) {
15127 + fqd = list_entry(fq_list, struct fq_duple, fq_list);
15128 + list_del(fq_list);
15129 + devm_kfree(dpa_oh_dev, fqd->fqs);
15130 + devm_kfree(dpa_oh_dev, fqd);
15131 + }
15132 +
15133 + devm_kfree(dpa_oh_dev, oh_config);
15134 + return _errno;
15135 +}
15136 +
15137 +static int __cold oh_port_remove(struct platform_device *_of_dev)
15138 +{
15139 + int _errno = 0, i;
15140 + struct dpa_oh_config_s *oh_config;
15141 +
15142 + pr_info("Removing OH port...\n");
15143 +
15144 + oh_config = dev_get_drvdata(&_of_dev->dev);
15145 + if (oh_config == NULL) {
15146 + pr_err(KBUILD_MODNAME
15147 + ": %s:%hu:%s(): No OH config in device private data!\n",
15148 + KBUILD_BASENAME".c", __LINE__, __func__);
15149 + _errno = -ENODEV;
15150 + goto return_error;
15151 + }
15152 +
15153 + if (oh_config->egress_fqs)
15154 + for (i = 0; i < oh_config->egress_cnt; i++)
15155 + oh_fq_destroy(oh_config->egress_fqs + i);
15156 +
15157 + if (oh_config->oh_port == NULL) {
15158 + pr_err(KBUILD_MODNAME
15159 + ": %s:%hu:%s(): No fm port in device private data!\n",
15160 + KBUILD_BASENAME".c", __LINE__, __func__);
15161 + _errno = -EINVAL;
15162 + goto free_egress_fqs;
15163 + }
15164 +
15165 + _errno = fm_port_disable(oh_config->oh_port);
15166 +
15167 +free_egress_fqs:
15168 + if (oh_config->egress_fqs)
15169 + devm_kfree(&_of_dev->dev, oh_config->egress_fqs);
15170 + devm_kfree(&_of_dev->dev, oh_config);
15171 + dev_set_drvdata(&_of_dev->dev, NULL);
15172 +
15173 +return_error:
15174 + return _errno;
15175 +}
15176 +
15177 +static struct platform_driver oh_port_driver = {
15178 + .driver = {
15179 + .name = KBUILD_MODNAME,
15180 + .of_match_table = oh_port_match_table,
15181 + .owner = THIS_MODULE,
15182 + .pm = OH_PM_OPS,
15183 + },
15184 + .probe = oh_port_probe,
15185 + .remove = oh_port_remove
15186 +};
15187 +
15188 +static int __init __cold oh_port_load(void)
15189 +{
15190 + int _errno;
15191 +
15192 + pr_info(OH_MOD_DESCRIPTION "\n");
15193 +
15194 + _errno = platform_driver_register(&oh_port_driver);
15195 + if (_errno < 0) {
15196 + pr_err(KBUILD_MODNAME
15197 + ": %s:%hu:%s(): platform_driver_register() = %d\n",
15198 + KBUILD_BASENAME".c", __LINE__, __func__, _errno);
15199 + }
15200 +
15201 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
15202 + KBUILD_BASENAME".c", __func__);
15203 + return _errno;
15204 +}
15205 +module_init(oh_port_load);
15206 +
15207 +static void __exit __cold oh_port_unload(void)
15208 +{
15209 + pr_debug(KBUILD_MODNAME ": -> %s:%s()\n",
15210 + KBUILD_BASENAME".c", __func__);
15211 +
15212 + platform_driver_unregister(&oh_port_driver);
15213 +
15214 + pr_debug(KBUILD_MODNAME ": %s:%s() ->\n",
15215 + KBUILD_BASENAME".c", __func__);
15216 +}
15217 +module_exit(oh_port_unload);
15218 --- /dev/null
15219 +++ b/drivers/net/ethernet/freescale/sdk_dpaa/offline_port.h
15220 @@ -0,0 +1,59 @@
15221 +/* Copyright 2011 Freescale Semiconductor Inc.
15222 + *
15223 + * Redistribution and use in source and binary forms, with or without
15224 + * modification, are permitted provided that the following conditions are met:
15225 + * * Redistributions of source code must retain the above copyright
15226 + * notice, this list of conditions and the following disclaimer.
15227 + * * Redistributions in binary form must reproduce the above copyright
15228 + * notice, this list of conditions and the following disclaimer in the
15229 + * documentation and/or other materials provided with the distribution.
15230 + * * Neither the name of Freescale Semiconductor nor the
15231 + * names of its contributors may be used to endorse or promote products
15232 + * derived from this software without specific prior written permission.
15233 + *
15234 + *
15235 + * ALTERNATIVELY, this software may be distributed under the terms of the
15236 + * GNU General Public License ("GPL") as published by the Free Software
15237 + * Foundation, either version 2 of that License or (at your option) any
15238 + * later version.
15239 + *
15240 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
15241 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15242 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15243 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
15244 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15245 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15246 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15247 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15248 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15249 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15250 + */
15251 +
15252 +#ifndef __OFFLINE_PORT_H
15253 +#define __OFFLINE_PORT_H
15254 +
15255 +struct fm_port;
15256 +struct qman_fq;
15257 +
15258 +/* fqs are defined in duples (base_fq, fq_count) */
15259 +struct fq_duple {
15260 + struct qman_fq *fqs;
15261 + int fqs_count;
15262 + uint16_t channel_id;
15263 + struct list_head fq_list;
15264 +};
15265 +
15266 +/* OH port configuration */
15267 +struct dpa_oh_config_s {
15268 + uint32_t error_fqid;
15269 + uint32_t default_fqid;
15270 + struct fm_port *oh_port;
15271 + uint32_t egress_cnt;
15272 + struct qman_fq *egress_fqs;
15273 + uint16_t channel;
15274 +
15275 + struct list_head fqs_ingress_list;
15276 + struct list_head fqs_egress_list;
15277 +};
15278 +
15279 +#endif /* __OFFLINE_PORT_H */
15280 --- /dev/null
15281 +++ b/drivers/net/ethernet/freescale/sdk_fman/Kconfig
15282 @@ -0,0 +1,153 @@
15283 +menu "Frame Manager support"
15284 +
15285 +menuconfig FSL_SDK_FMAN
15286 + bool "Freescale Frame Manager (datapath) support - SDK driver"
15287 + depends on (FSL_SOC || ARM64 || ARM) && FSL_SDK_BMAN && FSL_SDK_QMAN && !FSL_FMAN
15288 + default y
15289 + ---help---
15290 + If unsure, say Y.
15291 +
15292 +if FSL_SDK_FMAN
15293 +
15294 +config FSL_SDK_FMAN_TEST
15295 + bool "FMan test module"
15296 + default n
15297 + select FSL_DPAA_HOOKS
15298 + ---help---
15299 + This option compiles test code for FMan.
15300 +
15301 +menu "FMAN Processor support"
15302 +choice
15303 + depends on FSL_SDK_FMAN
15304 + prompt "Processor Type"
15305 +
15306 +config FMAN_ARM
15307 + bool "LS1043"
15308 + depends on ARM64 || ARM
15309 + ---help---
15310 + Choose "LS1043" for the ARM platforms:
15311 + LS1043
15312 +
15313 +config FMAN_P3040_P4080_P5020
15314 + bool "P3040 P4080 5020"
15315 +
15316 +config FMAN_P1023
15317 + bool "P1023"
15318 +
15319 +config FMAN_V3H
15320 + bool "FmanV3H"
15321 + ---help---
15322 + Choose "FmanV3H" for Fman rev3H:
15323 + B4860, T4240, T4160, etc
15324 +
15325 +config FMAN_V3L
15326 + bool "FmanV3L"
15327 + ---help---
15328 + Choose "FmanV3L" for Fman rev3L:
15329 + T1040, T1042, T1020, T1022, T1023, T1024, etc
15330 +
15331 +endchoice
15332 +endmenu
15333 +
15334 +config FMAN_MIB_CNT_OVF_IRQ_EN
15335 + bool "Enable the dTSEC MIB counters overflow interrupt"
15336 + default n
15337 + ---help---
15338 + Enable the dTSEC MIB counters overflow interrupt to get
15339 + accurate MIB counters values. Enabled it compensates
15340 + for the counters overflow but reduces performance and
15341 + triggers error messages in HV setups.
15342 +
15343 +config FSL_FM_MAX_FRAME_SIZE
15344 + int "Maximum L2 frame size"
15345 + depends on FSL_SDK_FMAN
15346 + range 64 9600
15347 + default "1522"
15348 + help
15349 + Configure this in relation to the maximum possible MTU of your
15350 + network configuration. In particular, one would need to
15351 + increase this value in order to use jumbo frames.
15352 + FSL_FM_MAX_FRAME_SIZE must accommodate the Ethernet FCS (4 bytes)
15353 + and one ETH+VLAN header (18 bytes), to a total of 22 bytes in
15354 + excess of the desired L3 MTU.
15355 +
15356 + Note that having too large a FSL_FM_MAX_FRAME_SIZE (much larger
15357 + than the actual MTU) may lead to buffer exhaustion, especially
15358 + in the case of badly fragmented datagrams on the Rx path.
15359 + Conversely, having a FSL_FM_MAX_FRAME_SIZE smaller than the actual
15360 + MTU will lead to frames being dropped.
15361 +
15362 + This can be overridden by specifying "fsl_fm_max_frm" in
15363 + the kernel bootargs:
15364 + * in Hypervisor-based scenarios, by adding a "chosen" node
15365 + with the "bootargs" property specifying
15366 + "fsl_fm_max_frm=<YourValue>";
15367 + * in non-Hypervisor-based scenarios, via u-boot's env, by
15368 + modifying the "bootargs" env variable.
15369 +
15370 +config FSL_FM_RX_EXTRA_HEADROOM
15371 + int "Add extra headroom at beginning of data buffers"
15372 + depends on FSL_SDK_FMAN
15373 + range 16 384
15374 + default "64"
15375 + help
15376 + Configure this to tell the Frame Manager to reserve some extra
15377 + space at the beginning of a data buffer on the receive path,
15378 + before Internal Context fields are copied. This is in addition
15379 + to the private data area already reserved for driver internal
15380 + use. The provided value must be a multiple of 16.
15381 +
15382 + This setting can be overridden by specifying
15383 + "fsl_fm_rx_extra_headroom" in the kernel bootargs:
15384 + * in Hypervisor-based scenarios, by adding a "chosen" node
15385 + with the "bootargs" property specifying
15386 + "fsl_fm_rx_extra_headroom=<YourValue>";
15387 + * in non-Hypervisor-based scenarios, via u-boot's env, by
15388 + modifying the "bootargs" env variable.
15389 +
15390 +config FMAN_PFC
15391 + bool "FMan PFC support (EXPERIMENTAL)"
15392 + depends on ( FMAN_V3H || FMAN_V3L || FMAN_ARM) && FSL_SDK_FMAN
15393 + default n
15394 + help
15395 + This option enables PFC support on FMan v3 ports.
15396 + Data Center Bridging defines Classes of Service that are
15397 + flow-controlled using PFC pause frames.
15398 +
15399 +if FMAN_PFC
15400 +config FMAN_PFC_COS_COUNT
15401 + int "Number of PFC Classes of Service"
15402 + depends on FMAN_PFC && FSL_SDK_FMAN
15403 + range 1 4
15404 + default "3"
15405 + help
15406 + The number of Classes of Service controlled by PFC.
15407 +
15408 +config FMAN_PFC_QUANTA_0
15409 + int "The pause quanta for PFC CoS 0"
15410 + depends on FMAN_PFC && FSL_SDK_FMAN
15411 + range 0 65535
15412 + default "65535"
15413 +
15414 +config FMAN_PFC_QUANTA_1
15415 + int "The pause quanta for PFC CoS 1"
15416 + depends on FMAN_PFC && FSL_SDK_FMAN
15417 + range 0 65535
15418 + default "65535"
15419 +
15420 +config FMAN_PFC_QUANTA_2
15421 + int "The pause quanta for PFC CoS 2"
15422 + depends on FMAN_PFC && FSL_SDK_FMAN
15423 + range 0 65535
15424 + default "65535"
15425 +
15426 +config FMAN_PFC_QUANTA_3
15427 + int "The pause quanta for PFC CoS 3"
15428 + depends on FMAN_PFC && FSL_SDK_FMAN
15429 + range 0 65535
15430 + default "65535"
15431 +endif
15432 +
15433 +endif # FSL_SDK_FMAN
15434 +
15435 +endmenu
15436 --- /dev/null
15437 +++ b/drivers/net/ethernet/freescale/sdk_fman/Makefile
15438 @@ -0,0 +1,11 @@
15439 +#
15440 +# Makefile for the Freescale Ethernet controllers
15441 +#
15442 +ccflags-y += -DVERSION=\"\"
15443 +#
15444 +#Include netcomm SW specific definitions
15445 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
15446 +#
15447 +obj-y += etc/
15448 +obj-y += Peripherals/FM/
15449 +obj-y += src/
15450 --- /dev/null
15451 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/Makefile
15452 @@ -0,0 +1,15 @@
15453 +#
15454 +# Makefile for the Freescale Ethernet controllers
15455 +#
15456 +ccflags-y += -DVERSION=\"\"
15457 +#
15458 +#Include netcomm SW specific definitions
15459 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
15460 +
15461 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
15462 +
15463 +ccflags-y += -I$(NCSW_FM_INC)
15464 +
15465 +obj-y += fsl-ncsw-Hc.o
15466 +
15467 +fsl-ncsw-Hc-objs := hc.o
15468 --- /dev/null
15469 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/HC/hc.c
15470 @@ -0,0 +1,1232 @@
15471 +/*
15472 + * Copyright 2008-2012 Freescale Semiconductor Inc.
15473 + *
15474 + * Redistribution and use in source and binary forms, with or without
15475 + * modification, are permitted provided that the following conditions are met:
15476 + * * Redistributions of source code must retain the above copyright
15477 + * notice, this list of conditions and the following disclaimer.
15478 + * * Redistributions in binary form must reproduce the above copyright
15479 + * notice, this list of conditions and the following disclaimer in the
15480 + * documentation and/or other materials provided with the distribution.
15481 + * * Neither the name of Freescale Semiconductor nor the
15482 + * names of its contributors may be used to endorse or promote products
15483 + * derived from this software without specific prior written permission.
15484 + *
15485 + *
15486 + * ALTERNATIVELY, this software may be distributed under the terms of the
15487 + * GNU General Public License ("GPL") as published by the Free Software
15488 + * Foundation, either version 2 of that License or (at your option) any
15489 + * later version.
15490 + *
15491 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
15492 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15493 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15494 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
15495 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15496 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
15497 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
15498 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
15499 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
15500 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15501 + */
15502 +
15503 +
15504 +#include "std_ext.h"
15505 +#include "error_ext.h"
15506 +#include "sprint_ext.h"
15507 +#include "string_ext.h"
15508 +
15509 +#include "fm_common.h"
15510 +#include "fm_hc.h"
15511 +
15512 +
15513 +/**************************************************************************//**
15514 + @Description defaults
15515 +*//***************************************************************************/
15516 +#define DEFAULT_dataMemId 0
15517 +
15518 +#define HC_HCOR_OPCODE_PLCR_PRFL 0x0
15519 +#define HC_HCOR_OPCODE_KG_SCM 0x1
15520 +#define HC_HCOR_OPCODE_SYNC 0x2
15521 +#define HC_HCOR_OPCODE_CC 0x3
15522 +#define HC_HCOR_OPCODE_CC_AGE_MASK 0x4
15523 +#define HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT 0x5
15524 +#define HC_HCOR_OPCODE_CC_REASSM_TIMEOUT 0x10
15525 +#define HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION 0x11
15526 +#define HC_HCOR_OPCODE_CC_UPDATE_WITH_AGING 0x13
15527 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT 24
15528 +#define HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT 24
15529 +#define HC_HCOR_EXTRA_REG_CC_AGING_ADD 0x80000000
15530 +#define HC_HCOR_EXTRA_REG_CC_AGING_REMOVE 0x40000000
15531 +#define HC_HCOR_EXTRA_REG_CC_AGING_CHANGE_MASK 0xC0000000
15532 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_SHIFT 24
15533 +#define HC_HCOR_EXTRA_REG_CC_REMOVE_INDX_MASK 0x1F000000
15534 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT 16
15535 +#define HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK 0xF
15536 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT 24
15537 +#define HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID 16
15538 +
15539 +#define HC_HCOR_GBL 0x20000000
15540 +
15541 +#define HC_HCOR_KG_SCHEME_COUNTER 0x00000400
15542 +
15543 +#if (DPAA_VERSION == 10)
15544 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFF800
15545 +#else
15546 +#define HC_HCOR_KG_SCHEME_REGS_MASK 0xFFFFFE00
15547 +#endif /* (DPAA_VERSION == 10) */
15548 +
15549 +#define SIZE_OF_HC_FRAME_PORT_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdKgPortRegs))
15550 +#define SIZE_OF_HC_FRAME_SCHEME_REGS sizeof(t_HcFrame)
15551 +#define SIZE_OF_HC_FRAME_PROFILES_REGS (sizeof(t_HcFrame)-sizeof(struct fman_kg_scheme_regs)+sizeof(t_FmPcdPlcrProfileRegs))
15552 +#define SIZE_OF_HC_FRAME_PROFILE_CNT (sizeof(t_HcFrame)-sizeof(t_FmPcdPlcrProfileRegs)+sizeof(uint32_t))
15553 +#define SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC 16
15554 +
15555 +#define HC_CMD_POOL_SIZE (INTG_MAX_NUM_OF_CORES)
15556 +
15557 +#define BUILD_FD(len) \
15558 +do { \
15559 + memset(&fmFd, 0, sizeof(t_DpaaFD)); \
15560 + DPAA_FD_SET_ADDR(&fmFd, p_HcFrame); \
15561 + DPAA_FD_SET_OFFSET(&fmFd, 0); \
15562 + DPAA_FD_SET_LENGTH(&fmFd, len); \
15563 +} while (0)
15564 +
15565 +
15566 +#if defined(__MWERKS__) && !defined(__GNUC__)
15567 +#pragma pack(push,1)
15568 +#endif /* defined(__MWERKS__) && ... */
15569 +
15570 +typedef struct t_FmPcdKgPortRegs {
15571 + volatile uint32_t spReg;
15572 + volatile uint32_t cppReg;
15573 +} t_FmPcdKgPortRegs;
15574 +
15575 +typedef struct t_HcFrame {
15576 + volatile uint32_t opcode;
15577 + volatile uint32_t actionReg;
15578 + volatile uint32_t extraReg;
15579 + volatile uint32_t commandSequence;
15580 + union {
15581 + struct fman_kg_scheme_regs schemeRegs;
15582 + struct fman_kg_scheme_regs schemeRegsWithoutCounter;
15583 + t_FmPcdPlcrProfileRegs profileRegs;
15584 + volatile uint32_t singleRegForWrite; /* for writing SP, CPP, profile counter */
15585 + t_FmPcdKgPortRegs portRegsForRead;
15586 + volatile uint32_t clsPlanEntries[CLS_PLAN_NUM_PER_GRP];
15587 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeout;
15588 + t_FmPcdCcReassmTimeoutParams ccReassmTimeout;
15589 + } hcSpecificData;
15590 +} t_HcFrame;
15591 +
15592 +#if defined(__MWERKS__) && !defined(__GNUC__)
15593 +#pragma pack(pop)
15594 +#endif /* defined(__MWERKS__) && ... */
15595 +
15596 +
15597 +typedef struct t_FmHc {
15598 + t_Handle h_FmPcd;
15599 + t_Handle h_HcPortDev;
15600 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< A callback for enqueuing frames to the QM */
15601 + t_Handle h_QmArg; /**< A handle to the QM module */
15602 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
15603 +
15604 + uint32_t seqNum[HC_CMD_POOL_SIZE]; /* FIFO of seqNum to use when
15605 + taking buffer */
15606 + uint32_t nextSeqNumLocation; /* seqNum location in seqNum[] for next buffer */
15607 + volatile bool enqueued[HC_CMD_POOL_SIZE]; /* HC is active - frame is enqueued
15608 + and not confirmed yet */
15609 + t_HcFrame *p_Frm[HC_CMD_POOL_SIZE];
15610 +} t_FmHc;
15611 +
15612 +
15613 +static t_Error FillBufPool(t_FmHc *p_FmHc)
15614 +{
15615 + uint32_t i;
15616 +
15617 + ASSERT_COND(p_FmHc);
15618 +
15619 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
15620 + {
15621 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
15622 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart((sizeof(t_HcFrame) + (16 - (sizeof(t_FmHc) % 16))),
15623 + p_FmHc->dataMemId,
15624 + 16);
15625 +#else
15626 + p_FmHc->p_Frm[i] = (t_HcFrame *)XX_MallocSmart(sizeof(t_HcFrame),
15627 + p_FmHc->dataMemId,
15628 + 16);
15629 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
15630 + if (!p_FmHc->p_Frm[i])
15631 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM HC frames!"));
15632 + }
15633 +
15634 + /* Initialize FIFO of seqNum to use during GetBuf */
15635 + for (i = 0; i < HC_CMD_POOL_SIZE; i++)
15636 + {
15637 + p_FmHc->seqNum[i] = i;
15638 + }
15639 + p_FmHc->nextSeqNumLocation = 0;
15640 +
15641 + return E_OK;
15642 +}
15643 +
15644 +static __inline__ t_HcFrame * GetBuf(t_FmHc *p_FmHc, uint32_t *p_SeqNum)
15645 +{
15646 + uint32_t intFlags;
15647 +
15648 + ASSERT_COND(p_FmHc);
15649 +
15650 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
15651 +
15652 + if (p_FmHc->nextSeqNumLocation == HC_CMD_POOL_SIZE)
15653 + {
15654 + /* No more buffers */
15655 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15656 + return NULL;
15657 + }
15658 +
15659 + *p_SeqNum = p_FmHc->seqNum[p_FmHc->nextSeqNumLocation];
15660 + p_FmHc->nextSeqNumLocation++;
15661 +
15662 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15663 + return p_FmHc->p_Frm[*p_SeqNum];
15664 +}
15665 +
15666 +static __inline__ void PutBuf(t_FmHc *p_FmHc, t_HcFrame *p_Buf, uint32_t seqNum)
15667 +{
15668 + uint32_t intFlags;
15669 +
15670 + UNUSED(p_Buf);
15671 +
15672 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
15673 + ASSERT_COND(p_FmHc->nextSeqNumLocation);
15674 + p_FmHc->nextSeqNumLocation--;
15675 + p_FmHc->seqNum[p_FmHc->nextSeqNumLocation] = seqNum;
15676 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15677 +}
15678 +
15679 +static __inline__ t_Error EnQFrm(t_FmHc *p_FmHc, t_DpaaFD *p_FmFd, uint32_t seqNum)
15680 +{
15681 + t_Error err = E_OK;
15682 + uint32_t intFlags;
15683 + uint32_t timeout=100;
15684 +
15685 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
15686 + ASSERT_COND(!p_FmHc->enqueued[seqNum]);
15687 + p_FmHc->enqueued[seqNum] = TRUE;
15688 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15689 + DBG(TRACE, ("Send Hc, SeqNum %d, buff@0x%x, fd offset 0x%x",
15690 + seqNum,
15691 + DPAA_FD_GET_ADDR(p_FmFd),
15692 + DPAA_FD_GET_OFFSET(p_FmFd)));
15693 + err = p_FmHc->f_QmEnqueue(p_FmHc->h_QmArg, (void *)p_FmFd);
15694 + if (err)
15695 + RETURN_ERROR(MINOR, err, ("HC enqueue failed"));
15696 +
15697 + while (p_FmHc->enqueued[seqNum] && --timeout)
15698 + XX_UDelay(100);
15699 +
15700 + if (!timeout)
15701 + RETURN_ERROR(MINOR, E_TIMEOUT, ("HC Callback, timeout exceeded"));
15702 +
15703 + return err;
15704 +}
15705 +
15706 +
15707 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams)
15708 +{
15709 + t_FmHc *p_FmHc;
15710 + t_FmPortParams fmPortParam;
15711 + t_Error err;
15712 +
15713 + p_FmHc = (t_FmHc *)XX_Malloc(sizeof(t_FmHc));
15714 + if (!p_FmHc)
15715 + {
15716 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC obj"));
15717 + return NULL;
15718 + }
15719 + memset(p_FmHc,0,sizeof(t_FmHc));
15720 +
15721 + p_FmHc->h_FmPcd = p_FmHcParams->h_FmPcd;
15722 + p_FmHc->f_QmEnqueue = p_FmHcParams->params.f_QmEnqueue;
15723 + p_FmHc->h_QmArg = p_FmHcParams->params.h_QmArg;
15724 + p_FmHc->dataMemId = DEFAULT_dataMemId;
15725 +
15726 + err = FillBufPool(p_FmHc);
15727 + if (err != E_OK)
15728 + {
15729 + REPORT_ERROR(MAJOR, err, NO_MSG);
15730 + FmHcFree(p_FmHc);
15731 + return NULL;
15732 + }
15733 +
15734 + if (!FmIsMaster(p_FmHcParams->h_Fm))
15735 + return (t_Handle)p_FmHc;
15736 +
15737 + memset(&fmPortParam, 0, sizeof(fmPortParam));
15738 + fmPortParam.baseAddr = p_FmHcParams->params.portBaseAddr;
15739 + fmPortParam.portType = e_FM_PORT_TYPE_OH_HOST_COMMAND;
15740 + fmPortParam.portId = p_FmHcParams->params.portId;
15741 + fmPortParam.liodnBase = p_FmHcParams->params.liodnBase;
15742 + fmPortParam.h_Fm = p_FmHcParams->h_Fm;
15743 +
15744 + fmPortParam.specificParams.nonRxParams.errFqid = p_FmHcParams->params.errFqid;
15745 + fmPortParam.specificParams.nonRxParams.dfltFqid = p_FmHcParams->params.confFqid;
15746 + fmPortParam.specificParams.nonRxParams.qmChannel = p_FmHcParams->params.qmChannel;
15747 +
15748 + p_FmHc->h_HcPortDev = FM_PORT_Config(&fmPortParam);
15749 + if (!p_FmHc->h_HcPortDev)
15750 + {
15751 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM HC port!"));
15752 + XX_Free(p_FmHc);
15753 + return NULL;
15754 + }
15755 +
15756 + err = FM_PORT_ConfigMaxFrameLength(p_FmHc->h_HcPortDev,
15757 + (uint16_t)sizeof(t_HcFrame));
15758 +
15759 + if (err != E_OK)
15760 + {
15761 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
15762 + FmHcFree(p_FmHc);
15763 + return NULL;
15764 + }
15765 +
15766 + /* final init */
15767 + err = FM_PORT_Init(p_FmHc->h_HcPortDev);
15768 + if (err != E_OK)
15769 + {
15770 + REPORT_ERROR(MAJOR, err, ("FM HC port init!"));
15771 + FmHcFree(p_FmHc);
15772 + return NULL;
15773 + }
15774 +
15775 + err = FM_PORT_Enable(p_FmHc->h_HcPortDev);
15776 + if (err != E_OK)
15777 + {
15778 + REPORT_ERROR(MAJOR, err, ("FM HC port enable!"));
15779 + FmHcFree(p_FmHc);
15780 + return NULL;
15781 + }
15782 +
15783 + return (t_Handle)p_FmHc;
15784 +}
15785 +
15786 +void FmHcFree(t_Handle h_FmHc)
15787 +{
15788 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15789 + int i;
15790 +
15791 + if (!p_FmHc)
15792 + return;
15793 +
15794 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
15795 + if (p_FmHc->p_Frm[i])
15796 + XX_FreeSmart(p_FmHc->p_Frm[i]);
15797 + else
15798 + break;
15799 +
15800 + if (p_FmHc->h_HcPortDev)
15801 + FM_PORT_Free(p_FmHc->h_HcPortDev);
15802 +
15803 + XX_Free(p_FmHc);
15804 +}
15805 +
15806 +/*****************************************************************************/
15807 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
15808 + uint8_t memId)
15809 +{
15810 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15811 + int i;
15812 +
15813 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
15814 +
15815 + p_FmHc->dataMemId = memId;
15816 +
15817 + for (i=0; i<HC_CMD_POOL_SIZE; i++)
15818 + if (p_FmHc->p_Frm[i])
15819 + XX_FreeSmart(p_FmHc->p_Frm[i]);
15820 +
15821 + return FillBufPool(p_FmHc);
15822 +}
15823 +
15824 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd)
15825 +{
15826 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15827 + t_HcFrame *p_HcFrame;
15828 + uint32_t intFlags;
15829 +
15830 + ASSERT_COND(p_FmHc);
15831 +
15832 + intFlags = FmPcdLock(p_FmHc->h_FmPcd);
15833 + p_HcFrame = (t_HcFrame *)PTR_MOVE(DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd));
15834 +
15835 + DBG(TRACE, ("Hc Conf, SeqNum %d, FD@0x%x, fd offset 0x%x",
15836 + p_HcFrame->commandSequence, DPAA_FD_GET_ADDR(p_Fd), DPAA_FD_GET_OFFSET(p_Fd)));
15837 +
15838 + if (!(p_FmHc->enqueued[p_HcFrame->commandSequence]))
15839 + REPORT_ERROR(MINOR, E_INVALID_FRAME, ("Not an Host-Command frame received!"));
15840 + else
15841 + p_FmHc->enqueued[p_HcFrame->commandSequence] = FALSE;
15842 + FmPcdUnlock(p_FmHc->h_FmPcd, intFlags);
15843 +}
15844 +
15845 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
15846 + t_Handle h_Scheme,
15847 + struct fman_kg_scheme_regs *p_SchemeRegs,
15848 + bool updateCounter)
15849 +{
15850 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15851 + t_Error err = E_OK;
15852 + t_HcFrame *p_HcFrame;
15853 + t_DpaaFD fmFd;
15854 + uint8_t physicalSchemeId;
15855 + uint32_t seqNum;
15856 +
15857 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15858 + if (!p_HcFrame)
15859 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15860 +
15861 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
15862 +
15863 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15864 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15865 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, updateCounter);
15866 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15867 + memcpy(&p_HcFrame->hcSpecificData.schemeRegs, p_SchemeRegs, sizeof(struct fman_kg_scheme_regs));
15868 + if (!updateCounter)
15869 + {
15870 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv0 = p_SchemeRegs->kgse_dv0;
15871 + p_HcFrame->hcSpecificData.schemeRegs.kgse_dv1 = p_SchemeRegs->kgse_dv1;
15872 + p_HcFrame->hcSpecificData.schemeRegs.kgse_ccbs = p_SchemeRegs->kgse_ccbs;
15873 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mv = p_SchemeRegs->kgse_mv;
15874 + }
15875 + p_HcFrame->commandSequence = seqNum;
15876 +
15877 + BUILD_FD(sizeof(t_HcFrame));
15878 +
15879 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15880 +
15881 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15882 +
15883 + if (err != E_OK)
15884 + RETURN_ERROR(MINOR, err, NO_MSG);
15885 +
15886 + return E_OK;
15887 +}
15888 +
15889 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme)
15890 +{
15891 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15892 + t_Error err = E_OK;
15893 + t_HcFrame *p_HcFrame;
15894 + t_DpaaFD fmFd;
15895 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
15896 + uint32_t seqNum;
15897 +
15898 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15899 + if (!p_HcFrame)
15900 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15901 +
15902 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15903 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15904 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
15905 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15906 + memset(&p_HcFrame->hcSpecificData.schemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
15907 + p_HcFrame->commandSequence = seqNum;
15908 +
15909 + BUILD_FD(sizeof(t_HcFrame));
15910 +
15911 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
15912 +
15913 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15914 +
15915 + if (err != E_OK)
15916 + RETURN_ERROR(MINOR, err, NO_MSG);
15917 +
15918 + return E_OK;
15919 +}
15920 +
15921 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
15922 +{
15923 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
15924 + t_Error err = E_OK;
15925 + t_HcFrame *p_HcFrame;
15926 + t_DpaaFD fmFd;
15927 + uint8_t relativeSchemeId;
15928 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
15929 + uint32_t tmpReg32 = 0;
15930 + uint32_t seqNum;
15931 +
15932 + /* Scheme is locked by calling routine */
15933 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
15934 + * "kgse_mode" or "kgse_om" without locking scheme !
15935 + */
15936 +
15937 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
15938 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
15939 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
15940 +
15941 + if (!FmPcdKgGetRequiredActionFlag(p_FmHc->h_FmPcd, relativeSchemeId) ||
15942 + !(FmPcdKgGetRequiredAction(p_FmHc->h_FmPcd, relativeSchemeId) & requiredAction))
15943 + {
15944 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
15945 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_PLCR))
15946 + {
15947 + if ((FmPcdKgIsDirectPlcr(p_FmHc->h_FmPcd, relativeSchemeId) == FALSE) ||
15948 + (FmPcdKgIsDistrOnPlcrProfile(p_FmHc->h_FmPcd, relativeSchemeId) == TRUE))
15949 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
15950 + err = FmPcdPlcrCcGetSetParams(p_FmHc->h_FmPcd, FmPcdKgGetRelativeProfileId(p_FmHc->h_FmPcd, relativeSchemeId), requiredAction);
15951 + if (err)
15952 + RETURN_ERROR(MAJOR, err, NO_MSG);
15953 + }
15954 + else /* From here we deal with KG-Schemes only */
15955 + {
15956 + /* Pre change general code */
15957 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
15958 + if (!p_HcFrame)
15959 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
15960 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
15961 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
15962 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
15963 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
15964 + p_HcFrame->commandSequence = seqNum;
15965 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
15966 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
15967 + {
15968 + PutBuf(p_FmHc, p_HcFrame, seqNum);
15969 + RETURN_ERROR(MINOR, err, NO_MSG);
15970 + }
15971 +
15972 + /* specific change */
15973 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA) &&
15974 + ((FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_DONE) &&
15975 + (FmPcdKgGetDoneAction(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_ENQ_FRAME)))
15976 + {
15977 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
15978 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
15979 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
15980 + }
15981 +
15982 + if ((requiredAction & UPDATE_KG_NIA_CC_WA) &&
15983 + (FmPcdKgGetNextEngine(p_FmHc->h_FmPcd, relativeSchemeId) == e_FM_PCD_CC))
15984 + {
15985 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
15986 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
15987 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
15988 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32 | NIA_FM_CTL_AC_PRE_CC;
15989 + }
15990 +
15991 + if (requiredAction & UPDATE_KG_OPT_MODE)
15992 + p_HcFrame->hcSpecificData.schemeRegs.kgse_om = value;
15993 +
15994 + if (requiredAction & UPDATE_KG_NIA)
15995 + {
15996 + tmpReg32 = p_HcFrame->hcSpecificData.schemeRegs.kgse_mode;
15997 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
15998 + tmpReg32 |= value;
15999 + p_HcFrame->hcSpecificData.schemeRegs.kgse_mode = tmpReg32;
16000 + }
16001 +
16002 + /* Post change general code */
16003 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
16004 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
16005 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
16006 +
16007 + BUILD_FD(sizeof(t_HcFrame));
16008 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16009 +
16010 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16011 +
16012 + if (err != E_OK)
16013 + RETURN_ERROR(MINOR, err, NO_MSG);
16014 + }
16015 + }
16016 +
16017 + return E_OK;
16018 +}
16019 +
16020 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme)
16021 +{
16022 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16023 + t_Error err;
16024 + t_HcFrame *p_HcFrame;
16025 + t_DpaaFD fmFd;
16026 + uint32_t retVal;
16027 + uint8_t relativeSchemeId;
16028 + uint8_t physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
16029 + uint32_t seqNum;
16030 +
16031 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
16032 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
16033 + {
16034 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
16035 + return 0;
16036 + }
16037 +
16038 + /* first read scheme and check that it is valid */
16039 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16040 + if (!p_HcFrame)
16041 + {
16042 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16043 + return 0;
16044 + }
16045 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16046 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
16047 + p_HcFrame->actionReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
16048 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
16049 + p_HcFrame->commandSequence = seqNum;
16050 +
16051 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
16052 +
16053 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16054 + if (err != E_OK)
16055 + {
16056 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16057 + REPORT_ERROR(MINOR, err, NO_MSG);
16058 + return 0;
16059 + }
16060 +
16061 + if (!FmPcdKgHwSchemeIsValid(p_HcFrame->hcSpecificData.schemeRegs.kgse_mode))
16062 + {
16063 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16064 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is invalid"));
16065 + return 0;
16066 + }
16067 +
16068 + retVal = p_HcFrame->hcSpecificData.schemeRegs.kgse_spc;
16069 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16070 +
16071 + return retVal;
16072 +}
16073 +
16074 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value)
16075 +{
16076 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16077 + t_Error err = E_OK;
16078 + t_HcFrame *p_HcFrame;
16079 + t_DpaaFD fmFd;
16080 + uint8_t relativeSchemeId, physicalSchemeId;
16081 + uint32_t seqNum;
16082 +
16083 + physicalSchemeId = FmPcdKgGetSchemeId(h_Scheme);
16084 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmHc->h_FmPcd, physicalSchemeId);
16085 + if ( relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
16086 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
16087 +
16088 + /* first read scheme and check that it is valid */
16089 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16090 + if (!p_HcFrame)
16091 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16092 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16093 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
16094 + p_HcFrame->actionReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
16095 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_COUNTER;
16096 + /* write counter */
16097 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
16098 + p_HcFrame->commandSequence = seqNum;
16099 +
16100 + BUILD_FD(sizeof(t_HcFrame));
16101 +
16102 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16103 +
16104 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16105 + return err;
16106 +}
16107 +
16108 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set)
16109 +{
16110 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16111 + t_HcFrame *p_HcFrame;
16112 + t_DpaaFD fmFd;
16113 + uint8_t i, idx;
16114 + uint32_t seqNum;
16115 + t_Error err = E_OK;
16116 +
16117 + ASSERT_COND(p_FmHc);
16118 +
16119 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16120 + if (!p_HcFrame)
16121 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16122 +
16123 + for (i = p_Set->baseEntry; i < (p_Set->baseEntry+p_Set->numOfClsPlanEntries); i+=8)
16124 + {
16125 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16126 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
16127 + p_HcFrame->actionReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
16128 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
16129 +
16130 + idx = (uint8_t)(i - p_Set->baseEntry);
16131 + ASSERT_COND(idx < FM_PCD_MAX_NUM_OF_CLS_PLANS);
16132 + memcpy(&p_HcFrame->hcSpecificData.clsPlanEntries, &p_Set->vectors[idx], CLS_PLAN_NUM_PER_GRP*sizeof(uint32_t));
16133 + p_HcFrame->commandSequence = seqNum;
16134 +
16135 + BUILD_FD(sizeof(t_HcFrame));
16136 +
16137 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16138 + {
16139 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16140 + RETURN_ERROR(MINOR, err, NO_MSG);
16141 + }
16142 + }
16143 +
16144 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16145 + return err;
16146 +}
16147 +
16148 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t grpId)
16149 +{
16150 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16151 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
16152 +
16153 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
16154 + if (!p_ClsPlanSet)
16155 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
16156 +
16157 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
16158 +
16159 + p_ClsPlanSet->baseEntry = FmPcdKgGetClsPlanGrpBase(p_FmHc->h_FmPcd, grpId);
16160 + p_ClsPlanSet->numOfClsPlanEntries = FmPcdKgGetClsPlanGrpSize(p_FmHc->h_FmPcd, grpId);
16161 + ASSERT_COND(p_ClsPlanSet->numOfClsPlanEntries <= FM_PCD_MAX_NUM_OF_CLS_PLANS);
16162 +
16163 + if (FmHcPcdKgSetClsPlan(p_FmHc, p_ClsPlanSet) != E_OK)
16164 + {
16165 + XX_Free(p_ClsPlanSet);
16166 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
16167 + }
16168 +
16169 + XX_Free(p_ClsPlanSet);
16170 + FmPcdKgDestroyClsPlanGrp(p_FmHc->h_FmPcd, grpId);
16171 +
16172 + return E_OK;
16173 +}
16174 +
16175 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams )
16176 +{
16177 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16178 + t_HcFrame *p_HcFrame;
16179 + t_DpaaFD fmFd;
16180 + t_Error err;
16181 + uint32_t seqNum;
16182 +
16183 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
16184 +
16185 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16186 + if (!p_HcFrame)
16187 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16188 +
16189 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16190 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_CAPWAP_REASSM_TIMEOUT);
16191 + memcpy(&p_HcFrame->hcSpecificData.ccCapwapReassmTimeout, p_CcCapwapReassmTimeoutParams, sizeof(t_FmPcdCcCapwapReassmTimeoutParams));
16192 + p_HcFrame->commandSequence = seqNum;
16193 + BUILD_FD(sizeof(t_HcFrame));
16194 +
16195 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16196 +
16197 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16198 + return err;
16199 +}
16200 +
16201 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams)
16202 +{
16203 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16204 + t_HcFrame *p_HcFrame;
16205 + t_DpaaFD fmFd;
16206 + t_Error err;
16207 + uint32_t seqNum;
16208 +
16209 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
16210 +
16211 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16212 + if (!p_HcFrame)
16213 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16214 +
16215 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16216 +
16217 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_IP_FRAG_INITIALIZATION);
16218 + p_HcFrame->actionReg = (uint32_t)(((fill == TRUE) ? 0 : 1) << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_CMD_SHIFT);
16219 + p_HcFrame->actionReg |= p_FmPcdCcFragScratchPoolCmdParams->bufferPoolId << HC_HCOR_ACTION_REG_IP_FRAG_SCRATCH_POOL_BPID;
16220 + if (fill == TRUE)
16221 + {
16222 + p_HcFrame->extraReg = p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers;
16223 + }
16224 + p_HcFrame->commandSequence = seqNum;
16225 +
16226 + BUILD_FD(sizeof(t_HcFrame));
16227 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16228 + {
16229 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16230 + RETURN_ERROR(MINOR, err, NO_MSG);
16231 + }
16232 +
16233 + p_FmPcdCcFragScratchPoolCmdParams->numOfBuffers = p_HcFrame->extraReg;
16234 +
16235 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16236 + return E_OK;
16237 +}
16238 +
16239 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result)
16240 +{
16241 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16242 + t_HcFrame *p_HcFrame;
16243 + t_DpaaFD fmFd;
16244 + t_Error err;
16245 + uint32_t seqNum;
16246 +
16247 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
16248 +
16249 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16250 + if (!p_HcFrame)
16251 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16252 +
16253 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16254 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC_REASSM_TIMEOUT);
16255 + p_HcFrame->actionReg = (uint32_t)((p_CcReassmTimeoutParams->activate ? 0 : 1) << HC_HCOR_ACTION_REG_REASSM_TIMEOUT_ACTIVE_SHIFT);
16256 + p_HcFrame->extraReg = (p_CcReassmTimeoutParams->tsbs << HC_HCOR_EXTRA_REG_REASSM_TIMEOUT_TSBS_SHIFT) | p_CcReassmTimeoutParams->iprcpt;
16257 + p_HcFrame->commandSequence = seqNum;
16258 +
16259 + BUILD_FD(sizeof(t_HcFrame));
16260 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16261 + {
16262 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16263 + RETURN_ERROR(MINOR, err, NO_MSG);
16264 + }
16265 +
16266 + *p_Result = (uint8_t)
16267 + ((p_HcFrame->actionReg >> HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_SHIFT) & HC_HCOR_ACTION_REG_REASSM_TIMEOUT_RES_MASK);
16268 +
16269 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16270 + return E_OK;
16271 +}
16272 +
16273 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction)
16274 +{
16275 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16276 + t_HcFrame *p_HcFrame;
16277 + t_DpaaFD fmFd;
16278 + t_Error err;
16279 + uint32_t tmpReg32 = 0;
16280 + uint32_t requiredActionTmp, requiredActionFlag;
16281 + uint32_t seqNum;
16282 +
16283 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
16284 +
16285 + /* Profile is locked by calling routine */
16286 + /* WARNING - this lock will not be efficient if other HC routine will attempt to change
16287 + * "fmpl_pegnia" "fmpl_peynia" or "fmpl_pernia" without locking Profile !
16288 + */
16289 +
16290 + requiredActionTmp = FmPcdPlcrGetRequiredAction(p_FmHc->h_FmPcd, absoluteProfileId);
16291 + requiredActionFlag = FmPcdPlcrGetRequiredActionFlag(p_FmHc->h_FmPcd, absoluteProfileId);
16292 +
16293 + if (!requiredActionFlag || !(requiredActionTmp & requiredAction))
16294 + {
16295 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
16296 + {
16297 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16298 + if (!p_HcFrame)
16299 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16300 + /* first read scheme and check that it is valid */
16301 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16302 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16303 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
16304 + p_HcFrame->extraReg = 0x00008000;
16305 + p_HcFrame->commandSequence = seqNum;
16306 +
16307 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
16308 +
16309 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16310 + {
16311 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16312 + RETURN_ERROR(MINOR, err, NO_MSG);
16313 + }
16314 +
16315 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegnia;
16316 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
16317 + {
16318 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16319 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
16320 + ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
16321 + }
16322 +
16323 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
16324 +
16325 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16326 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
16327 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(TRUE, FALSE, FALSE);
16328 + p_HcFrame->extraReg = 0x00008000;
16329 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
16330 +
16331 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
16332 +
16333 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16334 + {
16335 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16336 + RETURN_ERROR(MINOR, err, NO_MSG);
16337 + }
16338 +
16339 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_peynia;
16340 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
16341 + {
16342 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16343 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
16344 + }
16345 +
16346 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
16347 +
16348 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16349 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
16350 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, TRUE, FALSE);
16351 + p_HcFrame->extraReg = 0x00008000;
16352 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
16353 +
16354 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
16355 +
16356 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16357 + {
16358 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16359 + RETURN_ERROR(MINOR, err, NO_MSG);
16360 + }
16361 +
16362 + tmpReg32 = p_HcFrame->hcSpecificData.profileRegs.fmpl_pernia;
16363 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
16364 + {
16365 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16366 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
16367 + }
16368 +
16369 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
16370 +
16371 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16372 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
16373 + p_HcFrame->actionReg |= FmPcdPlcrBuildNiaProfileReg(FALSE, FALSE, TRUE);
16374 + p_HcFrame->extraReg = 0x00008000;
16375 + p_HcFrame->hcSpecificData.singleRegForWrite = tmpReg32;
16376 +
16377 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
16378 +
16379 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16380 + {
16381 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16382 + RETURN_ERROR(MINOR, err, NO_MSG);
16383 + }
16384 +
16385 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16386 + }
16387 + }
16388 +
16389 + return E_OK;
16390 +}
16391 +
16392 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs)
16393 +{
16394 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16395 + t_Error err = E_OK;
16396 + uint16_t profileIndx;
16397 + t_HcFrame *p_HcFrame;
16398 + t_DpaaFD fmFd;
16399 + uint32_t seqNum;
16400 +
16401 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16402 + if (!p_HcFrame)
16403 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16404 +
16405 + profileIndx = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
16406 +
16407 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16408 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16409 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
16410 + p_HcFrame->extraReg = 0x00008000;
16411 + memcpy(&p_HcFrame->hcSpecificData.profileRegs, p_PlcrRegs, sizeof(t_FmPcdPlcrProfileRegs));
16412 + p_HcFrame->commandSequence = seqNum;
16413 +
16414 + BUILD_FD(sizeof(t_HcFrame));
16415 +
16416 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16417 +
16418 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16419 +
16420 + if (err != E_OK)
16421 + RETURN_ERROR(MINOR, err, NO_MSG);
16422 +
16423 + return E_OK;
16424 +}
16425 +
16426 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile)
16427 +{
16428 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16429 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
16430 + t_Error err = E_OK;
16431 + t_HcFrame *p_HcFrame;
16432 + t_DpaaFD fmFd;
16433 + uint32_t seqNum;
16434 +
16435 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16436 + if (!p_HcFrame)
16437 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16438 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16439 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16440 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
16441 + p_HcFrame->actionReg |= 0x00008000;
16442 + p_HcFrame->extraReg = 0x00008000;
16443 + memset(&p_HcFrame->hcSpecificData.profileRegs, 0, sizeof(t_FmPcdPlcrProfileRegs));
16444 + p_HcFrame->commandSequence = seqNum;
16445 +
16446 + BUILD_FD(sizeof(t_HcFrame));
16447 +
16448 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16449 +
16450 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16451 +
16452 + if (err != E_OK)
16453 + RETURN_ERROR(MINOR, err, NO_MSG);
16454 +
16455 + return E_OK;
16456 +}
16457 +
16458 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
16459 +{
16460 +
16461 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16462 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
16463 + t_Error err = E_OK;
16464 + t_HcFrame *p_HcFrame;
16465 + t_DpaaFD fmFd;
16466 + uint32_t seqNum;
16467 +
16468 + /* first read scheme and check that it is valid */
16469 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16470 + if (!p_HcFrame)
16471 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16472 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16473 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16474 + p_HcFrame->actionReg = FmPcdPlcrBuildWritePlcrActionReg(absoluteProfileId);
16475 + p_HcFrame->actionReg |= FmPcdPlcrBuildCounterProfileReg(counter);
16476 + p_HcFrame->extraReg = 0x00008000;
16477 + p_HcFrame->hcSpecificData.singleRegForWrite = value;
16478 + p_HcFrame->commandSequence = seqNum;
16479 +
16480 + BUILD_FD(SIZE_OF_HC_FRAME_PROFILE_CNT);
16481 +
16482 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16483 +
16484 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16485 +
16486 + if (err != E_OK)
16487 + RETURN_ERROR(MINOR, err, NO_MSG);
16488 +
16489 + return E_OK;
16490 +}
16491 +
16492 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
16493 +{
16494 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16495 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
16496 + t_Error err;
16497 + t_HcFrame *p_HcFrame;
16498 + t_DpaaFD fmFd;
16499 + uint32_t retVal = 0;
16500 + uint32_t seqNum;
16501 +
16502 + SANITY_CHECK_RETURN_VALUE(h_FmHc, E_INVALID_HANDLE,0);
16503 +
16504 + /* first read scheme and check that it is valid */
16505 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16506 + if (!p_HcFrame)
16507 + {
16508 + REPORT_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16509 + return 0;
16510 + }
16511 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16512 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_PLCR_PRFL);
16513 + p_HcFrame->actionReg = FmPcdPlcrBuildReadPlcrActionReg(absoluteProfileId);
16514 + p_HcFrame->extraReg = 0x00008000;
16515 + p_HcFrame->commandSequence = seqNum;
16516 +
16517 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
16518 +
16519 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16520 + if (err != E_OK)
16521 + {
16522 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16523 + REPORT_ERROR(MINOR, err, NO_MSG);
16524 + return 0;
16525 + }
16526 +
16527 + switch (counter)
16528 + {
16529 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
16530 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_pegpc;
16531 + break;
16532 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
16533 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_peypc;
16534 + break;
16535 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
16536 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perpc;
16537 + break;
16538 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
16539 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perypc;
16540 + break;
16541 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
16542 + retVal = p_HcFrame->hcSpecificData.profileRegs.fmpl_perrpc;
16543 + break;
16544 + default:
16545 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
16546 + }
16547 +
16548 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16549 + return retVal;
16550 +}
16551 +
16552 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add)
16553 +{
16554 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16555 + t_HcFrame *p_HcFrame;
16556 + t_DpaaFD fmFd;
16557 + t_Error err = E_OK;
16558 + uint32_t seqNum;
16559 +
16560 + ASSERT_COND(p_FmHc);
16561 +
16562 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16563 + if (!p_HcFrame)
16564 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16565 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16566 + /* first read SP register */
16567 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
16568 + p_HcFrame->actionReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
16569 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
16570 + p_HcFrame->commandSequence = seqNum;
16571 +
16572 + BUILD_FD(SIZE_OF_HC_FRAME_PORT_REGS);
16573 +
16574 + if ((err = EnQFrm(p_FmHc, &fmFd, seqNum)) != E_OK)
16575 + {
16576 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16577 + RETURN_ERROR(MINOR, err, NO_MSG);
16578 + }
16579 +
16580 + /* spReg is the first reg, so we can use it both for read and for write */
16581 + if (add)
16582 + p_HcFrame->hcSpecificData.portRegsForRead.spReg |= spReg;
16583 + else
16584 + p_HcFrame->hcSpecificData.portRegsForRead.spReg &= ~spReg;
16585 +
16586 + p_HcFrame->actionReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
16587 +
16588 + BUILD_FD(sizeof(t_HcFrame));
16589 +
16590 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16591 +
16592 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16593 +
16594 + if (err != E_OK)
16595 + RETURN_ERROR(MINOR, err, NO_MSG);
16596 +
16597 + return E_OK;
16598 +}
16599 +
16600 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg)
16601 +{
16602 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16603 + t_HcFrame *p_HcFrame;
16604 + t_DpaaFD fmFd;
16605 + t_Error err = E_OK;
16606 + uint32_t seqNum;
16607 +
16608 + ASSERT_COND(p_FmHc);
16609 +
16610 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16611 + if (!p_HcFrame)
16612 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16613 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16614 + /* first read SP register */
16615 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_KG_SCM);
16616 + p_HcFrame->actionReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
16617 + p_HcFrame->extraReg = HC_HCOR_KG_SCHEME_REGS_MASK;
16618 + p_HcFrame->hcSpecificData.singleRegForWrite = cppReg;
16619 + p_HcFrame->commandSequence = seqNum;
16620 +
16621 + BUILD_FD(sizeof(t_HcFrame));
16622 +
16623 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16624 +
16625 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16626 +
16627 + if (err != E_OK)
16628 + RETURN_ERROR(MINOR, err, NO_MSG);
16629 +
16630 + return E_OK;
16631 +}
16632 +
16633 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset)
16634 +{
16635 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16636 + t_HcFrame *p_HcFrame;
16637 + t_DpaaFD fmFd;
16638 + t_Error err = E_OK;
16639 + uint32_t seqNum;
16640 +
16641 + SANITY_CHECK_RETURN_ERROR(p_FmHc, E_INVALID_HANDLE);
16642 +
16643 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16644 + if (!p_HcFrame)
16645 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16646 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16647 +
16648 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_CC);
16649 + p_HcFrame->actionReg = newAdAddrOffset;
16650 + p_HcFrame->actionReg |= 0xc0000000;
16651 + p_HcFrame->extraReg = oldAdAddrOffset;
16652 + p_HcFrame->commandSequence = seqNum;
16653 +
16654 + BUILD_FD(SIZE_OF_HC_FRAME_READ_OR_CC_DYNAMIC);
16655 +
16656 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16657 +
16658 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16659 +
16660 + if (err != E_OK)
16661 + RETURN_ERROR(MAJOR, err, NO_MSG);
16662 +
16663 + return E_OK;
16664 +}
16665 +
16666 +t_Error FmHcPcdSync(t_Handle h_FmHc)
16667 +{
16668 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16669 + t_HcFrame *p_HcFrame;
16670 + t_DpaaFD fmFd;
16671 + t_Error err = E_OK;
16672 + uint32_t seqNum;
16673 +
16674 + ASSERT_COND(p_FmHc);
16675 +
16676 + p_HcFrame = GetBuf(p_FmHc, &seqNum);
16677 + if (!p_HcFrame)
16678 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("HC Frame object"));
16679 + memset(p_HcFrame, 0, sizeof(t_HcFrame));
16680 + /* first read SP register */
16681 + p_HcFrame->opcode = (uint32_t)(HC_HCOR_GBL | HC_HCOR_OPCODE_SYNC);
16682 + p_HcFrame->actionReg = 0;
16683 + p_HcFrame->extraReg = 0;
16684 + p_HcFrame->commandSequence = seqNum;
16685 +
16686 + BUILD_FD(sizeof(t_HcFrame));
16687 +
16688 + err = EnQFrm(p_FmHc, &fmFd, seqNum);
16689 +
16690 + PutBuf(p_FmHc, p_HcFrame, seqNum);
16691 +
16692 + if (err != E_OK)
16693 + RETURN_ERROR(MINOR, err, NO_MSG);
16694 +
16695 + return E_OK;
16696 +}
16697 +
16698 +t_Handle FmHcGetPort(t_Handle h_FmHc)
16699 +{
16700 + t_FmHc *p_FmHc = (t_FmHc*)h_FmHc;
16701 + return p_FmHc->h_HcPortDev;
16702 +}
16703 --- /dev/null
16704 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/Makefile
16705 @@ -0,0 +1,28 @@
16706 +#
16707 +# Makefile for the Freescale Ethernet controllers
16708 +#
16709 +ccflags-y += -DVERSION=\"\"
16710 +#
16711 +#Include netcomm SW specific definitions
16712 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
16713 +
16714 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
16715 +
16716 +ccflags-y += -I$(NCSW_FM_INC)
16717 +
16718 +obj-y += fsl-ncsw-MAC.o
16719 +
16720 +fsl-ncsw-MAC-objs := dtsec.o dtsec_mii_acc.o fm_mac.o tgec.o tgec_mii_acc.o \
16721 + fman_dtsec.o fman_dtsec_mii_acc.o fman_memac.o \
16722 + fman_tgec.o fman_crc32.o
16723 +
16724 +ifeq ($(CONFIG_FMAN_V3H),y)
16725 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
16726 +endif
16727 +ifeq ($(CONFIG_FMAN_V3L),y)
16728 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
16729 +endif
16730 +ifeq ($(CONFIG_FMAN_ARM),y)
16731 +fsl-ncsw-MAC-objs += memac.o memac_mii_acc.o fman_memac_mii_acc.o
16732 +endif
16733 +
16734 --- /dev/null
16735 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.c
16736 @@ -0,0 +1,1504 @@
16737 +/*
16738 + * Copyright 2008-2013 Freescale Semiconductor Inc.
16739 + *
16740 + * Redistribution and use in source and binary forms, with or without
16741 + * modification, are permitted provided that the following conditions are met:
16742 + * * Redistributions of source code must retain the above copyright
16743 + * notice, this list of conditions and the following disclaimer.
16744 + * * Redistributions in binary form must reproduce the above copyright
16745 + * notice, this list of conditions and the following disclaimer in the
16746 + * documentation and/or other materials provided with the distribution.
16747 + * * Neither the name of Freescale Semiconductor nor the
16748 + * names of its contributors may be used to endorse or promote products
16749 + * derived from this software without specific prior written permission.
16750 + *
16751 + *
16752 + * ALTERNATIVELY, this software may be distributed under the terms of the
16753 + * GNU General Public License ("GPL") as published by the Free Software
16754 + * Foundation, either version 2 of that License or (at your option) any
16755 + * later version.
16756 + *
16757 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
16758 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16759 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16760 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
16761 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16762 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
16763 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
16764 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
16765 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
16766 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16767 + */
16768 +
16769 +/******************************************************************************
16770 + @File dtsec.c
16771 +
16772 + @Description FMan dTSEC driver
16773 +*//***************************************************************************/
16774 +
16775 +#include "std_ext.h"
16776 +#include "error_ext.h"
16777 +#include "string_ext.h"
16778 +#include "xx_ext.h"
16779 +#include "endian_ext.h"
16780 +#include "debug_ext.h"
16781 +#include "crc_mac_addr_ext.h"
16782 +
16783 +#include "fm_common.h"
16784 +#include "dtsec.h"
16785 +#include "fsl_fman_dtsec.h"
16786 +#include "fsl_fman_dtsec_mii_acc.h"
16787 +
16788 +/*****************************************************************************/
16789 +/* Internal routines */
16790 +/*****************************************************************************/
16791 +
16792 +static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
16793 +{
16794 + if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
16795 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
16796 + if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
16797 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
16798 + if (p_Dtsec->addr == 0)
16799 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
16800 + if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
16801 + p_Dtsec->p_DtsecDriverParam->halfdup_on)
16802 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
16803 + if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
16804 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
16805 +#ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
16806 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
16807 + if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
16808 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
16809 +#endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
16810 + if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
16811 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
16812 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
16813 + (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
16814 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
16815 + if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
16816 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
16817 + if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend > MAX_PACKET_ALIGNMENT)
16818 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
16819 + if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1 > MAX_INTER_PACKET_GAP) ||
16820 + ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
16821 + ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
16822 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
16823 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
16824 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
16825 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
16826 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
16827 + if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
16828 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
16829 +
16830 + /* If Auto negotiation process is disabled, need to */
16831 + /* Set up the PHY using the MII Management Interface */
16832 + if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
16833 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
16834 + if (!p_Dtsec->f_Exception)
16835 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
16836 + if (!p_Dtsec->f_Event)
16837 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
16838 +
16839 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
16840 + if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
16841 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
16842 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
16843 +
16844 + return E_OK;
16845 +}
16846 +
16847 +/* ......................................................................... */
16848 +
16849 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
16850 +{
16851 + uint32_t crc;
16852 +
16853 + /* CRC calculation */
16854 + GET_MAC_ADDR_CRC(ethAddr, crc);
16855 +
16856 + crc = GetMirror32(crc);
16857 +
16858 + return crc;
16859 +}
16860 +
16861 +/* ......................................................................... */
16862 +
16863 +static void UpdateStatistics(t_Dtsec *p_Dtsec)
16864 +{
16865 + uint32_t car1, car2;
16866 +
16867 + fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
16868 +
16869 + if (car1)
16870 + {
16871 + if (car1 & CAR1_TR64)
16872 + p_Dtsec->internalStatistics.tr64 += VAL22BIT;
16873 + if (car1 & CAR1_TR127)
16874 + p_Dtsec->internalStatistics.tr127 += VAL22BIT;
16875 + if (car1 & CAR1_TR255)
16876 + p_Dtsec->internalStatistics.tr255 += VAL22BIT;
16877 + if (car1 & CAR1_TR511)
16878 + p_Dtsec->internalStatistics.tr511 += VAL22BIT;
16879 + if (car1 & CAR1_TRK1)
16880 + p_Dtsec->internalStatistics.tr1k += VAL22BIT;
16881 + if (car1 & CAR1_TRMAX)
16882 + p_Dtsec->internalStatistics.trmax += VAL22BIT;
16883 + if (car1 & CAR1_TRMGV)
16884 + p_Dtsec->internalStatistics.trmgv += VAL22BIT;
16885 + if (car1 & CAR1_RBYT)
16886 + p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
16887 + if (car1 & CAR1_RPKT)
16888 + p_Dtsec->internalStatistics.rpkt += VAL22BIT;
16889 + if (car1 & CAR1_RMCA)
16890 + p_Dtsec->internalStatistics.rmca += VAL22BIT;
16891 + if (car1 & CAR1_RBCA)
16892 + p_Dtsec->internalStatistics.rbca += VAL22BIT;
16893 + if (car1 & CAR1_RXPF)
16894 + p_Dtsec->internalStatistics.rxpf += VAL16BIT;
16895 + if (car1 & CAR1_RALN)
16896 + p_Dtsec->internalStatistics.raln += VAL16BIT;
16897 + if (car1 & CAR1_RFLR)
16898 + p_Dtsec->internalStatistics.rflr += VAL16BIT;
16899 + if (car1 & CAR1_RCDE)
16900 + p_Dtsec->internalStatistics.rcde += VAL16BIT;
16901 + if (car1 & CAR1_RCSE)
16902 + p_Dtsec->internalStatistics.rcse += VAL16BIT;
16903 + if (car1 & CAR1_RUND)
16904 + p_Dtsec->internalStatistics.rund += VAL16BIT;
16905 + if (car1 & CAR1_ROVR)
16906 + p_Dtsec->internalStatistics.rovr += VAL16BIT;
16907 + if (car1 & CAR1_RFRG)
16908 + p_Dtsec->internalStatistics.rfrg += VAL16BIT;
16909 + if (car1 & CAR1_RJBR)
16910 + p_Dtsec->internalStatistics.rjbr += VAL16BIT;
16911 + if (car1 & CAR1_RDRP)
16912 + p_Dtsec->internalStatistics.rdrp += VAL16BIT;
16913 + }
16914 + if (car2)
16915 + {
16916 + if (car2 & CAR2_TFCS)
16917 + p_Dtsec->internalStatistics.tfcs += VAL12BIT;
16918 + if (car2 & CAR2_TBYT)
16919 + p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
16920 + if (car2 & CAR2_TPKT)
16921 + p_Dtsec->internalStatistics.tpkt += VAL22BIT;
16922 + if (car2 & CAR2_TMCA)
16923 + p_Dtsec->internalStatistics.tmca += VAL22BIT;
16924 + if (car2 & CAR2_TBCA)
16925 + p_Dtsec->internalStatistics.tbca += VAL22BIT;
16926 + if (car2 & CAR2_TXPF)
16927 + p_Dtsec->internalStatistics.txpf += VAL16BIT;
16928 + if (car2 & CAR2_TDRP)
16929 + p_Dtsec->internalStatistics.tdrp += VAL16BIT;
16930 + }
16931 +}
16932 +
16933 +/* .............................................................................. */
16934 +
16935 +static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
16936 +{
16937 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16938 +
16939 + SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
16940 + SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
16941 +
16942 + return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
16943 +}
16944 +
16945 +/* .............................................................................. */
16946 +
16947 +static void DtsecIsr(t_Handle h_Dtsec)
16948 +{
16949 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
16950 + uint32_t event;
16951 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
16952 +
16953 + /* do not handle MDIO events */
16954 + event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
16955 +
16956 + event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
16957 +
16958 + fman_dtsec_ack_event(p_DtsecMemMap, event);
16959 +
16960 + if (event & DTSEC_IMASK_BREN)
16961 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
16962 + if (event & DTSEC_IMASK_RXCEN)
16963 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
16964 + if (event & DTSEC_IMASK_MSROEN)
16965 + UpdateStatistics(p_Dtsec);
16966 + if (event & DTSEC_IMASK_GTSCEN)
16967 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
16968 + if (event & DTSEC_IMASK_BTEN)
16969 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
16970 + if (event & DTSEC_IMASK_TXCEN)
16971 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
16972 + if (event & DTSEC_IMASK_TXEEN)
16973 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
16974 + if (event & DTSEC_IMASK_LCEN)
16975 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
16976 + if (event & DTSEC_IMASK_CRLEN)
16977 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
16978 + if (event & DTSEC_IMASK_XFUNEN)
16979 + {
16980 +#ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
16981 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
16982 + {
16983 + uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
16984 + /* a. Write 0x00E0_0C00 to DTSEC_ID */
16985 + /* This is a read only regidter */
16986 +
16987 + /* b. Read and save the value of TPKT */
16988 + tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
16989 +
16990 + /* c. Read the register at dTSEC address offset 0x32C */
16991 + tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
16992 +
16993 + /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
16994 + if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
16995 + {
16996 + /* If they are not equal, save the value of this register and wait for at least
16997 + * MAXFRM*16 ns */
16998 + XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
16999 + }
17000 +
17001 + /* e. Read and save TPKT again and read the register at dTSEC address offset
17002 + 0x32C again*/
17003 + tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
17004 + tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
17005 +
17006 + /* f. Compare the value of TPKT saved in step b to value read in step e. Also
17007 + compare bits [9:15] of the register at offset 0x32C saved in step d to the value
17008 + of bits [9:15] saved in step e. If the two registers values are unchanged, then
17009 + the transmit portion of the dTSEC controller is locked up and the user should
17010 + proceed to the recover sequence. */
17011 + if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
17012 + {
17013 + /* recover sequence */
17014 +
17015 + /* a.Write a 1 to RCTRL[GRS]*/
17016 +
17017 + WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
17018 +
17019 + /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
17020 + for (i = 0 ; i < 100 ; i++ )
17021 + {
17022 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
17023 + break;
17024 + XX_UDelay(1);
17025 + }
17026 + if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
17027 + WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
17028 + else
17029 + DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
17030 +
17031 + /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
17032 + FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
17033 +
17034 + /* d.Wait 4 Tx clocks (32 ns) */
17035 + XX_UDelay(1);
17036 +
17037 + /* e.Write a 0 to bit n of FM_RSTC. */
17038 + /* cleared by FMAN */
17039 + }
17040 + }
17041 +#endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
17042 +
17043 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
17044 + }
17045 + if (event & DTSEC_IMASK_MAGEN)
17046 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
17047 + if (event & DTSEC_IMASK_GRSCEN)
17048 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
17049 + if (event & DTSEC_IMASK_TDPEEN)
17050 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
17051 + if (event & DTSEC_IMASK_RDPEEN)
17052 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
17053 +
17054 + /* - masked interrupts */
17055 + ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
17056 + ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
17057 +}
17058 +
17059 +static void DtsecMdioIsr(t_Handle h_Dtsec)
17060 +{
17061 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17062 + uint32_t event;
17063 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
17064 +
17065 + event = GET_UINT32(p_DtsecMemMap->ievent);
17066 + /* handle only MDIO events */
17067 + event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
17068 + if (event)
17069 + {
17070 + event &= GET_UINT32(p_DtsecMemMap->imask);
17071 +
17072 + WRITE_UINT32(p_DtsecMemMap->ievent, event);
17073 +
17074 + if (event & DTSEC_IMASK_MMRDEN)
17075 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
17076 + if (event & DTSEC_IMASK_MMWREN)
17077 + p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
17078 + }
17079 +}
17080 +
17081 +static void Dtsec1588Isr(t_Handle h_Dtsec)
17082 +{
17083 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17084 + uint32_t event;
17085 + struct dtsec_regs *p_DtsecMemMap = p_Dtsec->p_MemMap;
17086 +
17087 + if (p_Dtsec->ptpTsuEnabled)
17088 + {
17089 + event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
17090 +
17091 + if (event)
17092 + {
17093 + ASSERT_COND(event & TMR_PEVENT_TSRE);
17094 + p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
17095 + }
17096 + }
17097 +}
17098 +
17099 +/* ........................................................................... */
17100 +
17101 +static void FreeInitResources(t_Dtsec *p_Dtsec)
17102 +{
17103 + if (p_Dtsec->mdioIrq != NO_IRQ)
17104 + {
17105 + XX_DisableIntr(p_Dtsec->mdioIrq);
17106 + XX_FreeIntr(p_Dtsec->mdioIrq);
17107 + }
17108 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
17109 + FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
17110 +
17111 + /* release the driver's group hash table */
17112 + FreeHashTable(p_Dtsec->p_MulticastAddrHash);
17113 + p_Dtsec->p_MulticastAddrHash = NULL;
17114 +
17115 + /* release the driver's individual hash table */
17116 + FreeHashTable(p_Dtsec->p_UnicastAddrHash);
17117 + p_Dtsec->p_UnicastAddrHash = NULL;
17118 +}
17119 +
17120 +/* ........................................................................... */
17121 +
17122 +static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
17123 +{
17124 + struct dtsec_regs *p_MemMap;
17125 + int pollTimeout = 0;
17126 +
17127 + ASSERT_COND(p_Dtsec);
17128 +
17129 + p_MemMap = p_Dtsec->p_MemMap;
17130 + ASSERT_COND(p_MemMap);
17131 +
17132 + /* Assert the graceful transmit stop bit */
17133 + if (mode & e_COMM_MODE_RX)
17134 + {
17135 + fman_dtsec_stop_rx(p_MemMap);
17136 +
17137 +#ifdef FM_GRS_ERRATA_DTSEC_A002
17138 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
17139 + XX_UDelay(100);
17140 +#else /* FM_GRS_ERRATA_DTSEC_A002 */
17141 +#ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
17142 + XX_UDelay(10);
17143 +#endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
17144 +#endif /* FM_GRS_ERRATA_DTSEC_A002 */
17145 + }
17146 +
17147 + if (mode & e_COMM_MODE_TX)
17148 + {
17149 +#if defined(FM_GTS_ERRATA_DTSEC_A004)
17150 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
17151 + DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
17152 +#else /* not defined(FM_GTS_ERRATA_DTSEC_A004) */
17153 +
17154 + fman_dtsec_stop_tx(p_MemMap);
17155 +
17156 +#if defined(FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
17157 + XX_UDelay(10);
17158 +#endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 || FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012 */
17159 +#endif /* defined(FM_GTS_ERRATA_DTSEC_A004) */
17160 + }
17161 +
17162 + /* Poll GRSC/GTSC bits in IEVENT register until both are set */
17163 +#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)
17164 + XX_UDelay(10);
17165 +#else
17166 + while (fman_dtsec_get_event(p_MemMap, DTSEC_IMASK_GRSCEN | DTSEC_IMASK_GTSCEN) != (DTSEC_IMASK_GRSCEN | DTSEC_IMASK_GTSCEN))
17167 + {
17168 + if (pollTimeout == 100)
17169 + break;
17170 + XX_UDelay(1);
17171 + pollTimeout++;
17172 + }
17173 +#endif
17174 +
17175 + return E_OK;
17176 +}
17177 +
17178 +/* .............................................................................. */
17179 +
17180 +static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
17181 +{
17182 + struct dtsec_regs *p_MemMap;
17183 +
17184 + ASSERT_COND(p_Dtsec);
17185 + p_MemMap = p_Dtsec->p_MemMap;
17186 + ASSERT_COND(p_MemMap);
17187 +
17188 + /* clear the graceful receive stop bit */
17189 + if (mode & e_COMM_MODE_TX)
17190 + fman_dtsec_start_tx(p_MemMap);
17191 +
17192 + if (mode & e_COMM_MODE_RX)
17193 + fman_dtsec_start_rx(p_MemMap);
17194 +
17195 + return E_OK;
17196 +}
17197 +
17198 +
17199 +/*****************************************************************************/
17200 +/* dTSEC Configs modification functions */
17201 +/*****************************************************************************/
17202 +
17203 +/* .............................................................................. */
17204 +
17205 +static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
17206 +{
17207 +
17208 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17209 +
17210 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17211 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17212 +
17213 + p_Dtsec->p_DtsecDriverParam->loopback = newVal;
17214 +
17215 + return E_OK;
17216 +}
17217 +
17218 +/* .............................................................................. */
17219 +
17220 +static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
17221 +{
17222 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17223 +
17224 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17225 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17226 +
17227 + p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
17228 +
17229 + return E_OK;
17230 +}
17231 +
17232 +/* .............................................................................. */
17233 +
17234 +static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
17235 +{
17236 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17237 +
17238 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17239 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17240 +
17241 + p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
17242 +
17243 + return E_OK;
17244 +}
17245 +
17246 +/* .............................................................................. */
17247 +
17248 +static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
17249 +{
17250 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17251 +
17252 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17253 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17254 +
17255 + p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
17256 +
17257 + return E_OK;
17258 +}
17259 +
17260 +/* .............................................................................. */
17261 +
17262 +static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
17263 +{
17264 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17265 +
17266 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17267 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17268 +
17269 + p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
17270 +
17271 + return E_OK;
17272 +}
17273 +
17274 +/* .............................................................................. */
17275 +
17276 +static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
17277 +{
17278 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17279 +
17280 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17281 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17282 +
17283 + p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
17284 +
17285 + return E_OK;
17286 +}
17287 +
17288 +/* .............................................................................. */
17289 +
17290 +static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
17291 +{
17292 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17293 + uint32_t bitMask = 0;
17294 +
17295 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17296 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17297 +
17298 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
17299 + {
17300 + GET_EXCEPTION_FLAG(bitMask, exception);
17301 + if (bitMask)
17302 + {
17303 + if (enable)
17304 + p_Dtsec->exceptions |= bitMask;
17305 + else
17306 + p_Dtsec->exceptions &= ~bitMask;
17307 + }
17308 + else
17309 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
17310 + }
17311 + else
17312 + {
17313 + if (!p_Dtsec->ptpTsuEnabled)
17314 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
17315 +
17316 + if (enable)
17317 + p_Dtsec->enTsuErrExeption = TRUE;
17318 + else
17319 + p_Dtsec->enTsuErrExeption = FALSE;
17320 + }
17321 +
17322 + return E_OK;
17323 +}
17324 +
17325 +
17326 +/*****************************************************************************/
17327 +/* dTSEC Run Time API functions */
17328 +/*****************************************************************************/
17329 +
17330 +/* .............................................................................. */
17331 +
17332 +static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
17333 +{
17334 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17335 +
17336 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17337 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17338 +
17339 + fman_dtsec_enable(p_Dtsec->p_MemMap,
17340 + (bool)!!(mode & e_COMM_MODE_RX),
17341 + (bool)!!(mode & e_COMM_MODE_TX));
17342 +
17343 + GracefulRestart(p_Dtsec, mode);
17344 +
17345 + return E_OK;
17346 +}
17347 +
17348 +/* .............................................................................. */
17349 +
17350 +static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
17351 +{
17352 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17353 +
17354 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17355 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17356 +
17357 + GracefulStop(p_Dtsec, mode);
17358 +
17359 + fman_dtsec_disable(p_Dtsec->p_MemMap,
17360 + (bool)!!(mode & e_COMM_MODE_RX),
17361 + (bool)!!(mode & e_COMM_MODE_TX));
17362 +
17363 + return E_OK;
17364 +}
17365 +
17366 +/* .............................................................................. */
17367 +
17368 +static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
17369 + uint8_t priority,
17370 + uint16_t pauseTime,
17371 + uint16_t threshTime)
17372 +{
17373 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17374 +
17375 + UNUSED(priority);UNUSED(threshTime);
17376 +
17377 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
17378 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17379 +
17380 +#ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
17381 + if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
17382 + if (0 < pauseTime && pauseTime <= 320)
17383 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
17384 + ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
17385 + " value should be greater than 320."));
17386 +#endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
17387 +
17388 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17389 +
17390 + fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
17391 +
17392 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17393 +
17394 + return E_OK;
17395 +}
17396 +
17397 +/* .............................................................................. */
17398 +/* backward compatibility. will be removed in the future. */
17399 +static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
17400 +{
17401 + return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
17402 +}
17403 +
17404 +/* .............................................................................. */
17405 +
17406 +static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
17407 +{
17408 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17409 + bool accept_pause = !en;
17410 +
17411 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
17412 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17413 +
17414 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17415 +
17416 + fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
17417 +
17418 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17419 +
17420 + return E_OK;
17421 +}
17422 +
17423 +/* .............................................................................. */
17424 +
17425 +static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
17426 +{
17427 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17428 +
17429 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17430 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17431 +
17432 + p_Dtsec->ptpTsuEnabled = TRUE;
17433 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
17434 +
17435 + return E_OK;
17436 +}
17437 +
17438 +/* .............................................................................. */
17439 +
17440 +static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
17441 +{
17442 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17443 +
17444 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17445 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17446 +
17447 + p_Dtsec->ptpTsuEnabled = FALSE;
17448 + fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
17449 +
17450 + return E_OK;
17451 +}
17452 +
17453 +/* .............................................................................. */
17454 +
17455 +static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
17456 +{
17457 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17458 + struct dtsec_regs *p_DtsecMemMap;
17459 +
17460 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17461 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17462 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
17463 +
17464 + p_DtsecMemMap = p_Dtsec->p_MemMap;
17465 +
17466 + if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
17467 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
17468 +
17469 + memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
17470 +
17471 + if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
17472 + {
17473 + p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
17474 + + p_Dtsec->internalStatistics.tr64;
17475 + p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
17476 + + p_Dtsec->internalStatistics.tr127;
17477 + p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
17478 + + p_Dtsec->internalStatistics.tr255;
17479 + p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
17480 + + p_Dtsec->internalStatistics.tr511;
17481 + p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
17482 + + p_Dtsec->internalStatistics.tr1k;
17483 + p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
17484 + + p_Dtsec->internalStatistics.trmax;
17485 + p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
17486 + + p_Dtsec->internalStatistics.trmgv;
17487 +
17488 + /* MIB II */
17489 + p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
17490 + + p_Dtsec->internalStatistics.rbyt;
17491 + p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
17492 + + p_Dtsec->internalStatistics.rpkt;
17493 + p_Statistics->ifInUcastPkts = 0;
17494 + p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
17495 + + p_Dtsec->internalStatistics.rmca;
17496 + p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
17497 + + p_Dtsec->internalStatistics.rbca;
17498 + p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
17499 + + p_Dtsec->internalStatistics.tbyt;
17500 + p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
17501 + + p_Dtsec->internalStatistics.tpkt;
17502 + p_Statistics->ifOutUcastPkts = 0;
17503 + p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
17504 + + p_Dtsec->internalStatistics.tmca;
17505 + p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
17506 + + p_Dtsec->internalStatistics.tbca;
17507 + }
17508 +
17509 + p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
17510 + + p_Dtsec->internalStatistics.rfrg;
17511 + p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
17512 + + p_Dtsec->internalStatistics.rjbr;
17513 + p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
17514 + + p_Dtsec->internalStatistics.rdrp;
17515 + p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
17516 + + p_Dtsec->internalStatistics.raln;
17517 + p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
17518 + + p_Dtsec->internalStatistics.rund;
17519 + p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
17520 + + p_Dtsec->internalStatistics.rovr;
17521 + p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
17522 + + p_Dtsec->internalStatistics.rxpf;
17523 + p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
17524 + + p_Dtsec->internalStatistics.txpf;
17525 + p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
17526 + p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
17527 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
17528 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
17529 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
17530 +
17531 + p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
17532 + + p_Dtsec->internalStatistics.tdrp;
17533 + p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
17534 + + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
17535 + + p_Dtsec->internalStatistics.tfcs;
17536 +
17537 + return E_OK;
17538 +}
17539 +
17540 +/* .............................................................................. */
17541 +
17542 +static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
17543 +{
17544 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17545 +
17546 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17547 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17548 +
17549 + /* Initialize MAC Station Address registers (1 & 2) */
17550 + /* Station address have to be swapped (big endian to little endian */
17551 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
17552 +
17553 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17554 +
17555 + fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
17556 +
17557 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17558 +
17559 + return E_OK;
17560 +}
17561 +
17562 +/* .............................................................................. */
17563 +
17564 +static t_Error DtsecResetCounters (t_Handle h_Dtsec)
17565 +{
17566 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17567 +
17568 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17569 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17570 +
17571 + /* clear HW counters */
17572 + fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
17573 +
17574 + /* clear SW counters holding carries */
17575 + memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
17576 +
17577 + return E_OK;
17578 +}
17579 +
17580 +/* .............................................................................. */
17581 +
17582 +static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
17583 +{
17584 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
17585 + uint64_t ethAddr;
17586 + uint8_t paddrNum;
17587 +
17588 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17589 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17590 +
17591 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
17592 +
17593 + if (ethAddr & GROUP_ADDRESS)
17594 + /* Multicast address has no effect in PADDR */
17595 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
17596 +
17597 + /* Make sure no PADDR contains this address */
17598 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
17599 + if (p_Dtsec->indAddrRegUsed[paddrNum])
17600 + if (p_Dtsec->paddr[paddrNum] == ethAddr)
17601 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
17602 +
17603 + /* Find first unused PADDR */
17604 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
17605 + if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
17606 + {
17607 + /* mark this PADDR as used */
17608 + p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
17609 + /* store address */
17610 + p_Dtsec->paddr[paddrNum] = ethAddr;
17611 +
17612 + /* put in hardware */
17613 + fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
17614 + p_Dtsec->numOfIndAddrInRegs++;
17615 +
17616 + return E_OK;
17617 + }
17618 +
17619 + /* No free PADDR */
17620 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
17621 +}
17622 +
17623 +/* .............................................................................. */
17624 +
17625 +static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
17626 +{
17627 + t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
17628 + uint64_t ethAddr;
17629 + uint8_t paddrNum;
17630 +
17631 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17632 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17633 +
17634 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
17635 +
17636 + /* Find used PADDR containing this address */
17637 + for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
17638 + {
17639 + if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
17640 + (p_Dtsec->paddr[paddrNum] == ethAddr))
17641 + {
17642 + /* mark this PADDR as not used */
17643 + p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
17644 + /* clear in hardware */
17645 + fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
17646 + p_Dtsec->numOfIndAddrInRegs--;
17647 +
17648 + return E_OK;
17649 + }
17650 + }
17651 +
17652 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
17653 +}
17654 +
17655 +/* .............................................................................. */
17656 +
17657 +static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
17658 +{
17659 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17660 + t_EthHashEntry *p_HashEntry;
17661 + uint64_t ethAddr;
17662 + int32_t bucket;
17663 + uint32_t crc;
17664 + bool mcast, ghtx;
17665 +
17666 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17667 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17668 +
17669 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
17670 +
17671 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
17672 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
17673 +
17674 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
17675 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
17676 +
17677 + crc = GetMacAddrHashCode(ethAddr);
17678 +
17679 + /* considering the 9 highest order bits in crc H[8:0]:
17680 + * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
17681 + * and H[5:1] (next 5 bits) identify the hash bit
17682 + * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
17683 + * and H[4:0] (next 5 bits) identify the hash bit.
17684 + *
17685 + * In bucket index output the low 5 bits identify the hash register bit,
17686 + * while the higher 4 bits identify the hash register
17687 + */
17688 +
17689 + if (ghtx)
17690 + bucket = (int32_t)((crc >> 23) & 0x1ff);
17691 + else {
17692 + bucket = (int32_t)((crc >> 24) & 0xff);
17693 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
17694 + if (mcast)
17695 + bucket += 0x100;
17696 + }
17697 +
17698 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
17699 +
17700 + /* Create element to be added to the driver hash table */
17701 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
17702 + p_HashEntry->addr = ethAddr;
17703 + INIT_LIST(&p_HashEntry->node);
17704 +
17705 + if (ethAddr & MAC_GROUP_ADDRESS)
17706 + /* Group Address */
17707 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
17708 + else
17709 + LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
17710 +
17711 + return E_OK;
17712 +}
17713 +
17714 +/* .............................................................................. */
17715 +
17716 +static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
17717 +{
17718 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17719 + t_List *p_Pos;
17720 + t_EthHashEntry *p_HashEntry = NULL;
17721 + uint64_t ethAddr;
17722 + int32_t bucket;
17723 + uint32_t crc;
17724 + bool mcast, ghtx;
17725 +
17726 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17727 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17728 +
17729 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
17730 +
17731 + ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
17732 + mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
17733 +
17734 + if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
17735 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
17736 +
17737 + crc = GetMacAddrHashCode(ethAddr);
17738 +
17739 + if (ghtx)
17740 + bucket = (int32_t)((crc >> 23) & 0x1ff);
17741 + else {
17742 + bucket = (int32_t)((crc >> 24) & 0xff);
17743 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
17744 + if (mcast)
17745 + bucket += 0x100;
17746 + }
17747 +
17748 + if (ethAddr & MAC_GROUP_ADDRESS)
17749 + {
17750 + /* Group Address */
17751 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
17752 + {
17753 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
17754 + if (p_HashEntry->addr == ethAddr)
17755 + {
17756 + LIST_DelAndInit(&p_HashEntry->node);
17757 + XX_Free(p_HashEntry);
17758 + break;
17759 + }
17760 + }
17761 + if (LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
17762 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
17763 + }
17764 + else
17765 + {
17766 + /* Individual Address */
17767 + LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
17768 + {
17769 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
17770 + if (p_HashEntry->addr == ethAddr)
17771 + {
17772 + LIST_DelAndInit(&p_HashEntry->node);
17773 + XX_Free(p_HashEntry);
17774 + break;
17775 + }
17776 + }
17777 + if (LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
17778 + fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
17779 + }
17780 +
17781 + /* address does not exist */
17782 + ASSERT_COND(p_HashEntry != NULL);
17783 +
17784 + return E_OK;
17785 +}
17786 +
17787 +/* .............................................................................. */
17788 +
17789 +static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
17790 +{
17791 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17792 +
17793 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17794 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17795 +
17796 + fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
17797 + fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
17798 +
17799 + return E_OK;
17800 +}
17801 +
17802 +/* .............................................................................. */
17803 +
17804 +static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
17805 +{
17806 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17807 + t_Error err;
17808 +
17809 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17810 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17811 +
17812 + p_Dtsec->statisticsLevel = statisticsLevel;
17813 +
17814 + err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
17815 + (enum dtsec_stat_level)statisticsLevel);
17816 + if (err != E_OK)
17817 + return err;
17818 +
17819 + switch (statisticsLevel)
17820 + {
17821 + case (e_FM_MAC_NONE_STATISTICS):
17822 + p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
17823 + break;
17824 + case (e_FM_MAC_PARTIAL_STATISTICS):
17825 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
17826 + break;
17827 + case (e_FM_MAC_FULL_STATISTICS):
17828 + p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
17829 + break;
17830 + default:
17831 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
17832 + }
17833 +
17834 + return E_OK;
17835 +}
17836 +
17837 +/* .............................................................................. */
17838 +
17839 +static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
17840 +{
17841 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17842 +
17843 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
17844 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17845 +
17846 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17847 +
17848 + fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
17849 +
17850 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17851 +
17852 + return E_OK;
17853 +}
17854 +
17855 +/* .............................................................................. */
17856 +
17857 +static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
17858 +{
17859 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17860 + int err;
17861 + enum enet_interface enet_interface;
17862 + enum enet_speed enet_speed;
17863 +
17864 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17865 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17866 +
17867 + p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
17868 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
17869 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
17870 + p_Dtsec->halfDuplex = !fullDuplex;
17871 +
17872 + GracefulStop(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17873 +
17874 + err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
17875 +
17876 + if (err == -EINVAL)
17877 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
17878 +
17879 + GracefulRestart(p_Dtsec, e_COMM_MODE_RX_AND_TX);
17880 +
17881 + return (t_Error)err;
17882 +}
17883 +
17884 +/* .............................................................................. */
17885 +
17886 +static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
17887 +{
17888 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17889 + uint16_t tmpReg16;
17890 +
17891 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17892 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17893 +
17894 + DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
17895 +
17896 + tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
17897 + tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
17898 +
17899 + DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
17900 +
17901 + return E_OK;
17902 +}
17903 +
17904 +/* .............................................................................. */
17905 +
17906 +static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
17907 +{
17908 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17909 +
17910 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17911 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17912 +
17913 + *macId = p_Dtsec->macId;
17914 +
17915 + return E_OK;
17916 +}
17917 +
17918 +/* .............................................................................. */
17919 +
17920 +static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
17921 +{
17922 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17923 +
17924 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17925 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17926 +
17927 + *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
17928 +
17929 + return E_OK;
17930 +}
17931 +
17932 +/* .............................................................................. */
17933 +
17934 +static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
17935 +{
17936 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17937 + uint32_t bitMask = 0;
17938 +
17939 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17940 + SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17941 +
17942 + if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
17943 + {
17944 + GET_EXCEPTION_FLAG(bitMask, exception);
17945 + if (bitMask)
17946 + {
17947 + if (enable)
17948 + p_Dtsec->exceptions |= bitMask;
17949 + else
17950 + p_Dtsec->exceptions &= ~bitMask;
17951 + }
17952 + else
17953 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
17954 +
17955 + if (enable)
17956 + fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
17957 + else
17958 + fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
17959 + }
17960 + else
17961 + {
17962 + if (!p_Dtsec->ptpTsuEnabled)
17963 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
17964 +
17965 + if (enable)
17966 + {
17967 + p_Dtsec->enTsuErrExeption = TRUE;
17968 + fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
17969 + }
17970 + else
17971 + {
17972 + p_Dtsec->enTsuErrExeption = FALSE;
17973 + fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
17974 + }
17975 + }
17976 +
17977 + return E_OK;
17978 +}
17979 +
17980 +
17981 +/*****************************************************************************/
17982 +/* dTSEC Init & Free API */
17983 +/*****************************************************************************/
17984 +
17985 +/* .............................................................................. */
17986 +
17987 +static t_Error DtsecInit(t_Handle h_Dtsec)
17988 +{
17989 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
17990 + struct dtsec_cfg *p_DtsecDriverParam;
17991 + t_Error err;
17992 + uint16_t maxFrmLn;
17993 + enum enet_interface enet_interface;
17994 + enum enet_speed enet_speed;
17995 + t_EnetAddr ethAddr;
17996 +
17997 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
17998 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
17999 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
18000 +
18001 + FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
18002 + CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
18003 +
18004 + p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
18005 + p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
18006 +
18007 + enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
18008 + enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
18009 + MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
18010 +
18011 + err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
18012 + p_DtsecDriverParam,
18013 + enet_interface,
18014 + enet_speed,
18015 + (uint8_t*)ethAddr,
18016 + p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
18017 + p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
18018 + p_Dtsec->exceptions);
18019 + if (err)
18020 + {
18021 + FreeInitResources(p_Dtsec);
18022 + RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
18023 + }
18024 +
18025 + if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
18026 + {
18027 + uint16_t tmpReg16;
18028 +
18029 + /* Configure the TBI PHY Control Register */
18030 + tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
18031 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
18032 +
18033 + tmpReg16 = PHY_TBICON_CLK_SEL;
18034 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
18035 +
18036 + tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
18037 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
18038 +
18039 + if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
18040 + tmpReg16 = PHY_TBIANA_1000X;
18041 + else
18042 + tmpReg16 = PHY_TBIANA_SGMII;
18043 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
18044 +
18045 + tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
18046 +
18047 + DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
18048 + }
18049 +
18050 + /* Max Frame Length */
18051 + maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
18052 + err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
18053 + p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
18054 + if (err)
18055 + RETURN_ERROR(MINOR,err, NO_MSG);
18056 +
18057 + p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
18058 + if (!p_Dtsec->p_MulticastAddrHash) {
18059 + FreeInitResources(p_Dtsec);
18060 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
18061 + }
18062 +
18063 + p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
18064 + if (!p_Dtsec->p_UnicastAddrHash)
18065 + {
18066 + FreeInitResources(p_Dtsec);
18067 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
18068 + }
18069 +
18070 + /* register err intr handler for dtsec to FPM (err)*/
18071 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
18072 + e_FM_MOD_1G_MAC,
18073 + p_Dtsec->macId,
18074 + e_FM_INTR_TYPE_ERR,
18075 + DtsecIsr,
18076 + p_Dtsec);
18077 + /* register 1588 intr handler for TMR to FPM (normal)*/
18078 + FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
18079 + e_FM_MOD_1G_MAC,
18080 + p_Dtsec->macId,
18081 + e_FM_INTR_TYPE_NORMAL,
18082 + Dtsec1588Isr,
18083 + p_Dtsec);
18084 + /* register normal intr handler for dtsec to main interrupt controller. */
18085 + if (p_Dtsec->mdioIrq != NO_IRQ)
18086 + {
18087 + XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
18088 + XX_EnableIntr(p_Dtsec->mdioIrq);
18089 + }
18090 +
18091 + XX_Free(p_DtsecDriverParam);
18092 + p_Dtsec->p_DtsecDriverParam = NULL;
18093 +
18094 + err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
18095 + if (err)
18096 + {
18097 + FreeInitResources(p_Dtsec);
18098 + RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
18099 + }
18100 +
18101 + return E_OK;
18102 +}
18103 +
18104 +/* ........................................................................... */
18105 +
18106 +static t_Error DtsecFree(t_Handle h_Dtsec)
18107 +{
18108 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
18109 +
18110 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
18111 +
18112 + if (p_Dtsec->p_DtsecDriverParam)
18113 + {
18114 + /* Called after config */
18115 + XX_Free(p_Dtsec->p_DtsecDriverParam);
18116 + p_Dtsec->p_DtsecDriverParam = NULL;
18117 + }
18118 + else
18119 + /* Called after init */
18120 + FreeInitResources(p_Dtsec);
18121 +
18122 + XX_Free(p_Dtsec);
18123 +
18124 + return E_OK;
18125 +}
18126 +
18127 +/* .............................................................................. */
18128 +
18129 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
18130 +{
18131 + p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
18132 + p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
18133 +
18134 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
18135 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
18136 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
18137 +
18138 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
18139 +
18140 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
18141 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
18142 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
18143 + p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr = DtsecConfigTbiPhyAddr;
18144 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
18145 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
18146 +
18147 + p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
18148 + p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
18149 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
18150 +
18151 + p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
18152 +
18153 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
18154 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
18155 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = DtsecSetWakeOnLan;
18156 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = DtsecRestartAutoneg;
18157 +
18158 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
18159 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
18160 +
18161 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
18162 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = DtsecSetTxPauseFrames;
18163 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
18164 +
18165 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
18166 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
18167 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = NULL;
18168 +
18169 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
18170 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
18171 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
18172 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
18173 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
18174 + p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
18175 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
18176 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
18177 +
18178 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
18179 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
18180 +
18181 +}
18182 +
18183 +
18184 +/*****************************************************************************/
18185 +/* dTSEC Config Main Entry */
18186 +/*****************************************************************************/
18187 +
18188 +/* .............................................................................. */
18189 +
18190 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
18191 +{
18192 + t_Dtsec *p_Dtsec;
18193 + struct dtsec_cfg *p_DtsecDriverParam;
18194 + uintptr_t baseAddr;
18195 +
18196 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
18197 +
18198 + baseAddr = p_FmMacParam->baseAddr;
18199 +
18200 + /* allocate memory for the UCC GETH data structure. */
18201 + p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
18202 + if (!p_Dtsec)
18203 + {
18204 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
18205 + return NULL;
18206 + }
18207 + memset(p_Dtsec, 0, sizeof(t_Dtsec));
18208 + InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
18209 +
18210 + /* allocate memory for the dTSEC driver parameters data structure. */
18211 + p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
18212 + if (!p_DtsecDriverParam)
18213 + {
18214 + XX_Free(p_Dtsec);
18215 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
18216 + return NULL;
18217 + }
18218 + memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
18219 +
18220 + /* Plant parameter structure pointer */
18221 + p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
18222 +
18223 + fman_dtsec_defconfig(p_DtsecDriverParam);
18224 +
18225 + p_Dtsec->p_MemMap = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
18226 + p_Dtsec->p_MiiMemMap = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
18227 + p_Dtsec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
18228 + p_Dtsec->enetMode = p_FmMacParam->enetMode;
18229 + p_Dtsec->macId = p_FmMacParam->macId;
18230 + p_Dtsec->exceptions = DEFAULT_exceptions;
18231 + p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
18232 + p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
18233 + p_Dtsec->f_Event = p_FmMacParam->f_Event;
18234 + p_Dtsec->h_App = p_FmMacParam->h_App;
18235 + p_Dtsec->ptpTsuEnabled = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
18236 + p_Dtsec->enTsuErrExeption = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
18237 + p_Dtsec->tbi_phy_addr = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
18238 +
18239 + return p_Dtsec;
18240 +}
18241 --- /dev/null
18242 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec.h
18243 @@ -0,0 +1,228 @@
18244 +/*
18245 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18246 + *
18247 + * Redistribution and use in source and binary forms, with or without
18248 + * modification, are permitted provided that the following conditions are met:
18249 + * * Redistributions of source code must retain the above copyright
18250 + * notice, this list of conditions and the following disclaimer.
18251 + * * Redistributions in binary form must reproduce the above copyright
18252 + * notice, this list of conditions and the following disclaimer in the
18253 + * documentation and/or other materials provided with the distribution.
18254 + * * Neither the name of Freescale Semiconductor nor the
18255 + * names of its contributors may be used to endorse or promote products
18256 + * derived from this software without specific prior written permission.
18257 + *
18258 + *
18259 + * ALTERNATIVELY, this software may be distributed under the terms of the
18260 + * GNU General Public License ("GPL") as published by the Free Software
18261 + * Foundation, either version 2 of that License or (at your option) any
18262 + * later version.
18263 + *
18264 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18265 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18266 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18267 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18268 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18269 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18270 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18271 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18272 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18273 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18274 + */
18275 +
18276 +/******************************************************************************
18277 + @File dtsec.h
18278 +
18279 + @Description FM dTSEC ...
18280 +*//***************************************************************************/
18281 +#ifndef __DTSEC_H
18282 +#define __DTSEC_H
18283 +
18284 +#include "std_ext.h"
18285 +#include "error_ext.h"
18286 +#include "list_ext.h"
18287 +#include "enet_ext.h"
18288 +
18289 +#include "dtsec_mii_acc.h"
18290 +#include "fm_mac.h"
18291 +
18292 +
18293 +#define DEFAULT_exceptions \
18294 + ((uint32_t)(DTSEC_IMASK_BREN | \
18295 + DTSEC_IMASK_RXCEN | \
18296 + DTSEC_IMASK_BTEN | \
18297 + DTSEC_IMASK_TXCEN | \
18298 + DTSEC_IMASK_TXEEN | \
18299 + DTSEC_IMASK_ABRTEN | \
18300 + DTSEC_IMASK_LCEN | \
18301 + DTSEC_IMASK_CRLEN | \
18302 + DTSEC_IMASK_XFUNEN | \
18303 + DTSEC_IMASK_IFERREN | \
18304 + DTSEC_IMASK_MAGEN | \
18305 + DTSEC_IMASK_TDPEEN | \
18306 + DTSEC_IMASK_RDPEEN))
18307 +
18308 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
18309 + case e_FM_MAC_EX_1G_BAB_RX: \
18310 + bitMask = DTSEC_IMASK_BREN; break; \
18311 + case e_FM_MAC_EX_1G_RX_CTL: \
18312 + bitMask = DTSEC_IMASK_RXCEN; break; \
18313 + case e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET: \
18314 + bitMask = DTSEC_IMASK_GTSCEN ; break; \
18315 + case e_FM_MAC_EX_1G_BAB_TX: \
18316 + bitMask = DTSEC_IMASK_BTEN ; break; \
18317 + case e_FM_MAC_EX_1G_TX_CTL: \
18318 + bitMask = DTSEC_IMASK_TXCEN ; break; \
18319 + case e_FM_MAC_EX_1G_TX_ERR: \
18320 + bitMask = DTSEC_IMASK_TXEEN ; break; \
18321 + case e_FM_MAC_EX_1G_LATE_COL: \
18322 + bitMask = DTSEC_IMASK_LCEN ; break; \
18323 + case e_FM_MAC_EX_1G_COL_RET_LMT: \
18324 + bitMask = DTSEC_IMASK_CRLEN ; break; \
18325 + case e_FM_MAC_EX_1G_TX_FIFO_UNDRN: \
18326 + bitMask = DTSEC_IMASK_XFUNEN ; break; \
18327 + case e_FM_MAC_EX_1G_MAG_PCKT: \
18328 + bitMask = DTSEC_IMASK_MAGEN ; break; \
18329 + case e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET: \
18330 + bitMask = DTSEC_IMASK_MMRDEN; break; \
18331 + case e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET: \
18332 + bitMask = DTSEC_IMASK_MMWREN ; break; \
18333 + case e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET: \
18334 + bitMask = DTSEC_IMASK_GRSCEN; break; \
18335 + case e_FM_MAC_EX_1G_TX_DATA_ERR: \
18336 + bitMask = DTSEC_IMASK_TDPEEN; break; \
18337 + case e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL: \
18338 + bitMask = DTSEC_IMASK_MSROEN ; break; \
18339 + default: bitMask = 0;break;}
18340 +
18341 +
18342 +#define MAX_PACKET_ALIGNMENT 31
18343 +#define MAX_INTER_PACKET_GAP 0x7f
18344 +#define MAX_INTER_PALTERNATE_BEB 0x0f
18345 +#define MAX_RETRANSMISSION 0x0f
18346 +#define MAX_COLLISION_WINDOW 0x03ff
18347 +
18348 +
18349 +/********************* From mac ext ******************************************/
18350 +typedef uint32_t t_ErrorDisable;
18351 +
18352 +#define ERROR_DISABLE_TRANSMIT 0x00400000
18353 +#define ERROR_DISABLE_LATE_COLLISION 0x00040000
18354 +#define ERROR_DISABLE_COLLISION_RETRY_LIMIT 0x00020000
18355 +#define ERROR_DISABLE_TxFIFO_UNDERRUN 0x00010000
18356 +#define ERROR_DISABLE_TxABORT 0x00008000
18357 +#define ERROR_DISABLE_INTERFACE 0x00004000
18358 +#define ERROR_DISABLE_TxDATA_PARITY 0x00000002
18359 +#define ERROR_DISABLE_RxDATA_PARITY 0x00000001
18360 +
18361 +/*****************************************************************************/
18362 +#define DTSEC_NUM_OF_PADDRS 15 /* number of pattern match registers (entries) */
18363 +
18364 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
18365 +
18366 +#define HASH_TABLE_SIZE 256 /* Hash table size (= 32 bits * 8 regs) */
18367 +
18368 +#define HASH_TABLE_SIZE 256 /* Hash table size (32 bits * 8 regs) */
18369 +#define EXTENDED_HASH_TABLE_SIZE 512 /* Extended Hash table size (32 bits * 16 regs) */
18370 +
18371 +#define DTSEC_TO_MII_OFFSET 0x1000 /* number of pattern match registers (entries) */
18372 +
18373 +#define MAX_PHYS 32 /* maximum number of phys */
18374 +
18375 +#define VAL32BIT 0x100000000LL
18376 +#define VAL22BIT 0x00400000
18377 +#define VAL16BIT 0x00010000
18378 +#define VAL12BIT 0x00001000
18379 +
18380 +/* CAR1/2 bits */
18381 +#define CAR1_TR64 0x80000000
18382 +#define CAR1_TR127 0x40000000
18383 +#define CAR1_TR255 0x20000000
18384 +#define CAR1_TR511 0x10000000
18385 +#define CAR1_TRK1 0x08000000
18386 +#define CAR1_TRMAX 0x04000000
18387 +#define CAR1_TRMGV 0x02000000
18388 +
18389 +#define CAR1_RBYT 0x00010000
18390 +#define CAR1_RPKT 0x00008000
18391 +#define CAR1_RMCA 0x00002000
18392 +#define CAR1_RBCA 0x00001000
18393 +#define CAR1_RXPF 0x00000400
18394 +#define CAR1_RALN 0x00000100
18395 +#define CAR1_RFLR 0x00000080
18396 +#define CAR1_RCDE 0x00000040
18397 +#define CAR1_RCSE 0x00000020
18398 +#define CAR1_RUND 0x00000010
18399 +#define CAR1_ROVR 0x00000008
18400 +#define CAR1_RFRG 0x00000004
18401 +#define CAR1_RJBR 0x00000002
18402 +#define CAR1_RDRP 0x00000001
18403 +
18404 +#define CAR2_TFCS 0x00040000
18405 +#define CAR2_TBYT 0x00002000
18406 +#define CAR2_TPKT 0x00001000
18407 +#define CAR2_TMCA 0x00000800
18408 +#define CAR2_TBCA 0x00000400
18409 +#define CAR2_TXPF 0x00000200
18410 +#define CAR2_TDRP 0x00000001
18411 +
18412 +typedef struct t_InternalStatistics
18413 +{
18414 + uint64_t tr64;
18415 + uint64_t tr127;
18416 + uint64_t tr255;
18417 + uint64_t tr511;
18418 + uint64_t tr1k;
18419 + uint64_t trmax;
18420 + uint64_t trmgv;
18421 + uint64_t rfrg;
18422 + uint64_t rjbr;
18423 + uint64_t rdrp;
18424 + uint64_t raln;
18425 + uint64_t rund;
18426 + uint64_t rovr;
18427 + uint64_t rxpf;
18428 + uint64_t txpf;
18429 + uint64_t rbyt;
18430 + uint64_t rpkt;
18431 + uint64_t rmca;
18432 + uint64_t rbca;
18433 + uint64_t rflr;
18434 + uint64_t rcde;
18435 + uint64_t rcse;
18436 + uint64_t tbyt;
18437 + uint64_t tpkt;
18438 + uint64_t tmca;
18439 + uint64_t tbca;
18440 + uint64_t tdrp;
18441 + uint64_t tfcs;
18442 +} t_InternalStatistics;
18443 +
18444 +typedef struct {
18445 + t_FmMacControllerDriver fmMacControllerDriver;
18446 + t_Handle h_App; /**< Handle to the upper layer application */
18447 + struct dtsec_regs *p_MemMap; /**< pointer to dTSEC memory mapped registers. */
18448 + struct dtsec_mii_reg *p_MiiMemMap; /**< pointer to dTSEC MII memory mapped registers. */
18449 + uint64_t addr; /**< MAC address of device; */
18450 + e_EnetMode enetMode; /**< Ethernet physical interface */
18451 + t_FmMacExceptionCallback *f_Exception;
18452 + int mdioIrq;
18453 + t_FmMacExceptionCallback *f_Event;
18454 + bool indAddrRegUsed[DTSEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
18455 + uint64_t paddr[DTSEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
18456 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
18457 + bool halfDuplex;
18458 + t_InternalStatistics internalStatistics;
18459 + t_EthHash *p_MulticastAddrHash; /* pointer to driver's global address hash table */
18460 + t_EthHash *p_UnicastAddrHash; /* pointer to driver's individual address hash table */
18461 + uint8_t macId;
18462 + uint8_t tbi_phy_addr;
18463 + uint32_t exceptions;
18464 + bool ptpTsuEnabled;
18465 + bool enTsuErrExeption;
18466 + e_FmMacStatisticsLevel statisticsLevel;
18467 + struct dtsec_cfg *p_DtsecDriverParam;
18468 +} t_Dtsec;
18469 +
18470 +
18471 +#endif /* __DTSEC_H */
18472 --- /dev/null
18473 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.c
18474 @@ -0,0 +1,97 @@
18475 +/*
18476 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18477 + *
18478 + * Redistribution and use in source and binary forms, with or without
18479 + * modification, are permitted provided that the following conditions are met:
18480 + * * Redistributions of source code must retain the above copyright
18481 + * notice, this list of conditions and the following disclaimer.
18482 + * * Redistributions in binary form must reproduce the above copyright
18483 + * notice, this list of conditions and the following disclaimer in the
18484 + * documentation and/or other materials provided with the distribution.
18485 + * * Neither the name of Freescale Semiconductor nor the
18486 + * names of its contributors may be used to endorse or promote products
18487 + * derived from this software without specific prior written permission.
18488 + *
18489 + *
18490 + * ALTERNATIVELY, this software may be distributed under the terms of the
18491 + * GNU General Public License ("GPL") as published by the Free Software
18492 + * Foundation, either version 2 of that License or (at your option) any
18493 + * later version.
18494 + *
18495 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18496 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18497 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18498 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18499 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18500 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18501 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18502 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18503 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18504 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18505 + */
18506 +
18507 +
18508 +/******************************************************************************
18509 + @File dtsec_mii_acc.c
18510 +
18511 + @Description FM dtsec MII register access MAC ...
18512 +*//***************************************************************************/
18513 +
18514 +#include "error_ext.h"
18515 +#include "std_ext.h"
18516 +#include "fm_mac.h"
18517 +#include "dtsec.h"
18518 +#include "fsl_fman_dtsec_mii_acc.h"
18519 +
18520 +
18521 +/*****************************************************************************/
18522 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec,
18523 + uint8_t phyAddr,
18524 + uint8_t reg,
18525 + uint16_t data)
18526 +{
18527 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
18528 + struct dtsec_mii_reg *miiregs;
18529 + uint16_t dtsec_freq;
18530 + t_Error err;
18531 +
18532 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
18533 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
18534 +
18535 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
18536 + miiregs = p_Dtsec->p_MiiMemMap;
18537 +
18538 + err = (t_Error)fman_dtsec_mii_write_reg(miiregs, phyAddr, reg, data, dtsec_freq);
18539 +
18540 + return err;
18541 +}
18542 +
18543 +/*****************************************************************************/
18544 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec,
18545 + uint8_t phyAddr,
18546 + uint8_t reg,
18547 + uint16_t *p_Data)
18548 +{
18549 + t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
18550 + struct dtsec_mii_reg *miiregs;
18551 + uint16_t dtsec_freq;
18552 + t_Error err;
18553 +
18554 + SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
18555 + SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MiiMemMap, E_INVALID_HANDLE);
18556 +
18557 + dtsec_freq = (uint16_t)(p_Dtsec->fmMacControllerDriver.clkFreq >> 1);
18558 + miiregs = p_Dtsec->p_MiiMemMap;
18559 +
18560 + err = fman_dtsec_mii_read_reg(miiregs, phyAddr, reg, p_Data, dtsec_freq);
18561 +
18562 + if (*p_Data == 0xffff)
18563 + RETURN_ERROR(MINOR, E_NO_DEVICE,
18564 + ("Read wrong data (0xffff): phyAddr 0x%x, reg 0x%x",
18565 + phyAddr, reg));
18566 + if (err)
18567 + RETURN_ERROR(MINOR, (t_Error)err, NO_MSG);
18568 +
18569 + return E_OK;
18570 +}
18571 +
18572 --- /dev/null
18573 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/dtsec_mii_acc.h
18574 @@ -0,0 +1,42 @@
18575 +/*
18576 + * Copyright 2008-2013 Freescale Semiconductor Inc.
18577 + *
18578 + * Redistribution and use in source and binary forms, with or without
18579 + * modification, are permitted provided that the following conditions are met:
18580 + * * Redistributions of source code must retain the above copyright
18581 + * notice, this list of conditions and the following disclaimer.
18582 + * * Redistributions in binary form must reproduce the above copyright
18583 + * notice, this list of conditions and the following disclaimer in the
18584 + * documentation and/or other materials provided with the distribution.
18585 + * * Neither the name of Freescale Semiconductor nor the
18586 + * names of its contributors may be used to endorse or promote products
18587 + * derived from this software without specific prior written permission.
18588 + *
18589 + *
18590 + * ALTERNATIVELY, this software may be distributed under the terms of the
18591 + * GNU General Public License ("GPL") as published by the Free Software
18592 + * Foundation, either version 2 of that License or (at your option) any
18593 + * later version.
18594 + *
18595 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18596 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18597 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18598 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18599 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18600 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18601 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18602 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18603 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18604 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18605 + */
18606 +
18607 +#ifndef __DTSEC_MII_ACC_H
18608 +#define __DTSEC_MII_ACC_H
18609 +
18610 +#include "std_ext.h"
18611 +
18612 +
18613 +t_Error DTSEC_MII_WritePhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t data);
18614 +t_Error DTSEC_MII_ReadPhyReg(t_Handle h_Dtsec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
18615 +
18616 +#endif /* __DTSEC_MII_ACC_H */
18617 --- /dev/null
18618 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.c
18619 @@ -0,0 +1,674 @@
18620 +/*
18621 + * Copyright 2008-2012 Freescale Semiconductor Inc.
18622 + *
18623 + * Redistribution and use in source and binary forms, with or without
18624 + * modification, are permitted provided that the following conditions are met:
18625 + * * Redistributions of source code must retain the above copyright
18626 + * notice, this list of conditions and the following disclaimer.
18627 + * * Redistributions in binary form must reproduce the above copyright
18628 + * notice, this list of conditions and the following disclaimer in the
18629 + * documentation and/or other materials provided with the distribution.
18630 + * * Neither the name of Freescale Semiconductor nor the
18631 + * names of its contributors may be used to endorse or promote products
18632 + * derived from this software without specific prior written permission.
18633 + *
18634 + *
18635 + * ALTERNATIVELY, this software may be distributed under the terms of the
18636 + * GNU General Public License ("GPL") as published by the Free Software
18637 + * Foundation, either version 2 of that License or (at your option) any
18638 + * later version.
18639 + *
18640 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
18641 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18642 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18643 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
18644 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18645 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18646 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18647 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
18648 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
18649 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18650 + */
18651 +
18652 +
18653 +/******************************************************************************
18654 + @File fm_mac.c
18655 +
18656 + @Description FM MAC ...
18657 +*//***************************************************************************/
18658 +#include "std_ext.h"
18659 +#include "string_ext.h"
18660 +#include "sprint_ext.h"
18661 +#include "error_ext.h"
18662 +#include "fm_ext.h"
18663 +
18664 +#include "fm_common.h"
18665 +#include "fm_mac.h"
18666 +
18667 +
18668 +/* ......................................................................... */
18669 +
18670 +t_Handle FM_MAC_Config (t_FmMacParams *p_FmMacParam)
18671 +{
18672 + t_FmMacControllerDriver *p_FmMacControllerDriver;
18673 + uint16_t fmClkFreq;
18674 +
18675 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_INVALID_HANDLE, NULL);
18676 +
18677 + fmClkFreq = FmGetClockFreq(p_FmMacParam->h_Fm);
18678 + if (fmClkFreq == 0)
18679 + {
18680 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Can't get clock for MAC!"));
18681 + return NULL;
18682 + }
18683 +
18684 +#if (DPAA_VERSION == 10)
18685 + if (ENET_SPEED_FROM_MODE(p_FmMacParam->enetMode) < e_ENET_SPEED_10000)
18686 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)DTSEC_Config(p_FmMacParam);
18687 + else
18688 +#if FM_MAX_NUM_OF_10G_MACS > 0
18689 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)TGEC_Config(p_FmMacParam);
18690 +#else
18691 + p_FmMacControllerDriver = NULL;
18692 +#endif /* FM_MAX_NUM_OF_10G_MACS > 0 */
18693 +#else
18694 + p_FmMacControllerDriver = (t_FmMacControllerDriver *)MEMAC_Config(p_FmMacParam);
18695 +#endif /* (DPAA_VERSION == 10) */
18696 +
18697 + if (!p_FmMacControllerDriver)
18698 + return NULL;
18699 +
18700 + p_FmMacControllerDriver->h_Fm = p_FmMacParam->h_Fm;
18701 + p_FmMacControllerDriver->enetMode = p_FmMacParam->enetMode;
18702 + p_FmMacControllerDriver->macId = p_FmMacParam->macId;
18703 + p_FmMacControllerDriver->resetOnInit = DEFAULT_resetOnInit;
18704 +
18705 + p_FmMacControllerDriver->clkFreq = fmClkFreq;
18706 +
18707 + return (t_Handle)p_FmMacControllerDriver;
18708 +}
18709 +
18710 +/* ......................................................................... */
18711 +
18712 +t_Error FM_MAC_Init (t_Handle h_FmMac)
18713 +{
18714 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18715 +
18716 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18717 +
18718 + if (p_FmMacControllerDriver->resetOnInit &&
18719 + !p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit &&
18720 + (FmResetMac(p_FmMacControllerDriver->h_Fm,
18721 + ((ENET_INTERFACE_FROM_MODE(p_FmMacControllerDriver->enetMode) == e_ENET_IF_XGMII) ?
18722 + e_FM_MAC_10G : e_FM_MAC_1G),
18723 + p_FmMacControllerDriver->macId) != E_OK))
18724 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't reset MAC!"));
18725 +
18726 + if (p_FmMacControllerDriver->f_FM_MAC_Init)
18727 + return p_FmMacControllerDriver->f_FM_MAC_Init(h_FmMac);
18728 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18729 +}
18730 +
18731 +/* ......................................................................... */
18732 +
18733 +t_Error FM_MAC_Free (t_Handle h_FmMac)
18734 +{
18735 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18736 +
18737 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18738 +
18739 + if (p_FmMacControllerDriver->f_FM_MAC_Free)
18740 + return p_FmMacControllerDriver->f_FM_MAC_Free(h_FmMac);
18741 +
18742 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18743 +}
18744 +
18745 +/* ......................................................................... */
18746 +
18747 +t_Error FM_MAC_ConfigResetOnInit (t_Handle h_FmMac, bool enable)
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_ConfigResetOnInit)
18754 + return p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit(h_FmMac, enable);
18755 +
18756 + p_FmMacControllerDriver->resetOnInit = enable;
18757 +
18758 + return E_OK;
18759 +}
18760 +
18761 +/* ......................................................................... */
18762 +
18763 +t_Error FM_MAC_ConfigLoopback (t_Handle h_FmMac, bool newVal)
18764 +{
18765 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18766 +
18767 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18768 +
18769 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback)
18770 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback(h_FmMac, newVal);
18771 +
18772 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18773 +}
18774 +
18775 +/* ......................................................................... */
18776 +
18777 +t_Error FM_MAC_ConfigMaxFrameLength (t_Handle h_FmMac, uint16_t newVal)
18778 +{
18779 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18780 +
18781 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18782 +
18783 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength)
18784 + return p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength(h_FmMac, newVal);
18785 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18786 +}
18787 +
18788 +/* ......................................................................... */
18789 +
18790 +t_Error FM_MAC_ConfigWan (t_Handle h_FmMac, bool flag)
18791 +{
18792 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18793 +
18794 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18795 +
18796 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigWan)
18797 + return p_FmMacControllerDriver->f_FM_MAC_ConfigWan(h_FmMac, flag);
18798 +
18799 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18800 +}
18801 +
18802 +/* ......................................................................... */
18803 +
18804 +t_Error FM_MAC_ConfigPadAndCrc (t_Handle h_FmMac, bool newVal)
18805 +{
18806 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18807 +
18808 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18809 +
18810 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc)
18811 + return p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc(h_FmMac, newVal);
18812 +
18813 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18814 +}
18815 +
18816 +/* ......................................................................... */
18817 +
18818 +t_Error FM_MAC_ConfigHalfDuplex (t_Handle h_FmMac, bool newVal)
18819 +{
18820 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18821 +
18822 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18823 +
18824 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex)
18825 + return p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex(h_FmMac,newVal);
18826 +
18827 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18828 +}
18829 +
18830 +/* ......................................................................... */
18831 +
18832 +t_Error FM_MAC_ConfigTbiPhyAddr (t_Handle h_FmMac, uint8_t newVal)
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_ConfigTbiPhyAddr)
18839 + return p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr(h_FmMac,newVal);
18840 +
18841 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18842 +}
18843 +
18844 +/* ......................................................................... */
18845 +
18846 +t_Error FM_MAC_ConfigLengthCheck (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_ConfigLengthCheck)
18853 + return p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck(h_FmMac,newVal);
18854 +
18855 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18856 +}
18857 +
18858 +/* ......................................................................... */
18859 +
18860 +t_Error FM_MAC_ConfigException (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
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_ConfigException)
18867 + return p_FmMacControllerDriver->f_FM_MAC_ConfigException(h_FmMac, ex, enable);
18868 +
18869 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18870 +}
18871 +
18872 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
18873 +/* ......................................................................... */
18874 +
18875 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac)
18876 +{
18877 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18878 +
18879 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18880 +
18881 + if (p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround)
18882 + return p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround(h_FmMac);
18883 +
18884 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18885 +}
18886 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
18887 +
18888 +
18889 +/*****************************************************************************/
18890 +/* Run Time Control */
18891 +/*****************************************************************************/
18892 +
18893 +/* ......................................................................... */
18894 +
18895 +t_Error FM_MAC_Enable (t_Handle h_FmMac, e_CommMode mode)
18896 +{
18897 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18898 +
18899 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18900 +
18901 + if (p_FmMacControllerDriver->f_FM_MAC_Enable)
18902 + return p_FmMacControllerDriver->f_FM_MAC_Enable(h_FmMac, mode);
18903 +
18904 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18905 +}
18906 +
18907 +/* ......................................................................... */
18908 +
18909 +t_Error FM_MAC_Disable (t_Handle h_FmMac, e_CommMode mode)
18910 +{
18911 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18912 +
18913 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18914 +
18915 + if (p_FmMacControllerDriver->f_FM_MAC_Disable)
18916 + return p_FmMacControllerDriver->f_FM_MAC_Disable(h_FmMac, mode);
18917 +
18918 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18919 +}
18920 +
18921 +t_Error FM_MAC_Resume (t_Handle h_FmMac)
18922 +{
18923 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18924 +
18925 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18926 +
18927 + if (p_FmMacControllerDriver->f_FM_MAC_Resume)
18928 + return p_FmMacControllerDriver->f_FM_MAC_Resume(h_FmMac);
18929 +
18930 + return E_OK;
18931 +}
18932 +
18933 +/* ......................................................................... */
18934 +
18935 +t_Error FM_MAC_Enable1588TimeStamp (t_Handle h_FmMac)
18936 +{
18937 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18938 +
18939 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18940 +
18941 + if (p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp)
18942 + return p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp(h_FmMac);
18943 +
18944 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18945 +}
18946 +
18947 +/* ......................................................................... */
18948 +
18949 +t_Error FM_MAC_Disable1588TimeStamp (t_Handle h_FmMac)
18950 +{
18951 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18952 +
18953 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18954 +
18955 + if (p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp)
18956 + return p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp(h_FmMac);
18957 +
18958 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18959 +}
18960 +
18961 +/* ......................................................................... */
18962 +
18963 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
18964 + uint16_t pauseTime)
18965 +{
18966 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18967 +
18968 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18969 +
18970 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames)
18971 + return p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames(h_FmMac,
18972 + pauseTime);
18973 +
18974 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
18975 +}
18976 +
18977 +/* ......................................................................... */
18978 +
18979 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
18980 + uint8_t priority,
18981 + uint16_t pauseTime,
18982 + uint16_t threshTime)
18983 +{
18984 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
18985 +
18986 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
18987 +
18988 + if (p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames)
18989 + return p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames(h_FmMac,
18990 + priority,
18991 + pauseTime,
18992 + threshTime);
18993 +
18994 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
18995 +}
18996 +
18997 +/* ......................................................................... */
18998 +
18999 +t_Error FM_MAC_SetRxIgnorePauseFrames (t_Handle h_FmMac, bool en)
19000 +{
19001 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19002 +
19003 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19004 +
19005 + if (p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames)
19006 + return p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames(h_FmMac, en);
19007 +
19008 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19009 +}
19010 +
19011 +/* ......................................................................... */
19012 +
19013 +t_Error FM_MAC_SetWakeOnLan (t_Handle h_FmMac, bool en)
19014 +{
19015 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19016 +
19017 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19018 +
19019 + if (p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan)
19020 + return p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan(h_FmMac, en);
19021 +
19022 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19023 +}
19024 +
19025 +/* ......................................................................... */
19026 +
19027 +t_Error FM_MAC_ResetCounters (t_Handle h_FmMac)
19028 +{
19029 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19030 +
19031 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19032 +
19033 + if (p_FmMacControllerDriver->f_FM_MAC_ResetCounters)
19034 + return p_FmMacControllerDriver->f_FM_MAC_ResetCounters(h_FmMac);
19035 +
19036 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19037 +}
19038 +
19039 +/* ......................................................................... */
19040 +
19041 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable)
19042 +{
19043 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19044 +
19045 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19046 +
19047 + if (p_FmMacControllerDriver->f_FM_MAC_SetException)
19048 + return p_FmMacControllerDriver->f_FM_MAC_SetException(h_FmMac, ex, enable);
19049 +
19050 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19051 +}
19052 +
19053 +/* ......................................................................... */
19054 +
19055 +t_Error FM_MAC_SetStatistics (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel)
19056 +{
19057 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19058 +
19059 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19060 +
19061 + if (p_FmMacControllerDriver->f_FM_MAC_SetStatistics)
19062 + return p_FmMacControllerDriver->f_FM_MAC_SetStatistics(h_FmMac, statisticsLevel);
19063 +
19064 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19065 +}
19066 +
19067 +/* ......................................................................... */
19068 +
19069 +t_Error FM_MAC_GetStatistics (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics)
19070 +{
19071 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19072 +
19073 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19074 +
19075 + if (p_FmMacControllerDriver->f_FM_MAC_GetStatistics)
19076 + return p_FmMacControllerDriver->f_FM_MAC_GetStatistics(h_FmMac, p_Statistics);
19077 +
19078 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19079 +}
19080 +
19081 +/* ......................................................................... */
19082 +
19083 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
19084 +{
19085 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19086 +
19087 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19088 +
19089 + memset(p_FrameSizeCounters, 0, sizeof(t_FmMacFrameSizeCounters));
19090 +
19091 + if (p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters)
19092 + return p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters(h_FmMac, p_FrameSizeCounters, type);
19093 +
19094 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19095 +}
19096 +
19097 +/* ......................................................................... */
19098 +
19099 +t_Error FM_MAC_ModifyMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
19100 +{
19101 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19102 +
19103 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19104 +
19105 + if (p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr)
19106 + return p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr(h_FmMac, p_EnetAddr);
19107 +
19108 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19109 +}
19110 +
19111 +/* ......................................................................... */
19112 +
19113 +t_Error FM_MAC_AddHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
19114 +{
19115 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19116 +
19117 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19118 +
19119 + if (p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr)
19120 + return p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr(h_FmMac, p_EnetAddr);
19121 +
19122 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19123 +}
19124 +
19125 +/* ......................................................................... */
19126 +
19127 +t_Error FM_MAC_RemoveHashMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
19128 +{
19129 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19130 +
19131 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19132 +
19133 + if (p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr)
19134 + return p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr(h_FmMac, p_EnetAddr);
19135 +
19136 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19137 +}
19138 +
19139 +/* ......................................................................... */
19140 +
19141 +t_Error FM_MAC_AddExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
19142 +{
19143 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19144 +
19145 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19146 +
19147 + if (p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr)
19148 + return p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr(h_FmMac, p_EnetAddr);
19149 +
19150 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19151 +}
19152 +
19153 +/* ......................................................................... */
19154 +
19155 +t_Error FM_MAC_RemovelExactMatchMacAddr (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr)
19156 +{
19157 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19158 +
19159 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19160 +
19161 + if (p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr)
19162 + return p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr(h_FmMac, p_EnetAddr);
19163 +
19164 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19165 +}
19166 +
19167 +/* ......................................................................... */
19168 +
19169 +t_Error FM_MAC_GetVesrion (t_Handle h_FmMac, uint32_t *macVresion)
19170 +{
19171 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19172 +
19173 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19174 +
19175 + if (p_FmMacControllerDriver->f_FM_MAC_GetVersion)
19176 + return p_FmMacControllerDriver->f_FM_MAC_GetVersion(h_FmMac, macVresion);
19177 +
19178 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19179 +
19180 +}
19181 +
19182 +/* ......................................................................... */
19183 +
19184 +t_Error FM_MAC_GetId (t_Handle h_FmMac, uint32_t *macId)
19185 +{
19186 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19187 +
19188 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19189 +
19190 + if (p_FmMacControllerDriver->f_FM_MAC_GetId)
19191 + return p_FmMacControllerDriver->f_FM_MAC_GetId(h_FmMac, macId);
19192 +
19193 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19194 +}
19195 +
19196 +/* ......................................................................... */
19197 +
19198 +t_Error FM_MAC_SetPromiscuous (t_Handle h_FmMac, bool newVal)
19199 +{
19200 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19201 +
19202 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19203 +
19204 + if (p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous)
19205 + return p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous(h_FmMac, newVal);
19206 +
19207 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19208 +}
19209 +
19210 +/* ......................................................................... */
19211 +
19212 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex)
19213 +{
19214 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19215 +
19216 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19217 +
19218 + if (p_FmMacControllerDriver->f_FM_MAC_AdjustLink)
19219 + return p_FmMacControllerDriver->f_FM_MAC_AdjustLink(h_FmMac, speed, fullDuplex);
19220 +
19221 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19222 +}
19223 +
19224 +/* ......................................................................... */
19225 +
19226 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac)
19227 +{
19228 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19229 +
19230 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19231 +
19232 + if (p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg)
19233 + return p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg(h_FmMac);
19234 +
19235 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19236 +}
19237 +
19238 +/* ......................................................................... */
19239 +
19240 +t_Error FM_MAC_MII_WritePhyReg (t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data)
19241 +{
19242 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19243 +
19244 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19245 +
19246 + if (p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg)
19247 + return p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg(h_FmMac, phyAddr, reg, data);
19248 +
19249 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19250 +}
19251 +
19252 +/* ......................................................................... */
19253 +
19254 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data)
19255 +{
19256 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19257 +
19258 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19259 +
19260 + if (p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg)
19261 + return p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg(h_FmMac, phyAddr, reg, p_Data);
19262 +
19263 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19264 +}
19265 +
19266 +/* ......................................................................... */
19267 +
19268 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle h_FmMac)
19269 +{
19270 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19271 +
19272 + SANITY_CHECK_RETURN_VALUE(p_FmMacControllerDriver, E_INVALID_HANDLE, 0);
19273 +
19274 + if (p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength)
19275 + return p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength(h_FmMac);
19276 +
19277 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19278 + return 0;
19279 +}
19280 +
19281 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
19282 +/*****************************************************************************/
19283 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac)
19284 +{
19285 + t_FmMacControllerDriver *p_FmMacControllerDriver = (t_FmMacControllerDriver *)h_FmMac;
19286 +
19287 + SANITY_CHECK_RETURN_ERROR(p_FmMacControllerDriver, E_INVALID_HANDLE);
19288 +
19289 + if (p_FmMacControllerDriver->f_FM_MAC_DumpRegs)
19290 + return p_FmMacControllerDriver->f_FM_MAC_DumpRegs(h_FmMac);
19291 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
19292 +}
19293 +#endif /* (defined(DEBUG_ERRORS) && ... */
19294 --- /dev/null
19295 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fm_mac.h
19296 @@ -0,0 +1,226 @@
19297 +/*
19298 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19299 + *
19300 + * Redistribution and use in source and binary forms, with or without
19301 + * modification, are permitted provided that the following conditions are met:
19302 + * * Redistributions of source code must retain the above copyright
19303 + * notice, this list of conditions and the following disclaimer.
19304 + * * Redistributions in binary form must reproduce the above copyright
19305 + * notice, this list of conditions and the following disclaimer in the
19306 + * documentation and/or other materials provided with the distribution.
19307 + * * Neither the name of Freescale Semiconductor nor the
19308 + * names of its contributors may be used to endorse or promote products
19309 + * derived from this software without specific prior written permission.
19310 + *
19311 + *
19312 + * ALTERNATIVELY, this software may be distributed under the terms of the
19313 + * GNU General Public License ("GPL") as published by the Free Software
19314 + * Foundation, either version 2 of that License or (at your option) any
19315 + * later version.
19316 + *
19317 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19318 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19319 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19320 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19321 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19322 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19323 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19324 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19325 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19326 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19327 + */
19328 +
19329 +
19330 +/******************************************************************************
19331 + @File fm_mac.h
19332 +
19333 + @Description FM MAC ...
19334 +*//***************************************************************************/
19335 +#ifndef __FM_MAC_H
19336 +#define __FM_MAC_H
19337 +
19338 +#include "std_ext.h"
19339 +#include "error_ext.h"
19340 +#include "list_ext.h"
19341 +#include "fm_mac_ext.h"
19342 +#include "fm_common.h"
19343 +
19344 +
19345 +#define __ERR_MODULE__ MODULE_FM_MAC
19346 +
19347 +/**************************************************************************//**
19348 + @Description defaults
19349 +*//***************************************************************************/
19350 +
19351 +
19352 +#define DEFAULT_halfDuplex FALSE
19353 +#define DEFAULT_padAndCrcEnable TRUE
19354 +#define DEFAULT_resetOnInit FALSE
19355 +
19356 +
19357 +typedef struct {
19358 + uint64_t addr; /* Ethernet Address */
19359 + t_List node;
19360 +} t_EthHashEntry;
19361 +#define ETH_HASH_ENTRY_OBJ(ptr) LIST_OBJECT(ptr, t_EthHashEntry, node)
19362 +
19363 +typedef struct {
19364 + uint16_t size;
19365 + t_List *p_Lsts;
19366 +} t_EthHash;
19367 +
19368 +typedef struct {
19369 + t_Error (*f_FM_MAC_Init) (t_Handle h_FmMac);
19370 + t_Error (*f_FM_MAC_Free) (t_Handle h_FmMac);
19371 +
19372 + t_Error (*f_FM_MAC_SetStatistics) (t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
19373 + t_Error (*f_FM_MAC_ConfigLoopback) (t_Handle h_FmMac, bool newVal);
19374 + t_Error (*f_FM_MAC_ConfigMaxFrameLength) (t_Handle h_FmMac, uint16_t newVal);
19375 + t_Error (*f_FM_MAC_ConfigWan) (t_Handle h_FmMac, bool flag);
19376 + t_Error (*f_FM_MAC_ConfigPadAndCrc) (t_Handle h_FmMac, bool newVal);
19377 + t_Error (*f_FM_MAC_ConfigHalfDuplex) (t_Handle h_FmMac, bool newVal);
19378 + t_Error (*f_FM_MAC_ConfigLengthCheck) (t_Handle h_FmMac, bool newVal);
19379 + t_Error (*f_FM_MAC_ConfigTbiPhyAddr) (t_Handle h_FmMac, uint8_t newVal);
19380 + t_Error (*f_FM_MAC_ConfigException) (t_Handle h_FmMac, e_FmMacExceptions, bool enable);
19381 + t_Error (*f_FM_MAC_ConfigResetOnInit) (t_Handle h_FmMac, bool enable);
19382 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
19383 + t_Error (*f_FM_MAC_ConfigSkipFman11Workaround) (t_Handle h_FmMac);
19384 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
19385 +
19386 + t_Error (*f_FM_MAC_SetException) (t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
19387 +
19388 + t_Error (*f_FM_MAC_Enable) (t_Handle h_FmMac, e_CommMode mode);
19389 + t_Error (*f_FM_MAC_Disable) (t_Handle h_FmMac, e_CommMode mode);
19390 + t_Error (*f_FM_MAC_Resume) (t_Handle h_FmMac);
19391 + t_Error (*f_FM_MAC_Enable1588TimeStamp) (t_Handle h_FmMac);
19392 + t_Error (*f_FM_MAC_Disable1588TimeStamp) (t_Handle h_FmMac);
19393 + t_Error (*f_FM_MAC_Reset) (t_Handle h_FmMac, bool wait);
19394 +
19395 + t_Error (*f_FM_MAC_SetTxAutoPauseFrames) (t_Handle h_FmMac,
19396 + uint16_t pauseTime);
19397 + t_Error (*f_FM_MAC_SetTxPauseFrames) (t_Handle h_FmMac,
19398 + uint8_t priority,
19399 + uint16_t pauseTime,
19400 + uint16_t threshTime);
19401 + t_Error (*f_FM_MAC_SetRxIgnorePauseFrames) (t_Handle h_FmMac, bool en);
19402 +
19403 + t_Error (*f_FM_MAC_ResetCounters) (t_Handle h_FmMac);
19404 + t_Error (*f_FM_MAC_GetStatistics) (t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
19405 + t_Error (*f_FM_MAC_GetFrameSizeCounters) (t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
19406 +
19407 + t_Error (*f_FM_MAC_ModifyMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19408 + t_Error (*f_FM_MAC_AddHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19409 + t_Error (*f_FM_MAC_RemoveHashMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19410 + t_Error (*f_FM_MAC_AddExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19411 + t_Error (*f_FM_MAC_RemovelExactMatchMacAddr) (t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
19412 +
19413 + t_Error (*f_FM_MAC_SetPromiscuous) (t_Handle h_FmMac, bool newVal);
19414 + t_Error (*f_FM_MAC_AdjustLink) (t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
19415 + t_Error (*f_FM_MAC_RestartAutoneg) (t_Handle h_FmMac);
19416 +
19417 + t_Error (*f_FM_MAC_SetWakeOnLan) (t_Handle h_FmMac, bool en);
19418 +
19419 + t_Error (*f_FM_MAC_GetId) (t_Handle h_FmMac, uint32_t *macId);
19420 +
19421 + t_Error (*f_FM_MAC_GetVersion) (t_Handle h_FmMac, uint32_t *macVersion);
19422 +
19423 + uint16_t (*f_FM_MAC_GetMaxFrameLength) (t_Handle h_FmMac);
19424 +
19425 + t_Error (*f_FM_MAC_MII_WritePhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
19426 + t_Error (*f_FM_MAC_MII_ReadPhyReg)(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
19427 +
19428 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
19429 + t_Error (*f_FM_MAC_DumpRegs) (t_Handle h_FmMac);
19430 +#endif /* (defined(DEBUG_ERRORS) && ... */
19431 +
19432 + t_Handle h_Fm;
19433 + t_FmRevisionInfo fmRevInfo;
19434 + e_EnetMode enetMode;
19435 + uint8_t macId;
19436 + bool resetOnInit;
19437 + uint16_t clkFreq;
19438 +} t_FmMacControllerDriver;
19439 +
19440 +
19441 +#if (DPAA_VERSION == 10)
19442 +t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam);
19443 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParams);
19444 +#else
19445 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam);
19446 +#endif /* (DPAA_VERSION == 10) */
19447 +uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
19448 +
19449 +
19450 +/* ........................................................................... */
19451 +
19452 +static __inline__ t_EthHashEntry *DequeueAddrFromHashEntry(t_List *p_AddrLst)
19453 +{
19454 + t_EthHashEntry *p_HashEntry = NULL;
19455 + if (!LIST_IsEmpty(p_AddrLst))
19456 + {
19457 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_AddrLst->p_Next);
19458 + LIST_DelAndInit(&p_HashEntry->node);
19459 + }
19460 + return p_HashEntry;
19461 +}
19462 +
19463 +/* ........................................................................... */
19464 +
19465 +static __inline__ void FreeHashTable(t_EthHash *p_Hash)
19466 +{
19467 + t_EthHashEntry *p_HashEntry;
19468 + int i = 0;
19469 +
19470 + if (p_Hash)
19471 + {
19472 + if (p_Hash->p_Lsts)
19473 + {
19474 + for (i=0; i<p_Hash->size; i++)
19475 + {
19476 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
19477 + while (p_HashEntry)
19478 + {
19479 + XX_Free(p_HashEntry);
19480 + p_HashEntry = DequeueAddrFromHashEntry(&p_Hash->p_Lsts[i]);
19481 + }
19482 + }
19483 +
19484 + XX_Free(p_Hash->p_Lsts);
19485 + }
19486 +
19487 + XX_Free(p_Hash);
19488 + }
19489 +}
19490 +
19491 +/* ........................................................................... */
19492 +
19493 +static __inline__ t_EthHash * AllocHashTable(uint16_t size)
19494 +{
19495 + uint32_t i;
19496 + t_EthHash *p_Hash;
19497 +
19498 + /* Allocate address hash table */
19499 + p_Hash = (t_EthHash *)XX_Malloc(sizeof(t_EthHash));
19500 + if (!p_Hash)
19501 + {
19502 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
19503 + return NULL;
19504 + }
19505 + p_Hash->size = size;
19506 +
19507 + p_Hash->p_Lsts = (t_List *)XX_Malloc(p_Hash->size*sizeof(t_List));
19508 + if (!p_Hash->p_Lsts)
19509 + {
19510 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Address hash table"));
19511 + XX_Free(p_Hash);
19512 + return NULL;
19513 + }
19514 +
19515 + for (i=0 ; i<p_Hash->size; i++)
19516 + INIT_LIST(&p_Hash->p_Lsts[i]);
19517 +
19518 + return p_Hash;
19519 +}
19520 +
19521 +
19522 +#endif /* __FM_MAC_H */
19523 --- /dev/null
19524 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.c
19525 @@ -0,0 +1,119 @@
19526 +/*
19527 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19528 + *
19529 + * Redistribution and use in source and binary forms, with or without
19530 + * modification, are permitted provided that the following conditions are met:
19531 + * * Redistributions of source code must retain the above copyright
19532 + * notice, this list of conditions and the following disclaimer.
19533 + * * Redistributions in binary form must reproduce the above copyright
19534 + * notice, this list of conditions and the following disclaimer in the
19535 + * documentation and/or other materials provided with the distribution.
19536 + * * Neither the name of Freescale Semiconductor nor the
19537 + * names of its contributors may be used to endorse or promote products
19538 + * derived from this software without specific prior written permission.
19539 + *
19540 + *
19541 + * ALTERNATIVELY, this software may be distributed under the terms of the
19542 + * GNU General Public License ("GPL") as published by the Free Software
19543 + * Foundation, either version 2 of that License or (at your option) any
19544 + * later version.
19545 + *
19546 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19547 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19548 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19549 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19550 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19551 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19552 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19553 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19554 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19555 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19556 + */
19557 +
19558 +
19559 +#include "fman_crc32.h"
19560 +#include "common/general.h"
19561 +
19562 +
19563 +/* precomputed CRC values for address hashing */
19564 +static const uint32_t crc_tbl[256] = {
19565 + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
19566 + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
19567 + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
19568 + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
19569 + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
19570 + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
19571 + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
19572 + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
19573 + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
19574 + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
19575 + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
19576 + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
19577 + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
19578 + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
19579 + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
19580 + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
19581 + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
19582 + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
19583 + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
19584 + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
19585 + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
19586 + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
19587 + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
19588 + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
19589 + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
19590 + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
19591 + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
19592 + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
19593 + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
19594 + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
19595 + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
19596 + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
19597 + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
19598 + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
19599 + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
19600 + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
19601 + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
19602 + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
19603 + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
19604 + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
19605 + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
19606 + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
19607 + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
19608 +};
19609 +
19610 +/* Get the mirrored value of a byte size number. (0x11010011 --> 0x11001011) */
19611 +static inline uint8_t get_mirror8(uint8_t n)
19612 +{
19613 + uint8_t mirror[16] = {
19614 + 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
19615 + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f
19616 + };
19617 + return (uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4])));
19618 +}
19619 +
19620 +static inline uint32_t get_mirror32(uint32_t n)
19621 +{
19622 + return ((uint32_t)get_mirror8((uint8_t)(n))<<24) |
19623 + ((uint32_t)get_mirror8((uint8_t)(n>>8))<<16) |
19624 + ((uint32_t)get_mirror8((uint8_t)(n>>16))<<8) |
19625 + ((uint32_t)get_mirror8((uint8_t)(n>>24)));
19626 +}
19627 +
19628 +uint32_t get_mac_addr_crc(uint64_t _addr)
19629 +{
19630 + uint32_t i;
19631 + uint8_t data;
19632 + uint32_t crc;
19633 +
19634 + /* CRC calculation */
19635 + crc = 0xffffffff;
19636 + for (i = 0; i < 6; i++) {
19637 + data = (uint8_t)(_addr >> ((5-i)*8));
19638 + crc = crc ^ data;
19639 + crc = crc_tbl[crc&0xff] ^ (crc>>8);
19640 + }
19641 +
19642 + crc = get_mirror32(crc);
19643 + return crc;
19644 +}
19645 --- /dev/null
19646 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_crc32.h
19647 @@ -0,0 +1,43 @@
19648 +/*
19649 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19650 + *
19651 + * Redistribution and use in source and binary forms, with or without
19652 + * modification, are permitted provided that the following conditions are met:
19653 + * * Redistributions of source code must retain the above copyright
19654 + * notice, this list of conditions and the following disclaimer.
19655 + * * Redistributions in binary form must reproduce the above copyright
19656 + * notice, this list of conditions and the following disclaimer in the
19657 + * documentation and/or other materials provided with the distribution.
19658 + * * Neither the name of Freescale Semiconductor nor the
19659 + * names of its contributors may be used to endorse or promote products
19660 + * derived from this software without specific prior written permission.
19661 + *
19662 + *
19663 + * ALTERNATIVELY, this software may be distributed under the terms of the
19664 + * GNU General Public License ("GPL") as published by the Free Software
19665 + * Foundation, either version 2 of that License or (at your option) any
19666 + * later version.
19667 + *
19668 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19669 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19670 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19671 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19672 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19673 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19674 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19675 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19676 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19677 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19678 + */
19679 +
19680 +
19681 +#ifndef __FMAN_CRC32_H
19682 +#define __FMAN_CRC32_H
19683 +
19684 +#include "common/general.h"
19685 +
19686 +
19687 +uint32_t get_mac_addr_crc(uint64_t _addr);
19688 +
19689 +
19690 +#endif /* __FMAN_CRC32_H */
19691 --- /dev/null
19692 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec.c
19693 @@ -0,0 +1,847 @@
19694 +/*
19695 + * Copyright 2008-2012 Freescale Semiconductor Inc.
19696 + *
19697 + * Redistribution and use in source and binary forms, with or without
19698 + * modification, are permitted provided that the following conditions are met:
19699 + * * Redistributions of source code must retain the above copyright
19700 + * notice, this list of conditions and the following disclaimer.
19701 + * * Redistributions in binary form must reproduce the above copyright
19702 + * notice, this list of conditions and the following disclaimer in the
19703 + * documentation and/or other materials provided with the distribution.
19704 + * * Neither the name of Freescale Semiconductor nor the
19705 + * names of its contributors may be used to endorse or promote products
19706 + * derived from this software without specific prior written permission.
19707 + *
19708 + *
19709 + * ALTERNATIVELY, this software may be distributed under the terms of the
19710 + * GNU General Public License ("GPL") as published by the Free Software
19711 + * Foundation, either version 2 of that License or (at your option) any
19712 + * later version.
19713 + *
19714 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
19715 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19716 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19717 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
19718 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19719 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19720 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19721 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19722 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19723 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19724 + */
19725 +
19726 +
19727 +#include "std_ext.h"
19728 +#include "error_ext.h"
19729 +#include "fsl_fman_dtsec.h"
19730 +
19731 +
19732 +void fman_dtsec_stop_rx(struct dtsec_regs *regs)
19733 +{
19734 + /* Assert the graceful stop bit */
19735 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_GRS, &regs->rctrl);
19736 +}
19737 +
19738 +void fman_dtsec_stop_tx(struct dtsec_regs *regs)
19739 +{
19740 + /* Assert the graceful stop bit */
19741 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_GTS, &regs->tctrl);
19742 +}
19743 +
19744 +void fman_dtsec_start_tx(struct dtsec_regs *regs)
19745 +{
19746 + /* clear the graceful stop bit */
19747 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS, &regs->tctrl);
19748 +}
19749 +
19750 +void fman_dtsec_start_rx(struct dtsec_regs *regs)
19751 +{
19752 + /* clear the graceful stop bit */
19753 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS, &regs->rctrl);
19754 +}
19755 +
19756 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg)
19757 +{
19758 + cfg->halfdup_on = DEFAULT_HALFDUP_ON;
19759 + cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
19760 + cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
19761 + cfg->halfdup_excess_defer = DEFAULT_HALFDUP_EXCESS_DEFER;
19762 + cfg->halfdup_no_backoff = DEFAULT_HALFDUP_NO_BACKOFF;
19763 + cfg->halfdup_bp_no_backoff = DEFAULT_HALFDUP_BP_NO_BACKOFF;
19764 + cfg->halfdup_alt_backoff_val = DEFAULT_HALFDUP_ALT_BACKOFF_VAL;
19765 + cfg->halfdup_alt_backoff_en = DEFAULT_HALFDUP_ALT_BACKOFF_EN;
19766 + cfg->rx_drop_bcast = DEFAULT_RX_DROP_BCAST;
19767 + cfg->rx_short_frm = DEFAULT_RX_SHORT_FRM;
19768 + cfg->rx_len_check = DEFAULT_RX_LEN_CHECK;
19769 + cfg->tx_pad_crc = DEFAULT_TX_PAD_CRC;
19770 + cfg->tx_crc = DEFAULT_TX_CRC;
19771 + cfg->rx_ctrl_acc = DEFAULT_RX_CTRL_ACC;
19772 + cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
19773 + cfg->tbipa = DEFAULT_TBIPA; /* PHY address 0 is reserved (DPAA RM)*/
19774 + cfg->rx_prepend = DEFAULT_RX_PREPEND;
19775 + cfg->ptp_tsu_en = DEFAULT_PTP_TSU_EN;
19776 + cfg->ptp_exception_en = DEFAULT_PTP_EXCEPTION_EN;
19777 + cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
19778 + cfg->rx_preamble = DEFAULT_RX_PREAMBLE;
19779 + cfg->tx_preamble = DEFAULT_TX_PREAMBLE;
19780 + cfg->loopback = DEFAULT_LOOPBACK;
19781 + cfg->rx_time_stamp_en = DEFAULT_RX_TIME_STAMP_EN;
19782 + cfg->tx_time_stamp_en = DEFAULT_TX_TIME_STAMP_EN;
19783 + cfg->rx_flow = DEFAULT_RX_FLOW;
19784 + cfg->tx_flow = DEFAULT_TX_FLOW;
19785 + cfg->rx_group_hash_exd = DEFAULT_RX_GROUP_HASH_EXD;
19786 + cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
19787 + cfg->rx_promisc = DEFAULT_RX_PROMISC;
19788 + cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
19789 + cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
19790 + cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
19791 + cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
19792 + cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
19793 + cfg->tbi_phy_addr = DEFAULT_TBI_PHY_ADDR;
19794 + cfg->wake_on_lan = DEFAULT_WAKE_ON_LAN;
19795 +}
19796 +
19797 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
19798 + enum enet_interface iface_mode,
19799 + enum enet_speed iface_speed,
19800 + uint8_t *macaddr,
19801 + uint8_t fm_rev_maj,
19802 + uint8_t fm_rev_min,
19803 + uint32_t exception_mask)
19804 +{
19805 + bool is_rgmii = FALSE;
19806 + bool is_sgmii = FALSE;
19807 + bool is_qsgmii = FALSE;
19808 + int i;
19809 + uint32_t tmp;
19810 +
19811 +UNUSED(fm_rev_maj);UNUSED(fm_rev_min);
19812 +
19813 + /* let's start with a soft reset */
19814 + iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
19815 + iowrite32be(0, &regs->maccfg1);
19816 +
19817 + /*************dtsec_id2******************/
19818 + tmp = ioread32be(&regs->tsec_id2);
19819 +
19820 + /* check RGMII support */
19821 + if (iface_mode == E_ENET_IF_RGMII ||
19822 + iface_mode == E_ENET_IF_RMII)
19823 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
19824 + return -EINVAL;
19825 +
19826 + if (iface_mode == E_ENET_IF_SGMII ||
19827 + iface_mode == E_ENET_IF_MII)
19828 + if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
19829 + return -EINVAL;
19830 +
19831 + /***************ECNTRL************************/
19832 +
19833 + is_rgmii = (bool)((iface_mode == E_ENET_IF_RGMII) ? TRUE : FALSE);
19834 + is_sgmii = (bool)((iface_mode == E_ENET_IF_SGMII) ? TRUE : FALSE);
19835 + is_qsgmii = (bool)((iface_mode == E_ENET_IF_QSGMII) ? TRUE : FALSE);
19836 +
19837 + tmp = 0;
19838 + if (is_rgmii || iface_mode == E_ENET_IF_GMII)
19839 + tmp |= DTSEC_ECNTRL_GMIIM;
19840 + if (is_sgmii)
19841 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
19842 + if (is_qsgmii)
19843 + tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
19844 + DTSEC_ECNTRL_QSGMIIM);
19845 + if (is_rgmii)
19846 + tmp |= DTSEC_ECNTRL_RPM;
19847 + if (iface_speed == E_ENET_SPEED_100)
19848 + tmp |= DTSEC_ECNTRL_R100M;
19849 +
19850 + iowrite32be(tmp, &regs->ecntrl);
19851 + /***************ECNTRL************************/
19852 +
19853 + /***************TCTRL************************/
19854 + tmp = 0;
19855 + if (cfg->halfdup_on)
19856 + tmp |= DTSEC_TCTRL_THDF;
19857 + if (cfg->tx_time_stamp_en)
19858 + tmp |= DTSEC_TCTRL_TTSE;
19859 +
19860 + iowrite32be(tmp, &regs->tctrl);
19861 +
19862 + /***************TCTRL************************/
19863 +
19864 + /***************PTV************************/
19865 + tmp = 0;
19866 +
19867 +#ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
19868 + if ((fm_rev_maj == 1) && (fm_rev_min == 0))
19869 + cfg->tx_pause_time += 2;
19870 +#endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
19871 +
19872 + if (cfg->tx_pause_time)
19873 + tmp |= cfg->tx_pause_time;
19874 + if (cfg->tx_pause_time_extd)
19875 + tmp |= cfg->tx_pause_time_extd << PTV_PTE_OFST;
19876 + iowrite32be(tmp, &regs->ptv);
19877 +
19878 + /***************RCTRL************************/
19879 + tmp = 0;
19880 + tmp |= ((uint32_t)(cfg->rx_prepend & 0x0000001f)) << 16;
19881 + if (cfg->rx_ctrl_acc)
19882 + tmp |= RCTRL_CFA;
19883 + if (cfg->rx_group_hash_exd)
19884 + tmp |= RCTRL_GHTX;
19885 + if (cfg->rx_time_stamp_en)
19886 + tmp |= RCTRL_RTSE;
19887 + if (cfg->rx_drop_bcast)
19888 + tmp |= RCTRL_BC_REJ;
19889 + if (cfg->rx_short_frm)
19890 + tmp |= RCTRL_RSF;
19891 + if (cfg->rx_promisc)
19892 + tmp |= RCTRL_PROM;
19893 +
19894 + iowrite32be(tmp, &regs->rctrl);
19895 + /***************RCTRL************************/
19896 +
19897 + /*
19898 + * Assign a Phy Address to the TBI (TBIPA).
19899 + * Done also in cases where TBI is not selected to avoid conflict with
19900 + * the external PHY's Physical address
19901 + */
19902 + iowrite32be(cfg->tbipa, &regs->tbipa);
19903 +
19904 + /***************TMR_CTL************************/
19905 + iowrite32be(0, &regs->tmr_ctrl);
19906 +
19907 + if (cfg->ptp_tsu_en) {
19908 + tmp = 0;
19909 + tmp |= TMR_PEVENT_TSRE;
19910 + iowrite32be(tmp, &regs->tmr_pevent);
19911 +
19912 + if (cfg->ptp_exception_en) {
19913 + tmp = 0;
19914 + tmp |= TMR_PEMASK_TSREEN;
19915 + iowrite32be(tmp, &regs->tmr_pemask);
19916 + }
19917 + }
19918 +
19919 + /***************MACCFG1***********************/
19920 + tmp = 0;
19921 + if (cfg->loopback)
19922 + tmp |= MACCFG1_LOOPBACK;
19923 + if (cfg->rx_flow)
19924 + tmp |= MACCFG1_RX_FLOW;
19925 + if (cfg->tx_flow)
19926 + tmp |= MACCFG1_TX_FLOW;
19927 + iowrite32be(tmp, &regs->maccfg1);
19928 +
19929 + /***************MACCFG1***********************/
19930 +
19931 + /***************MACCFG2***********************/
19932 + tmp = 0;
19933 +
19934 + if (iface_speed < E_ENET_SPEED_1000)
19935 + tmp |= MACCFG2_NIBBLE_MODE;
19936 + else if (iface_speed == E_ENET_SPEED_1000)
19937 + tmp |= MACCFG2_BYTE_MODE;
19938 +
19939 + tmp |= ((uint32_t) cfg->preamble_len & 0x0000000f)
19940 + << PREAMBLE_LENGTH_SHIFT;
19941 +
19942 + if (cfg->rx_preamble)
19943 + tmp |= MACCFG2_PRE_AM_Rx_EN;
19944 + if (cfg->tx_preamble)
19945 + tmp |= MACCFG2_PRE_AM_Tx_EN;
19946 + if (cfg->rx_len_check)
19947 + tmp |= MACCFG2_LENGTH_CHECK;
19948 + if (cfg->tx_pad_crc)
19949 + tmp |= MACCFG2_PAD_CRC_EN;
19950 + if (cfg->tx_crc)
19951 + tmp |= MACCFG2_CRC_EN;
19952 + if (!cfg->halfdup_on)
19953 + tmp |= MACCFG2_FULL_DUPLEX;
19954 + iowrite32be(tmp, &regs->maccfg2);
19955 +
19956 + /***************MACCFG2***********************/
19957 +
19958 + /***************IPGIFG************************/
19959 + tmp = (((cfg->non_back_to_back_ipg1 <<
19960 + IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
19961 + & IPGIFG_NON_BACK_TO_BACK_IPG_1)
19962 + | ((cfg->non_back_to_back_ipg2 <<
19963 + IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
19964 + & IPGIFG_NON_BACK_TO_BACK_IPG_2)
19965 + | ((cfg->min_ifg_enforcement <<
19966 + IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
19967 + & IPGIFG_MIN_IFG_ENFORCEMENT)
19968 + | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
19969 + iowrite32be(tmp, &regs->ipgifg);
19970 +
19971 + /***************IPGIFG************************/
19972 +
19973 + /***************HAFDUP************************/
19974 + tmp = 0;
19975 +
19976 + if (cfg->halfdup_alt_backoff_en)
19977 + tmp = (uint32_t)(HAFDUP_ALT_BEB |
19978 + ((cfg->halfdup_alt_backoff_val & 0x0000000f)
19979 + << HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
19980 + if (cfg->halfdup_bp_no_backoff)
19981 + tmp |= HAFDUP_BP_NO_BACKOFF;
19982 + if (cfg->halfdup_no_backoff)
19983 + tmp |= HAFDUP_NO_BACKOFF;
19984 + if (cfg->halfdup_excess_defer)
19985 + tmp |= HAFDUP_EXCESS_DEFER;
19986 + tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
19987 + & HAFDUP_RETRANSMISSION_MAX);
19988 + tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
19989 +
19990 + iowrite32be(tmp, &regs->hafdup);
19991 + /***************HAFDUP************************/
19992 +
19993 + /***************MAXFRM************************/
19994 + /* Initialize MAXFRM */
19995 + iowrite32be(cfg->maximum_frame, &regs->maxfrm);
19996 +
19997 + /***************MAXFRM************************/
19998 +
19999 + /***************CAM1************************/
20000 + iowrite32be(0xffffffff, &regs->cam1);
20001 + iowrite32be(0xffffffff, &regs->cam2);
20002 +
20003 + /***************IMASK************************/
20004 + iowrite32be(exception_mask, &regs->imask);
20005 + /***************IMASK************************/
20006 +
20007 + /***************IEVENT************************/
20008 + iowrite32be(0xffffffff, &regs->ievent);
20009 +
20010 + /***************MACSTNADDR1/2*****************/
20011 +
20012 + tmp = (uint32_t)((macaddr[5] << 24) |
20013 + (macaddr[4] << 16) |
20014 + (macaddr[3] << 8) |
20015 + macaddr[2]);
20016 + iowrite32be(tmp, &regs->macstnaddr1);
20017 +
20018 + tmp = (uint32_t)((macaddr[1] << 24) |
20019 + (macaddr[0] << 16));
20020 + iowrite32be(tmp, &regs->macstnaddr2);
20021 +
20022 + /***************MACSTNADDR1/2*****************/
20023 +
20024 + /*****************HASH************************/
20025 + for (i = 0; i < NUM_OF_HASH_REGS ; i++) {
20026 + /* Initialize IADDRx */
20027 + iowrite32be(0, &regs->igaddr[i]);
20028 + /* Initialize GADDRx */
20029 + iowrite32be(0, &regs->gaddr[i]);
20030 + }
20031 +
20032 + fman_dtsec_reset_stat(regs);
20033 +
20034 + return 0;
20035 +}
20036 +
20037 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs)
20038 +{
20039 + return (uint16_t)ioread32be(&regs->maxfrm);
20040 +}
20041 +
20042 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length)
20043 +{
20044 + iowrite32be(length, &regs->maxfrm);
20045 +}
20046 +
20047 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *adr)
20048 +{
20049 + uint32_t tmp;
20050 +
20051 + tmp = (uint32_t)((adr[5] << 24) |
20052 + (adr[4] << 16) |
20053 + (adr[3] << 8) |
20054 + adr[2]);
20055 + iowrite32be(tmp, &regs->macstnaddr1);
20056 +
20057 + tmp = (uint32_t)((adr[1] << 24) |
20058 + (adr[0] << 16));
20059 + iowrite32be(tmp, &regs->macstnaddr2);
20060 +}
20061 +
20062 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr)
20063 +{
20064 + uint32_t tmp1, tmp2;
20065 +
20066 + tmp1 = ioread32be(&regs->macstnaddr1);
20067 + tmp2 = ioread32be(&regs->macstnaddr2);
20068 +
20069 + macaddr[0] = (uint8_t)((tmp2 & 0x00ff0000) >> 16);
20070 + macaddr[1] = (uint8_t)((tmp2 & 0xff000000) >> 24);
20071 + macaddr[2] = (uint8_t)(tmp1 & 0x000000ff);
20072 + macaddr[3] = (uint8_t)((tmp1 & 0x0000ff00) >> 8);
20073 + macaddr[4] = (uint8_t)((tmp1 & 0x00ff0000) >> 16);
20074 + macaddr[5] = (uint8_t)((tmp1 & 0xff000000) >> 24);
20075 +}
20076 +
20077 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc, bool mcast, bool ghtx)
20078 +{
20079 + int32_t bucket;
20080 + if (ghtx)
20081 + bucket = (int32_t)((crc >> 23) & 0x1ff);
20082 + else {
20083 + bucket = (int32_t)((crc >> 24) & 0xff);
20084 + /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
20085 + if (mcast)
20086 + bucket += 0x100;
20087 + }
20088 + fman_dtsec_set_bucket(regs, bucket, TRUE);
20089 +}
20090 +
20091 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable)
20092 +{
20093 + int reg_idx = (bucket >> 5) & 0xf;
20094 + int bit_idx = bucket & 0x1f;
20095 + uint32_t bit_mask = 0x80000000 >> bit_idx;
20096 + uint32_t *reg;
20097 +
20098 + if (reg_idx > 7)
20099 + reg = &regs->gaddr[reg_idx-8];
20100 + else
20101 + reg = &regs->igaddr[reg_idx];
20102 +
20103 + if (enable)
20104 + iowrite32be(ioread32be(reg) | bit_mask, reg);
20105 + else
20106 + iowrite32be(ioread32be(reg) & (~bit_mask), reg);
20107 +}
20108 +
20109 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast, bool ucast)
20110 +{
20111 + int i;
20112 + bool ghtx;
20113 +
20114 + ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? TRUE : FALSE);
20115 +
20116 + if (ucast || (ghtx && mcast)) {
20117 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
20118 + iowrite32be(0, &regs->igaddr[i]);
20119 + }
20120 + if (mcast) {
20121 + for (i = 0; i < NUM_OF_HASH_REGS; i++)
20122 + iowrite32be(0, &regs->gaddr[i]);
20123 + }
20124 +}
20125 +
20126 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
20127 + uint8_t addr)
20128 +{
20129 + if (addr > 0 && addr < 32)
20130 + iowrite32be(addr, &regs->tbipa);
20131 + else
20132 + return -EINVAL;
20133 +
20134 + return 0;
20135 +}
20136 +
20137 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en)
20138 +{
20139 + uint32_t tmp;
20140 +
20141 + tmp = ioread32be(&regs->maccfg2);
20142 + if (en)
20143 + tmp |= MACCFG2_MAGIC_PACKET_EN;
20144 + else
20145 + tmp &= ~MACCFG2_MAGIC_PACKET_EN;
20146 + iowrite32be(tmp, &regs->maccfg2);
20147 +}
20148 +
20149 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
20150 + enum enet_interface iface_mode,
20151 + enum enet_speed speed, bool full_dx)
20152 +{
20153 + uint32_t tmp;
20154 +
20155 + UNUSED(iface_mode);
20156 +
20157 + if ((speed == E_ENET_SPEED_1000) && !full_dx)
20158 + return -EINVAL;
20159 +
20160 + tmp = ioread32be(&regs->maccfg2);
20161 + if (!full_dx)
20162 + tmp &= ~MACCFG2_FULL_DUPLEX;
20163 + else
20164 + tmp |= MACCFG2_FULL_DUPLEX;
20165 +
20166 + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
20167 + if (speed < E_ENET_SPEED_1000)
20168 + tmp |= MACCFG2_NIBBLE_MODE;
20169 + else if (speed == E_ENET_SPEED_1000)
20170 + tmp |= MACCFG2_BYTE_MODE;
20171 + iowrite32be(tmp, &regs->maccfg2);
20172 +
20173 + tmp = ioread32be(&regs->ecntrl);
20174 + if (speed == E_ENET_SPEED_100)
20175 + tmp |= DTSEC_ECNTRL_R100M;
20176 + else
20177 + tmp &= ~DTSEC_ECNTRL_R100M;
20178 + iowrite32be(tmp, &regs->ecntrl);
20179 +
20180 + return 0;
20181 +}
20182 +
20183 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable)
20184 +{
20185 + uint32_t tmp;
20186 +
20187 + tmp = ioread32be(&regs->rctrl);
20188 +
20189 + if (enable)
20190 + tmp |= RCTRL_UPROM;
20191 + else
20192 + tmp &= ~RCTRL_UPROM;
20193 +
20194 + iowrite32be(tmp, &regs->rctrl);
20195 +}
20196 +
20197 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable)
20198 +{
20199 + uint32_t tmp;
20200 +
20201 + tmp = ioread32be(&regs->rctrl);
20202 +
20203 + if (enable)
20204 + tmp |= RCTRL_MPROM;
20205 + else
20206 + tmp &= ~RCTRL_MPROM;
20207 +
20208 + iowrite32be(tmp, &regs->rctrl);
20209 +}
20210 +
20211 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
20212 + uint32_t *car1, uint32_t *car2)
20213 +{
20214 + /* read carry registers */
20215 + *car1 = ioread32be(&regs->car1);
20216 + *car2 = ioread32be(&regs->car2);
20217 + /* clear carry registers */
20218 + if (*car1)
20219 + iowrite32be(*car1, &regs->car1);
20220 + if (*car2)
20221 + iowrite32be(*car2, &regs->car2);
20222 +
20223 + return (bool)((*car1 | *car2) ? TRUE : FALSE);
20224 +}
20225 +
20226 +void fman_dtsec_reset_stat(struct dtsec_regs *regs)
20227 +{
20228 + /* clear HW counters */
20229 + iowrite32be(ioread32be(&regs->ecntrl) |
20230 + DTSEC_ECNTRL_CLRCNT, &regs->ecntrl);
20231 +}
20232 +
20233 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs, enum dtsec_stat_level level)
20234 +{
20235 + switch (level) {
20236 + case E_MAC_STAT_NONE:
20237 + iowrite32be(0xffffffff, &regs->cam1);
20238 + iowrite32be(0xffffffff, &regs->cam2);
20239 + iowrite32be(ioread32be(&regs->ecntrl) & ~DTSEC_ECNTRL_STEN,
20240 + &regs->ecntrl);
20241 + iowrite32be(ioread32be(&regs->imask) & ~DTSEC_IMASK_MSROEN,
20242 + &regs->imask);
20243 + break;
20244 + case E_MAC_STAT_PARTIAL:
20245 + iowrite32be(CAM1_ERRORS_ONLY, &regs->cam1);
20246 + iowrite32be(CAM2_ERRORS_ONLY, &regs->cam2);
20247 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
20248 + &regs->ecntrl);
20249 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
20250 + &regs->imask);
20251 + break;
20252 + case E_MAC_STAT_MIB_GRP1:
20253 + iowrite32be((uint32_t)~CAM1_MIB_GRP_1, &regs->cam1);
20254 + iowrite32be((uint32_t)~CAM2_MIB_GRP_1, &regs->cam2);
20255 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
20256 + &regs->ecntrl);
20257 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
20258 + &regs->imask);
20259 + break;
20260 + case E_MAC_STAT_FULL:
20261 + iowrite32be(0, &regs->cam1);
20262 + iowrite32be(0, &regs->cam2);
20263 + iowrite32be(ioread32be(&regs->ecntrl) | DTSEC_ECNTRL_STEN,
20264 + &regs->ecntrl);
20265 + iowrite32be(ioread32be(&regs->imask) | DTSEC_IMASK_MSROEN,
20266 + &regs->imask);
20267 + break;
20268 + default:
20269 + return -EINVAL;
20270 + }
20271 +
20272 + return 0;
20273 +}
20274 +
20275 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en)
20276 +{
20277 + if (en) {
20278 + iowrite32be(ioread32be(&regs->rctrl) | RCTRL_RTSE,
20279 + &regs->rctrl);
20280 + iowrite32be(ioread32be(&regs->tctrl) | DTSEC_TCTRL_TTSE,
20281 + &regs->tctrl);
20282 + } else {
20283 + iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_RTSE,
20284 + &regs->rctrl);
20285 + iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_TTSE,
20286 + &regs->tctrl);
20287 + }
20288 +}
20289 +
20290 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
20291 +{
20292 + uint32_t tmp;
20293 +
20294 + tmp = ioread32be(&regs->maccfg1);
20295 +
20296 + if (apply_rx)
20297 + tmp |= MACCFG1_RX_EN ;
20298 +
20299 + if (apply_tx)
20300 + tmp |= MACCFG1_TX_EN ;
20301 +
20302 + iowrite32be(tmp, &regs->maccfg1);
20303 +}
20304 +
20305 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs, uint8_t paddr_num)
20306 +{
20307 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match1);
20308 + iowrite32be(0, &regs->macaddr[paddr_num].exact_match2);
20309 +}
20310 +
20311 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
20312 + uint64_t addr,
20313 + uint8_t paddr_num)
20314 +{
20315 + uint32_t tmp;
20316 +
20317 + tmp = (uint32_t)(addr);
20318 + /* swap */
20319 + tmp = (((tmp & 0x000000FF) << 24) |
20320 + ((tmp & 0x0000FF00) << 8) |
20321 + ((tmp & 0x00FF0000) >> 8) |
20322 + ((tmp & 0xFF000000) >> 24));
20323 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match1);
20324 +
20325 + tmp = (uint32_t)(addr>>32);
20326 + /* swap */
20327 + tmp = (((tmp & 0x000000FF) << 24) |
20328 + ((tmp & 0x0000FF00) << 8) |
20329 + ((tmp & 0x00FF0000) >> 8) |
20330 + ((tmp & 0xFF000000) >> 24));
20331 + iowrite32be(tmp, &regs->macaddr[paddr_num].exact_match2);
20332 +}
20333 +
20334 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx)
20335 +{
20336 + uint32_t tmp;
20337 +
20338 + tmp = ioread32be(&regs->maccfg1);
20339 +
20340 + if (apply_rx)
20341 + tmp &= ~MACCFG1_RX_EN;
20342 +
20343 + if (apply_tx)
20344 + tmp &= ~MACCFG1_TX_EN;
20345 +
20346 + iowrite32be(tmp, &regs->maccfg1);
20347 +}
20348 +
20349 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time)
20350 +{
20351 + uint32_t ptv = 0;
20352 +
20353 + /* fixme: don't enable tx pause for half-duplex */
20354 +
20355 + if (time) {
20356 + ptv = ioread32be(&regs->ptv);
20357 + ptv &= 0xffff0000;
20358 + ptv |= time & 0x0000ffff;
20359 + iowrite32be(ptv, &regs->ptv);
20360 +
20361 + /* trigger the transmission of a flow-control pause frame */
20362 + iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
20363 + &regs->maccfg1);
20364 + } else
20365 + iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
20366 + &regs->maccfg1);
20367 +}
20368 +
20369 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en)
20370 +{
20371 + uint32_t tmp;
20372 +
20373 + /* todo: check if mac is set to full-duplex */
20374 +
20375 + tmp = ioread32be(&regs->maccfg1);
20376 + if (en)
20377 + tmp |= MACCFG1_RX_FLOW;
20378 + else
20379 + tmp &= ~MACCFG1_RX_FLOW;
20380 + iowrite32be(tmp, &regs->maccfg1);
20381 +}
20382 +
20383 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs)
20384 +{
20385 + return ioread32be(&regs->rctrl);
20386 +}
20387 +
20388 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs)
20389 +{
20390 + return ioread32be(&regs->tsec_id);
20391 +}
20392 +
20393 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask)
20394 +{
20395 + return ioread32be(&regs->ievent) & ev_mask;
20396 +}
20397 +
20398 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask)
20399 +{
20400 + iowrite32be(ev_mask, &regs->ievent);
20401 +}
20402 +
20403 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs)
20404 +{
20405 + return ioread32be(&regs->imask);
20406 +}
20407 +
20408 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs)
20409 +{
20410 + uint32_t event;
20411 +
20412 + event = ioread32be(&regs->tmr_pevent);
20413 + event &= ioread32be(&regs->tmr_pemask);
20414 +
20415 + if (event)
20416 + iowrite32be(event, &regs->tmr_pevent);
20417 + return event;
20418 +}
20419 +
20420 +void fman_dtsec_enable_tmr_interrupt(struct dtsec_regs *regs)
20421 +{
20422 + iowrite32be(ioread32be(&regs->tmr_pemask) | TMR_PEMASK_TSREEN,
20423 + &regs->tmr_pemask);
20424 +}
20425 +
20426 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs)
20427 +{
20428 + iowrite32be(ioread32be(&regs->tmr_pemask) & ~TMR_PEMASK_TSREEN,
20429 + &regs->tmr_pemask);
20430 +}
20431 +
20432 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
20433 +{
20434 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
20435 +}
20436 +
20437 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask)
20438 +{
20439 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
20440 +}
20441 +
20442 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
20443 + enum dtsec_stat_counters reg_name)
20444 +{
20445 + uint32_t ret_val;
20446 +
20447 + switch (reg_name) {
20448 + case E_DTSEC_STAT_TR64:
20449 + ret_val = ioread32be(&regs->tr64);
20450 + break;
20451 + case E_DTSEC_STAT_TR127:
20452 + ret_val = ioread32be(&regs->tr127);
20453 + break;
20454 + case E_DTSEC_STAT_TR255:
20455 + ret_val = ioread32be(&regs->tr255);
20456 + break;
20457 + case E_DTSEC_STAT_TR511:
20458 + ret_val = ioread32be(&regs->tr511);
20459 + break;
20460 + case E_DTSEC_STAT_TR1K:
20461 + ret_val = ioread32be(&regs->tr1k);
20462 + break;
20463 + case E_DTSEC_STAT_TRMAX:
20464 + ret_val = ioread32be(&regs->trmax);
20465 + break;
20466 + case E_DTSEC_STAT_TRMGV:
20467 + ret_val = ioread32be(&regs->trmgv);
20468 + break;
20469 + case E_DTSEC_STAT_RBYT:
20470 + ret_val = ioread32be(&regs->rbyt);
20471 + break;
20472 + case E_DTSEC_STAT_RPKT:
20473 + ret_val = ioread32be(&regs->rpkt);
20474 + break;
20475 + case E_DTSEC_STAT_RMCA:
20476 + ret_val = ioread32be(&regs->rmca);
20477 + break;
20478 + case E_DTSEC_STAT_RBCA:
20479 + ret_val = ioread32be(&regs->rbca);
20480 + break;
20481 + case E_DTSEC_STAT_RXPF:
20482 + ret_val = ioread32be(&regs->rxpf);
20483 + break;
20484 + case E_DTSEC_STAT_RALN:
20485 + ret_val = ioread32be(&regs->raln);
20486 + break;
20487 + case E_DTSEC_STAT_RFLR:
20488 + ret_val = ioread32be(&regs->rflr);
20489 + break;
20490 + case E_DTSEC_STAT_RCDE:
20491 + ret_val = ioread32be(&regs->rcde);
20492 + break;
20493 + case E_DTSEC_STAT_RCSE:
20494 + ret_val = ioread32be(&regs->rcse);
20495 + break;
20496 + case E_DTSEC_STAT_RUND:
20497 + ret_val = ioread32be(&regs->rund);
20498 + break;
20499 + case E_DTSEC_STAT_ROVR:
20500 + ret_val = ioread32be(&regs->rovr);
20501 + break;
20502 + case E_DTSEC_STAT_RFRG:
20503 + ret_val = ioread32be(&regs->rfrg);
20504 + break;
20505 + case E_DTSEC_STAT_RJBR:
20506 + ret_val = ioread32be(&regs->rjbr);
20507 + break;
20508 + case E_DTSEC_STAT_RDRP:
20509 + ret_val = ioread32be(&regs->rdrp);
20510 + break;
20511 + case E_DTSEC_STAT_TFCS:
20512 + ret_val = ioread32be(&regs->tfcs);
20513 + break;
20514 + case E_DTSEC_STAT_TBYT:
20515 + ret_val = ioread32be(&regs->tbyt);
20516 + break;
20517 + case E_DTSEC_STAT_TPKT:
20518 + ret_val = ioread32be(&regs->tpkt);
20519 + break;
20520 + case E_DTSEC_STAT_TMCA:
20521 + ret_val = ioread32be(&regs->tmca);
20522 + break;
20523 + case E_DTSEC_STAT_TBCA:
20524 + ret_val = ioread32be(&regs->tbca);
20525 + break;
20526 + case E_DTSEC_STAT_TXPF:
20527 + ret_val = ioread32be(&regs->txpf);
20528 + break;
20529 + case E_DTSEC_STAT_TNCL:
20530 + ret_val = ioread32be(&regs->tncl);
20531 + break;
20532 + case E_DTSEC_STAT_TDRP:
20533 + ret_val = ioread32be(&regs->tdrp);
20534 + break;
20535 + default:
20536 + ret_val = 0;
20537 + }
20538 +
20539 + return ret_val;
20540 +}
20541 --- /dev/null
20542 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_dtsec_mii_acc.c
20543 @@ -0,0 +1,165 @@
20544 +/*
20545 + * Copyright 2008-2013 Freescale Semiconductor Inc.
20546 + *
20547 + * Redistribution and use in source and binary forms, with or without
20548 + * modification, are permitted provided that the following conditions are met:
20549 + * * Redistributions of source code must retain the above copyright
20550 + * notice, this list of conditions and the following disclaimer.
20551 + * * Redistributions in binary form must reproduce the above copyright
20552 + * notice, this list of conditions and the following disclaimer in the
20553 + * documentation and/or other materials provided with the distribution.
20554 + * * Neither the name of Freescale Semiconductor nor the
20555 + * names of its contributors may be used to endorse or promote products
20556 + * derived from this software without specific prior written permission.
20557 + *
20558 + *
20559 + * ALTERNATIVELY, this software may be distributed under the terms of the
20560 + * GNU General Public License ("GPL") as published by the Free Software
20561 + * Foundation, either version 2 of that License or (at your option) any
20562 + * later version.
20563 + *
20564 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20565 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20566 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20567 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20568 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20569 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20570 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20571 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20572 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20573 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20574 + */
20575 +
20576 +
20577 +#include "std_ext.h"
20578 +#include "error_ext.h"
20579 +#include "common/general.h"
20580 +#include "fsl_fman_dtsec_mii_acc.h"
20581 +
20582 +
20583 +/**
20584 + * dtsec_mii_get_div() - calculates the value of the dtsec mii divider
20585 + * @dtsec_freq: dtsec clock frequency (in Mhz)
20586 + *
20587 + * This function calculates the dtsec mii clock divider that determines
20588 + * the MII MDC clock. MII MDC clock will be set to work in the range
20589 + * of 1.5 to 2.5Mhz
20590 + * The output of this function is the value of MIIMCFG[MgmtClk] which
20591 + * implicitly determines the divider value.
20592 + * Note: the dTSEC system clock is equal to 1/2 of the FMan clock.
20593 + *
20594 + * The table below which reflects dtsec_mii_get_div() functionality
20595 + * shows the relations among dtsec_freq, MgmtClk, actual divider
20596 + * and the MII frequency:
20597 + *
20598 + * dtsec freq MgmtClk div MII freq Mhz
20599 + * [0.....80] 1 (1/4)(1/8) [0 to 2.5]
20600 + * [81...120] 2 (1/6)(1/8) [1.6 to 2.5]
20601 + * [121..160] 3 (1/8)(1/8) [1.8 to 2.5]
20602 + * [161..200] 4 (1/10)(1/8) [2.0 to 2.5]
20603 + * [201..280] 5 (1/14)(1/8) [1.8 to 2.5]
20604 + * [281..400] 6 (1/20)(1/8) [1.1 to 2.5]
20605 + * [401..560] 7 (1/28)(1/8) [1.8 to 2.5]
20606 + * [560..frq] 7 (1/28)(1/8) [frq/224]
20607 + *
20608 + * Returns: the MIIMCFG[MgmtClk] appropriate value
20609 + */
20610 +
20611 +static uint8_t dtsec_mii_get_div(uint16_t dtsec_freq)
20612 +{
20613 + uint16_t mgmt_clk;
20614 +
20615 + if (dtsec_freq < 80) mgmt_clk = 1;
20616 + else if (dtsec_freq < 120) mgmt_clk = 2;
20617 + else if (dtsec_freq < 160) mgmt_clk = 3;
20618 + else if (dtsec_freq < 200) mgmt_clk = 4;
20619 + else if (dtsec_freq < 280) mgmt_clk = 5;
20620 + else if (dtsec_freq < 400) mgmt_clk = 6;
20621 + else mgmt_clk = 7;
20622 +
20623 + return (uint8_t)mgmt_clk;
20624 +}
20625 +
20626 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs)
20627 +{
20628 + /* Reset the management interface */
20629 + iowrite32be(ioread32be(&regs->miimcfg) | MIIMCFG_RESET_MGMT,
20630 + &regs->miimcfg);
20631 + iowrite32be(ioread32be(&regs->miimcfg) & ~MIIMCFG_RESET_MGMT,
20632 + &regs->miimcfg);
20633 +}
20634 +
20635 +
20636 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs, uint8_t addr,
20637 + uint8_t reg, uint16_t data, uint16_t dtsec_freq)
20638 +{
20639 + uint32_t tmp;
20640 +
20641 + /* Setup the MII Mgmt clock speed */
20642 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
20643 + wmb();
20644 +
20645 + /* Stop the MII management read cycle */
20646 + iowrite32be(0, &regs->miimcom);
20647 + /* Dummy read to make sure MIIMCOM is written */
20648 + tmp = ioread32be(&regs->miimcom);
20649 + wmb();
20650 +
20651 + /* Setting up MII Management Address Register */
20652 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
20653 + iowrite32be(tmp, &regs->miimadd);
20654 + wmb();
20655 +
20656 + /* Setting up MII Management Control Register with data */
20657 + iowrite32be((uint32_t)data, &regs->miimcon);
20658 + /* Dummy read to make sure MIIMCON is written */
20659 + tmp = ioread32be(&regs->miimcon);
20660 + wmb();
20661 +
20662 + /* Wait until MII management write is complete */
20663 + /* todo: a timeout could be useful here */
20664 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
20665 + /* busy wait */;
20666 +
20667 + return 0;
20668 +}
20669 +
20670 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs, uint8_t addr,
20671 + uint8_t reg, uint16_t *data, uint16_t dtsec_freq)
20672 +{
20673 + uint32_t tmp;
20674 +
20675 + /* Setup the MII Mgmt clock speed */
20676 + iowrite32be((uint32_t)dtsec_mii_get_div(dtsec_freq), &regs->miimcfg);
20677 + wmb();
20678 +
20679 + /* Setting up the MII Management Address Register */
20680 + tmp = (uint32_t)((addr << MIIMADD_PHY_ADDR_SHIFT) | reg);
20681 + iowrite32be(tmp, &regs->miimadd);
20682 + wmb();
20683 +
20684 + /* Perform an MII management read cycle */
20685 + iowrite32be(MIIMCOM_READ_CYCLE, &regs->miimcom);
20686 + /* Dummy read to make sure MIIMCOM is written */
20687 + tmp = ioread32be(&regs->miimcom);
20688 + wmb();
20689 +
20690 + /* Wait until MII management read is complete */
20691 + /* todo: a timeout could be useful here */
20692 + while ((ioread32be(&regs->miimind)) & MIIMIND_BUSY)
20693 + /* busy wait */;
20694 +
20695 + /* Read MII management status */
20696 + *data = (uint16_t)ioread32be(&regs->miimstat);
20697 + wmb();
20698 +
20699 + iowrite32be(0, &regs->miimcom);
20700 + /* Dummy read to make sure MIIMCOM is written */
20701 + tmp = ioread32be(&regs->miimcom);
20702 +
20703 + if (*data == 0xffff)
20704 + return -ENXIO;
20705 +
20706 + return 0;
20707 +}
20708 +
20709 --- /dev/null
20710 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac.c
20711 @@ -0,0 +1,532 @@
20712 +/*
20713 + * Copyright 2008-2012 Freescale Semiconductor Inc.
20714 + *
20715 + * Redistribution and use in source and binary forms, with or without
20716 + * modification, are permitted provided that the following conditions are met:
20717 + * * Redistributions of source code must retain the above copyright
20718 + * notice, this list of conditions and the following disclaimer.
20719 + * * Redistributions in binary form must reproduce the above copyright
20720 + * notice, this list of conditions and the following disclaimer in the
20721 + * documentation and/or other materials provided with the distribution.
20722 + * * Neither the name of Freescale Semiconductor nor the
20723 + * names of its contributors may be used to endorse or promote products
20724 + * derived from this software without specific prior written permission.
20725 + *
20726 + *
20727 + * ALTERNATIVELY, this software may be distributed under the terms of the
20728 + * GNU General Public License ("GPL") as published by the Free Software
20729 + * Foundation, either version 2 of that License or (at your option) any
20730 + * later version.
20731 + *
20732 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
20733 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20734 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20735 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
20736 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20737 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20738 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20739 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20740 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20741 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20742 + */
20743 +
20744 +
20745 +#include "fsl_fman_memac.h"
20746 +
20747 +
20748 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask)
20749 +{
20750 + return ioread32be(&regs->ievent) & ev_mask;
20751 +}
20752 +
20753 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs)
20754 +{
20755 + return ioread32be(&regs->imask);
20756 +}
20757 +
20758 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask)
20759 +{
20760 + iowrite32be(ev_mask, &regs->ievent);
20761 +}
20762 +
20763 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val)
20764 +{
20765 + uint32_t tmp;
20766 +
20767 + tmp = ioread32be(&regs->command_config);
20768 +
20769 + if (val)
20770 + tmp |= CMD_CFG_PROMIS_EN;
20771 + else
20772 + tmp &= ~CMD_CFG_PROMIS_EN;
20773 +
20774 + iowrite32be(tmp, &regs->command_config);
20775 +}
20776 +
20777 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
20778 + uint8_t paddr_num)
20779 +{
20780 + if (paddr_num == 0) {
20781 + iowrite32be(0, &regs->mac_addr0.mac_addr_l);
20782 + iowrite32be(0, &regs->mac_addr0.mac_addr_u);
20783 + } else {
20784 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
20785 + iowrite32be(0x0, &regs->mac_addr[paddr_num - 1].mac_addr_u);
20786 + }
20787 +}
20788 +
20789 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
20790 + uint8_t *adr,
20791 + uint8_t paddr_num)
20792 +{
20793 + uint32_t tmp0, tmp1;
20794 +
20795 + tmp0 = (uint32_t)(adr[0] |
20796 + adr[1] << 8 |
20797 + adr[2] << 16 |
20798 + adr[3] << 24);
20799 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
20800 +
20801 + if (paddr_num == 0) {
20802 + iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
20803 + iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
20804 + } else {
20805 + iowrite32be(tmp0, &regs->mac_addr[paddr_num-1].mac_addr_l);
20806 + iowrite32be(tmp1, &regs->mac_addr[paddr_num-1].mac_addr_u);
20807 + }
20808 +}
20809 +
20810 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
20811 +{
20812 + uint32_t tmp;
20813 +
20814 + tmp = ioread32be(&regs->command_config);
20815 +
20816 + if (apply_rx)
20817 + tmp |= CMD_CFG_RX_EN;
20818 +
20819 + if (apply_tx)
20820 + tmp |= CMD_CFG_TX_EN;
20821 +
20822 + iowrite32be(tmp, &regs->command_config);
20823 +}
20824 +
20825 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx)
20826 +{
20827 + uint32_t tmp;
20828 +
20829 + tmp = ioread32be(&regs->command_config);
20830 +
20831 + if (apply_rx)
20832 + tmp &= ~CMD_CFG_RX_EN;
20833 +
20834 + if (apply_tx)
20835 + tmp &= ~CMD_CFG_TX_EN;
20836 +
20837 + iowrite32be(tmp, &regs->command_config);
20838 +}
20839 +
20840 +void fman_memac_reset_stat(struct memac_regs *regs)
20841 +{
20842 + uint32_t tmp;
20843 +
20844 + tmp = ioread32be(&regs->statn_config);
20845 +
20846 + tmp |= STATS_CFG_CLR;
20847 +
20848 + iowrite32be(tmp, &regs->statn_config);
20849 +
20850 + while (ioread32be(&regs->statn_config) & STATS_CFG_CLR);
20851 +}
20852 +
20853 +void fman_memac_reset(struct memac_regs *regs)
20854 +{
20855 + uint32_t tmp;
20856 +
20857 + tmp = ioread32be(&regs->command_config);
20858 +
20859 + tmp |= CMD_CFG_SW_RESET;
20860 +
20861 + iowrite32be(tmp, &regs->command_config);
20862 +
20863 + while (ioread32be(&regs->command_config) & CMD_CFG_SW_RESET);
20864 +}
20865 +
20866 +int fman_memac_init(struct memac_regs *regs,
20867 + struct memac_cfg *cfg,
20868 + enum enet_interface enet_interface,
20869 + enum enet_speed enet_speed,
20870 + bool slow_10g_if,
20871 + uint32_t exceptions)
20872 +{
20873 + uint32_t tmp;
20874 +
20875 + /* Config */
20876 + tmp = 0;
20877 + if (cfg->wan_mode_enable)
20878 + tmp |= CMD_CFG_WAN_MODE;
20879 + if (cfg->promiscuous_mode_enable)
20880 + tmp |= CMD_CFG_PROMIS_EN;
20881 + if (cfg->pause_forward_enable)
20882 + tmp |= CMD_CFG_PAUSE_FWD;
20883 + if (cfg->pause_ignore)
20884 + tmp |= CMD_CFG_PAUSE_IGNORE;
20885 + if (cfg->tx_addr_ins_enable)
20886 + tmp |= CMD_CFG_TX_ADDR_INS;
20887 + if (cfg->loopback_enable)
20888 + tmp |= CMD_CFG_LOOPBACK_EN;
20889 + if (cfg->cmd_frame_enable)
20890 + tmp |= CMD_CFG_CNT_FRM_EN;
20891 + if (cfg->send_idle_enable)
20892 + tmp |= CMD_CFG_SEND_IDLE;
20893 + if (cfg->no_length_check_enable)
20894 + tmp |= CMD_CFG_NO_LEN_CHK;
20895 + if (cfg->rx_sfd_any)
20896 + tmp |= CMD_CFG_SFD_ANY;
20897 + if (cfg->pad_enable)
20898 + tmp |= CMD_CFG_TX_PAD_EN;
20899 + if (cfg->wake_on_lan)
20900 + tmp |= CMD_CFG_MG;
20901 +
20902 + tmp |= CMD_CFG_CRC_FWD;
20903 +
20904 + iowrite32be(tmp, &regs->command_config);
20905 +
20906 + /* Max Frame Length */
20907 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
20908 +
20909 + /* Pause Time */
20910 + iowrite32be((uint32_t)cfg->pause_quanta, &regs->pause_quanta[0]);
20911 + iowrite32be((uint32_t)0, &regs->pause_thresh[0]);
20912 +
20913 + /* IF_MODE */
20914 + tmp = 0;
20915 + switch (enet_interface) {
20916 + case E_ENET_IF_XGMII:
20917 + case E_ENET_IF_XFI:
20918 + tmp |= IF_MODE_XGMII;
20919 + break;
20920 + default:
20921 + tmp |= IF_MODE_GMII;
20922 + if (enet_interface == E_ENET_IF_RGMII && !cfg->loopback_enable)
20923 + tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
20924 + }
20925 + iowrite32be(tmp, &regs->if_mode);
20926 +
20927 + /* TX_FIFO_SECTIONS */
20928 + tmp = 0;
20929 + if (enet_interface == E_ENET_IF_XGMII ||
20930 + enet_interface == E_ENET_IF_XFI) {
20931 + if(slow_10g_if) {
20932 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
20933 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
20934 + } else {
20935 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
20936 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
20937 + }
20938 + } else {
20939 + tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
20940 + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
20941 + }
20942 + iowrite32be(tmp, &regs->tx_fifo_sections);
20943 +
20944 + /* clear all pending events and set-up interrupts */
20945 + fman_memac_ack_event(regs, 0xffffffff);
20946 + fman_memac_set_exception(regs, exceptions, TRUE);
20947 +
20948 + return 0;
20949 +}
20950 +
20951 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val, bool enable)
20952 +{
20953 + uint32_t tmp;
20954 +
20955 + tmp = ioread32be(&regs->imask);
20956 + if (enable)
20957 + tmp |= val;
20958 + else
20959 + tmp &= ~val;
20960 +
20961 + iowrite32be(tmp, &regs->imask);
20962 +}
20963 +
20964 +void fman_memac_reset_filter_table(struct memac_regs *regs)
20965 +{
20966 + uint32_t i;
20967 + for (i = 0; i < 64; i++)
20968 + iowrite32be(i & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
20969 +}
20970 +
20971 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc)
20972 +{
20973 + iowrite32be(crc | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
20974 +}
20975 +
20976 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val)
20977 +{
20978 + iowrite32be(val, &regs->hashtable_ctrl);
20979 +}
20980 +
20981 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs)
20982 +{
20983 + uint32_t tmp;
20984 +
20985 + tmp = ioread32be(&regs->maxfrm);
20986 +
20987 + return(uint16_t)tmp;
20988 +}
20989 +
20990 +
20991 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
20992 + uint8_t priority,
20993 + uint16_t pause_time,
20994 + uint16_t thresh_time)
20995 +{
20996 + uint32_t tmp;
20997 +
20998 + tmp = ioread32be(&regs->tx_fifo_sections);
20999 +
21000 + if (priority == 0xff) {
21001 + GET_TX_EMPTY_DEFAULT_VALUE(tmp);
21002 + iowrite32be(tmp, &regs->tx_fifo_sections);
21003 +
21004 + tmp = ioread32be(&regs->command_config);
21005 + tmp &= ~CMD_CFG_PFC_MODE;
21006 + priority = 0;
21007 + } else {
21008 + GET_TX_EMPTY_PFC_VALUE(tmp);
21009 + iowrite32be(tmp, &regs->tx_fifo_sections);
21010 +
21011 + tmp = ioread32be(&regs->command_config);
21012 + tmp |= CMD_CFG_PFC_MODE;
21013 + }
21014 +
21015 + iowrite32be(tmp, &regs->command_config);
21016 +
21017 + tmp = ioread32be(&regs->pause_quanta[priority / 2]);
21018 + if (priority % 2)
21019 + tmp &= 0x0000FFFF;
21020 + else
21021 + tmp &= 0xFFFF0000;
21022 + tmp |= ((uint32_t)pause_time << (16 * (priority % 2)));
21023 + iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
21024 +
21025 + tmp = ioread32be(&regs->pause_thresh[priority / 2]);
21026 + if (priority % 2)
21027 + tmp &= 0x0000FFFF;
21028 + else
21029 + tmp &= 0xFFFF0000;
21030 + tmp |= ((uint32_t)thresh_time<<(16 * (priority % 2)));
21031 + iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
21032 +}
21033 +
21034 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,bool enable)
21035 +{
21036 + uint32_t tmp;
21037 +
21038 + tmp = ioread32be(&regs->command_config);
21039 + if (enable)
21040 + tmp |= CMD_CFG_PAUSE_IGNORE;
21041 + else
21042 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
21043 +
21044 + iowrite32be(tmp, &regs->command_config);
21045 +}
21046 +
21047 +void fman_memac_set_wol(struct memac_regs *regs, bool enable)
21048 +{
21049 + uint32_t tmp;
21050 +
21051 + tmp = ioread32be(&regs->command_config);
21052 +
21053 + if (enable)
21054 + tmp |= CMD_CFG_MG;
21055 + else
21056 + tmp &= ~CMD_CFG_MG;
21057 +
21058 + iowrite32be(tmp, &regs->command_config);
21059 +}
21060 +
21061 +#define GET_MEMAC_CNTR_64(bn) \
21062 + (ioread32be(&regs->bn ## _l) | \
21063 + ((uint64_t)ioread32be(&regs->bn ## _u) << 32))
21064 +
21065 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
21066 + enum memac_counters reg_name)
21067 +{
21068 + uint64_t ret_val;
21069 +
21070 + switch (reg_name) {
21071 + case E_MEMAC_COUNTER_R64:
21072 + ret_val = GET_MEMAC_CNTR_64(r64);
21073 + break;
21074 + case E_MEMAC_COUNTER_T64:
21075 + ret_val = GET_MEMAC_CNTR_64(t64);
21076 + break;
21077 + case E_MEMAC_COUNTER_R127:
21078 + ret_val = GET_MEMAC_CNTR_64(r127);
21079 + break;
21080 + case E_MEMAC_COUNTER_T127:
21081 + ret_val = GET_MEMAC_CNTR_64(t127);
21082 + break;
21083 + case E_MEMAC_COUNTER_R255:
21084 + ret_val = GET_MEMAC_CNTR_64(r255);
21085 + break;
21086 + case E_MEMAC_COUNTER_T255:
21087 + ret_val = GET_MEMAC_CNTR_64(t255);
21088 + break;
21089 + case E_MEMAC_COUNTER_R511:
21090 + ret_val = GET_MEMAC_CNTR_64(r511);
21091 + break;
21092 + case E_MEMAC_COUNTER_T511:
21093 + ret_val = GET_MEMAC_CNTR_64(t511);
21094 + break;
21095 + case E_MEMAC_COUNTER_R1023:
21096 + ret_val = GET_MEMAC_CNTR_64(r1023);
21097 + break;
21098 + case E_MEMAC_COUNTER_T1023:
21099 + ret_val = GET_MEMAC_CNTR_64(t1023);
21100 + break;
21101 + case E_MEMAC_COUNTER_R1518:
21102 + ret_val = GET_MEMAC_CNTR_64(r1518);
21103 + break;
21104 + case E_MEMAC_COUNTER_T1518:
21105 + ret_val = GET_MEMAC_CNTR_64(t1518);
21106 + break;
21107 + case E_MEMAC_COUNTER_R1519X:
21108 + ret_val = GET_MEMAC_CNTR_64(r1519x);
21109 + break;
21110 + case E_MEMAC_COUNTER_T1519X:
21111 + ret_val = GET_MEMAC_CNTR_64(t1519x);
21112 + break;
21113 + case E_MEMAC_COUNTER_RFRG:
21114 + ret_val = GET_MEMAC_CNTR_64(rfrg);
21115 + break;
21116 + case E_MEMAC_COUNTER_RJBR:
21117 + ret_val = GET_MEMAC_CNTR_64(rjbr);
21118 + break;
21119 + case E_MEMAC_COUNTER_RDRP:
21120 + ret_val = GET_MEMAC_CNTR_64(rdrp);
21121 + break;
21122 + case E_MEMAC_COUNTER_RALN:
21123 + ret_val = GET_MEMAC_CNTR_64(raln);
21124 + break;
21125 + case E_MEMAC_COUNTER_TUND:
21126 + ret_val = GET_MEMAC_CNTR_64(tund);
21127 + break;
21128 + case E_MEMAC_COUNTER_ROVR:
21129 + ret_val = GET_MEMAC_CNTR_64(rovr);
21130 + break;
21131 + case E_MEMAC_COUNTER_RXPF:
21132 + ret_val = GET_MEMAC_CNTR_64(rxpf);
21133 + break;
21134 + case E_MEMAC_COUNTER_TXPF:
21135 + ret_val = GET_MEMAC_CNTR_64(txpf);
21136 + break;
21137 + case E_MEMAC_COUNTER_ROCT:
21138 + ret_val = GET_MEMAC_CNTR_64(roct);
21139 + break;
21140 + case E_MEMAC_COUNTER_RMCA:
21141 + ret_val = GET_MEMAC_CNTR_64(rmca);
21142 + break;
21143 + case E_MEMAC_COUNTER_RBCA:
21144 + ret_val = GET_MEMAC_CNTR_64(rbca);
21145 + break;
21146 + case E_MEMAC_COUNTER_RPKT:
21147 + ret_val = GET_MEMAC_CNTR_64(rpkt);
21148 + break;
21149 + case E_MEMAC_COUNTER_RUCA:
21150 + ret_val = GET_MEMAC_CNTR_64(ruca);
21151 + break;
21152 + case E_MEMAC_COUNTER_RERR:
21153 + ret_val = GET_MEMAC_CNTR_64(rerr);
21154 + break;
21155 + case E_MEMAC_COUNTER_TOCT:
21156 + ret_val = GET_MEMAC_CNTR_64(toct);
21157 + break;
21158 + case E_MEMAC_COUNTER_TMCA:
21159 + ret_val = GET_MEMAC_CNTR_64(tmca);
21160 + break;
21161 + case E_MEMAC_COUNTER_TBCA:
21162 + ret_val = GET_MEMAC_CNTR_64(tbca);
21163 + break;
21164 + case E_MEMAC_COUNTER_TUCA:
21165 + ret_val = GET_MEMAC_CNTR_64(tuca);
21166 + break;
21167 + case E_MEMAC_COUNTER_TERR:
21168 + ret_val = GET_MEMAC_CNTR_64(terr);
21169 + break;
21170 + default:
21171 + ret_val = 0;
21172 + }
21173 +
21174 + return ret_val;
21175 +}
21176 +
21177 +void fman_memac_adjust_link(struct memac_regs *regs,
21178 + enum enet_interface iface_mode,
21179 + enum enet_speed speed, bool full_dx)
21180 +{
21181 + uint32_t tmp;
21182 +
21183 + tmp = ioread32be(&regs->if_mode);
21184 +
21185 + if (full_dx)
21186 + tmp &= ~IF_MODE_HD;
21187 + else
21188 + tmp |= IF_MODE_HD;
21189 +
21190 + if (iface_mode == E_ENET_IF_RGMII) {
21191 + /* Configure RGMII in manual mode */
21192 + tmp &= ~IF_MODE_RGMII_AUTO;
21193 + tmp &= ~IF_MODE_RGMII_SP_MASK;
21194 +
21195 + if (full_dx)
21196 + tmp |= IF_MODE_RGMII_FD;
21197 + else
21198 + tmp &= ~IF_MODE_RGMII_FD;
21199 +
21200 + switch (speed) {
21201 + case E_ENET_SPEED_1000:
21202 + tmp |= IF_MODE_RGMII_1000;
21203 + break;
21204 + case E_ENET_SPEED_100:
21205 + tmp |= IF_MODE_RGMII_100;
21206 + break;
21207 + case E_ENET_SPEED_10:
21208 + tmp |= IF_MODE_RGMII_10;
21209 + break;
21210 + default:
21211 + break;
21212 + }
21213 + }
21214 +
21215 + iowrite32be(tmp, &regs->if_mode);
21216 +}
21217 +
21218 +void fman_memac_defconfig(struct memac_cfg *cfg)
21219 +{
21220 + cfg->reset_on_init = FALSE;
21221 + cfg->wan_mode_enable = FALSE;
21222 + cfg->promiscuous_mode_enable = FALSE;
21223 + cfg->pause_forward_enable = FALSE;
21224 + cfg->pause_ignore = FALSE;
21225 + cfg->tx_addr_ins_enable = FALSE;
21226 + cfg->loopback_enable = FALSE;
21227 + cfg->cmd_frame_enable = FALSE;
21228 + cfg->rx_error_discard = FALSE;
21229 + cfg->send_idle_enable = FALSE;
21230 + cfg->no_length_check_enable = TRUE;
21231 + cfg->lgth_check_nostdr = FALSE;
21232 + cfg->time_stamp_enable = FALSE;
21233 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
21234 + cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
21235 + cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
21236 + cfg->pad_enable = TRUE;
21237 + cfg->phy_tx_ena_on = FALSE;
21238 + cfg->rx_sfd_any = FALSE;
21239 + cfg->rx_pbl_fwd = FALSE;
21240 + cfg->tx_pbl_fwd = FALSE;
21241 + cfg->debug_mode = FALSE;
21242 + cfg->wake_on_lan = FALSE;
21243 +}
21244 --- /dev/null
21245 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_memac_mii_acc.c
21246 @@ -0,0 +1,215 @@
21247 +/*
21248 + * Copyright 2008-2013 Freescale Semiconductor Inc.
21249 + *
21250 + * Redistribution and use in source and binary forms, with or without
21251 + * modification, are permitted provided that the following conditions are met:
21252 + * * Redistributions of source code must retain the above copyright
21253 + * notice, this list of conditions and the following disclaimer.
21254 + * * Redistributions in binary form must reproduce the above copyright
21255 + * notice, this list of conditions and the following disclaimer in the
21256 + * documentation and/or other materials provided with the distribution.
21257 + * * Neither the name of Freescale Semiconductor nor the
21258 + * names of its contributors may be used to endorse or promote products
21259 + * derived from this software without specific prior written permission.
21260 + *
21261 + *
21262 + * ALTERNATIVELY, this software may be distributed under the terms of the
21263 + * GNU General Public License ("GPL") as published by the Free Software
21264 + * Foundation, either version 2 of that License or (at your option) any
21265 + * later version.
21266 + *
21267 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21268 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21269 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21270 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21271 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21272 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21273 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21274 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21275 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21276 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21277 + */
21278 +
21279 +
21280 +#include "std_ext.h"
21281 +#include "error_ext.h"
21282 +#include "fsl_fman_memac_mii_acc.h"
21283 +
21284 +static void write_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
21285 + uint8_t phy_addr, uint8_t reg, uint16_t data)
21286 +{
21287 + uint32_t tmp_reg;
21288 +
21289 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
21290 + /* Leave only MDIO_CLK_DIV bits set on */
21291 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
21292 + /* Set maximum MDIO_HOLD value to allow phy to see
21293 + change of data signal */
21294 + tmp_reg |= MDIO_CFG_HOLD_MASK;
21295 + /* Add 10G interface mode */
21296 + tmp_reg |= MDIO_CFG_ENC45;
21297 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
21298 +
21299 + /* Wait for command completion */
21300 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21301 + udelay(1);
21302 +
21303 + /* Specify phy and register to be accessed */
21304 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
21305 + iowrite32be(reg, &mii_regs->mdio_addr);
21306 + wmb();
21307 +
21308 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21309 + udelay(1);
21310 +
21311 + /* Write data */
21312 + iowrite32be(data, &mii_regs->mdio_data);
21313 + wmb();
21314 +
21315 + /* Wait for write transaction end */
21316 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
21317 + udelay(1);
21318 +}
21319 +
21320 +static uint32_t read_phy_reg_10g(struct memac_mii_access_mem_map *mii_regs,
21321 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
21322 +{
21323 + uint32_t tmp_reg;
21324 +
21325 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
21326 + /* Leave only MDIO_CLK_DIV bits set on */
21327 + tmp_reg &= MDIO_CFG_CLK_DIV_MASK;
21328 + /* Set maximum MDIO_HOLD value to allow phy to see
21329 + change of data signal */
21330 + tmp_reg |= MDIO_CFG_HOLD_MASK;
21331 + /* Add 10G interface mode */
21332 + tmp_reg |= MDIO_CFG_ENC45;
21333 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
21334 +
21335 + /* Wait for command completion */
21336 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21337 + udelay(1);
21338 +
21339 + /* Specify phy and register to be accessed */
21340 + iowrite32be(phy_addr, &mii_regs->mdio_ctrl);
21341 + iowrite32be(reg, &mii_regs->mdio_addr);
21342 + wmb();
21343 +
21344 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21345 + udelay(1);
21346 +
21347 + /* Read cycle */
21348 + tmp_reg = phy_addr;
21349 + tmp_reg |= MDIO_CTL_READ;
21350 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
21351 + wmb();
21352 +
21353 + /* Wait for data to be available */
21354 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
21355 + udelay(1);
21356 +
21357 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
21358 +
21359 + /* Check if there was an error */
21360 + return ioread32be(&mii_regs->mdio_cfg);
21361 +}
21362 +
21363 +static void write_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
21364 + uint8_t phy_addr, uint8_t reg, uint16_t data)
21365 +{
21366 + uint32_t tmp_reg;
21367 +
21368 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
21369 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
21370 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
21371 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
21372 +
21373 + /* Wait for command completion */
21374 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21375 + udelay(1);
21376 +
21377 + /* Write transaction */
21378 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
21379 + tmp_reg |= reg;
21380 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
21381 +
21382 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21383 + udelay(1);
21384 +
21385 + iowrite32be(data, &mii_regs->mdio_data);
21386 +
21387 + wmb();
21388 +
21389 + /* Wait for write transaction to end */
21390 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
21391 + udelay(1);
21392 +}
21393 +
21394 +static uint32_t read_phy_reg_1g(struct memac_mii_access_mem_map *mii_regs,
21395 + uint8_t phy_addr, uint8_t reg, uint16_t *data)
21396 +{
21397 + uint32_t tmp_reg;
21398 +
21399 + /* Leave only MDIO_CLK_DIV and MDIO_HOLD bits set on */
21400 + tmp_reg = ioread32be(&mii_regs->mdio_cfg);
21401 + tmp_reg &= (MDIO_CFG_CLK_DIV_MASK | MDIO_CFG_HOLD_MASK);
21402 + iowrite32be(tmp_reg, &mii_regs->mdio_cfg);
21403 +
21404 + /* Wait for command completion */
21405 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21406 + udelay(1);
21407 +
21408 + /* Read transaction */
21409 + tmp_reg = (phy_addr << MDIO_CTL_PHY_ADDR_SHIFT);
21410 + tmp_reg |= reg;
21411 + tmp_reg |= MDIO_CTL_READ;
21412 + iowrite32be(tmp_reg, &mii_regs->mdio_ctrl);
21413 +
21414 + while ((ioread32be(&mii_regs->mdio_cfg)) & MDIO_CFG_BSY)
21415 + udelay(1);
21416 +
21417 + /* Wait for data to be available */
21418 + while ((ioread32be(&mii_regs->mdio_data)) & MDIO_DATA_BSY)
21419 + udelay(1);
21420 +
21421 + *data = (uint16_t)ioread32be(&mii_regs->mdio_data);
21422 +
21423 + /* Check error */
21424 + return ioread32be(&mii_regs->mdio_cfg);
21425 +}
21426 +
21427 +/*****************************************************************************/
21428 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
21429 + uint8_t phy_addr, uint8_t reg, uint16_t data,
21430 + enum enet_speed enet_speed)
21431 +{
21432 + /* Figure out interface type - 10G vs 1G.
21433 + In 10G interface both phy_addr and devAddr present. */
21434 + if (enet_speed == E_ENET_SPEED_10000)
21435 + write_phy_reg_10g(mii_regs, phy_addr, reg, data);
21436 + else
21437 + write_phy_reg_1g(mii_regs, phy_addr, reg, data);
21438 +
21439 + return 0;
21440 +}
21441 +
21442 +/*****************************************************************************/
21443 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
21444 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
21445 + enum enet_speed enet_speed)
21446 +{
21447 + uint32_t ans;
21448 + /* Figure out interface type - 10G vs 1G.
21449 + In 10G interface both phy_addr and devAddr present. */
21450 + if (enet_speed == E_ENET_SPEED_10000)
21451 + ans = read_phy_reg_10g(mii_regs, phy_addr, reg, data);
21452 + else
21453 + ans = read_phy_reg_1g(mii_regs, phy_addr, reg, data);
21454 +
21455 + if (ans & MDIO_CFG_READ_ERR)
21456 + return -EINVAL;
21457 + return 0;
21458 +}
21459 +
21460 +/* ......................................................................... */
21461 +
21462 --- /dev/null
21463 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/fman_tgec.c
21464 @@ -0,0 +1,367 @@
21465 +/*
21466 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21467 + *
21468 + * Redistribution and use in source and binary forms, with or without
21469 + * modification, are permitted provided that the following conditions are met:
21470 + * * Redistributions of source code must retain the above copyright
21471 + * notice, this list of conditions and the following disclaimer.
21472 + * * Redistributions in binary form must reproduce the above copyright
21473 + * notice, this list of conditions and the following disclaimer in the
21474 + * documentation and/or other materials provided with the distribution.
21475 + * * Neither the name of Freescale Semiconductor nor the
21476 + * names of its contributors may be used to endorse or promote products
21477 + * derived from this software without specific prior written permission.
21478 + *
21479 + *
21480 + * ALTERNATIVELY, this software may be distributed under the terms of the
21481 + * GNU General Public License ("GPL") as published by the Free Software
21482 + * Foundation, either version 2 of that License or (at your option) any
21483 + * later version.
21484 + *
21485 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21486 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21487 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21488 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21489 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21490 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21491 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21492 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21493 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21494 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21495 + */
21496 +
21497 +
21498 +#include "fsl_fman_tgec.h"
21499 +
21500 +
21501 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *adr)
21502 +{
21503 + uint32_t tmp0, tmp1;
21504 +
21505 + tmp0 = (uint32_t)(adr[0] |
21506 + adr[1] << 8 |
21507 + adr[2] << 16 |
21508 + adr[3] << 24);
21509 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
21510 + iowrite32be(tmp0, &regs->mac_addr_0);
21511 + iowrite32be(tmp1, &regs->mac_addr_1);
21512 +}
21513 +
21514 +void fman_tgec_reset_stat(struct tgec_regs *regs)
21515 +{
21516 + uint32_t tmp;
21517 +
21518 + tmp = ioread32be(&regs->command_config);
21519 +
21520 + tmp |= CMD_CFG_STAT_CLR;
21521 +
21522 + iowrite32be(tmp, &regs->command_config);
21523 +
21524 + while (ioread32be(&regs->command_config) & CMD_CFG_STAT_CLR) ;
21525 +}
21526 +
21527 +#define GET_TGEC_CNTR_64(bn) \
21528 + (((uint64_t)ioread32be(&regs->bn ## _u) << 32) | \
21529 + ioread32be(&regs->bn ## _l))
21530 +
21531 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs, enum tgec_counters reg_name)
21532 +{
21533 + uint64_t ret_val;
21534 +
21535 + switch (reg_name) {
21536 + case E_TGEC_COUNTER_R64:
21537 + ret_val = GET_TGEC_CNTR_64(r64);
21538 + break;
21539 + case E_TGEC_COUNTER_R127:
21540 + ret_val = GET_TGEC_CNTR_64(r127);
21541 + break;
21542 + case E_TGEC_COUNTER_R255:
21543 + ret_val = GET_TGEC_CNTR_64(r255);
21544 + break;
21545 + case E_TGEC_COUNTER_R511:
21546 + ret_val = GET_TGEC_CNTR_64(r511);
21547 + break;
21548 + case E_TGEC_COUNTER_R1023:
21549 + ret_val = GET_TGEC_CNTR_64(r1023);
21550 + break;
21551 + case E_TGEC_COUNTER_R1518:
21552 + ret_val = GET_TGEC_CNTR_64(r1518);
21553 + break;
21554 + case E_TGEC_COUNTER_R1519X:
21555 + ret_val = GET_TGEC_CNTR_64(r1519x);
21556 + break;
21557 + case E_TGEC_COUNTER_TRFRG:
21558 + ret_val = GET_TGEC_CNTR_64(trfrg);
21559 + break;
21560 + case E_TGEC_COUNTER_TRJBR:
21561 + ret_val = GET_TGEC_CNTR_64(trjbr);
21562 + break;
21563 + case E_TGEC_COUNTER_RDRP:
21564 + ret_val = GET_TGEC_CNTR_64(rdrp);
21565 + break;
21566 + case E_TGEC_COUNTER_RALN:
21567 + ret_val = GET_TGEC_CNTR_64(raln);
21568 + break;
21569 + case E_TGEC_COUNTER_TRUND:
21570 + ret_val = GET_TGEC_CNTR_64(trund);
21571 + break;
21572 + case E_TGEC_COUNTER_TROVR:
21573 + ret_val = GET_TGEC_CNTR_64(trovr);
21574 + break;
21575 + case E_TGEC_COUNTER_RXPF:
21576 + ret_val = GET_TGEC_CNTR_64(rxpf);
21577 + break;
21578 + case E_TGEC_COUNTER_TXPF:
21579 + ret_val = GET_TGEC_CNTR_64(txpf);
21580 + break;
21581 + case E_TGEC_COUNTER_ROCT:
21582 + ret_val = GET_TGEC_CNTR_64(roct);
21583 + break;
21584 + case E_TGEC_COUNTER_RMCA:
21585 + ret_val = GET_TGEC_CNTR_64(rmca);
21586 + break;
21587 + case E_TGEC_COUNTER_RBCA:
21588 + ret_val = GET_TGEC_CNTR_64(rbca);
21589 + break;
21590 + case E_TGEC_COUNTER_RPKT:
21591 + ret_val = GET_TGEC_CNTR_64(rpkt);
21592 + break;
21593 + case E_TGEC_COUNTER_RUCA:
21594 + ret_val = GET_TGEC_CNTR_64(ruca);
21595 + break;
21596 + case E_TGEC_COUNTER_RERR:
21597 + ret_val = GET_TGEC_CNTR_64(rerr);
21598 + break;
21599 + case E_TGEC_COUNTER_TOCT:
21600 + ret_val = GET_TGEC_CNTR_64(toct);
21601 + break;
21602 + case E_TGEC_COUNTER_TMCA:
21603 + ret_val = GET_TGEC_CNTR_64(tmca);
21604 + break;
21605 + case E_TGEC_COUNTER_TBCA:
21606 + ret_val = GET_TGEC_CNTR_64(tbca);
21607 + break;
21608 + case E_TGEC_COUNTER_TUCA:
21609 + ret_val = GET_TGEC_CNTR_64(tuca);
21610 + break;
21611 + case E_TGEC_COUNTER_TERR:
21612 + ret_val = GET_TGEC_CNTR_64(terr);
21613 + break;
21614 + default:
21615 + ret_val = 0;
21616 + }
21617 +
21618 + return ret_val;
21619 +}
21620 +
21621 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
21622 +{
21623 + uint32_t tmp;
21624 +
21625 + tmp = ioread32be(&regs->command_config);
21626 + if (apply_rx)
21627 + tmp |= CMD_CFG_RX_EN;
21628 + if (apply_tx)
21629 + tmp |= CMD_CFG_TX_EN;
21630 + iowrite32be(tmp, &regs->command_config);
21631 +}
21632 +
21633 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx)
21634 +{
21635 + uint32_t tmp_reg_32;
21636 +
21637 + tmp_reg_32 = ioread32be(&regs->command_config);
21638 + if (apply_rx)
21639 + tmp_reg_32 &= ~CMD_CFG_RX_EN;
21640 + if (apply_tx)
21641 + tmp_reg_32 &= ~CMD_CFG_TX_EN;
21642 + iowrite32be(tmp_reg_32, &regs->command_config);
21643 +}
21644 +
21645 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val)
21646 +{
21647 + uint32_t tmp;
21648 +
21649 + tmp = ioread32be(&regs->command_config);
21650 + if (val)
21651 + tmp |= CMD_CFG_PROMIS_EN;
21652 + else
21653 + tmp &= ~CMD_CFG_PROMIS_EN;
21654 + iowrite32be(tmp, &regs->command_config);
21655 +}
21656 +
21657 +void fman_tgec_reset_filter_table(struct tgec_regs *regs)
21658 +{
21659 + uint32_t i;
21660 + for (i = 0; i < 512; i++)
21661 + iowrite32be(i & ~TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
21662 +}
21663 +
21664 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc)
21665 +{
21666 + uint32_t hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
21667 + iowrite32be(hash | TGEC_HASH_MCAST_EN, &regs->hashtable_ctrl);
21668 +}
21669 +
21670 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value)
21671 +{
21672 + iowrite32be(value, &regs->hashtable_ctrl);
21673 +}
21674 +
21675 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time)
21676 +{
21677 + iowrite32be((uint32_t)pause_time, &regs->pause_quant);
21678 +}
21679 +
21680 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en)
21681 +{
21682 + uint32_t tmp;
21683 +
21684 + tmp = ioread32be(&regs->command_config);
21685 + if (en)
21686 + tmp |= CMD_CFG_PAUSE_IGNORE;
21687 + else
21688 + tmp &= ~CMD_CFG_PAUSE_IGNORE;
21689 + iowrite32be(tmp, &regs->command_config);
21690 +}
21691 +
21692 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en)
21693 +{
21694 + uint32_t tmp;
21695 +
21696 + tmp = ioread32be(&regs->command_config);
21697 + if (en)
21698 + tmp |= CMD_CFG_EN_TIMESTAMP;
21699 + else
21700 + tmp &= ~CMD_CFG_EN_TIMESTAMP;
21701 + iowrite32be(tmp, &regs->command_config);
21702 +}
21703 +
21704 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask)
21705 +{
21706 + return ioread32be(&regs->ievent) & ev_mask;
21707 +}
21708 +
21709 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask)
21710 +{
21711 + iowrite32be(ev_mask, &regs->ievent);
21712 +}
21713 +
21714 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs)
21715 +{
21716 + return ioread32be(&regs->imask);
21717 +}
21718 +
21719 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *adr)
21720 +{
21721 + uint32_t tmp0, tmp1;
21722 +
21723 + tmp0 = (uint32_t)(adr[0] |
21724 + adr[1] << 8 |
21725 + adr[2] << 16 |
21726 + adr[3] << 24);
21727 + tmp1 = (uint32_t)(adr[4] | adr[5] << 8);
21728 + iowrite32be(tmp0, &regs->mac_addr_2);
21729 + iowrite32be(tmp1, &regs->mac_addr_3);
21730 +}
21731 +
21732 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs)
21733 +{
21734 + iowrite32be(0, &regs->mac_addr_2);
21735 + iowrite32be(0, &regs->mac_addr_3);
21736 +}
21737 +
21738 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs)
21739 +{
21740 + return ioread32be(&regs->tgec_id);
21741 +}
21742 +
21743 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
21744 +{
21745 + iowrite32be(ioread32be(&regs->imask) | ev_mask, &regs->imask);
21746 +}
21747 +
21748 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask)
21749 +{
21750 + iowrite32be(ioread32be(&regs->imask) & ~ev_mask, &regs->imask);
21751 +}
21752 +
21753 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs)
21754 +{
21755 + return (uint16_t) ioread32be(&regs->maxfrm);
21756 +}
21757 +
21758 +void fman_tgec_defconfig(struct tgec_cfg *cfg)
21759 +{
21760 + cfg->wan_mode_enable = DEFAULT_WAN_MODE_ENABLE;
21761 + cfg->promiscuous_mode_enable = DEFAULT_PROMISCUOUS_MODE_ENABLE;
21762 + cfg->pause_forward_enable = DEFAULT_PAUSE_FORWARD_ENABLE;
21763 + cfg->pause_ignore = DEFAULT_PAUSE_IGNORE;
21764 + cfg->tx_addr_ins_enable = DEFAULT_TX_ADDR_INS_ENABLE;
21765 + cfg->loopback_enable = DEFAULT_LOOPBACK_ENABLE;
21766 + cfg->cmd_frame_enable = DEFAULT_CMD_FRAME_ENABLE;
21767 + cfg->rx_error_discard = DEFAULT_RX_ERROR_DISCARD;
21768 + cfg->send_idle_enable = DEFAULT_SEND_IDLE_ENABLE;
21769 + cfg->no_length_check_enable = DEFAULT_NO_LENGTH_CHECK_ENABLE;
21770 + cfg->lgth_check_nostdr = DEFAULT_LGTH_CHECK_NOSTDR;
21771 + cfg->time_stamp_enable = DEFAULT_TIME_STAMP_ENABLE;
21772 + cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
21773 + cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
21774 + cfg->pause_quant = DEFAULT_PAUSE_QUANT;
21775 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
21776 + cfg->skip_fman11_workaround = FALSE;
21777 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
21778 +}
21779 +
21780 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
21781 + uint32_t exception_mask)
21782 +{
21783 + uint32_t tmp;
21784 +
21785 + /* Config */
21786 + tmp = 0x40; /* CRC forward */
21787 + if (cfg->wan_mode_enable)
21788 + tmp |= CMD_CFG_WAN_MODE;
21789 + if (cfg->promiscuous_mode_enable)
21790 + tmp |= CMD_CFG_PROMIS_EN;
21791 + if (cfg->pause_forward_enable)
21792 + tmp |= CMD_CFG_PAUSE_FWD;
21793 + if (cfg->pause_ignore)
21794 + tmp |= CMD_CFG_PAUSE_IGNORE;
21795 + if (cfg->tx_addr_ins_enable)
21796 + tmp |= CMD_CFG_TX_ADDR_INS;
21797 + if (cfg->loopback_enable)
21798 + tmp |= CMD_CFG_LOOPBACK_EN;
21799 + if (cfg->cmd_frame_enable)
21800 + tmp |= CMD_CFG_CMD_FRM_EN;
21801 + if (cfg->rx_error_discard)
21802 + tmp |= CMD_CFG_RX_ER_DISC;
21803 + if (cfg->send_idle_enable)
21804 + tmp |= CMD_CFG_SEND_IDLE;
21805 + if (cfg->no_length_check_enable)
21806 + tmp |= CMD_CFG_NO_LEN_CHK;
21807 + if (cfg->time_stamp_enable)
21808 + tmp |= CMD_CFG_EN_TIMESTAMP;
21809 + iowrite32be(tmp, &regs->command_config);
21810 +
21811 + /* Max Frame Length */
21812 + iowrite32be((uint32_t)cfg->max_frame_length, &regs->maxfrm);
21813 + /* Pause Time */
21814 + iowrite32be(cfg->pause_quant, &regs->pause_quant);
21815 +
21816 + /* clear all pending events and set-up interrupts */
21817 + fman_tgec_ack_event(regs, 0xffffffff);
21818 + fman_tgec_enable_interrupt(regs, exception_mask);
21819 +
21820 + return 0;
21821 +}
21822 +
21823 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs *regs)
21824 +{
21825 + uint32_t tmp;
21826 +
21827 + /* restore the default tx ipg Length */
21828 + tmp = (ioread32be(&regs->tx_ipg_len) & ~TGEC_TX_IPG_LENGTH_MASK) | 12;
21829 +
21830 + iowrite32be(tmp, &regs->tx_ipg_len);
21831 +}
21832 --- /dev/null
21833 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.c
21834 @@ -0,0 +1,1166 @@
21835 +/*
21836 + * Copyright 2008-2012 Freescale Semiconductor Inc.
21837 + *
21838 + * Redistribution and use in source and binary forms, with or without
21839 + * modification, are permitted provided that the following conditions are met:
21840 + * * Redistributions of source code must retain the above copyright
21841 + * notice, this list of conditions and the following disclaimer.
21842 + * * Redistributions in binary form must reproduce the above copyright
21843 + * notice, this list of conditions and the following disclaimer in the
21844 + * documentation and/or other materials provided with the distribution.
21845 + * * Neither the name of Freescale Semiconductor nor the
21846 + * names of its contributors may be used to endorse or promote products
21847 + * derived from this software without specific prior written permission.
21848 + *
21849 + *
21850 + * ALTERNATIVELY, this software may be distributed under the terms of the
21851 + * GNU General Public License ("GPL") as published by the Free Software
21852 + * Foundation, either version 2 of that License or (at your option) any
21853 + * later version.
21854 + *
21855 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
21856 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21857 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21858 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
21859 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21860 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21861 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21862 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21863 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21864 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21865 + */
21866 +
21867 +
21868 +/******************************************************************************
21869 + @File memac.c
21870 +
21871 + @Description FM mEMAC driver
21872 +*//***************************************************************************/
21873 +#include <../../../../sdk_dpaa/mac.h>
21874 +#include <linux/phy_fixed.h>
21875 +
21876 +#include "std_ext.h"
21877 +#include "string_ext.h"
21878 +#include "error_ext.h"
21879 +#include "xx_ext.h"
21880 +#include "endian_ext.h"
21881 +#include "debug_ext.h"
21882 +
21883 +#include "fm_common.h"
21884 +#include "memac.h"
21885 +
21886 +
21887 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex);
21888 +
21889 +/*****************************************************************************/
21890 +/* Internal routines */
21891 +/*****************************************************************************/
21892 +
21893 +/* ......................................................................... */
21894 +
21895 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
21896 +{
21897 + uint64_t mask1, mask2;
21898 + uint32_t xorVal = 0;
21899 + uint8_t i, j;
21900 +
21901 + for (i=0; i<6; i++)
21902 + {
21903 + mask1 = ethAddr & (uint64_t)0x01;
21904 + ethAddr >>= 1;
21905 +
21906 + for (j=0; j<7; j++)
21907 + {
21908 + mask2 = ethAddr & (uint64_t)0x01;
21909 + mask1 ^= mask2;
21910 + ethAddr >>= 1;
21911 + }
21912 +
21913 + xorVal |= (mask1 << (5-i));
21914 + }
21915 +
21916 + return xorVal;
21917 +}
21918 +
21919 +/* ......................................................................... */
21920 +
21921 +static void SetupSgmiiInternalPhy(t_Memac *p_Memac, uint8_t phyAddr)
21922 +{
21923 + uint16_t tmpReg16;
21924 + e_EnetMode enetMode;
21925 +
21926 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
21927 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
21928 + to 1G one, so MII functions can work correctly. */
21929 + enetMode = p_Memac->enetMode;
21930 +
21931 + /* SGMII mode + AN enable */
21932 + tmpReg16 = PHY_SGMII_IF_MODE_AN | PHY_SGMII_IF_MODE_SGMII;
21933 + if ((p_Memac->enetMode) == e_ENET_MODE_SGMII_2500)
21934 + tmpReg16 = PHY_SGMII_CR_PHY_RESET | PHY_SGMII_IF_SPEED_GIGABIT | PHY_SGMII_IF_MODE_SGMII;
21935 +
21936 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
21937 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
21938 +
21939 + /* Device ability according to SGMII specification */
21940 + tmpReg16 = PHY_SGMII_DEV_ABILITY_SGMII;
21941 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
21942 +
21943 + /* Adjust link timer for SGMII -
21944 + According to Cisco SGMII specification the timer should be 1.6 ms.
21945 + The link_timer register is configured in units of the clock.
21946 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
21947 + unit = 1 / (125*10^6 Hz) = 8 ns.
21948 + 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2 * 10^5 = 0x30d40
21949 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
21950 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
21951 + 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120.
21952 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
21953 + we always set up here a value of 2.5 SGMII. */
21954 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x0007);
21955 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xa120);
21956 +
21957 + /* Restart AN */
21958 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
21959 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
21960 +
21961 + /* Restore original enet mode */
21962 + p_Memac->enetMode = enetMode;
21963 +}
21964 +
21965 +/* ......................................................................... */
21966 +
21967 +static void SetupSgmiiInternalPhyBaseX(t_Memac *p_Memac, uint8_t phyAddr)
21968 +{
21969 + uint16_t tmpReg16;
21970 + e_EnetMode enetMode;
21971 +
21972 + /* In case the higher MACs are used (i.e. the MACs that should support 10G),
21973 + speed=10000 is provided for SGMII ports. Temporary modify enet mode
21974 + to 1G one, so MII functions can work correctly. */
21975 + enetMode = p_Memac->enetMode;
21976 + p_Memac->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Memac->enetMode), e_ENET_SPEED_1000);
21977 +
21978 + /* 1000BaseX mode */
21979 + tmpReg16 = PHY_SGMII_IF_MODE_1000X;
21980 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x14, tmpReg16);
21981 +
21982 + /* AN Device capability */
21983 + tmpReg16 = PHY_SGMII_DEV_ABILITY_1000X;
21984 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x4, tmpReg16);
21985 +
21986 + /* Adjust link timer for SGMII -
21987 + For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
21988 + The link_timer register is configured in units of the clock.
21989 + - When running as 1G SGMII, Serdes clock is 125 MHz, so
21990 + unit = 1 / (125*10^6 Hz) = 8 ns.
21991 + 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
21992 + - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
21993 + unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
21994 + 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
21995 + Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
21996 + we always set up here a value of 2.5 SGMII. */
21997 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x13, 0x002f);
21998 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x12, 0xaf08);
21999 +
22000 + /* Restart AN */
22001 + tmpReg16 = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN;
22002 + MEMAC_MII_WritePhyReg(p_Memac, phyAddr, 0x0, tmpReg16);
22003 +
22004 + /* Restore original enet mode */
22005 + p_Memac->enetMode = enetMode;
22006 +}
22007 +
22008 +/* ......................................................................... */
22009 +
22010 +static t_Error CheckInitParameters(t_Memac *p_Memac)
22011 +{
22012 + e_FmMacType portType;
22013 +
22014 + portType = ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
22015 +
22016 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
22017 + if ((portType == e_FM_MAC_10G) && (p_Memac->macId >= FM_MAX_NUM_OF_10G_MACS))
22018 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("10G MAC ID must be less than %d", FM_MAX_NUM_OF_10G_MACS));
22019 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
22020 +
22021 + if ((portType == e_FM_MAC_1G) && (p_Memac->macId >= FM_MAX_NUM_OF_1G_MACS))
22022 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("1G MAC ID must be less than %d", FM_MAX_NUM_OF_1G_MACS));
22023 + if (p_Memac->addr == 0)
22024 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC must have a valid MAC address"));
22025 + if (!p_Memac->f_Exception)
22026 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Exception"));
22027 + if (!p_Memac->f_Event)
22028 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Uninitialized f_Event"));
22029 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
22030 + if (!p_Memac->p_MemacDriverParam->no_length_check_enable)
22031 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
22032 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
22033 +
22034 + return E_OK;
22035 +}
22036 +
22037 +/* ........................................................................... */
22038 +
22039 +static void MemacErrException(t_Handle h_Memac)
22040 +{
22041 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22042 + uint32_t event, imask;
22043 +
22044 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
22045 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
22046 +
22047 + /* Imask include both error and notification/event bits.
22048 + Leaving only error bits enabled by imask.
22049 + The imask error bits are shifted by 16 bits offset from
22050 + their corresponding location in the ievent - hence the >> 16 */
22051 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
22052 +
22053 + fman_memac_ack_event(p_Memac->p_MemMap, event);
22054 +
22055 + if (event & MEMAC_IEVNT_TS_ECC_ER)
22056 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_TS_FIFO_ECC_ERR);
22057 + if (event & MEMAC_IEVNT_TX_ECC_ER)
22058 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
22059 + if (event & MEMAC_IEVNT_RX_ECC_ER)
22060 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
22061 +}
22062 +
22063 +static void MemacException(t_Handle h_Memac)
22064 +{
22065 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22066 + uint32_t event, imask;
22067 +
22068 + event = fman_memac_get_event(p_Memac->p_MemMap, 0xffffffff);
22069 + imask = fman_memac_get_interrupt_mask(p_Memac->p_MemMap);
22070 +
22071 + /* Imask include both error and notification/event bits.
22072 + Leaving only error bits enabled by imask.
22073 + The imask error bits are shifted by 16 bits offset from
22074 + their corresponding location in the ievent - hence the >> 16 */
22075 + event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
22076 +
22077 + fman_memac_ack_event(p_Memac->p_MemMap, event);
22078 +
22079 + if (event & MEMAC_IEVNT_MGI)
22080 + p_Memac->f_Exception(p_Memac->h_App, e_FM_MAC_EX_MAGIC_PACKET_INDICATION);
22081 +}
22082 +
22083 +/* ......................................................................... */
22084 +
22085 +static void FreeInitResources(t_Memac *p_Memac)
22086 +{
22087 + e_FmMacType portType;
22088 +
22089 + portType =
22090 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
22091 +
22092 + if (portType == e_FM_MAC_10G)
22093 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
22094 + else
22095 + FmUnregisterIntr(p_Memac->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Memac->macId, e_FM_INTR_TYPE_ERR);
22096 +
22097 + /* release the driver's group hash table */
22098 + FreeHashTable(p_Memac->p_MulticastAddrHash);
22099 + p_Memac->p_MulticastAddrHash = NULL;
22100 +
22101 + /* release the driver's individual hash table */
22102 + FreeHashTable(p_Memac->p_UnicastAddrHash);
22103 + p_Memac->p_UnicastAddrHash = NULL;
22104 +}
22105 +
22106 +
22107 +/*****************************************************************************/
22108 +/* mEMAC API routines */
22109 +/*****************************************************************************/
22110 +
22111 +/* ......................................................................... */
22112 +
22113 +static t_Error MemacEnable(t_Handle h_Memac, e_CommMode mode)
22114 +{
22115 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22116 +
22117 + struct mac_device *mac_dev = (struct mac_device *)p_Memac->h_App;
22118 +
22119 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22120 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22121 +
22122 + fman_memac_enable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
22123 +
22124 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_RGMII) {
22125 + if (mac_dev->fixed_link) {
22126 + printk(KERN_INFO "This is a fixed-link, forcing speed %d duplex %d\n",mac_dev->fixed_link->speed,mac_dev->fixed_link->duplex);
22127 + MemacAdjustLink(h_Memac,mac_dev->fixed_link->speed,mac_dev->fixed_link->duplex);
22128 + }
22129 + }
22130 +
22131 + return E_OK;
22132 +}
22133 +
22134 +/* ......................................................................... */
22135 +
22136 +static t_Error MemacDisable (t_Handle h_Memac, e_CommMode mode)
22137 +{
22138 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22139 +
22140 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22141 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22142 +
22143 + fman_memac_disable(p_Memac->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
22144 +
22145 + return E_OK;
22146 +}
22147 +
22148 +/* ......................................................................... */
22149 +
22150 +static t_Error MemacSetPromiscuous(t_Handle h_Memac, bool newVal)
22151 +{
22152 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22153 +
22154 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22155 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22156 +
22157 + fman_memac_set_promiscuous(p_Memac->p_MemMap, newVal);
22158 +
22159 + return E_OK;
22160 +}
22161 +
22162 +/* .............................................................................. */
22163 +
22164 +static t_Error MemacAdjustLink(t_Handle h_Memac, e_EnetSpeed speed, bool fullDuplex)
22165 +{
22166 + t_Memac *p_Memac = (t_Memac *)h_Memac;
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 + if ((speed >= e_ENET_SPEED_1000) && (!fullDuplex))
22172 + RETURN_ERROR(MAJOR, E_CONFLICT,
22173 + ("Ethernet MAC 1G or 10G does not support half-duplex"));
22174 +
22175 + fman_memac_adjust_link(p_Memac->p_MemMap,
22176 + (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Memac->enetMode),
22177 + (enum enet_speed)speed,
22178 + fullDuplex);
22179 + return E_OK;
22180 +}
22181 +
22182 +
22183 +/*****************************************************************************/
22184 +/* Memac Configs modification functions */
22185 +/*****************************************************************************/
22186 +
22187 +/* ......................................................................... */
22188 +
22189 +static t_Error MemacConfigLoopback(t_Handle h_Memac, bool newVal)
22190 +{
22191 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22192 +
22193 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22194 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22195 +
22196 + p_Memac->p_MemacDriverParam->loopback_enable = newVal;
22197 +
22198 + return E_OK;
22199 +}
22200 +
22201 +/* ......................................................................... */
22202 +
22203 +static t_Error MemacConfigWan(t_Handle h_Memac, bool newVal)
22204 +{
22205 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22206 +
22207 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22208 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22209 +
22210 + p_Memac->p_MemacDriverParam->wan_mode_enable = newVal;
22211 +
22212 + return E_OK;
22213 +}
22214 +
22215 +/* ......................................................................... */
22216 +
22217 +static t_Error MemacConfigMaxFrameLength(t_Handle h_Memac, uint16_t newVal)
22218 +{
22219 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22220 +
22221 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22222 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22223 +
22224 + p_Memac->p_MemacDriverParam->max_frame_length = newVal;
22225 +
22226 + return E_OK;
22227 +}
22228 +
22229 +/* ......................................................................... */
22230 +
22231 +static t_Error MemacConfigPad(t_Handle h_Memac, bool newVal)
22232 +{
22233 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22234 +
22235 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22236 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22237 +
22238 + p_Memac->p_MemacDriverParam->pad_enable = newVal;
22239 +
22240 + return E_OK;
22241 +}
22242 +
22243 +/* ......................................................................... */
22244 +
22245 +static t_Error MemacConfigLengthCheck(t_Handle h_Memac, bool newVal)
22246 +{
22247 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22248 +
22249 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22250 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22251 +
22252 + p_Memac->p_MemacDriverParam->no_length_check_enable = !newVal;
22253 +
22254 + return E_OK;
22255 +}
22256 +
22257 +/* ......................................................................... */
22258 +
22259 +static t_Error MemacConfigException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
22260 +{
22261 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22262 + uint32_t bitMask = 0;
22263 +
22264 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22265 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22266 +
22267 + GET_EXCEPTION_FLAG(bitMask, exception);
22268 + if (bitMask)
22269 + {
22270 + if (enable)
22271 + p_Memac->exceptions |= bitMask;
22272 + else
22273 + p_Memac->exceptions &= ~bitMask;
22274 + }
22275 + else
22276 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
22277 +
22278 + return E_OK;
22279 +}
22280 +
22281 +/* ......................................................................... */
22282 +
22283 +static t_Error MemacConfigResetOnInit(t_Handle h_Memac, bool enable)
22284 +{
22285 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22286 +
22287 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22288 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22289 +
22290 + p_Memac->p_MemacDriverParam->reset_on_init = enable;
22291 +
22292 + return E_OK;
22293 +}
22294 +
22295 +
22296 +/*****************************************************************************/
22297 +/* Memac Run Time API functions */
22298 +/*****************************************************************************/
22299 +
22300 +/* ......................................................................... */
22301 +
22302 +static t_Error MemacSetTxPauseFrames(t_Handle h_Memac,
22303 + uint8_t priority,
22304 + uint16_t pauseTime,
22305 + uint16_t threshTime)
22306 +{
22307 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22308 +
22309 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
22310 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22311 +
22312 + if (priority != 0xFF)
22313 + {
22314 + bool PortConfigured, PreFetchEnabled;
22315 +
22316 + if (FmGetTnumAgingPeriod(p_Memac->fmMacControllerDriver.h_Fm) == 0)
22317 + RETURN_ERROR(MAJOR, E_CONFLICT, ("For PFC operation, TNUM aging must be enabled"));
22318 +
22319 + FmGetPortPreFetchConfiguration(p_Memac->fmMacControllerDriver.h_Fm,
22320 + p_Memac->fmMacControllerDriver.macId,
22321 + &PortConfigured,
22322 + &PreFetchEnabled);
22323 +
22324 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && !PortConfigured)
22325 + DBG(INFO, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
22326 +
22327 + if ((ENET_SPEED_FROM_MODE(p_Memac->fmMacControllerDriver.enetMode) == e_ENET_SPEED_1000) && PortConfigured && !PreFetchEnabled)
22328 + DBG(WARNING, ("For PFC correct operation, prefetch must be configured on the FM Tx PORT"));
22329 + }
22330 +
22331 + fman_memac_set_tx_pause_frames(p_Memac->p_MemMap, priority, pauseTime, threshTime);
22332 +
22333 + return E_OK;
22334 +}
22335 +
22336 +/* ......................................................................... */
22337 +
22338 +static t_Error MemacSetTxAutoPauseFrames(t_Handle h_Memac,
22339 + uint16_t pauseTime)
22340 +{
22341 + return MemacSetTxPauseFrames(h_Memac, FM_MAC_NO_PFC, pauseTime, 0);
22342 +}
22343 +
22344 +/* ......................................................................... */
22345 +
22346 +static t_Error MemacSetRxIgnorePauseFrames(t_Handle h_Memac, bool en)
22347 +{
22348 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22349 +
22350 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
22351 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22352 +
22353 + fman_memac_set_rx_ignore_pause_frames(p_Memac->p_MemMap, en);
22354 +
22355 + return E_OK;
22356 +}
22357 +
22358 +/* ......................................................................... */
22359 +
22360 +static t_Error MemacSetWakeOnLan(t_Handle h_Memac, bool en)
22361 +{
22362 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22363 +
22364 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_STATE);
22365 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22366 +
22367 + fman_memac_set_wol(p_Memac->p_MemMap, en);
22368 +
22369 + return E_OK;
22370 +}
22371 +
22372 +/* .............................................................................. */
22373 +
22374 +static t_Error MemacEnable1588TimeStamp(t_Handle h_Memac)
22375 +{
22376 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22377 +
22378 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22379 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22380 +UNUSED(p_Memac);
22381 +DBG(WARNING, ("mEMAC has 1588 always enabled!"));
22382 +
22383 + return E_OK;
22384 +}
22385 +
22386 +/* Counters handling */
22387 +/* ......................................................................... */
22388 +
22389 +static t_Error MemacGetStatistics(t_Handle h_Memac, t_FmMacStatistics *p_Statistics)
22390 +{
22391 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22392 +
22393 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22394 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22395 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
22396 +
22397 + p_Statistics->eStatPkts64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
22398 + p_Statistics->eStatPkts65to127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
22399 + p_Statistics->eStatPkts128to255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
22400 + p_Statistics->eStatPkts256to511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
22401 + p_Statistics->eStatPkts512to1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
22402 + p_Statistics->eStatPkts1024to1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
22403 + p_Statistics->eStatPkts1519to1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
22404 +/* */
22405 + p_Statistics->eStatFragments = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RFRG);
22406 + p_Statistics->eStatJabbers = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RJBR);
22407 +
22408 + p_Statistics->eStatsDropEvents = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RDRP);
22409 + p_Statistics->eStatCRCAlignErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RALN);
22410 +
22411 + p_Statistics->eStatUndersizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUND);
22412 + p_Statistics->eStatOversizePkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROVR);
22413 +/* Pause */
22414 + p_Statistics->reStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RXPF);
22415 + p_Statistics->teStatPause = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TXPF);
22416 +
22417 +/* MIB II */
22418 + p_Statistics->ifInOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_ROCT);
22419 + p_Statistics->ifInUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RUCA);
22420 + p_Statistics->ifInMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RMCA);
22421 + p_Statistics->ifInBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RBCA);
22422 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
22423 + + p_Statistics->ifInMcastPkts
22424 + + p_Statistics->ifInBcastPkts;
22425 + p_Statistics->ifInDiscards = 0;
22426 + p_Statistics->ifInErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_RERR);
22427 +
22428 + p_Statistics->ifOutOctets = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TOCT);
22429 + p_Statistics->ifOutUcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TUCA);
22430 + p_Statistics->ifOutMcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TMCA);
22431 + p_Statistics->ifOutBcastPkts = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TBCA);
22432 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
22433 + + p_Statistics->ifOutMcastPkts
22434 + + p_Statistics->ifOutBcastPkts;
22435 + p_Statistics->ifOutDiscards = 0;
22436 + p_Statistics->ifOutErrors = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_TERR);
22437 +
22438 + return E_OK;
22439 +}
22440 +
22441 +/* ......................................................................... */
22442 +
22443 +static t_Error MemacGetFrameSizeCounters(t_Handle h_Memac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
22444 +{
22445 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22446 +
22447 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22448 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22449 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
22450 +
22451 + switch (type)
22452 + {
22453 + case e_COMM_MODE_NONE:
22454 + break;
22455 +
22456 + case e_COMM_MODE_RX:
22457 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64);
22458 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127);
22459 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255);
22460 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511);
22461 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023);
22462 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518);
22463 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X);
22464 + break;
22465 +
22466 + case e_COMM_MODE_TX:
22467 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
22468 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
22469 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
22470 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
22471 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
22472 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
22473 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
22474 + break;
22475 +
22476 + case e_COMM_MODE_RX_AND_TX:
22477 + p_FrameSizeCounters->count_pkts_64 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R64)
22478 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T64);
22479 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R127)
22480 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T127);
22481 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R255)
22482 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T255);
22483 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R511)
22484 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T511);
22485 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1023)
22486 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1023);
22487 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1518)
22488 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1518);
22489 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_R1519X)
22490 + + fman_memac_get_counter(p_Memac->p_MemMap, E_MEMAC_COUNTER_T1519X);
22491 + break;
22492 + }
22493 +
22494 + return E_OK;
22495 +}
22496 +
22497 +/* ......................................................................... */
22498 +
22499 +static t_Error MemacModifyMacAddress (t_Handle h_Memac, t_EnetAddr *p_EnetAddr)
22500 +{
22501 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22502 +
22503 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22504 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22505 +
22506 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t *)(*p_EnetAddr), 0);
22507 +
22508 + return E_OK;
22509 +}
22510 +
22511 +/* ......................................................................... */
22512 +
22513 +static t_Error MemacResetCounters (t_Handle h_Memac)
22514 +{
22515 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22516 +
22517 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22518 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22519 +
22520 + fman_memac_reset_stat(p_Memac->p_MemMap);
22521 +
22522 + return E_OK;
22523 +}
22524 +
22525 +/* ......................................................................... */
22526 +
22527 +static t_Error MemacAddExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
22528 +{
22529 + t_Memac *p_Memac = (t_Memac *) h_Memac;
22530 + uint64_t ethAddr;
22531 + uint8_t paddrNum;
22532 +
22533 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22534 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22535 +
22536 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22537 +
22538 + if (ethAddr & GROUP_ADDRESS)
22539 + /* Multicast address has no effect in PADDR */
22540 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
22541 +
22542 + /* Make sure no PADDR contains this address */
22543 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
22544 + if (p_Memac->indAddrRegUsed[paddrNum])
22545 + if (p_Memac->paddr[paddrNum] == ethAddr)
22546 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
22547 +
22548 + /* Find first unused PADDR */
22549 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
22550 + if (!(p_Memac->indAddrRegUsed[paddrNum]))
22551 + {
22552 + /* mark this PADDR as used */
22553 + p_Memac->indAddrRegUsed[paddrNum] = TRUE;
22554 + /* store address */
22555 + p_Memac->paddr[paddrNum] = ethAddr;
22556 +
22557 + /* put in hardware */
22558 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)(*p_EthAddr), paddrNum);
22559 + p_Memac->numOfIndAddrInRegs++;
22560 +
22561 + return E_OK;
22562 + }
22563 +
22564 + /* No free PADDR */
22565 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
22566 +}
22567 +
22568 +/* ......................................................................... */
22569 +
22570 +static t_Error MemacDelExactMatchMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
22571 +{
22572 + t_Memac *p_Memac = (t_Memac *) h_Memac;
22573 + uint64_t ethAddr;
22574 + uint8_t paddrNum;
22575 +
22576 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22577 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22578 +
22579 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22580 +
22581 + /* Find used PADDR containing this address */
22582 + for (paddrNum = 0; paddrNum < MEMAC_NUM_OF_PADDRS; paddrNum++)
22583 + {
22584 + if ((p_Memac->indAddrRegUsed[paddrNum]) &&
22585 + (p_Memac->paddr[paddrNum] == ethAddr))
22586 + {
22587 + /* mark this PADDR as not used */
22588 + p_Memac->indAddrRegUsed[paddrNum] = FALSE;
22589 + /* clear in hardware */
22590 + fman_memac_clear_addr_in_paddr(p_Memac->p_MemMap, paddrNum);
22591 + p_Memac->numOfIndAddrInRegs--;
22592 +
22593 + return E_OK;
22594 + }
22595 + }
22596 +
22597 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
22598 +}
22599 +
22600 +/* ......................................................................... */
22601 +
22602 +static t_Error MemacGetId(t_Handle h_Memac, uint32_t *macId)
22603 +{
22604 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22605 +
22606 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22607 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22608 +
22609 + *macId = p_Memac->macId;
22610 +
22611 + return E_OK;
22612 +}
22613 +
22614 +/* ......................................................................... */
22615 +
22616 +
22617 +static t_Error MemacAddHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
22618 +{
22619 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22620 + t_EthHashEntry *p_HashEntry;
22621 + uint32_t hash;
22622 + uint64_t ethAddr;
22623 +
22624 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22625 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22626 +
22627 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22628 +
22629 + if (!(ethAddr & GROUP_ADDRESS))
22630 + /* Unicast addresses not supported in hash */
22631 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
22632 +
22633 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
22634 +
22635 + /* Create element to be added to the driver hash table */
22636 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
22637 + p_HashEntry->addr = ethAddr;
22638 + INIT_LIST(&p_HashEntry->node);
22639 +
22640 + LIST_AddToTail(&(p_HashEntry->node), &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]));
22641 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash | HASH_CTRL_MCAST_EN));
22642 +
22643 + return E_OK;
22644 +}
22645 +
22646 +/* ......................................................................... */
22647 +
22648 +static t_Error MemacDelHashMacAddress(t_Handle h_Memac, t_EnetAddr *p_EthAddr)
22649 +{
22650 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22651 + t_EthHashEntry *p_HashEntry = NULL;
22652 + t_List *p_Pos;
22653 + uint32_t hash;
22654 + uint64_t ethAddr;
22655 +
22656 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_NULL_POINTER);
22657 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22658 +
22659 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
22660 +
22661 + hash = GetMacAddrHashCode(ethAddr) & HASH_CTRL_ADDR_MASK;
22662 +
22663 + LIST_FOR_EACH(p_Pos, &(p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
22664 + {
22665 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
22666 + if (p_HashEntry->addr == ethAddr)
22667 + {
22668 + LIST_DelAndInit(&p_HashEntry->node);
22669 + XX_Free(p_HashEntry);
22670 + break;
22671 + }
22672 + }
22673 + if (LIST_IsEmpty(&p_Memac->p_MulticastAddrHash->p_Lsts[hash]))
22674 + fman_memac_set_hash_table(p_Memac->p_MemMap, (hash & ~HASH_CTRL_MCAST_EN));
22675 +
22676 + return E_OK;
22677 +}
22678 +
22679 +
22680 +/* ......................................................................... */
22681 +
22682 +static t_Error MemacSetException(t_Handle h_Memac, e_FmMacExceptions exception, bool enable)
22683 +{
22684 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22685 + uint32_t bitMask = 0;
22686 +
22687 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22688 + SANITY_CHECK_RETURN_ERROR(!p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22689 +
22690 + GET_EXCEPTION_FLAG(bitMask, exception);
22691 + if (bitMask)
22692 + {
22693 + if (enable)
22694 + p_Memac->exceptions |= bitMask;
22695 + else
22696 + p_Memac->exceptions &= ~bitMask;
22697 + }
22698 + else
22699 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
22700 +
22701 + fman_memac_set_exception(p_Memac->p_MemMap, bitMask, enable);
22702 +
22703 + return E_OK;
22704 +}
22705 +
22706 +/* ......................................................................... */
22707 +
22708 +static uint16_t MemacGetMaxFrameLength(t_Handle h_Memac)
22709 +{
22710 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22711 +
22712 + SANITY_CHECK_RETURN_VALUE(p_Memac, E_INVALID_HANDLE, 0);
22713 + SANITY_CHECK_RETURN_VALUE(!p_Memac->p_MemacDriverParam, E_INVALID_STATE, 0);
22714 +
22715 + return fman_memac_get_max_frame_len(p_Memac->p_MemMap);
22716 +}
22717 +
22718 +static t_Error MemacInitInternalPhy(t_Handle h_Memac)
22719 +{
22720 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22721 + uint8_t i, phyAddr;
22722 +
22723 + if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_SGMII)
22724 + {
22725 + /* Configure internal SGMII PHY */
22726 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
22727 + SetupSgmiiInternalPhyBaseX(p_Memac, PHY_MDIO_ADDR);
22728 + else
22729 + SetupSgmiiInternalPhy(p_Memac, PHY_MDIO_ADDR);
22730 + }
22731 + else if (ENET_INTERFACE_FROM_MODE(p_Memac->enetMode) == e_ENET_IF_QSGMII)
22732 + {
22733 + /* Configure 4 internal SGMII PHYs */
22734 + for (i = 0; i < 4; i++)
22735 + {
22736 + /* QSGMII PHY address occupies 3 upper bits of 5-bit
22737 + phyAddress; the lower 2 bits are used to extend
22738 + register address space and access each one of 4
22739 + ports inside QSGMII. */
22740 + phyAddr = (uint8_t)((PHY_MDIO_ADDR << 2) | i);
22741 + if (p_Memac->enetMode & ENET_IF_SGMII_BASEX)
22742 + SetupSgmiiInternalPhyBaseX(p_Memac, phyAddr);
22743 + else
22744 + SetupSgmiiInternalPhy(p_Memac, phyAddr);
22745 + }
22746 + }
22747 + return E_OK;
22748 +}
22749 +
22750 +/*****************************************************************************/
22751 +/* mEMAC Init & Free API */
22752 +/*****************************************************************************/
22753 +
22754 +/* ......................................................................... */
22755 +void *g_MemacRegs;
22756 +static t_Error MemacInit(t_Handle h_Memac)
22757 +{
22758 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22759 + struct memac_cfg *p_MemacDriverParam;
22760 + enum enet_interface enet_interface;
22761 + enum enet_speed enet_speed;
22762 + t_EnetAddr ethAddr;
22763 + e_FmMacType portType;
22764 + t_Error err;
22765 + bool slow_10g_if = FALSE;
22766 + if (p_Memac->macId == 3) /* This is a quick WA */
22767 + g_MemacRegs = p_Memac->p_MemMap;
22768 +
22769 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22770 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MemacDriverParam, E_INVALID_STATE);
22771 + SANITY_CHECK_RETURN_ERROR(p_Memac->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
22772 +
22773 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
22774 + if (p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6 &&
22775 + p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 4)
22776 + slow_10g_if = TRUE;
22777 +
22778 + CHECK_INIT_PARAMETERS(p_Memac, CheckInitParameters);
22779 +
22780 + p_MemacDriverParam = p_Memac->p_MemacDriverParam;
22781 +
22782 + portType =
22783 + ((ENET_SPEED_FROM_MODE(p_Memac->enetMode) < e_ENET_SPEED_10000) ? e_FM_MAC_1G : e_FM_MAC_10G);
22784 +
22785 + /* First, reset the MAC if desired. */
22786 + if (p_MemacDriverParam->reset_on_init)
22787 + fman_memac_reset(p_Memac->p_MemMap);
22788 +
22789 + /* MAC Address */
22790 + MAKE_ENET_ADDR_FROM_UINT64(p_Memac->addr, ethAddr);
22791 + fman_memac_add_addr_in_paddr(p_Memac->p_MemMap, (uint8_t*)ethAddr, 0);
22792 +
22793 + enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Memac->enetMode);
22794 + enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Memac->enetMode);
22795 +
22796 + fman_memac_init(p_Memac->p_MemMap,
22797 + p_Memac->p_MemacDriverParam,
22798 + enet_interface,
22799 + enet_speed,
22800 + slow_10g_if,
22801 + p_Memac->exceptions);
22802 +
22803 +#ifdef FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
22804 + {
22805 + uint32_t tmpReg = 0;
22806 +
22807 + FM_GetRevision(p_Memac->fmMacControllerDriver.h_Fm, &p_Memac->fmMacControllerDriver.fmRevInfo);
22808 + /* check the FMAN version - the bug exists only in rev1 */
22809 + if ((p_Memac->fmMacControllerDriver.fmRevInfo.majorRev == 6) &&
22810 + (p_Memac->fmMacControllerDriver.fmRevInfo.minorRev == 0))
22811 + {
22812 + /* MAC strips CRC from received frames - this workaround should
22813 + decrease the likelihood of bug appearance
22814 + */
22815 + tmpReg = GET_UINT32(p_Memac->p_MemMap->command_config);
22816 + tmpReg &= ~CMD_CFG_CRC_FWD;
22817 + WRITE_UINT32(p_Memac->p_MemMap->command_config, tmpReg);
22818 + /* DBG(WARNING, ("mEMAC strips CRC from received frames as part of A006320 errata workaround"));*/
22819 + }
22820 + }
22821 +#endif /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 */
22822 +
22823 + MemacInitInternalPhy(h_Memac);
22824 +
22825 + /* Max Frame Length */
22826 + err = FmSetMacMaxFrame(p_Memac->fmMacControllerDriver.h_Fm,
22827 + portType,
22828 + p_Memac->fmMacControllerDriver.macId,
22829 + p_MemacDriverParam->max_frame_length);
22830 + if (err)
22831 + RETURN_ERROR(MAJOR, err, ("settings Mac max frame length is FAILED"));
22832 +
22833 + p_Memac->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22834 + if (!p_Memac->p_MulticastAddrHash)
22835 + {
22836 + FreeInitResources(p_Memac);
22837 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22838 + }
22839 +
22840 + p_Memac->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
22841 + if (!p_Memac->p_UnicastAddrHash)
22842 + {
22843 + FreeInitResources(p_Memac);
22844 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
22845 + }
22846 +
22847 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
22848 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
22849 + p_Memac->macId,
22850 + e_FM_INTR_TYPE_ERR,
22851 + MemacErrException,
22852 + p_Memac);
22853 +
22854 + FmRegisterIntr(p_Memac->fmMacControllerDriver.h_Fm,
22855 + (portType == e_FM_MAC_10G) ? e_FM_MOD_10G_MAC : e_FM_MOD_1G_MAC,
22856 + p_Memac->macId,
22857 + e_FM_INTR_TYPE_NORMAL,
22858 + MemacException,
22859 + p_Memac);
22860 +
22861 + XX_Free(p_MemacDriverParam);
22862 + p_Memac->p_MemacDriverParam = NULL;
22863 +
22864 + return E_OK;
22865 +}
22866 +
22867 +/* ......................................................................... */
22868 +
22869 +static t_Error MemacFree(t_Handle h_Memac)
22870 +{
22871 + t_Memac *p_Memac = (t_Memac *)h_Memac;
22872 +
22873 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
22874 +
22875 + if (p_Memac->p_MemacDriverParam)
22876 + {
22877 + /* Called after config */
22878 + XX_Free(p_Memac->p_MemacDriverParam);
22879 + p_Memac->p_MemacDriverParam = NULL;
22880 + }
22881 + else
22882 + /* Called after init */
22883 + FreeInitResources(p_Memac);
22884 +
22885 + XX_Free(p_Memac);
22886 +
22887 + return E_OK;
22888 +}
22889 +
22890 +/* ......................................................................... */
22891 +
22892 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
22893 +{
22894 + p_FmMacControllerDriver->f_FM_MAC_Init = MemacInit;
22895 + p_FmMacControllerDriver->f_FM_MAC_Free = MemacFree;
22896 +
22897 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
22898 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = MemacConfigLoopback;
22899 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = MemacConfigMaxFrameLength;
22900 +
22901 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = MemacConfigWan;
22902 +
22903 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = MemacConfigPad;
22904 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is detected automatically */
22905 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = MemacConfigLengthCheck;
22906 +
22907 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = MemacConfigException;
22908 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = MemacConfigResetOnInit;
22909 +
22910 + p_FmMacControllerDriver->f_FM_MAC_SetException = MemacSetException;
22911 +
22912 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = MemacEnable1588TimeStamp; /* always enabled */
22913 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = NULL;
22914 +
22915 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = MemacSetPromiscuous;
22916 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = MemacAdjustLink;
22917 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
22918 +
22919 + p_FmMacControllerDriver->f_FM_MAC_Enable = MemacEnable;
22920 + p_FmMacControllerDriver->f_FM_MAC_Disable = MemacDisable;
22921 + p_FmMacControllerDriver->f_FM_MAC_Resume = MemacInitInternalPhy;
22922 +
22923 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = MemacSetTxAutoPauseFrames;
22924 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = MemacSetTxPauseFrames;
22925 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = MemacSetRxIgnorePauseFrames;
22926 +
22927 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = MemacSetWakeOnLan;
22928 +
22929 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = MemacResetCounters;
22930 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = MemacGetStatistics;
22931 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = MemacGetFrameSizeCounters;
22932 +
22933 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = MemacModifyMacAddress;
22934 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = MemacAddHashMacAddress;
22935 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = MemacDelHashMacAddress;
22936 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = MemacAddExactMatchMacAddress;
22937 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = MemacDelExactMatchMacAddress;
22938 + p_FmMacControllerDriver->f_FM_MAC_GetId = MemacGetId;
22939 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = NULL;
22940 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = MemacGetMaxFrameLength;
22941 +
22942 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = MEMAC_MII_WritePhyReg;
22943 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = MEMAC_MII_ReadPhyReg;
22944 +}
22945 +
22946 +
22947 +/*****************************************************************************/
22948 +/* mEMAC Config Main Entry */
22949 +/*****************************************************************************/
22950 +
22951 +/* ......................................................................... */
22952 +
22953 +t_Handle MEMAC_Config(t_FmMacParams *p_FmMacParam)
22954 +{
22955 + t_Memac *p_Memac;
22956 + struct memac_cfg *p_MemacDriverParam;
22957 + uintptr_t baseAddr;
22958 +
22959 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
22960 +
22961 + baseAddr = p_FmMacParam->baseAddr;
22962 + /* Allocate memory for the mEMAC data structure */
22963 + p_Memac = (t_Memac *)XX_Malloc(sizeof(t_Memac));
22964 + if (!p_Memac)
22965 + {
22966 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver structure"));
22967 + return NULL;
22968 + }
22969 + memset(p_Memac, 0, sizeof(t_Memac));
22970 + InitFmMacControllerDriver(&p_Memac->fmMacControllerDriver);
22971 +
22972 + /* Allocate memory for the mEMAC driver parameters data structure */
22973 + p_MemacDriverParam = (struct memac_cfg *)XX_Malloc(sizeof(struct memac_cfg));
22974 + if (!p_MemacDriverParam)
22975 + {
22976 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("mEMAC driver parameters"));
22977 + XX_Free(p_Memac);
22978 + return NULL;
22979 + }
22980 + memset(p_MemacDriverParam, 0, sizeof(struct memac_cfg));
22981 +
22982 + /* Plant parameter structure pointer */
22983 + p_Memac->p_MemacDriverParam = p_MemacDriverParam;
22984 +
22985 + fman_memac_defconfig(p_MemacDriverParam);
22986 +
22987 + p_Memac->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
22988 +
22989 + p_Memac->p_MemMap = (struct memac_regs *)UINT_TO_PTR(baseAddr);
22990 + p_Memac->p_MiiMemMap = (struct memac_mii_access_mem_map*)UINT_TO_PTR(baseAddr + MEMAC_TO_MII_OFFSET);
22991 +
22992 + p_Memac->enetMode = p_FmMacParam->enetMode;
22993 + p_Memac->macId = p_FmMacParam->macId;
22994 + p_Memac->exceptions = MEMAC_default_exceptions;
22995 + p_Memac->f_Exception = p_FmMacParam->f_Exception;
22996 + p_Memac->f_Event = p_FmMacParam->f_Event;
22997 + p_Memac->h_App = p_FmMacParam->h_App;
22998 +
22999 + return p_Memac;
23000 +}
23001 --- /dev/null
23002 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac.h
23003 @@ -0,0 +1,110 @@
23004 +/*
23005 + * Copyright 2008-2012 Freescale Semiconductor Inc.
23006 + *
23007 + * Redistribution and use in source and binary forms, with or without
23008 + * modification, are permitted provided that the following conditions are met:
23009 + * * Redistributions of source code must retain the above copyright
23010 + * notice, this list of conditions and the following disclaimer.
23011 + * * Redistributions in binary form must reproduce the above copyright
23012 + * notice, this list of conditions and the following disclaimer in the
23013 + * documentation and/or other materials provided with the distribution.
23014 + * * Neither the name of Freescale Semiconductor nor the
23015 + * names of its contributors may be used to endorse or promote products
23016 + * derived from this software without specific prior written permission.
23017 + *
23018 + *
23019 + * ALTERNATIVELY, this software may be distributed under the terms of the
23020 + * GNU General Public License ("GPL") as published by the Free Software
23021 + * Foundation, either version 2 of that License or (at your option) any
23022 + * later version.
23023 + *
23024 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23025 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23026 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23027 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23028 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23029 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23030 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23031 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23032 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23033 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23034 + */
23035 +
23036 +
23037 +/******************************************************************************
23038 + @File memac.h
23039 +
23040 + @Description FM Multirate Ethernet MAC (mEMAC)
23041 +*//***************************************************************************/
23042 +#ifndef __MEMAC_H
23043 +#define __MEMAC_H
23044 +
23045 +#include "std_ext.h"
23046 +#include "error_ext.h"
23047 +#include "list_ext.h"
23048 +
23049 +#include "fsl_fman_memac_mii_acc.h"
23050 +#include "fm_mac.h"
23051 +#include "fsl_fman_memac.h"
23052 +
23053 +
23054 +#define MEMAC_default_exceptions \
23055 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI))
23056 +
23057 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
23058 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
23059 + bitMask = MEMAC_IMASK_TECC_ER; break; \
23060 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
23061 + bitMask = MEMAC_IMASK_RECC_ER; break; \
23062 + case e_FM_MAC_EX_TS_FIFO_ECC_ERR: \
23063 + bitMask = MEMAC_IMASK_TSECC_ER; break; \
23064 + case e_FM_MAC_EX_MAGIC_PACKET_INDICATION: \
23065 + bitMask = MEMAC_IMASK_MGI; break; \
23066 + default: bitMask = 0;break;}
23067 +
23068 +
23069 +typedef struct
23070 +{
23071 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
23072 + t_Handle h_App; /**< Handle to the upper layer application */
23073 + struct memac_regs *p_MemMap; /**< Pointer to MAC memory mapped registers */
23074 + struct memac_mii_access_mem_map *p_MiiMemMap; /**< Pointer to MII memory mapped registers */
23075 + uint64_t addr; /**< MAC address of device */
23076 + e_EnetMode enetMode; /**< Ethernet physical interface */
23077 + t_FmMacExceptionCallback *f_Exception;
23078 + int mdioIrq;
23079 + t_FmMacExceptionCallback *f_Event;
23080 + bool indAddrRegUsed[MEMAC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
23081 + uint64_t paddr[MEMAC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
23082 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
23083 + t_EthHash *p_MulticastAddrHash; /**< Pointer to driver's global address hash table */
23084 + t_EthHash *p_UnicastAddrHash; /**< Pointer to driver's individual address hash table */
23085 + bool debugMode;
23086 + uint8_t macId;
23087 + uint32_t exceptions;
23088 + struct memac_cfg *p_MemacDriverParam;
23089 +} t_Memac;
23090 +
23091 +
23092 +/* Internal PHY access */
23093 +#define PHY_MDIO_ADDR 0
23094 +
23095 +/* Internal PHY Registers - SGMII */
23096 +#define PHY_SGMII_CR_PHY_RESET 0x8000
23097 +#define PHY_SGMII_CR_RESET_AN 0x0200
23098 +#define PHY_SGMII_CR_DEF_VAL 0x1140
23099 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
23100 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
23101 +#define PHY_SGMII_IF_SPEED_GIGABIT 0x0008
23102 +#define PHY_SGMII_IF_MODE_AN 0x0002
23103 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
23104 +#define PHY_SGMII_IF_MODE_1000X 0x0000
23105 +
23106 +
23107 +#define MEMAC_TO_MII_OFFSET 0x030 /* Offset from the MEM map to the MDIO mem map */
23108 +
23109 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t data);
23110 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
23111 +
23112 +
23113 +#endif /* __MEMAC_H */
23114 --- /dev/null
23115 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.c
23116 @@ -0,0 +1,78 @@
23117 +/*
23118 + * Copyright 2008-2012 Freescale Semiconductor Inc.
23119 + *
23120 + * Redistribution and use in source and binary forms, with or without
23121 + * modification, are permitted provided that the following conditions are met:
23122 + * * Redistributions of source code must retain the above copyright
23123 + * notice, this list of conditions and the following disclaimer.
23124 + * * Redistributions in binary form must reproduce the above copyright
23125 + * notice, this list of conditions and the following disclaimer in the
23126 + * documentation and/or other materials provided with the distribution.
23127 + * * Neither the name of Freescale Semiconductor nor the
23128 + * names of its contributors may be used to endorse or promote products
23129 + * derived from this software without specific prior written permission.
23130 + *
23131 + *
23132 + * ALTERNATIVELY, this software may be distributed under the terms of the
23133 + * GNU General Public License ("GPL") as published by the Free Software
23134 + * Foundation, either version 2 of that License or (at your option) any
23135 + * later version.
23136 + *
23137 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23138 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23139 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23140 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23141 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23142 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23143 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23144 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23145 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23146 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23147 + */
23148 +
23149 +
23150 +#include "error_ext.h"
23151 +#include "std_ext.h"
23152 +#include "fm_mac.h"
23153 +#include "memac.h"
23154 +#include "xx_ext.h"
23155 +
23156 +#include "fm_common.h"
23157 +#include "memac_mii_acc.h"
23158 +
23159 +
23160 +/*****************************************************************************/
23161 +t_Error MEMAC_MII_WritePhyReg(t_Handle h_Memac,
23162 + uint8_t phyAddr,
23163 + uint8_t reg,
23164 + uint16_t data)
23165 +{
23166 + t_Memac *p_Memac = (t_Memac *)h_Memac;
23167 +
23168 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
23169 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
23170 +
23171 + return (t_Error)fman_memac_mii_write_phy_reg(p_Memac->p_MiiMemMap,
23172 + phyAddr,
23173 + reg,
23174 + data,
23175 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
23176 +}
23177 +
23178 +/*****************************************************************************/
23179 +t_Error MEMAC_MII_ReadPhyReg(t_Handle h_Memac,
23180 + uint8_t phyAddr,
23181 + uint8_t reg,
23182 + uint16_t *p_Data)
23183 +{
23184 + t_Memac *p_Memac = (t_Memac *)h_Memac;
23185 +
23186 + SANITY_CHECK_RETURN_ERROR(p_Memac, E_INVALID_HANDLE);
23187 + SANITY_CHECK_RETURN_ERROR(p_Memac->p_MiiMemMap, E_INVALID_HANDLE);
23188 +
23189 + return fman_memac_mii_read_phy_reg(p_Memac->p_MiiMemMap,
23190 + phyAddr,
23191 + reg,
23192 + p_Data,
23193 + (enum enet_speed)ENET_SPEED_FROM_MODE(p_Memac->enetMode));
23194 +}
23195 --- /dev/null
23196 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/memac_mii_acc.h
23197 @@ -0,0 +1,73 @@
23198 +/*
23199 + * Copyright 2008-2012 Freescale Semiconductor Inc.
23200 + *
23201 + * Redistribution and use in source and binary forms, with or without
23202 + * modification, are permitted provided that the following conditions are met:
23203 + * * Redistributions of source code must retain the above copyright
23204 + * notice, this list of conditions and the following disclaimer.
23205 + * * Redistributions in binary form must reproduce the above copyright
23206 + * notice, this list of conditions and the following disclaimer in the
23207 + * documentation and/or other materials provided with the distribution.
23208 + * * Neither the name of Freescale Semiconductor nor the
23209 + * names of its contributors may be used to endorse or promote products
23210 + * derived from this software without specific prior written permission.
23211 + *
23212 + *
23213 + * ALTERNATIVELY, this software may be distributed under the terms of the
23214 + * GNU General Public License ("GPL") as published by the Free Software
23215 + * Foundation, either version 2 of that License or (at your option) any
23216 + * later version.
23217 + *
23218 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23219 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23220 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23221 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23222 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23223 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23224 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23225 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23226 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23227 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23228 + */
23229 +
23230 +
23231 +#ifndef __MEMAC_MII_ACC_H
23232 +#define __MEMAC_MII_ACC_H
23233 +
23234 +#include "std_ext.h"
23235 +
23236 +
23237 +/* MII Management Registers */
23238 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
23239 +#define MDIO_CFG_CLK_DIV_SHIFT 7
23240 +#define MDIO_CFG_HOLD_MASK 0x0000001c
23241 +#define MDIO_CFG_ENC45 0x00000040
23242 +#define MDIO_CFG_READ_ERR 0x00000002
23243 +#define MDIO_CFG_BSY 0x00000001
23244 +
23245 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
23246 +#define MDIO_CTL_READ 0x00008000
23247 +
23248 +#define MDIO_DATA_BSY 0x80000000
23249 +
23250 +#if defined(__MWERKS__) && !defined(__GNUC__)
23251 +#pragma pack(push,1)
23252 +#endif /* defined(__MWERKS__) && ... */
23253 +
23254 +/*----------------------------------------------------*/
23255 +/* MII Configuration Control Memory Map Registers */
23256 +/*----------------------------------------------------*/
23257 +typedef struct t_MemacMiiAccessMemMap
23258 +{
23259 + volatile uint32_t mdio_cfg; /* 0x030 */
23260 + volatile uint32_t mdio_ctrl; /* 0x034 */
23261 + volatile uint32_t mdio_data; /* 0x038 */
23262 + volatile uint32_t mdio_addr; /* 0x03c */
23263 +} t_MemacMiiAccessMemMap ;
23264 +
23265 +#if defined(__MWERKS__) && !defined(__GNUC__)
23266 +#pragma pack(pop)
23267 +#endif /* defined(__MWERKS__) && ... */
23268 +
23269 +
23270 +#endif /* __MEMAC_MII_ACC_H */
23271 --- /dev/null
23272 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.c
23273 @@ -0,0 +1,1017 @@
23274 +/*
23275 + * Copyright 2008-2012 Freescale Semiconductor Inc.
23276 + *
23277 + * Redistribution and use in source and binary forms, with or without
23278 + * modification, are permitted provided that the following conditions are met:
23279 + * * Redistributions of source code must retain the above copyright
23280 + * notice, this list of conditions and the following disclaimer.
23281 + * * Redistributions in binary form must reproduce the above copyright
23282 + * notice, this list of conditions and the following disclaimer in the
23283 + * documentation and/or other materials provided with the distribution.
23284 + * * Neither the name of Freescale Semiconductor nor the
23285 + * names of its contributors may be used to endorse or promote products
23286 + * derived from this software without specific prior written permission.
23287 + *
23288 + *
23289 + * ALTERNATIVELY, this software may be distributed under the terms of the
23290 + * GNU General Public License ("GPL") as published by the Free Software
23291 + * Foundation, either version 2 of that License or (at your option) any
23292 + * later version.
23293 + *
23294 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
23295 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23296 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23297 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
23298 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23299 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23300 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23301 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23302 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23303 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23304 + */
23305 +
23306 +
23307 +/******************************************************************************
23308 + @File tgec.c
23309 +
23310 + @Description FM 10G MAC ...
23311 +*//***************************************************************************/
23312 +
23313 +#include "std_ext.h"
23314 +#include "string_ext.h"
23315 +#include "error_ext.h"
23316 +#include "xx_ext.h"
23317 +#include "endian_ext.h"
23318 +#include "debug_ext.h"
23319 +#include "crc_mac_addr_ext.h"
23320 +
23321 +#include "fm_common.h"
23322 +#include "fsl_fman_tgec.h"
23323 +#include "tgec.h"
23324 +
23325 +
23326 +/*****************************************************************************/
23327 +/* Internal routines */
23328 +/*****************************************************************************/
23329 +
23330 +static t_Error CheckInitParameters(t_Tgec *p_Tgec)
23331 +{
23332 + if (ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
23333 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
23334 +#if (FM_MAX_NUM_OF_10G_MACS > 0)
23335 + if (p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
23336 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
23337 +#endif /* (FM_MAX_NUM_OF_10G_MACS > 0) */
23338 +
23339 + if (p_Tgec->addr == 0)
23340 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
23341 + if (!p_Tgec->f_Exception)
23342 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
23343 + if (!p_Tgec->f_Event)
23344 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
23345 +#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
23346 + if (!p_Tgec->p_TgecDriverParam->no_length_check_enable)
23347 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
23348 +#endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
23349 + return E_OK;
23350 +}
23351 +
23352 +/* ......................................................................... */
23353 +
23354 +static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
23355 +{
23356 + uint32_t crc;
23357 +
23358 + /* CRC calculation */
23359 + GET_MAC_ADDR_CRC(ethAddr, crc);
23360 +
23361 + crc = GetMirror32(crc);
23362 +
23363 + return crc;
23364 +}
23365 +
23366 +/* ......................................................................... */
23367 +
23368 +static void TgecErrException(t_Handle h_Tgec)
23369 +{
23370 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23371 + uint32_t event;
23372 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
23373 +
23374 + /* do not handle MDIO events */
23375 + event = fman_tgec_get_event(p_TgecMemMap, ~(TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
23376 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
23377 +
23378 + fman_tgec_ack_event(p_TgecMemMap, event);
23379 +
23380 + if (event & TGEC_IMASK_REM_FAULT)
23381 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
23382 + if (event & TGEC_IMASK_LOC_FAULT)
23383 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
23384 + if (event & TGEC_IMASK_TX_ECC_ER)
23385 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
23386 + if (event & TGEC_IMASK_TX_FIFO_UNFL)
23387 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
23388 + if (event & TGEC_IMASK_TX_FIFO_OVFL)
23389 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
23390 + if (event & TGEC_IMASK_TX_ER)
23391 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
23392 + if (event & TGEC_IMASK_RX_FIFO_OVFL)
23393 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
23394 + if (event & TGEC_IMASK_RX_ECC_ER)
23395 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
23396 + if (event & TGEC_IMASK_RX_JAB_FRM)
23397 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
23398 + if (event & TGEC_IMASK_RX_OVRSZ_FRM)
23399 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
23400 + if (event & TGEC_IMASK_RX_RUNT_FRM)
23401 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
23402 + if (event & TGEC_IMASK_RX_FRAG_FRM)
23403 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
23404 + if (event & TGEC_IMASK_RX_LEN_ER)
23405 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
23406 + if (event & TGEC_IMASK_RX_CRC_ER)
23407 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
23408 + if (event & TGEC_IMASK_RX_ALIGN_ER)
23409 + p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
23410 +}
23411 +
23412 +/* ......................................................................... */
23413 +
23414 +static void TgecException(t_Handle h_Tgec)
23415 +{
23416 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23417 + uint32_t event;
23418 + struct tgec_regs *p_TgecMemMap = p_Tgec->p_MemMap;
23419 +
23420 + /* handle only MDIO events */
23421 + event = fman_tgec_get_event(p_TgecMemMap, (TGEC_IMASK_MDIO_SCAN_EVENT | TGEC_IMASK_MDIO_CMD_CMPL));
23422 + event &= fman_tgec_get_interrupt_mask(p_TgecMemMap);
23423 +
23424 + fman_tgec_ack_event(p_TgecMemMap, event);
23425 +
23426 + if (event & TGEC_IMASK_MDIO_SCAN_EVENT)
23427 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
23428 + if (event & TGEC_IMASK_MDIO_CMD_CMPL)
23429 + p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
23430 +}
23431 +
23432 +/* ......................................................................... */
23433 +
23434 +static void FreeInitResources(t_Tgec *p_Tgec)
23435 +{
23436 + if (p_Tgec->mdioIrq != NO_IRQ)
23437 + {
23438 + XX_DisableIntr(p_Tgec->mdioIrq);
23439 + XX_FreeIntr(p_Tgec->mdioIrq);
23440 + }
23441 +
23442 + FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
23443 +
23444 + /* release the driver's group hash table */
23445 + FreeHashTable(p_Tgec->p_MulticastAddrHash);
23446 + p_Tgec->p_MulticastAddrHash = NULL;
23447 +
23448 + /* release the driver's individual hash table */
23449 + FreeHashTable(p_Tgec->p_UnicastAddrHash);
23450 + p_Tgec->p_UnicastAddrHash = NULL;
23451 +}
23452 +
23453 +
23454 +/*****************************************************************************/
23455 +/* 10G MAC API routines */
23456 +/*****************************************************************************/
23457 +
23458 +/* ......................................................................... */
23459 +
23460 +static t_Error TgecEnable(t_Handle h_Tgec, e_CommMode mode)
23461 +{
23462 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23463 +
23464 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23465 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23466 +
23467 + fman_tgec_enable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
23468 +
23469 + return E_OK;
23470 +}
23471 +
23472 +/* ......................................................................... */
23473 +
23474 +static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
23475 +{
23476 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23477 +
23478 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23479 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23480 +
23481 + fman_tgec_disable(p_Tgec->p_MemMap, (mode & e_COMM_MODE_RX), (mode & e_COMM_MODE_TX));
23482 +
23483 + return E_OK;
23484 +}
23485 +
23486 +/* ......................................................................... */
23487 +
23488 +static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
23489 +{
23490 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23491 +
23492 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23493 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23494 +
23495 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, newVal);
23496 +
23497 + return E_OK;
23498 +}
23499 +
23500 +
23501 +/*****************************************************************************/
23502 +/* Tgec Configs modification functions */
23503 +/*****************************************************************************/
23504 +
23505 +/* ......................................................................... */
23506 +
23507 +static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
23508 +{
23509 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23510 +
23511 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23512 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23513 +
23514 + p_Tgec->p_TgecDriverParam->loopback_enable = newVal;
23515 +
23516 + return E_OK;
23517 +}
23518 +
23519 +/* ......................................................................... */
23520 +
23521 +static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
23522 +{
23523 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23524 +
23525 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23526 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23527 +
23528 + p_Tgec->p_TgecDriverParam->wan_mode_enable = newVal;
23529 +
23530 + return E_OK;
23531 +}
23532 +
23533 +/* ......................................................................... */
23534 +
23535 +static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
23536 +{
23537 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23538 +
23539 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23540 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23541 +
23542 + p_Tgec->p_TgecDriverParam->max_frame_length = newVal;
23543 +
23544 + return E_OK;
23545 +}
23546 +
23547 +/* ......................................................................... */
23548 +
23549 +static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
23550 +{
23551 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23552 +
23553 + UNUSED(newVal);
23554 +
23555 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23556 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23557 +
23558 + p_Tgec->p_TgecDriverParam->no_length_check_enable = !newVal;
23559 +
23560 + return E_OK;
23561 +}
23562 +
23563 +/* ......................................................................... */
23564 +
23565 +static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
23566 +{
23567 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23568 + uint32_t bitMask = 0;
23569 +
23570 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23571 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23572 +
23573 + GET_EXCEPTION_FLAG(bitMask, exception);
23574 + if (bitMask)
23575 + {
23576 + if (enable)
23577 + p_Tgec->exceptions |= bitMask;
23578 + else
23579 + p_Tgec->exceptions &= ~bitMask;
23580 + }
23581 + else
23582 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
23583 +
23584 + return E_OK;
23585 +}
23586 +
23587 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
23588 +/* ......................................................................... */
23589 +
23590 +static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
23591 +{
23592 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23593 +
23594 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23595 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23596 +
23597 + p_Tgec->p_TgecDriverParam->skip_fman11_workaround = TRUE;
23598 +
23599 + return E_OK;
23600 +}
23601 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
23602 +
23603 +
23604 +/*****************************************************************************/
23605 +/* Tgec Run Time API functions */
23606 +/*****************************************************************************/
23607 +
23608 +/* ......................................................................... */
23609 +/* backward compatibility. will be removed in the future. */
23610 +static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
23611 +{
23612 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23613 +
23614 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
23615 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23616 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
23617 +
23618 +
23619 + return E_OK;
23620 +}
23621 +
23622 +/* ......................................................................... */
23623 +
23624 +static t_Error TgecSetTxPauseFrames(t_Handle h_Tgec,
23625 + uint8_t priority,
23626 + uint16_t pauseTime,
23627 + uint16_t threshTime)
23628 +{
23629 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23630 +
23631 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
23632 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23633 +
23634 + UNUSED(priority); UNUSED(threshTime);
23635 +
23636 + fman_tgec_set_tx_pause_frames(p_Tgec->p_MemMap, pauseTime);
23637 +
23638 + return E_OK;
23639 +}
23640 +
23641 +/* ......................................................................... */
23642 +
23643 +static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
23644 +{
23645 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23646 +
23647 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
23648 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23649 +
23650 + fman_tgec_set_rx_ignore_pause_frames(p_Tgec->p_MemMap, en);
23651 +
23652 + return E_OK;
23653 +}
23654 +
23655 +/* ......................................................................... */
23656 +
23657 +static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
23658 +{
23659 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23660 + struct tgec_regs *p_TgecMemMap;
23661 +
23662 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23663 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23664 + SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
23665 +
23666 + p_TgecMemMap = p_Tgec->p_MemMap;
23667 +
23668 + p_Statistics->eStatPkts64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
23669 + p_Statistics->eStatPkts65to127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
23670 + p_Statistics->eStatPkts128to255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
23671 + p_Statistics->eStatPkts256to511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
23672 + p_Statistics->eStatPkts512to1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
23673 + p_Statistics->eStatPkts1024to1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
23674 + p_Statistics->eStatPkts1519to1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
23675 +/* */
23676 + p_Statistics->eStatFragments = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRFRG);
23677 + p_Statistics->eStatJabbers = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRJBR);
23678 +
23679 + p_Statistics->eStatsDropEvents = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RDRP);
23680 + p_Statistics->eStatCRCAlignErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RALN);
23681 +
23682 + p_Statistics->eStatUndersizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TRUND);
23683 + p_Statistics->eStatOversizePkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TROVR);
23684 +/* Pause */
23685 + p_Statistics->reStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RXPF);
23686 + p_Statistics->teStatPause = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TXPF);
23687 +
23688 +/* MIB II */
23689 + p_Statistics->ifInOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_ROCT);
23690 + p_Statistics->ifInUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RUCA);
23691 + p_Statistics->ifInMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RMCA);
23692 + p_Statistics->ifInBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RBCA);
23693 + p_Statistics->ifInPkts = p_Statistics->ifInUcastPkts
23694 + + p_Statistics->ifInMcastPkts
23695 + + p_Statistics->ifInBcastPkts;
23696 + p_Statistics->ifInDiscards = 0;
23697 + p_Statistics->ifInErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_RERR);
23698 +
23699 + p_Statistics->ifOutOctets = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TOCT);
23700 + p_Statistics->ifOutUcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TUCA);
23701 + p_Statistics->ifOutMcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TMCA);
23702 + p_Statistics->ifOutBcastPkts = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TBCA);
23703 + p_Statistics->ifOutPkts = p_Statistics->ifOutUcastPkts
23704 + + p_Statistics->ifOutMcastPkts
23705 + + p_Statistics->ifOutBcastPkts;
23706 + p_Statistics->ifOutDiscards = 0;
23707 + p_Statistics->ifOutErrors = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_TERR);
23708 +
23709 + return E_OK;
23710 +}
23711 +
23712 +/* ......................................................................... */
23713 +
23714 +static t_Error TgecGetFrameSizeCounters(t_Handle h_Tgec, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type)
23715 +{
23716 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23717 + struct tgec_regs *p_TgecMemMap;
23718 +
23719 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23720 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23721 + SANITY_CHECK_RETURN_ERROR(p_FrameSizeCounters, E_NULL_POINTER);
23722 +
23723 + p_TgecMemMap = p_Tgec->p_MemMap;
23724 +
23725 + switch (type)
23726 + {
23727 + case e_COMM_MODE_NONE:
23728 + break;
23729 +
23730 + case e_COMM_MODE_RX:
23731 + p_FrameSizeCounters->count_pkts_64 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R64);
23732 + p_FrameSizeCounters->count_pkts_65_to_127 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R127);
23733 + p_FrameSizeCounters->count_pkts_128_to_255 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R255);
23734 + p_FrameSizeCounters->count_pkts_256_to_511 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R511);
23735 + p_FrameSizeCounters->count_pkts_512_to_1023 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1023);
23736 + p_FrameSizeCounters->count_pkts_1024_to_1518 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1518);
23737 + p_FrameSizeCounters->count_pkts_1519_to_1522 = fman_tgec_get_counter(p_TgecMemMap, E_TGEC_COUNTER_R1519X);
23738 + break;
23739 +
23740 + case e_COMM_MODE_TX:
23741 + //Tx counters not supported
23742 + break;
23743 +
23744 + case e_COMM_MODE_RX_AND_TX:
23745 + //Tx counters not supported
23746 + break;
23747 + }
23748 +
23749 + return E_OK;
23750 +}
23751 +
23752 +
23753 +/* ......................................................................... */
23754 +
23755 +static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
23756 +{
23757 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23758 +
23759 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23760 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23761 +
23762 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 1);
23763 +
23764 + return E_OK;
23765 +}
23766 +
23767 +/* ......................................................................... */
23768 +
23769 +static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
23770 +{
23771 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23772 +
23773 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23774 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23775 +
23776 + fman_tgec_enable_1588_time_stamp(p_Tgec->p_MemMap, 0);
23777 +
23778 + return E_OK;
23779 +}
23780 +
23781 +/* ......................................................................... */
23782 +
23783 +static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
23784 +{
23785 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23786 +
23787 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23788 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23789 +
23790 + p_Tgec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
23791 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)(*p_EnetAddr));
23792 +
23793 + return E_OK;
23794 +}
23795 +
23796 +/* ......................................................................... */
23797 +
23798 +static t_Error TgecResetCounters (t_Handle h_Tgec)
23799 +{
23800 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23801 +
23802 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23803 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23804 +
23805 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
23806 +
23807 + return E_OK;
23808 +}
23809 +
23810 +/* ......................................................................... */
23811 +
23812 +static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
23813 +{
23814 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
23815 + uint64_t ethAddr;
23816 + uint8_t paddrNum;
23817 +
23818 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23819 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23820 +
23821 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
23822 +
23823 + if (ethAddr & GROUP_ADDRESS)
23824 + /* Multicast address has no effect in PADDR */
23825 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
23826 +
23827 + /* Make sure no PADDR contains this address */
23828 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
23829 + if (p_Tgec->indAddrRegUsed[paddrNum])
23830 + if (p_Tgec->paddr[paddrNum] == ethAddr)
23831 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
23832 +
23833 + /* Find first unused PADDR */
23834 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
23835 + {
23836 + if (!(p_Tgec->indAddrRegUsed[paddrNum]))
23837 + {
23838 + /* mark this PADDR as used */
23839 + p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
23840 + /* store address */
23841 + p_Tgec->paddr[paddrNum] = ethAddr;
23842 +
23843 + /* put in hardware */
23844 + fman_tgec_add_addr_in_paddr(p_Tgec->p_MemMap, (uint8_t*)(*p_EthAddr)/* , paddrNum */);
23845 + p_Tgec->numOfIndAddrInRegs++;
23846 +
23847 + return E_OK;
23848 + }
23849 + }
23850 +
23851 + /* No free PADDR */
23852 + RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
23853 +}
23854 +
23855 +/* ......................................................................... */
23856 +
23857 +static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
23858 +{
23859 + t_Tgec *p_Tgec = (t_Tgec *) h_Tgec;
23860 + uint64_t ethAddr;
23861 + uint8_t paddrNum;
23862 +
23863 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23864 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23865 +
23866 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
23867 +
23868 + /* Find used PADDR containing this address */
23869 + for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
23870 + {
23871 + if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
23872 + (p_Tgec->paddr[paddrNum] == ethAddr))
23873 + {
23874 + /* mark this PADDR as not used */
23875 + p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
23876 + /* clear in hardware */
23877 + fman_tgec_clear_addr_in_paddr(p_Tgec->p_MemMap /*, paddrNum */);
23878 + p_Tgec->numOfIndAddrInRegs--;
23879 +
23880 + return E_OK;
23881 + }
23882 + }
23883 +
23884 + RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
23885 +}
23886 +
23887 +/* ......................................................................... */
23888 +
23889 +static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
23890 +{
23891 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23892 + t_EthHashEntry *p_HashEntry;
23893 + uint32_t crc;
23894 + uint32_t hash;
23895 + uint64_t ethAddr;
23896 +
23897 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23898 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23899 +
23900 + ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
23901 +
23902 + if (!(ethAddr & GROUP_ADDRESS))
23903 + /* Unicast addresses not supported in hash */
23904 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
23905 +
23906 + /* CRC calculation */
23907 + crc = GetMacAddrHashCode(ethAddr);
23908 +
23909 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
23910 +
23911 + /* Create element to be added to the driver hash table */
23912 + p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
23913 + p_HashEntry->addr = ethAddr;
23914 + INIT_LIST(&p_HashEntry->node);
23915 +
23916 + LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
23917 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash | TGEC_HASH_MCAST_EN));
23918 +
23919 + return E_OK;
23920 +}
23921 +
23922 +/* ......................................................................... */
23923 +
23924 +static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
23925 +{
23926 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23927 + t_EthHashEntry *p_HashEntry = NULL;
23928 + t_List *p_Pos;
23929 + uint32_t crc;
23930 + uint32_t hash;
23931 + uint64_t ethAddr;
23932 +
23933 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
23934 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23935 +
23936 + ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
23937 +
23938 + /* CRC calculation */
23939 + crc = GetMacAddrHashCode(ethAddr);
23940 +
23941 + hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Take 9 MSB bits */
23942 +
23943 + LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
23944 + {
23945 + p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
23946 + if (p_HashEntry->addr == ethAddr)
23947 + {
23948 + LIST_DelAndInit(&p_HashEntry->node);
23949 + XX_Free(p_HashEntry);
23950 + break;
23951 + }
23952 + }
23953 + if (LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
23954 + fman_tgec_set_hash_table(p_Tgec->p_MemMap, (hash & ~TGEC_HASH_MCAST_EN));
23955 +
23956 + return E_OK;
23957 +}
23958 +
23959 +/* ......................................................................... */
23960 +
23961 +static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
23962 +{
23963 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23964 +
23965 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23966 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23967 +
23968 + UNUSED(p_Tgec);
23969 + UNUSED(macId);
23970 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
23971 +}
23972 +
23973 +/* ......................................................................... */
23974 +
23975 +static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
23976 +{
23977 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23978 +
23979 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23980 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23981 +
23982 + *macVersion = fman_tgec_get_revision(p_Tgec->p_MemMap);
23983 +
23984 + return E_OK;
23985 +}
23986 +
23987 +/* ......................................................................... */
23988 +
23989 +static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
23990 +{
23991 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
23992 + uint32_t bitMask = 0;
23993 +
23994 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
23995 + SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
23996 +
23997 + GET_EXCEPTION_FLAG(bitMask, exception);
23998 + if (bitMask)
23999 + {
24000 + if (enable)
24001 + p_Tgec->exceptions |= bitMask;
24002 + else
24003 + p_Tgec->exceptions &= ~bitMask;
24004 + }
24005 + else
24006 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
24007 +
24008 + if (enable)
24009 + fman_tgec_enable_interrupt(p_Tgec->p_MemMap, bitMask);
24010 + else
24011 + fman_tgec_disable_interrupt(p_Tgec->p_MemMap, bitMask);
24012 +
24013 + return E_OK;
24014 +}
24015 +
24016 +/* ......................................................................... */
24017 +
24018 +static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
24019 +{
24020 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
24021 +
24022 + SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
24023 + SANITY_CHECK_RETURN_VALUE(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE, 0);
24024 +
24025 + return fman_tgec_get_max_frame_len(p_Tgec->p_MemMap);
24026 +}
24027 +
24028 +/* ......................................................................... */
24029 +
24030 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
24031 +static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
24032 +{
24033 + t_Error err;
24034 +
24035 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
24036 + XX_Print("Applying 10G TX ECC workaround (10GMAC-A004) ... ");
24037 +#endif /* (DEBUG_ERRORS > 0) */
24038 + /* enable and set promiscuous */
24039 + fman_tgec_enable(p_Tgec->p_MemMap, TRUE, TRUE);
24040 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, TRUE);
24041 + err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
24042 + /* disable */
24043 + fman_tgec_set_promiscuous(p_Tgec->p_MemMap, FALSE);
24044 + fman_tgec_enable(p_Tgec->p_MemMap, FALSE, FALSE);
24045 + fman_tgec_reset_stat(p_Tgec->p_MemMap);
24046 + fman_tgec_ack_event(p_Tgec->p_MemMap, 0xffffffff);
24047 +#if defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)
24048 + if (err)
24049 + XX_Print("FAILED!\n");
24050 + else
24051 + XX_Print("done.\n");
24052 +#endif /* (DEBUG_ERRORS > 0) */
24053 +
24054 + return err;
24055 +}
24056 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
24057 +
24058 +/*****************************************************************************/
24059 +/* FM Init & Free API */
24060 +/*****************************************************************************/
24061 +
24062 +/* ......................................................................... */
24063 +
24064 +static t_Error TgecInit(t_Handle h_Tgec)
24065 +{
24066 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
24067 + struct tgec_cfg *p_TgecDriverParam;
24068 + t_EnetAddr ethAddr;
24069 + t_Error err;
24070 +
24071 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
24072 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
24073 + SANITY_CHECK_RETURN_ERROR(p_Tgec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
24074 +
24075 + FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &p_Tgec->fmMacControllerDriver.fmRevInfo);
24076 + CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
24077 +
24078 + p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
24079 +
24080 + MAKE_ENET_ADDR_FROM_UINT64(p_Tgec->addr, ethAddr);
24081 + fman_tgec_set_mac_address(p_Tgec->p_MemMap, (uint8_t *)ethAddr);
24082 +
24083 + /* interrupts */
24084 +#ifdef FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
24085 + {
24086 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev <=2)
24087 + p_Tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT | TGEC_IMASK_LOC_FAULT);
24088 + }
24089 +#endif /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 */
24090 +
24091 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
24092 + if (!p_Tgec->p_TgecDriverParam->skip_fman11_workaround &&
24093 + ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
24094 + {
24095 + FreeInitResources(p_Tgec);
24096 + REPORT_ERROR(MINOR, err, ("TgecTxEccWorkaround FAILED"));
24097 + }
24098 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
24099 +
24100 + err = fman_tgec_init(p_Tgec->p_MemMap, p_TgecDriverParam, p_Tgec->exceptions);
24101 + if (err)
24102 + {
24103 + FreeInitResources(p_Tgec);
24104 + RETURN_ERROR(MAJOR, err, ("This TGEC version does not support the required i/f mode"));
24105 + }
24106 +
24107 + /* Max Frame Length */
24108 + err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm,
24109 + e_FM_MAC_10G,
24110 + p_Tgec->fmMacControllerDriver.macId,
24111 + p_TgecDriverParam->max_frame_length);
24112 + if (err != E_OK)
24113 + {
24114 + FreeInitResources(p_Tgec);
24115 + RETURN_ERROR(MINOR, err, NO_MSG);
24116 + }
24117 +/* we consider having no IPC a non crasher... */
24118 +
24119 +#ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
24120 + if (p_Tgec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
24121 + fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(p_Tgec->p_MemMap);
24122 +#endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
24123 +
24124 + p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
24125 + if (!p_Tgec->p_MulticastAddrHash)
24126 + {
24127 + FreeInitResources(p_Tgec);
24128 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
24129 + }
24130 +
24131 + p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
24132 + if (!p_Tgec->p_UnicastAddrHash)
24133 + {
24134 + FreeInitResources(p_Tgec);
24135 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
24136 + }
24137 +
24138 + FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm,
24139 + e_FM_MOD_10G_MAC,
24140 + p_Tgec->macId,
24141 + e_FM_INTR_TYPE_ERR,
24142 + TgecErrException,
24143 + p_Tgec);
24144 + if (p_Tgec->mdioIrq != NO_IRQ)
24145 + {
24146 + XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
24147 + XX_EnableIntr(p_Tgec->mdioIrq);
24148 + }
24149 +
24150 + XX_Free(p_TgecDriverParam);
24151 + p_Tgec->p_TgecDriverParam = NULL;
24152 +
24153 + return E_OK;
24154 +}
24155 +
24156 +/* ......................................................................... */
24157 +
24158 +static t_Error TgecFree(t_Handle h_Tgec)
24159 +{
24160 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
24161 +
24162 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
24163 +
24164 + if (p_Tgec->p_TgecDriverParam)
24165 + {
24166 + /* Called after config */
24167 + XX_Free(p_Tgec->p_TgecDriverParam);
24168 + p_Tgec->p_TgecDriverParam = NULL;
24169 + }
24170 + else
24171 + /* Called after init */
24172 + FreeInitResources(p_Tgec);
24173 +
24174 + XX_Free(p_Tgec);
24175 +
24176 + return E_OK;
24177 +}
24178 +
24179 +/* ......................................................................... */
24180 +
24181 +static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
24182 +{
24183 + p_FmMacControllerDriver->f_FM_MAC_Init = TgecInit;
24184 + p_FmMacControllerDriver->f_FM_MAC_Free = TgecFree;
24185 +
24186 + p_FmMacControllerDriver->f_FM_MAC_SetStatistics = NULL;
24187 + p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = TgecConfigLoopback;
24188 + p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = TgecConfigMaxFrameLength;
24189 +
24190 + p_FmMacControllerDriver->f_FM_MAC_ConfigWan = TgecConfigWan;
24191 +
24192 + p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = NULL; /* TGEC always works with pad+crc */
24193 + p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = NULL; /* half-duplex is not supported in xgec */
24194 + p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = TgecConfigLengthCheck;
24195 + p_FmMacControllerDriver->f_FM_MAC_ConfigException = TgecConfigException;
24196 + p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit = NULL;
24197 +
24198 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
24199 + p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
24200 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
24201 +
24202 + p_FmMacControllerDriver->f_FM_MAC_SetException = TgecSetExcpetion;
24203 +
24204 + p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = TgecEnable1588TimeStamp;
24205 + p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = TgecDisable1588TimeStamp;
24206 +
24207 + p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = TgecSetPromiscuous;
24208 + p_FmMacControllerDriver->f_FM_MAC_AdjustLink = NULL;
24209 + p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan = NULL;
24210 + p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg = NULL;
24211 +
24212 + p_FmMacControllerDriver->f_FM_MAC_Enable = TgecEnable;
24213 + p_FmMacControllerDriver->f_FM_MAC_Disable = TgecDisable;
24214 + p_FmMacControllerDriver->f_FM_MAC_Resume = NULL;
24215 +
24216 + p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = TgecTxMacPause;
24217 + p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames = TgecSetTxPauseFrames;
24218 + p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = TgecRxIgnoreMacPause;
24219 +
24220 + p_FmMacControllerDriver->f_FM_MAC_ResetCounters = TgecResetCounters;
24221 + p_FmMacControllerDriver->f_FM_MAC_GetStatistics = TgecGetStatistics;
24222 + p_FmMacControllerDriver->f_FM_MAC_GetFrameSizeCounters = TgecGetFrameSizeCounters;
24223 +
24224 + p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = TgecModifyMacAddress;
24225 + p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = TgecAddHashMacAddress;
24226 + p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = TgecDelHashMacAddress;
24227 + p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = TgecAddExactMatchMacAddress;
24228 + p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = TgecDelExactMatchMacAddress;
24229 + p_FmMacControllerDriver->f_FM_MAC_GetId = TgecGetId;
24230 + p_FmMacControllerDriver->f_FM_MAC_GetVersion = TgecGetVersion;
24231 + p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = TgecGetMaxFrameLength;
24232 +
24233 + p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = TGEC_MII_WritePhyReg;
24234 + p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = TGEC_MII_ReadPhyReg;
24235 +}
24236 +
24237 +
24238 +/*****************************************************************************/
24239 +/* Tgec Config Main Entry */
24240 +/*****************************************************************************/
24241 +
24242 +/* ......................................................................... */
24243 +
24244 +t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
24245 +{
24246 + t_Tgec *p_Tgec;
24247 + struct tgec_cfg *p_TgecDriverParam;
24248 + uintptr_t baseAddr;
24249 +
24250 + SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
24251 +
24252 + baseAddr = p_FmMacParam->baseAddr;
24253 + /* allocate memory for the UCC GETH data structure. */
24254 + p_Tgec = (t_Tgec *)XX_Malloc(sizeof(t_Tgec));
24255 + if (!p_Tgec)
24256 + {
24257 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
24258 + return NULL;
24259 + }
24260 + memset(p_Tgec, 0, sizeof(t_Tgec));
24261 + InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
24262 +
24263 + /* allocate memory for the 10G MAC driver parameters data structure. */
24264 + p_TgecDriverParam = (struct tgec_cfg *) XX_Malloc(sizeof(struct tgec_cfg));
24265 + if (!p_TgecDriverParam)
24266 + {
24267 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
24268 + XX_Free(p_Tgec);
24269 + return NULL;
24270 + }
24271 + memset(p_TgecDriverParam, 0, sizeof(struct tgec_cfg));
24272 +
24273 + /* Plant parameter structure pointer */
24274 + p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
24275 +
24276 + fman_tgec_defconfig(p_TgecDriverParam);
24277 +
24278 + p_Tgec->p_MemMap = (struct tgec_regs *)UINT_TO_PTR(baseAddr);
24279 + p_Tgec->p_MiiMemMap = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
24280 + p_Tgec->addr = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
24281 + p_Tgec->enetMode = p_FmMacParam->enetMode;
24282 + p_Tgec->macId = p_FmMacParam->macId;
24283 + p_Tgec->exceptions = DEFAULT_exceptions;
24284 + p_Tgec->mdioIrq = p_FmMacParam->mdioIrq;
24285 + p_Tgec->f_Exception = p_FmMacParam->f_Exception;
24286 + p_Tgec->f_Event = p_FmMacParam->f_Event;
24287 + p_Tgec->h_App = p_FmMacParam->h_App;
24288 +
24289 + return p_Tgec;
24290 +}
24291 --- /dev/null
24292 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec.h
24293 @@ -0,0 +1,151 @@
24294 +/*
24295 + * Copyright 2008-2012 Freescale Semiconductor Inc.
24296 + *
24297 + * Redistribution and use in source and binary forms, with or without
24298 + * modification, are permitted provided that the following conditions are met:
24299 + * * Redistributions of source code must retain the above copyright
24300 + * notice, this list of conditions and the following disclaimer.
24301 + * * Redistributions in binary form must reproduce the above copyright
24302 + * notice, this list of conditions and the following disclaimer in the
24303 + * documentation and/or other materials provided with the distribution.
24304 + * * Neither the name of Freescale Semiconductor nor the
24305 + * names of its contributors may be used to endorse or promote products
24306 + * derived from this software without specific prior written permission.
24307 + *
24308 + *
24309 + * ALTERNATIVELY, this software may be distributed under the terms of the
24310 + * GNU General Public License ("GPL") as published by the Free Software
24311 + * Foundation, either version 2 of that License or (at your option) any
24312 + * later version.
24313 + *
24314 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24315 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24316 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24317 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24318 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24319 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24320 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24321 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24322 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24323 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24324 + */
24325 +
24326 +
24327 +/******************************************************************************
24328 + @File tgec.h
24329 +
24330 + @Description FM 10G MAC ...
24331 +*//***************************************************************************/
24332 +#ifndef __TGEC_H
24333 +#define __TGEC_H
24334 +
24335 +#include "std_ext.h"
24336 +#include "error_ext.h"
24337 +#include "list_ext.h"
24338 +#include "enet_ext.h"
24339 +
24340 +#include "tgec_mii_acc.h"
24341 +#include "fm_mac.h"
24342 +
24343 +
24344 +#define DEFAULT_exceptions \
24345 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
24346 + TGEC_IMASK_REM_FAULT | \
24347 + TGEC_IMASK_LOC_FAULT | \
24348 + TGEC_IMASK_TX_ECC_ER | \
24349 + TGEC_IMASK_TX_FIFO_UNFL | \
24350 + TGEC_IMASK_TX_FIFO_OVFL | \
24351 + TGEC_IMASK_TX_ER | \
24352 + TGEC_IMASK_RX_FIFO_OVFL | \
24353 + TGEC_IMASK_RX_ECC_ER | \
24354 + TGEC_IMASK_RX_JAB_FRM | \
24355 + TGEC_IMASK_RX_OVRSZ_FRM | \
24356 + TGEC_IMASK_RX_RUNT_FRM | \
24357 + TGEC_IMASK_RX_FRAG_FRM | \
24358 + TGEC_IMASK_RX_CRC_ER | \
24359 + TGEC_IMASK_RX_ALIGN_ER))
24360 +
24361 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
24362 + case e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO: \
24363 + bitMask = TGEC_IMASK_MDIO_SCAN_EVENT ; break; \
24364 + case e_FM_MAC_EX_10G_MDIO_CMD_CMPL: \
24365 + bitMask = TGEC_IMASK_MDIO_CMD_CMPL ; break; \
24366 + case e_FM_MAC_EX_10G_REM_FAULT: \
24367 + bitMask = TGEC_IMASK_REM_FAULT ; break; \
24368 + case e_FM_MAC_EX_10G_LOC_FAULT: \
24369 + bitMask = TGEC_IMASK_LOC_FAULT ; break; \
24370 + case e_FM_MAC_EX_10G_1TX_ECC_ER: \
24371 + bitMask = TGEC_IMASK_TX_ECC_ER ; break; \
24372 + case e_FM_MAC_EX_10G_TX_FIFO_UNFL: \
24373 + bitMask = TGEC_IMASK_TX_FIFO_UNFL ; break; \
24374 + case e_FM_MAC_EX_10G_TX_FIFO_OVFL: \
24375 + bitMask = TGEC_IMASK_TX_FIFO_OVFL ; break; \
24376 + case e_FM_MAC_EX_10G_TX_ER: \
24377 + bitMask = TGEC_IMASK_TX_ER ; break; \
24378 + case e_FM_MAC_EX_10G_RX_FIFO_OVFL: \
24379 + bitMask = TGEC_IMASK_RX_FIFO_OVFL ; break; \
24380 + case e_FM_MAC_EX_10G_RX_ECC_ER: \
24381 + bitMask = TGEC_IMASK_RX_ECC_ER ; break; \
24382 + case e_FM_MAC_EX_10G_RX_JAB_FRM: \
24383 + bitMask = TGEC_IMASK_RX_JAB_FRM ; break; \
24384 + case e_FM_MAC_EX_10G_RX_OVRSZ_FRM: \
24385 + bitMask = TGEC_IMASK_RX_OVRSZ_FRM ; break; \
24386 + case e_FM_MAC_EX_10G_RX_RUNT_FRM: \
24387 + bitMask = TGEC_IMASK_RX_RUNT_FRM ; break; \
24388 + case e_FM_MAC_EX_10G_RX_FRAG_FRM: \
24389 + bitMask = TGEC_IMASK_RX_FRAG_FRM ; break; \
24390 + case e_FM_MAC_EX_10G_RX_LEN_ER: \
24391 + bitMask = TGEC_IMASK_RX_LEN_ER ; break; \
24392 + case e_FM_MAC_EX_10G_RX_CRC_ER: \
24393 + bitMask = TGEC_IMASK_RX_CRC_ER ; break; \
24394 + case e_FM_MAC_EX_10G_RX_ALIGN_ER: \
24395 + bitMask = TGEC_IMASK_RX_ALIGN_ER ; break; \
24396 + default: bitMask = 0;break;}
24397 +
24398 +#define MAX_PACKET_ALIGNMENT 31
24399 +#define MAX_INTER_PACKET_GAP 0x7f
24400 +#define MAX_INTER_PALTERNATE_BEB 0x0f
24401 +#define MAX_RETRANSMISSION 0x0f
24402 +#define MAX_COLLISION_WINDOW 0x03ff
24403 +
24404 +#define TGEC_NUM_OF_PADDRS 1 /* number of pattern match registers (entries) */
24405 +
24406 +#define GROUP_ADDRESS 0x0000010000000000LL /* Group address bit indication */
24407 +
24408 +#define HASH_TABLE_SIZE 512 /* Hash table size (= 32 bits * 8 regs) */
24409 +
24410 +#define TGEC_TO_MII_OFFSET 0x1030 /* Offset from the MEM map to the MDIO mem map */
24411 +
24412 +/* 10-gigabit Ethernet MAC Controller ID (10GEC_ID) */
24413 +#define TGEC_ID_ID 0xffff0000
24414 +#define TGEC_ID_MAC_VERSION 0x0000FF00
24415 +#define TGEC_ID_MAC_REV 0x000000ff
24416 +
24417 +
24418 +typedef struct {
24419 + t_FmMacControllerDriver fmMacControllerDriver; /**< Upper Mac control block */
24420 + t_Handle h_App; /**< Handle to the upper layer application */
24421 + struct tgec_regs *p_MemMap; /**< pointer to 10G memory mapped registers. */
24422 + t_TgecMiiAccessMemMap *p_MiiMemMap; /**< pointer to MII memory mapped registers. */
24423 + uint64_t addr; /**< MAC address of device; */
24424 + e_EnetMode enetMode; /**< Ethernet physical interface */
24425 + t_FmMacExceptionCallback *f_Exception;
24426 + int mdioIrq;
24427 + t_FmMacExceptionCallback *f_Event;
24428 + bool indAddrRegUsed[TGEC_NUM_OF_PADDRS]; /**< Whether a particular individual address recognition register is being used */
24429 + uint64_t paddr[TGEC_NUM_OF_PADDRS]; /**< MAC address for particular individual address recognition register */
24430 + uint8_t numOfIndAddrInRegs; /**< Number of individual addresses in registers for this station. */
24431 + t_EthHash *p_MulticastAddrHash; /**< pointer to driver's global address hash table */
24432 + t_EthHash *p_UnicastAddrHash; /**< pointer to driver's individual address hash table */
24433 + bool debugMode;
24434 + uint8_t macId;
24435 + uint32_t exceptions;
24436 + struct tgec_cfg *p_TgecDriverParam;
24437 +} t_Tgec;
24438 +
24439 +
24440 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t data);
24441 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
24442 +
24443 +
24444 +#endif /* __TGEC_H */
24445 --- /dev/null
24446 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.c
24447 @@ -0,0 +1,139 @@
24448 +/*
24449 + * Copyright 2008-2012 Freescale Semiconductor Inc.
24450 + *
24451 + * Redistribution and use in source and binary forms, with or without
24452 + * modification, are permitted provided that the following conditions are met:
24453 + * * Redistributions of source code must retain the above copyright
24454 + * notice, this list of conditions and the following disclaimer.
24455 + * * Redistributions in binary form must reproduce the above copyright
24456 + * notice, this list of conditions and the following disclaimer in the
24457 + * documentation and/or other materials provided with the distribution.
24458 + * * Neither the name of Freescale Semiconductor nor the
24459 + * names of its contributors may be used to endorse or promote products
24460 + * derived from this software without specific prior written permission.
24461 + *
24462 + *
24463 + * ALTERNATIVELY, this software may be distributed under the terms of the
24464 + * GNU General Public License ("GPL") as published by the Free Software
24465 + * Foundation, either version 2 of that License or (at your option) any
24466 + * later version.
24467 + *
24468 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24469 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24470 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24471 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24472 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24473 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24474 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24475 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24476 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24477 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24478 + */
24479 +
24480 +
24481 +
24482 +#include "error_ext.h"
24483 +#include "std_ext.h"
24484 +#include "fm_mac.h"
24485 +#include "tgec.h"
24486 +#include "xx_ext.h"
24487 +
24488 +#include "fm_common.h"
24489 +
24490 +
24491 +/*****************************************************************************/
24492 +t_Error TGEC_MII_WritePhyReg(t_Handle h_Tgec,
24493 + uint8_t phyAddr,
24494 + uint8_t reg,
24495 + uint16_t data)
24496 +{
24497 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
24498 + t_TgecMiiAccessMemMap *p_MiiAccess;
24499 + uint32_t cfgStatusReg;
24500 +
24501 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
24502 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
24503 +
24504 + p_MiiAccess = p_Tgec->p_MiiMemMap;
24505 +
24506 + /* Configure MII */
24507 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
24508 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
24509 + /* (one half of fm clock => 2.5Mhz) */
24510 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
24511 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
24512 +
24513 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
24514 + XX_UDelay (1);
24515 +
24516 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
24517 +
24518 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
24519 +
24520 + CORE_MemoryBarrier();
24521 +
24522 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
24523 + XX_UDelay (1);
24524 +
24525 + WRITE_UINT32(p_MiiAccess->mdio_data, data);
24526 +
24527 + CORE_MemoryBarrier();
24528 +
24529 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
24530 + XX_UDelay (1);
24531 +
24532 + return E_OK;
24533 +}
24534 +
24535 +/*****************************************************************************/
24536 +t_Error TGEC_MII_ReadPhyReg(t_Handle h_Tgec,
24537 + uint8_t phyAddr,
24538 + uint8_t reg,
24539 + uint16_t *p_Data)
24540 +{
24541 + t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
24542 + t_TgecMiiAccessMemMap *p_MiiAccess;
24543 + uint32_t cfgStatusReg;
24544 +
24545 + SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
24546 + SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MiiMemMap, E_INVALID_HANDLE);
24547 +
24548 + p_MiiAccess = p_Tgec->p_MiiMemMap;
24549 +
24550 + /* Configure MII */
24551 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
24552 + cfgStatusReg &= ~MIIMCOM_DIV_MASK;
24553 + /* (one half of fm clock => 2.5Mhz) */
24554 + cfgStatusReg |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
24555 + WRITE_UINT32(p_MiiAccess->mdio_cfg_status, cfgStatusReg);
24556 +
24557 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
24558 + XX_UDelay (1);
24559 +
24560 + WRITE_UINT32(p_MiiAccess->mdio_command, phyAddr);
24561 +
24562 + WRITE_UINT32(p_MiiAccess->mdio_regaddr, reg);
24563 +
24564 + CORE_MemoryBarrier();
24565 +
24566 + while ((GET_UINT32(p_MiiAccess->mdio_cfg_status)) & MIIMIND_BUSY)
24567 + XX_UDelay (1);
24568 +
24569 + WRITE_UINT32(p_MiiAccess->mdio_command, (uint32_t)(phyAddr | MIIMCOM_READ_CYCLE));
24570 +
24571 + CORE_MemoryBarrier();
24572 +
24573 + while ((GET_UINT32(p_MiiAccess->mdio_data)) & MIIDATA_BUSY)
24574 + XX_UDelay (1);
24575 +
24576 + *p_Data = (uint16_t)GET_UINT32(p_MiiAccess->mdio_data);
24577 +
24578 + cfgStatusReg = GET_UINT32(p_MiiAccess->mdio_cfg_status);
24579 +
24580 + if (cfgStatusReg & MIIMIND_READ_ERROR)
24581 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
24582 + ("Read Error: phyAddr 0x%x, dev 0x%x, reg 0x%x, cfgStatusReg 0x%x",
24583 + ((phyAddr & 0xe0)>>5), (phyAddr & 0x1f), reg, cfgStatusReg));
24584 +
24585 + return E_OK;
24586 +}
24587 --- /dev/null
24588 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MAC/tgec_mii_acc.h
24589 @@ -0,0 +1,80 @@
24590 +/*
24591 + * Copyright 2008-2012 Freescale Semiconductor Inc.
24592 + *
24593 + * Redistribution and use in source and binary forms, with or without
24594 + * modification, are permitted provided that the following conditions are met:
24595 + * * Redistributions of source code must retain the above copyright
24596 + * notice, this list of conditions and the following disclaimer.
24597 + * * Redistributions in binary form must reproduce the above copyright
24598 + * notice, this list of conditions and the following disclaimer in the
24599 + * documentation and/or other materials provided with the distribution.
24600 + * * Neither the name of Freescale Semiconductor nor the
24601 + * names of its contributors may be used to endorse or promote products
24602 + * derived from this software without specific prior written permission.
24603 + *
24604 + *
24605 + * ALTERNATIVELY, this software may be distributed under the terms of the
24606 + * GNU General Public License ("GPL") as published by the Free Software
24607 + * Foundation, either version 2 of that License or (at your option) any
24608 + * later version.
24609 + *
24610 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24611 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24612 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24613 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24614 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24615 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24616 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24617 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24618 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24619 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24620 + */
24621 +
24622 +
24623 +#ifndef __TGEC_MII_ACC_H
24624 +#define __TGEC_MII_ACC_H
24625 +
24626 +#include "std_ext.h"
24627 +
24628 +
24629 +/* MII Management Command Register */
24630 +#define MIIMCOM_READ_POST_INCREMENT 0x00004000
24631 +#define MIIMCOM_READ_CYCLE 0x00008000
24632 +#define MIIMCOM_SCAN_CYCLE 0x00000800
24633 +#define MIIMCOM_PREAMBLE_DISABLE 0x00000400
24634 +
24635 +#define MIIMCOM_MDIO_HOLD_1_REG_CLK 0
24636 +#define MIIMCOM_MDIO_HOLD_2_REG_CLK 1
24637 +#define MIIMCOM_MDIO_HOLD_3_REG_CLK 2
24638 +#define MIIMCOM_MDIO_HOLD_4_REG_CLK 3
24639 +
24640 +#define MIIMCOM_DIV_MASK 0x0000ff00
24641 +#define MIIMCOM_DIV_SHIFT 8
24642 +
24643 +/* MII Management Indicator Register */
24644 +#define MIIMIND_BUSY 0x00000001
24645 +#define MIIMIND_READ_ERROR 0x00000002
24646 +
24647 +#define MIIDATA_BUSY 0x80000000
24648 +
24649 +#if defined(__MWERKS__) && !defined(__GNUC__)
24650 +#pragma pack(push,1)
24651 +#endif /* defined(__MWERKS__) && ... */
24652 +
24653 +/*----------------------------------------------------*/
24654 +/* MII Configuration Control Memory Map Registers */
24655 +/*----------------------------------------------------*/
24656 +typedef _Packed struct t_TgecMiiAccessMemMap
24657 +{
24658 + volatile uint32_t mdio_cfg_status; /* 0x030 */
24659 + volatile uint32_t mdio_command; /* 0x034 */
24660 + volatile uint32_t mdio_data; /* 0x038 */
24661 + volatile uint32_t mdio_regaddr; /* 0x03c */
24662 +} _PackedType t_TgecMiiAccessMemMap ;
24663 +
24664 +#if defined(__MWERKS__) && !defined(__GNUC__)
24665 +#pragma pack(pop)
24666 +#endif /* defined(__MWERKS__) && ... */
24667 +
24668 +
24669 +#endif /* __TGEC_MII_ACC_H */
24670 --- /dev/null
24671 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/Makefile
24672 @@ -0,0 +1,15 @@
24673 +#
24674 +# Makefile for the Freescale Ethernet controllers
24675 +#
24676 +ccflags-y += -DVERSION=\"\"
24677 +#
24678 +#Include netcomm SW specific definitions
24679 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
24680 +
24681 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
24682 +
24683 +ccflags-y += -I$(NCSW_FM_INC)
24684 +
24685 +obj-y += fsl-ncsw-macsec.o
24686 +
24687 +fsl-ncsw-macsec-objs := fm_macsec.o fm_macsec_guest.o fm_macsec_master.o fm_macsec_secy.o
24688 --- /dev/null
24689 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.c
24690 @@ -0,0 +1,237 @@
24691 +/*
24692 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24693 + *
24694 + * Redistribution and use in source and binary forms, with or without
24695 + * modification, are permitted provided that the following conditions are met:
24696 + * * Redistributions of source code must retain the above copyright
24697 + * notice, this list of conditions and the following disclaimer.
24698 + * * Redistributions in binary form must reproduce the above copyright
24699 + * notice, this list of conditions and the following disclaimer in the
24700 + * documentation and/or other materials provided with the distribution.
24701 + * * Neither the name of Freescale Semiconductor nor the
24702 + * names of its contributors may be used to endorse or promote products
24703 + * derived from this software without specific prior written permission.
24704 + *
24705 + *
24706 + * ALTERNATIVELY, this software may be distributed under the terms of the
24707 + * GNU General Public License ("GPL") as published by the Free Software
24708 + * Foundation, either version 2 of that License or (at your option) any
24709 + * later version.
24710 + *
24711 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24712 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24713 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24714 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24715 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24716 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24717 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24718 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24719 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24720 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24721 + */
24722 +/******************************************************************************
24723 +
24724 + @File fm_macsec.c
24725 +
24726 + @Description FM MACSEC driver routines implementation.
24727 +*//***************************************************************************/
24728 +
24729 +#include "std_ext.h"
24730 +#include "error_ext.h"
24731 +#include "xx_ext.h"
24732 +#include "string_ext.h"
24733 +#include "sprint_ext.h"
24734 +#include "debug_ext.h"
24735 +
24736 +#include "fm_macsec.h"
24737 +
24738 +
24739 +/****************************************/
24740 +/* API Init unit functions */
24741 +/****************************************/
24742 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam)
24743 +{
24744 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver;
24745 +
24746 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecParam, E_INVALID_HANDLE, NULL);
24747 +
24748 + if (p_FmMacsecParam->guestMode)
24749 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_GUEST_Config(p_FmMacsecParam);
24750 + else
24751 + p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)FM_MACSEC_MASTER_Config(p_FmMacsecParam);
24752 +
24753 + if (!p_FmMacsecControllerDriver)
24754 + return NULL;
24755 +
24756 + return (t_Handle)p_FmMacsecControllerDriver;
24757 +}
24758 +
24759 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec)
24760 +{
24761 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24762 +
24763 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24764 +
24765 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Init)
24766 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Init(h_FmMacsec);
24767 +
24768 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24769 +}
24770 +
24771 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec)
24772 +{
24773 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24774 +
24775 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24776 +
24777 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Free)
24778 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Free(h_FmMacsec);
24779 +
24780 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24781 +}
24782 +
24783 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
24784 +{
24785 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24786 +
24787 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24788 +
24789 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment)
24790 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment(h_FmMacsec, treatMode);
24791 +
24792 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24793 +}
24794 +
24795 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
24796 +{
24797 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24798 +
24799 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24800 +
24801 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment)
24802 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment(h_FmMacsec, deliverUncontrolled);
24803 +
24804 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24805 +}
24806 +
24807 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
24808 +{
24809 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24810 +
24811 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24812 +
24813 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment)
24814 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(h_FmMacsec, discardUncontrolled);
24815 +
24816 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24817 +}
24818 +
24819 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
24820 +{
24821 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24822 +
24823 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24824 +
24825 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment)
24826 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment(h_FmMacsec, treatMode);
24827 +
24828 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24829 +}
24830 +
24831 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
24832 +{
24833 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24834 +
24835 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24836 +
24837 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold)
24838 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold(h_FmMacsec, pnExhThr);
24839 +
24840 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24841 +}
24842 +
24843 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec)
24844 +{
24845 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24846 +
24847 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24848 +
24849 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable)
24850 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable(h_FmMacsec);
24851 +
24852 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24853 +}
24854 +
24855 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec)
24856 +{
24857 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24858 +
24859 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24860 +
24861 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI)
24862 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI(h_FmMacsec);
24863 +
24864 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24865 +}
24866 +
24867 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
24868 +{
24869 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24870 +
24871 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24872 +
24873 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException)
24874 + return p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException(h_FmMacsec, exception, enable);
24875 +
24876 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24877 +}
24878 +
24879 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
24880 +{
24881 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24882 +
24883 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24884 +
24885 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision)
24886 + return p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision(h_FmMacsec, p_MacsecRevision);
24887 +
24888 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24889 +}
24890 +
24891 +
24892 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec)
24893 +{
24894 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24895 +
24896 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24897 +
24898 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Enable)
24899 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Enable(h_FmMacsec);
24900 +
24901 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24902 +}
24903 +
24904 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec)
24905 +{
24906 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24907 +
24908 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24909 +
24910 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_Disable)
24911 + return p_FmMacsecControllerDriver->f_FM_MACSEC_Disable(h_FmMacsec);
24912 +
24913 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24914 +}
24915 +
24916 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
24917 +{
24918 + t_FmMacsecControllerDriver *p_FmMacsecControllerDriver = (t_FmMacsecControllerDriver *)h_FmMacsec;
24919 +
24920 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecControllerDriver, E_INVALID_HANDLE);
24921 +
24922 + if (p_FmMacsecControllerDriver->f_FM_MACSEC_SetException)
24923 + return p_FmMacsecControllerDriver->f_FM_MACSEC_SetException(h_FmMacsec, exception, enable);
24924 +
24925 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
24926 +}
24927 +
24928 --- /dev/null
24929 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec.h
24930 @@ -0,0 +1,203 @@
24931 +/*
24932 + * Copyright 2008-2015 Freescale Semiconductor Inc.
24933 + *
24934 + * Redistribution and use in source and binary forms, with or without
24935 + * modification, are permitted provided that the following conditions are met:
24936 + * * Redistributions of source code must retain the above copyright
24937 + * notice, this list of conditions and the following disclaimer.
24938 + * * Redistributions in binary form must reproduce the above copyright
24939 + * notice, this list of conditions and the following disclaimer in the
24940 + * documentation and/or other materials provided with the distribution.
24941 + * * Neither the name of Freescale Semiconductor nor the
24942 + * names of its contributors may be used to endorse or promote products
24943 + * derived from this software without specific prior written permission.
24944 + *
24945 + *
24946 + * ALTERNATIVELY, this software may be distributed under the terms of the
24947 + * GNU General Public License ("GPL") as published by the Free Software
24948 + * Foundation, either version 2 of that License or (at your option) any
24949 + * later version.
24950 + *
24951 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24952 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24953 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24954 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
24955 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24956 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24957 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24958 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24959 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24960 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24961 + */
24962 +
24963 +/******************************************************************************
24964 + @File fm_macsec.h
24965 +
24966 + @Description FM MACSEC internal structures and definitions.
24967 +*//***************************************************************************/
24968 +#ifndef __FM_MACSEC_H
24969 +#define __FM_MACSEC_H
24970 +
24971 +#include "error_ext.h"
24972 +#include "std_ext.h"
24973 +#include "fm_macsec_ext.h"
24974 +
24975 +#include "fm_common.h"
24976 +
24977 +
24978 +#define __ERR_MODULE__ MODULE_FM_MACSEC
24979 +
24980 +
24981 +typedef struct
24982 +{
24983 + t_Error (*f_FM_MACSEC_Init) (t_Handle h_FmMacsec);
24984 + t_Error (*f_FM_MACSEC_Free) (t_Handle h_FmMacsec);
24985 +
24986 + t_Error (*f_FM_MACSEC_ConfigUnknownSciFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
24987 + t_Error (*f_FM_MACSEC_ConfigInvalidTagsFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
24988 + t_Error (*f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment) (t_Handle h_FmMacsec, bool discardUncontrolled);
24989 + t_Error (*f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
24990 + t_Error (*f_FM_MACSEC_ConfigUntagFrameTreatment) (t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
24991 + t_Error (*f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment) (t_Handle h_FmMacsec, bool deliverUncontrolled);
24992 + t_Error (*f_FM_MACSEC_ConfigPnExhaustionThreshold) (t_Handle h_FmMacsec, uint32_t pnExhThr);
24993 + t_Error (*f_FM_MACSEC_ConfigKeysUnreadable) (t_Handle h_FmMacsec);
24994 + t_Error (*f_FM_MACSEC_ConfigSectagWithoutSCI) (t_Handle h_FmMacsec);
24995 + t_Error (*f_FM_MACSEC_ConfigException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
24996 +
24997 + t_Error (*f_FM_MACSEC_GetRevision) (t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
24998 + t_Error (*f_FM_MACSEC_Enable) (t_Handle h_FmMacsec);
24999 + t_Error (*f_FM_MACSEC_Disable) (t_Handle h_FmMacsec);
25000 + t_Error (*f_FM_MACSEC_SetException) (t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
25001 +
25002 +} t_FmMacsecControllerDriver;
25003 +
25004 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam);
25005 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParams);
25006 +
25007 +/***********************************************************************/
25008 +/* MACSEC internal routines */
25009 +/***********************************************************************/
25010 +
25011 +/**************************************************************************//**
25012 +
25013 + @Group FM_MACSEC_InterModule_grp FM MACSEC Inter-Module Unit
25014 +
25015 + @Description FM MACSEC Inter Module functions -
25016 + These are not User API routines but routines that may be called
25017 + from other modules. This will be the case in a single core environment,
25018 + where instead of using the XX messaging mechanism, the routines may be
25019 + called from other modules. In a multicore environment, the other modules may
25020 + be run by other cores and therefore these routines may not be called directly.
25021 +
25022 + @{
25023 +*//***************************************************************************/
25024 +
25025 +#define MAX_NUM_OF_SA_PER_SC 4
25026 +
25027 +typedef enum
25028 +{
25029 + e_SC_RX = 0,
25030 + e_SC_TX
25031 +} e_ScType;
25032 +
25033 +typedef enum
25034 +{
25035 + e_SC_SA_A = 0,
25036 + e_SC_SA_B ,
25037 + e_SC_SA_C ,
25038 + e_SC_SA_D
25039 +} e_ScSaId;
25040 +
25041 +typedef struct
25042 +{
25043 + uint32_t scId;
25044 + macsecSCI_t sci;
25045 + bool replayProtect;
25046 + uint32_t replayWindow;
25047 + e_FmMacsecValidFrameBehavior validateFrames;
25048 + uint16_t confidentialityOffset;
25049 + e_FmMacsecSecYCipherSuite cipherSuite;
25050 +} t_RxScParams;
25051 +
25052 +typedef struct
25053 +{
25054 + uint32_t scId;
25055 + macsecSCI_t sci;
25056 + bool protectFrames;
25057 + e_FmMacsecSciInsertionMode sciInsertionMode;
25058 + bool confidentialityEnable;
25059 + uint16_t confidentialityOffset;
25060 + e_FmMacsecSecYCipherSuite cipherSuite;
25061 +} t_TxScParams;
25062 +
25063 +typedef enum e_FmMacsecGlobalExceptions {
25064 + e_FM_MACSEC_EX_TX_SC, /**< Tx Sc 0 frame discarded error. */
25065 + e_FM_MACSEC_EX_ECC /**< MACSEC memory ECC multiple-bit error. */
25066 +} e_FmMacsecGlobalExceptions;
25067 +
25068 +typedef enum e_FmMacsecGlobalEvents {
25069 + e_FM_MACSEC_EV_TX_SC_NEXT_PN /**< Tx Sc 0 Next Pn exhaustion threshold reached. */
25070 +} e_FmMacsecGlobalEvents;
25071 +
25072 +/**************************************************************************//**
25073 + @Description Enum for inter-module interrupts registration
25074 +*//***************************************************************************/
25075 +typedef enum e_FmMacsecEventModules{
25076 + e_FM_MACSEC_MOD_SC_TX,
25077 + e_FM_MACSEC_MOD_DUMMY_LAST
25078 +} e_FmMacsecEventModules;
25079 +
25080 +typedef enum e_FmMacsecInterModuleEvent {
25081 + e_FM_MACSEC_EV_SC_TX,
25082 + e_FM_MACSEC_EV_ERR_SC_TX,
25083 + e_FM_MACSEC_EV_DUMMY_LAST
25084 +} e_FmMacsecInterModuleEvent;
25085 +
25086 +#define NUM_OF_INTER_MODULE_EVENTS (NUM_OF_TX_SC * 2)
25087 +
25088 +#define GET_MACSEC_MODULE_EVENT(mod, id, intrType, event) \
25089 + switch(mod){ \
25090 + case e_FM_MACSEC_MOD_SC_TX: \
25091 + event = (intrType == e_FM_INTR_TYPE_ERR) ? \
25092 + e_FM_MACSEC_EV_ERR_SC_TX: \
25093 + e_FM_MACSEC_EV_SC_TX; \
25094 + event += (uint8_t)(2 * id);break; \
25095 + break; \
25096 + default:event = e_FM_MACSEC_EV_DUMMY_LAST; \
25097 + break;}
25098 +
25099 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
25100 + e_FmMacsecEventModules module,
25101 + uint8_t modId,
25102 + e_FmIntrType intrType,
25103 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
25104 + t_Handle h_Arg);
25105 +
25106 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
25107 + e_FmMacsecEventModules module,
25108 + uint8_t modId,
25109 + e_FmIntrType intrType);
25110 +
25111 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds);
25112 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds);
25113 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams);
25114 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId);
25115 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_RxScParams);
25116 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId);
25117 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
25118 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key);
25119 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
25120 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId);
25121 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive);
25122 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN);
25123 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN);
25124 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an);
25125 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An);
25126 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable);
25127 +
25128 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable);
25129 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable);
25130 +
25131 +
25132 +
25133 +#endif /* __FM_MACSEC_H */
25134 --- /dev/null
25135 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_guest.c
25136 @@ -0,0 +1,59 @@
25137 +/*
25138 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25139 + *
25140 + * Redistribution and use in source and binary forms, with or without
25141 + * modification, are permitted provided that the following conditions are met:
25142 + * * Redistributions of source code must retain the above copyright
25143 + * notice, this list of conditions and the following disclaimer.
25144 + * * Redistributions in binary form must reproduce the above copyright
25145 + * notice, this list of conditions and the following disclaimer in the
25146 + * documentation and/or other materials provided with the distribution.
25147 + * * Neither the name of Freescale Semiconductor nor the
25148 + * names of its contributors may be used to endorse or promote products
25149 + * derived from this software without specific prior written permission.
25150 + *
25151 + *
25152 + * ALTERNATIVELY, this software may be distributed under the terms of the
25153 + * GNU General Public License ("GPL") as published by the Free Software
25154 + * Foundation, either version 2 of that License or (at your option) any
25155 + * later version.
25156 + *
25157 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25158 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25159 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25160 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25161 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25162 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25163 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25164 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25165 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25166 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25167 + */
25168 +
25169 +/******************************************************************************
25170 + @File fm_macsec.c
25171 +
25172 + @Description FM MACSEC driver routines implementation.
25173 +*//***************************************************************************/
25174 +
25175 +#include "std_ext.h"
25176 +#include "error_ext.h"
25177 +#include "xx_ext.h"
25178 +#include "string_ext.h"
25179 +#include "sprint_ext.h"
25180 +#include "debug_ext.h"
25181 +#include "fm_macsec.h"
25182 +
25183 +
25184 +/****************************************/
25185 +/* static functions */
25186 +/****************************************/
25187 +
25188 +/****************************************/
25189 +/* API Init unit functions */
25190 +/****************************************/
25191 +t_Handle FM_MACSEC_GUEST_Config(t_FmMacsecParams *p_FmMacsecParam)
25192 +{
25193 + UNUSED(p_FmMacsecParam);
25194 + return NULL;
25195 +}
25196 --- /dev/null
25197 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.c
25198 @@ -0,0 +1,1031 @@
25199 +/*
25200 + * Copyright 2008-2015 Freescale Semiconductor Inc.
25201 + *
25202 + * Redistribution and use in source and binary forms, with or without
25203 + * modification, are permitted provided that the following conditions are met:
25204 + * * Redistributions of source code must retain the above copyright
25205 + * notice, this list of conditions and the following disclaimer.
25206 + * * Redistributions in binary form must reproduce the above copyright
25207 + * notice, this list of conditions and the following disclaimer in the
25208 + * documentation and/or other materials provided with the distribution.
25209 + * * Neither the name of Freescale Semiconductor nor the
25210 + * names of its contributors may be used to endorse or promote products
25211 + * derived from this software without specific prior written permission.
25212 + *
25213 + *
25214 + * ALTERNATIVELY, this software may be distributed under the terms of the
25215 + * GNU General Public License ("GPL") as published by the Free Software
25216 + * Foundation, either version 2 of that License or (at your option) any
25217 + * later version.
25218 + *
25219 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
25220 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25221 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25222 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25223 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25224 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25225 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25226 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25227 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25228 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25229 + */
25230 +
25231 +/******************************************************************************
25232 + @File fm_macsec.c
25233 +
25234 + @Description FM MACSEC driver routines implementation.
25235 +*//***************************************************************************/
25236 +
25237 +#include "std_ext.h"
25238 +#include "error_ext.h"
25239 +#include "xx_ext.h"
25240 +#include "string_ext.h"
25241 +#include "sprint_ext.h"
25242 +#include "fm_mac_ext.h"
25243 +
25244 +#include "fm_macsec_master.h"
25245 +
25246 +
25247 +extern uint16_t FM_MAC_GetMaxFrameLength(t_Handle FmMac);
25248 +
25249 +
25250 +/****************************************/
25251 +/* static functions */
25252 +/****************************************/
25253 +static t_Error CheckFmMacsecParameters(t_FmMacsec *p_FmMacsec)
25254 +{
25255 + if (!p_FmMacsec->f_Exception)
25256 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
25257 +
25258 + return E_OK;
25259 +}
25260 +
25261 +static void UnimplementedIsr(t_Handle h_Arg, uint32_t id)
25262 +{
25263 + UNUSED(h_Arg); UNUSED(id);
25264 +
25265 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented Isr!"));
25266 +}
25267 +
25268 +static void MacsecEventIsr(t_Handle h_FmMacsec)
25269 +{
25270 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25271 + uint32_t events,event,i;
25272 +
25273 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
25274 +
25275 + events = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->evr);
25276 + events |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ever);
25277 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->evr,events);
25278 +
25279 + for (i=0; i<NUM_OF_TX_SC; i++)
25280 + if (events & FM_MACSEC_EV_TX_SC_NEXT_PN(i))
25281 + {
25282 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_NORMAL, event);
25283 + p_FmMacsec->intrMng[event].f_Isr(p_FmMacsec->intrMng[event].h_SrcHandle, i);
25284 + }
25285 +}
25286 +
25287 +static void MacsecErrorIsr(t_Handle h_FmMacsec)
25288 +{
25289 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25290 + uint32_t errors,error,i;
25291 +
25292 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
25293 +
25294 + errors = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->err);
25295 + errors |= GET_UINT32(p_FmMacsec->p_FmMacsecRegs->erer);
25296 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->err,errors);
25297 +
25298 + for (i=0; i<NUM_OF_TX_SC; i++)
25299 + if (errors & FM_MACSEC_EX_TX_SC(i))
25300 + {
25301 + GET_MACSEC_MODULE_EVENT(e_FM_MACSEC_MOD_SC_TX, i, e_FM_INTR_TYPE_ERR, error);
25302 + p_FmMacsec->intrMng[error].f_Isr(p_FmMacsec->intrMng[error].h_SrcHandle, i);
25303 + }
25304 +
25305 + if (errors & FM_MACSEC_EX_ECC)
25306 + {
25307 + uint8_t eccType;
25308 + uint32_t tmpReg;
25309 +
25310 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->meec);
25311 + ASSERT_COND(tmpReg & MECC_CAP);
25312 + eccType = (uint8_t)((tmpReg & MECC_CET) >> MECC_CET_SHIFT);
25313 +
25314 + if (!eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_SINGLE_BIT_ECC))
25315 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_SINGLE_BIT_ECC);
25316 + else if (eccType && (p_FmMacsec->userExceptions & FM_MACSEC_USER_EX_MULTI_BIT_ECC))
25317 + p_FmMacsec->f_Exception(p_FmMacsec->h_App,e_FM_MACSEC_EX_MULTI_BIT_ECC);
25318 + else
25319 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->meec,tmpReg);
25320 + }
25321 +}
25322 +
25323 +static t_Error MacsecInit(t_Handle h_FmMacsec)
25324 +{
25325 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25326 + t_FmMacsecDriverParam *p_FmMacsecDriverParam = NULL;
25327 + uint32_t tmpReg,i,macId;
25328 +
25329 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25330 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25331 +
25332 + CHECK_INIT_PARAMETERS(p_FmMacsec, CheckFmMacsecParameters);
25333 +
25334 + p_FmMacsecDriverParam = p_FmMacsec->p_FmMacsecDriverParam;
25335 +
25336 + for (i=0;i<e_FM_MACSEC_EV_DUMMY_LAST;i++)
25337 + p_FmMacsec->intrMng[i].f_Isr = UnimplementedIsr;
25338 +
25339 + tmpReg = 0;
25340 + tmpReg |= (p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled << CFG_UECT_SHIFT)|
25341 + (p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled << CFG_ESCBT_SHIFT) |
25342 + (p_FmMacsecDriverParam->unknownSciTreatMode << CFG_USFT_SHIFT) |
25343 + (p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled << CFG_ITT_SHIFT) |
25344 + (p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled << CFG_KFT_SHIFT) |
25345 + (p_FmMacsecDriverParam->untagTreatMode << CFG_UFT_SHIFT) |
25346 + (p_FmMacsecDriverParam->keysUnreadable << CFG_KSS_SHIFT) |
25347 + (p_FmMacsecDriverParam->reservedSc0 << CFG_S0I_SHIFT) |
25348 + (p_FmMacsecDriverParam->byPassMode << CFG_BYPN_SHIFT);
25349 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
25350 +
25351 + tmpReg = FM_MAC_GetMaxFrameLength(p_FmMacsec->h_FmMac);
25352 + /* At least Ethernet FCS (4 bytes) overhead must be subtracted from MFL.
25353 + * In addition, the SCI (8 bytes) overhead might be subtracted as well. */
25354 + tmpReg -= p_FmMacsecDriverParam->mflSubtract;
25355 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->mfl, tmpReg);
25356 +
25357 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->tpnet, p_FmMacsecDriverParam->pnExhThr);
25358 +
25359 + if (!p_FmMacsec->userExceptions)
25360 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
25361 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
25362 +
25363 + p_FmMacsec->numRxScAvailable = NUM_OF_RX_SC;
25364 + if (p_FmMacsecDriverParam->reservedSc0)
25365 + p_FmMacsec->numRxScAvailable --;
25366 + p_FmMacsec->numTxScAvailable = NUM_OF_TX_SC;
25367 +
25368 + XX_Free(p_FmMacsecDriverParam);
25369 + p_FmMacsec->p_FmMacsecDriverParam = NULL;
25370 +
25371 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
25372 + FmRegisterIntr(p_FmMacsec->h_Fm,
25373 + e_FM_MOD_MACSEC,
25374 + (uint8_t)macId,
25375 + e_FM_INTR_TYPE_NORMAL,
25376 + MacsecEventIsr,
25377 + p_FmMacsec);
25378 +
25379 + FmRegisterIntr(p_FmMacsec->h_Fm,
25380 + e_FM_MOD_MACSEC,
25381 + 0,
25382 + e_FM_INTR_TYPE_ERR,
25383 + MacsecErrorIsr,
25384 + p_FmMacsec);
25385 +
25386 + return E_OK;
25387 +}
25388 +
25389 +static t_Error MacsecFree(t_Handle h_FmMacsec)
25390 +{
25391 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25392 + uint32_t macId;
25393 +
25394 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25395 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25396 +
25397 + FM_MAC_GetId(p_FmMacsec->h_FmMac, &macId);
25398 + FmUnregisterIntr(p_FmMacsec->h_Fm,
25399 + e_FM_MOD_MACSEC,
25400 + (uint8_t)macId,
25401 + e_FM_INTR_TYPE_NORMAL);
25402 +
25403 + FmUnregisterIntr(p_FmMacsec->h_Fm,
25404 + e_FM_MOD_MACSEC,
25405 + 0,
25406 + e_FM_INTR_TYPE_ERR);
25407 +
25408 + if (p_FmMacsec->rxScSpinLock)
25409 + XX_FreeSpinlock(p_FmMacsec->rxScSpinLock);
25410 + if (p_FmMacsec->txScSpinLock)
25411 + XX_FreeSpinlock(p_FmMacsec->txScSpinLock);
25412 +
25413 + XX_Free(p_FmMacsec);
25414 +
25415 + return E_OK;
25416 +}
25417 +
25418 +static t_Error MacsecConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode)
25419 +{
25420 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25421 +
25422 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25423 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25424 +
25425 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = treatMode;
25426 +
25427 + return E_OK;
25428 +}
25429 +
25430 +static t_Error MacsecConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
25431 +{
25432 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25433 +
25434 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25435 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25436 +
25437 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = deliverUncontrolled;
25438 +
25439 + return E_OK;
25440 +}
25441 +
25442 +static t_Error MacsecConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
25443 +{
25444 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25445 +
25446 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25447 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25448 +
25449 + p_FmMacsec->p_FmMacsecDriverParam->changedTextWithNoEncryptDeliverUncontrolled = deliverUncontrolled;
25450 +
25451 + return E_OK;
25452 +}
25453 +
25454 +static t_Error MacsecConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled)
25455 +{
25456 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25457 +
25458 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25459 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25460 +
25461 + p_FmMacsec->p_FmMacsecDriverParam->onlyScbIsSetDeliverUncontrolled = deliverUncontrolled;
25462 +
25463 + return E_OK;
25464 +}
25465 +
25466 +static t_Error MacsecConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled)
25467 +{
25468 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25469 +
25470 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25471 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25472 +
25473 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = discardUncontrolled;
25474 +
25475 + return E_OK;
25476 +}
25477 +
25478 +static t_Error MacsecConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode)
25479 +{
25480 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25481 +
25482 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25483 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25484 +
25485 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = treatMode;
25486 +
25487 + return E_OK;
25488 +}
25489 +
25490 +static t_Error MacsecConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr)
25491 +{
25492 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25493 +
25494 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25495 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25496 +
25497 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = pnExhThr;
25498 +
25499 + return E_OK;
25500 +}
25501 +
25502 +static t_Error MacsecConfigKeysUnreadable(t_Handle h_FmMacsec)
25503 +{
25504 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25505 +
25506 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25507 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25508 +
25509 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = TRUE;
25510 +
25511 + return E_OK;
25512 +}
25513 +
25514 +static t_Error MacsecConfigSectagWithoutSCI(t_Handle h_FmMacsec)
25515 +{
25516 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25517 +
25518 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25519 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25520 +
25521 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead -= MACSEC_SCI_SIZE;
25522 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract += MACSEC_SCI_SIZE;
25523 +
25524 + return E_OK;
25525 +}
25526 +
25527 +static t_Error MacsecConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
25528 +{
25529 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25530 + uint32_t bitMask = 0;
25531 +
25532 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25533 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25534 +
25535 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
25536 + if (bitMask)
25537 + {
25538 + if (enable)
25539 + p_FmMacsec->userExceptions |= bitMask;
25540 + else
25541 + p_FmMacsec->userExceptions &= ~bitMask;
25542 + }
25543 + else
25544 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25545 +
25546 + return E_OK;
25547 +}
25548 +
25549 +static t_Error MacsecGetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision)
25550 +{
25551 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25552 +
25553 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25554 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25555 +
25556 + *p_MacsecRevision = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->ip_rev1);
25557 +
25558 + return E_OK;
25559 +}
25560 +
25561 +static t_Error MacsecEnable(t_Handle h_FmMacsec)
25562 +{
25563 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25564 + uint32_t tmpReg;
25565 +
25566 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25567 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25568 +
25569 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
25570 + tmpReg |= CFG_BYPN;
25571 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
25572 +
25573 + return E_OK;
25574 +}
25575 +
25576 +static t_Error MacsecDisable(t_Handle h_FmMacsec)
25577 +{
25578 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25579 + uint32_t tmpReg;
25580 +
25581 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25582 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25583 +
25584 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
25585 + tmpReg &= ~CFG_BYPN;
25586 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg,tmpReg);
25587 +
25588 + return E_OK;
25589 +}
25590 +
25591 +static t_Error MacsecSetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable)
25592 +{
25593 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25594 + uint32_t bitMask;
25595 +
25596 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25597 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
25598 +
25599 + GET_USER_EXCEPTION_FLAG(bitMask, exception);
25600 + if (bitMask)
25601 + {
25602 + if (enable)
25603 + p_FmMacsec->userExceptions |= bitMask;
25604 + else
25605 + p_FmMacsec->userExceptions &= ~bitMask;
25606 + }
25607 + else
25608 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
25609 +
25610 + if (!p_FmMacsec->userExceptions)
25611 + p_FmMacsec->exceptions &= ~FM_MACSEC_EX_ECC;
25612 + else
25613 + p_FmMacsec->exceptions |= FM_MACSEC_EX_ECC;
25614 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
25615 +
25616 + return E_OK;
25617 +}
25618 +
25619 +static void InitFmMacsecControllerDriver(t_FmMacsecControllerDriver *p_FmMacsecControllerDriver)
25620 +{
25621 + p_FmMacsecControllerDriver->f_FM_MACSEC_Init = MacsecInit;
25622 + p_FmMacsecControllerDriver->f_FM_MACSEC_Free = MacsecFree;
25623 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUnknownSciFrameTreatment = MacsecConfigUnknownSciFrameTreatment;
25624 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigInvalidTagsFrameTreatment = MacsecConfigInvalidTagsFrameTreatment;
25625 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment = MacsecConfigEncryptWithNoChangedTextFrameTreatment;
25626 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigUntagFrameTreatment = MacsecConfigUntagFrameTreatment;
25627 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment = MacsecConfigChangedTextWithNoEncryptFrameTreatment;
25628 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment = MacsecConfigOnlyScbIsSetFrameTreatment;
25629 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigPnExhaustionThreshold = MacsecConfigPnExhaustionThreshold;
25630 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigKeysUnreadable = MacsecConfigKeysUnreadable;
25631 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigSectagWithoutSCI = MacsecConfigSectagWithoutSCI;
25632 + p_FmMacsecControllerDriver->f_FM_MACSEC_ConfigException = MacsecConfigException;
25633 + p_FmMacsecControllerDriver->f_FM_MACSEC_GetRevision = MacsecGetRevision;
25634 + p_FmMacsecControllerDriver->f_FM_MACSEC_Enable = MacsecEnable;
25635 + p_FmMacsecControllerDriver->f_FM_MACSEC_Disable = MacsecDisable;
25636 + p_FmMacsecControllerDriver->f_FM_MACSEC_SetException = MacsecSetException;
25637 +}
25638 +
25639 +/****************************************/
25640 +/* Inter-Module functions */
25641 +/****************************************/
25642 +
25643 +void FmMacsecRegisterIntr(t_Handle h_FmMacsec,
25644 + e_FmMacsecEventModules module,
25645 + uint8_t modId,
25646 + e_FmIntrType intrType,
25647 + void (*f_Isr) (t_Handle h_Arg, uint32_t id),
25648 + t_Handle h_Arg)
25649 +{
25650 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25651 + uint8_t event= 0;
25652 +
25653 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
25654 +
25655 + GET_MACSEC_MODULE_EVENT(module, modId, intrType, event);
25656 +
25657 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
25658 + p_FmMacsec->intrMng[event].f_Isr = f_Isr;
25659 + p_FmMacsec->intrMng[event].h_SrcHandle = h_Arg;
25660 +}
25661 +
25662 +void FmMacsecUnregisterIntr(t_Handle h_FmMacsec,
25663 + e_FmMacsecEventModules module,
25664 + uint8_t modId,
25665 + e_FmIntrType intrType)
25666 +{
25667 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25668 + uint8_t event= 0;
25669 +
25670 + SANITY_CHECK_RETURN(p_FmMacsec, E_INVALID_HANDLE);
25671 +
25672 + GET_MACSEC_MODULE_EVENT(module, modId,intrType, event);
25673 +
25674 + ASSERT_COND(event != e_FM_MACSEC_EV_DUMMY_LAST);
25675 + p_FmMacsec->intrMng[event].f_Isr = NULL;
25676 + p_FmMacsec->intrMng[event].h_SrcHandle = NULL;
25677 +}
25678 +
25679 +t_Error FmMacsecAllocScs(t_Handle h_FmMacsec, e_ScType type, bool isPtp, uint32_t numOfScs, uint32_t *p_ScIds)
25680 +{
25681 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25682 + t_Error err = E_OK;
25683 + bool *p_ScTable;
25684 + uint32_t *p_ScAvailable,i;
25685 +
25686 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25687 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
25688 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
25689 +
25690 + if (type == e_SC_RX)
25691 + {
25692 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
25693 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
25694 + i = (NUM_OF_RX_SC - 1);
25695 + }
25696 + else
25697 + {
25698 + p_ScTable = (bool *)p_FmMacsec->txScTable;
25699 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
25700 + i = (NUM_OF_TX_SC - 1);
25701 +
25702 + }
25703 + if (*p_ScAvailable < numOfScs)
25704 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not enough SCs available"));
25705 +
25706 + if (isPtp)
25707 + {
25708 + i = 0;
25709 + if (p_ScTable[i])
25710 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Sc 0 Not available"));
25711 + }
25712 +
25713 + for (;numOfScs;i--)
25714 + {
25715 + if (p_ScTable[i])
25716 + continue;
25717 + numOfScs --;
25718 + (*p_ScAvailable)--;
25719 + p_ScIds[numOfScs] = i;
25720 + p_ScTable[i] = TRUE;
25721 + }
25722 +
25723 + return err;
25724 +}
25725 +
25726 +t_Error FmMacsecFreeScs(t_Handle h_FmMacsec, e_ScType type, uint32_t numOfScs, uint32_t *p_ScIds)
25727 +{
25728 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25729 + t_Error err = E_OK;
25730 + bool *p_ScTable;
25731 + uint32_t *p_ScAvailable,maxNumOfSc,i;
25732 +
25733 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25734 + SANITY_CHECK_RETURN_ERROR(p_ScIds, E_INVALID_HANDLE);
25735 + SANITY_CHECK_RETURN_ERROR(numOfScs, E_INVALID_HANDLE);
25736 +
25737 + if (type == e_SC_RX)
25738 + {
25739 + p_ScTable = (bool *)p_FmMacsec->rxScTable;
25740 + p_ScAvailable = &p_FmMacsec->numRxScAvailable;
25741 + maxNumOfSc = NUM_OF_RX_SC;
25742 + }
25743 + else
25744 + {
25745 + p_ScTable = (bool *)p_FmMacsec->txScTable;
25746 + p_ScAvailable = &p_FmMacsec->numTxScAvailable;
25747 + maxNumOfSc = NUM_OF_TX_SC;
25748 + }
25749 +
25750 + if ((*p_ScAvailable + numOfScs) > maxNumOfSc)
25751 + RETURN_ERROR(MINOR, E_FULL, ("Too much SCs"));
25752 +
25753 + for (i=0;i<numOfScs;i++)
25754 + {
25755 + p_ScTable[p_ScIds[i]] = FALSE;
25756 + (*p_ScAvailable)++;
25757 + }
25758 +
25759 + return err;
25760 +
25761 +}
25762 +
25763 +t_Error FmMacsecSetPTP(t_Handle h_FmMacsec, bool enable)
25764 +{
25765 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25766 + uint32_t tmpReg = 0;
25767 +
25768 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25769 +
25770 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg);
25771 + if (enable && (tmpReg & CFG_S0I))
25772 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("MACSEC already in point-to-point mode"));
25773 +
25774 + if (enable)
25775 + tmpReg |= CFG_S0I;
25776 + else
25777 + tmpReg &= ~CFG_S0I;
25778 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->cfg, tmpReg);
25779 +
25780 + return E_OK;
25781 +}
25782 +
25783 +t_Error FmMacsecCreateRxSc(t_Handle h_FmMacsec, t_RxScParams *p_RxScParams)
25784 +{
25785 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25786 + t_Error err = E_OK;
25787 + uint32_t tmpReg = 0, intFlags;
25788 +
25789 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25790 + SANITY_CHECK_RETURN_ERROR(p_RxScParams, E_INVALID_HANDLE);
25791 + SANITY_CHECK_RETURN_ERROR(p_RxScParams->scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25792 +
25793 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25794 +
25795 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, p_RxScParams->scId);
25796 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg);
25797 + if (tmpReg & RX_SCCFG_SCI_EN_MASK)
25798 + {
25799 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25800 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Rx Sc %d must be disable",p_RxScParams->scId));
25801 + }
25802 +
25803 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci1h, GET_SCI_FIRST_HALF(p_RxScParams->sci));
25804 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsci2h, GET_SCI_SECOND_HALF(p_RxScParams->sci));
25805 + tmpReg |= ((p_RxScParams->replayProtect << RX_SCCFG_RP_SHIFT) & RX_SCCFG_RP_MASK);
25806 + tmpReg |= ((p_RxScParams->validateFrames << RX_SCCFG_VF_SHIFT) & RX_SCCFG_VF_MASK);
25807 + tmpReg |= ((p_RxScParams->confidentialityOffset << RX_SCCFG_CO_SHIFT) & RX_SCCFG_CO_MASK);
25808 + tmpReg |= RX_SCCFG_SCI_EN_MASK;
25809 + tmpReg |= (p_RxScParams->cipherSuite << RX_SCCFG_CS_SHIFT);
25810 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
25811 +
25812 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rpw, p_RxScParams->replayWindow);
25813 +
25814 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25815 +
25816 + return err;
25817 +}
25818 +
25819 +t_Error FmMacsecDeleteRxSc(t_Handle h_FmMacsec, uint32_t scId)
25820 +{
25821 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25822 + t_Error err = E_OK;
25823 + uint32_t tmpReg = 0, intFlags;
25824 +
25825 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25826 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25827 +
25828 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25829 +
25830 + tmpReg &= ~RX_SCCFG_SCI_EN_MASK;
25831 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25832 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsccfg, tmpReg);
25833 +
25834 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25835 +
25836 + return err;
25837 +}
25838 +
25839 +t_Error FmMacsecCreateTxSc(t_Handle h_FmMacsec, t_TxScParams *p_TxScParams)
25840 +{
25841 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25842 + t_Error err = E_OK;
25843 + uint32_t tmpReg = 0, intFlags;
25844 + bool alwaysIncludeSCI = FALSE, useES = FALSE, useSCB = FALSE;
25845 +
25846 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25847 + SANITY_CHECK_RETURN_ERROR(p_TxScParams, E_INVALID_HANDLE);
25848 + SANITY_CHECK_RETURN_ERROR(p_TxScParams->scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
25849 +
25850 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25851 +
25852 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, p_TxScParams->scId);
25853 +
25854 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
25855 + if (tmpReg & TX_SCCFG_SCE_MASK)
25856 + {
25857 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25858 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Tx Sc %d must be disable",p_TxScParams->scId));
25859 + }
25860 +
25861 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci1h, GET_SCI_FIRST_HALF(p_TxScParams->sci));
25862 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsci2h, GET_SCI_SECOND_HALF(p_TxScParams->sci));
25863 + alwaysIncludeSCI = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG);
25864 + useES = (p_TxScParams->sciInsertionMode == e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA);
25865 +
25866 + tmpReg |= ((p_TxScParams->protectFrames << TX_SCCFG_PF_SHIFT) & TX_SCCFG_PF_MASK);
25867 + tmpReg |= ((alwaysIncludeSCI << TX_SCCFG_AIS_SHIFT) & TX_SCCFG_AIS_MASK);
25868 + tmpReg |= ((useES << TX_SCCFG_UES_SHIFT) & TX_SCCFG_UES_MASK);
25869 + tmpReg |= ((useSCB << TX_SCCFG_USCB_SHIFT) & TX_SCCFG_USCB_MASK);
25870 + tmpReg |= ((p_TxScParams->confidentialityEnable << TX_SCCFG_CE_SHIFT) & TX_SCCFG_CE_MASK);
25871 + tmpReg |= ((p_TxScParams->confidentialityOffset << TX_SCCFG_CO_SHIFT) & TX_SCCFG_CO_MASK);
25872 + tmpReg |= TX_SCCFG_SCE_MASK;
25873 + tmpReg |= (p_TxScParams->cipherSuite << TX_SCCFG_CS_SHIFT);
25874 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
25875 +
25876 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25877 +
25878 + return err;
25879 +}
25880 +
25881 +t_Error FmMacsecDeleteTxSc(t_Handle h_FmMacsec, uint32_t scId)
25882 +{
25883 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25884 + t_Error err = E_OK;
25885 + uint32_t tmpReg = 0, intFlags;
25886 +
25887 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25888 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_TX_SC, E_INVALID_HANDLE);
25889 +
25890 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25891 +
25892 + tmpReg &= ~TX_SCCFG_SCE_MASK;
25893 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
25894 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
25895 +
25896 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25897 +
25898 + return err;
25899 +}
25900 +
25901 +t_Error FmMacsecCreateRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
25902 +{
25903 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25904 + t_Error err = E_OK;
25905 + uint32_t tmpReg = 0, intFlags;
25906 +
25907 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25908 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25909 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
25910 +
25911 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25912 +
25913 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25914 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, DEFAULT_initNextPn);
25915 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, lowestPn);
25916 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak, key, sizeof(macsecSAKey_t));
25917 +
25918 + tmpReg |= RX_SACFG_ACTIVE;
25919 + tmpReg |= ((an << RX_SACFG_AN_SHIFT) & RX_SACFG_AN_MASK);
25920 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
25921 +
25922 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25923 +
25924 + return err;
25925 +}
25926 +
25927 +t_Error FmMacsecCreateTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecSAKey_t key)
25928 +{
25929 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25930 + t_Error err = E_OK;
25931 + uint32_t tmpReg = 0, intFlags;
25932 +
25933 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25934 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25935 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
25936 +
25937 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25938 +
25939 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
25940 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, DEFAULT_initNextPn);
25941 + MemCpy8((void*)p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak, key, sizeof(macsecSAKey_t));
25942 +
25943 + tmpReg |= TX_SACFG_ACTIVE;
25944 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
25945 +
25946 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25947 +
25948 + return err;
25949 +}
25950 +
25951 +t_Error FmMacsecDeleteRxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
25952 +{
25953 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25954 + t_Error err = E_OK;
25955 + uint32_t tmpReg = 0, i, intFlags;
25956 +
25957 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25958 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25959 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
25960 +
25961 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
25962 +
25963 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
25964 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, 0x0);
25965 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, 0x0);
25966 + for (i=0; i<4; i++)
25967 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsak[i], 0x0);
25968 +
25969 + tmpReg |= RX_SACFG_ACTIVE;
25970 + tmpReg &= ~RX_SACFG_EN_MASK;
25971 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
25972 +
25973 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
25974 +
25975 + return err;
25976 +}
25977 +
25978 +t_Error FmMacsecDeleteTxSa(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId)
25979 +{
25980 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
25981 + t_Error err = E_OK;
25982 + uint32_t tmpReg = 0, i, intFlags;
25983 +
25984 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
25985 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
25986 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
25987 +
25988 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
25989 +
25990 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
25991 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsanpn, 0x0);
25992 + for (i=0; i<4; i++)
25993 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsak[i], 0x0);
25994 +
25995 + tmpReg |= TX_SACFG_ACTIVE;
25996 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecTxScSa[saId].txsacs, tmpReg);
25997 +
25998 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
25999 +
26000 + return err;
26001 +}
26002 +
26003 +t_Error FmMacsecRxSaSetReceive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, bool enableReceive)
26004 +{
26005 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
26006 + t_Error err = E_OK;
26007 + uint32_t tmpReg = 0, intFlags;
26008 +
26009 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
26010 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
26011 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
26012 +
26013 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
26014 +
26015 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
26016 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs);
26017 + if (enableReceive)
26018 + tmpReg |= RX_SACFG_EN_MASK;
26019 + else
26020 + tmpReg &= ~RX_SACFG_EN_MASK;
26021 +
26022 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsacs, tmpReg);
26023 +
26024 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
26025 +
26026 + return err;
26027 +}
26028 +
26029 +t_Error FmMacsecRxSaUpdateNextPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtNextPN)
26030 +{
26031 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
26032 + t_Error err = E_OK;
26033 + uint32_t intFlags;
26034 +
26035 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
26036 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
26037 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
26038 +
26039 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
26040 +
26041 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
26042 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsanpn, updtNextPN);
26043 +
26044 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
26045 +
26046 + return err;
26047 +}
26048 +
26049 +t_Error FmMacsecRxSaUpdateLowestPn(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, uint32_t updtLowestPN)
26050 +{
26051 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
26052 + t_Error err = E_OK;
26053 + uint32_t intFlags;
26054 +
26055 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
26056 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
26057 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_RX_SC, E_INVALID_HANDLE);
26058 +
26059 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->rxScSpinLock);
26060 +
26061 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->rxsca, scId);
26062 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->fmMacsecRxScSa[saId].rxsalpn, updtLowestPN);
26063 +
26064 + XX_UnlockIntrSpinlock(p_FmMacsec->rxScSpinLock, intFlags);
26065 +
26066 + return err;
26067 +}
26068 +
26069 +t_Error FmMacsecTxSaSetActive(t_Handle h_FmMacsec, uint32_t scId, e_ScSaId saId, macsecAN_t an)
26070 +{
26071 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
26072 + t_Error err = E_OK;
26073 + uint32_t tmpReg = 0, intFlags;
26074 +
26075 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
26076 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
26077 + SANITY_CHECK_RETURN_ERROR(saId < NUM_OF_SA_PER_TX_SC, E_INVALID_HANDLE);
26078 +
26079 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
26080 +
26081 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
26082 +
26083 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
26084 +
26085 + tmpReg |= ((an << TX_SCCFG_AN_SHIFT) & TX_SCCFG_AN_MASK);
26086 + tmpReg |= ((saId << TX_SCCFG_ASA_SHIFT) & TX_SCCFG_ASA_MASK);
26087 +
26088 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg, tmpReg);
26089 +
26090 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
26091 +
26092 + return err;
26093 +}
26094 +
26095 +t_Error FmMacsecTxSaGetActive(t_Handle h_FmMacsec, uint32_t scId, macsecAN_t *p_An)
26096 +{
26097 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
26098 + t_Error err = E_OK;
26099 + uint32_t tmpReg = 0, intFlags;
26100 +
26101 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
26102 + SANITY_CHECK_RETURN_ERROR(scId < NUM_OF_RX_SC, E_INVALID_HANDLE);
26103 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
26104 +
26105 + intFlags = XX_LockIntrSpinlock(p_FmMacsec->txScSpinLock);
26106 +
26107 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->txsca, scId);
26108 +
26109 + tmpReg = GET_UINT32(p_FmMacsec->p_FmMacsecRegs->txsccfg);
26110 +
26111 + XX_UnlockIntrSpinlock(p_FmMacsec->txScSpinLock, intFlags);
26112 +
26113 + *p_An = (macsecAN_t)((tmpReg & TX_SCCFG_AN_MASK) >> TX_SCCFG_AN_SHIFT);
26114 +
26115 + return err;
26116 +}
26117 +
26118 +t_Error FmMacsecSetException(t_Handle h_FmMacsec, e_FmMacsecGlobalExceptions exception, uint32_t scId, bool enable)
26119 +{
26120 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
26121 + uint32_t bitMask;
26122 +
26123 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
26124 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
26125 +
26126 + GET_EXCEPTION_FLAG(bitMask, exception, scId);
26127 + if (bitMask)
26128 + {
26129 + if (enable)
26130 + p_FmMacsec->exceptions |= bitMask;
26131 + else
26132 + p_FmMacsec->exceptions &= ~bitMask;
26133 + }
26134 + else
26135 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
26136 +
26137 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->erer, p_FmMacsec->exceptions);
26138 +
26139 + return E_OK;
26140 +}
26141 +
26142 +t_Error FmMacsecSetEvent(t_Handle h_FmMacsec, e_FmMacsecGlobalEvents event, uint32_t scId, bool enable)
26143 +{
26144 + t_FmMacsec *p_FmMacsec = (t_FmMacsec*)h_FmMacsec;
26145 + uint32_t bitMask;
26146 +
26147 + SANITY_CHECK_RETURN_ERROR(p_FmMacsec, E_INVALID_HANDLE);
26148 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsec->p_FmMacsecDriverParam, E_INVALID_HANDLE);
26149 +
26150 + GET_EVENT_FLAG(bitMask, event, scId);
26151 + if (bitMask)
26152 + {
26153 + if (enable)
26154 + p_FmMacsec->events |= bitMask;
26155 + else
26156 + p_FmMacsec->events &= ~bitMask;
26157 + }
26158 + else
26159 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
26160 +
26161 + WRITE_UINT32(p_FmMacsec->p_FmMacsecRegs->ever, p_FmMacsec->events);
26162 +
26163 + return E_OK;
26164 +}
26165 +
26166 +/****************************************/
26167 +/* API Init unit functions */
26168 +/****************************************/
26169 +t_Handle FM_MACSEC_MASTER_Config(t_FmMacsecParams *p_FmMacsecParam)
26170 +{
26171 + t_FmMacsec *p_FmMacsec;
26172 + uint32_t macId;
26173 +
26174 + /* Allocate FM MACSEC structure */
26175 + p_FmMacsec = (t_FmMacsec *) XX_Malloc(sizeof(t_FmMacsec));
26176 + if (!p_FmMacsec)
26177 + {
26178 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver structure"));
26179 + return NULL;
26180 + }
26181 + memset(p_FmMacsec, 0, sizeof(t_FmMacsec));
26182 + InitFmMacsecControllerDriver(&p_FmMacsec->fmMacsecControllerDriver);
26183 +
26184 + /* Allocate the FM MACSEC driver's parameters structure */
26185 + p_FmMacsec->p_FmMacsecDriverParam = (t_FmMacsecDriverParam *)XX_Malloc(sizeof(t_FmMacsecDriverParam));
26186 + if (!p_FmMacsec->p_FmMacsecDriverParam)
26187 + {
26188 + XX_Free(p_FmMacsec);
26189 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC driver parameters"));
26190 + return NULL;
26191 + }
26192 + memset(p_FmMacsec->p_FmMacsecDriverParam, 0, sizeof(t_FmMacsecDriverParam));
26193 +
26194 + /* Initialize FM MACSEC parameters which will be kept by the driver */
26195 + p_FmMacsec->h_Fm = p_FmMacsecParam->h_Fm;
26196 + p_FmMacsec->h_FmMac = p_FmMacsecParam->nonGuestParams.h_FmMac;
26197 + p_FmMacsec->p_FmMacsecRegs = (t_FmMacsecRegs *)UINT_TO_PTR(p_FmMacsecParam->nonGuestParams.baseAddr);
26198 + p_FmMacsec->f_Exception = p_FmMacsecParam->nonGuestParams.f_Exception;
26199 + p_FmMacsec->h_App = p_FmMacsecParam->nonGuestParams.h_App;
26200 + p_FmMacsec->userExceptions = DEFAULT_userExceptions;
26201 + p_FmMacsec->exceptions = DEFAULT_exceptions;
26202 + p_FmMacsec->events = DEFAULT_events;
26203 + p_FmMacsec->rxScSpinLock = XX_InitSpinlock();
26204 + p_FmMacsec->txScSpinLock = XX_InitSpinlock();
26205 +
26206 + /* Initialize FM MACSEC driver parameters parameters (for initialization phase only) */
26207 + p_FmMacsec->p_FmMacsecDriverParam->unknownSciTreatMode = DEFAULT_unknownSciFrameTreatment;
26208 + p_FmMacsec->p_FmMacsecDriverParam->invalidTagsDeliverUncontrolled = DEFAULT_invalidTagsFrameTreatment;
26209 + p_FmMacsec->p_FmMacsecDriverParam->encryptWithNoChangedTextDiscardUncontrolled = DEFAULT_encryptWithNoChangedTextFrameTreatment;
26210 + p_FmMacsec->p_FmMacsecDriverParam->untagTreatMode = DEFAULT_untagFrameTreatment;
26211 + p_FmMacsec->p_FmMacsecDriverParam->keysUnreadable = DEFAULT_keysUnreadable;
26212 + p_FmMacsec->p_FmMacsecDriverParam->reservedSc0 = DEFAULT_sc0ReservedForPTP;
26213 + p_FmMacsec->p_FmMacsecDriverParam->byPassMode = !DEFAULT_normalMode;
26214 + p_FmMacsec->p_FmMacsecDriverParam->pnExhThr = DEFAULT_pnExhThr;
26215 + p_FmMacsec->p_FmMacsecDriverParam->sectagOverhead = DEFAULT_sectagOverhead;
26216 + p_FmMacsec->p_FmMacsecDriverParam->mflSubtract = DEFAULT_mflSubtract;
26217 + /* build the FM MACSEC master IPC address */
26218 + memset(p_FmMacsec->fmMacsecModuleName, 0, (sizeof(char))*MODULE_NAME_SIZE);
26219 + FM_MAC_GetId(p_FmMacsec->h_FmMac,&macId);
26220 + if (Sprint (p_FmMacsec->fmMacsecModuleName, "FM-%d-MAC-%d-MACSEC-Master",
26221 + FmGetId(p_FmMacsec->h_Fm),macId) != 24)
26222 + {
26223 + XX_Free(p_FmMacsec->p_FmMacsecDriverParam);
26224 + XX_Free(p_FmMacsec);
26225 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
26226 + return NULL;
26227 + }
26228 + return p_FmMacsec;
26229 +}
26230 --- /dev/null
26231 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_master.h
26232 @@ -0,0 +1,479 @@
26233 +/*
26234 + * Copyright 2008-2015 Freescale Semiconductor Inc.
26235 + *
26236 + * Redistribution and use in source and binary forms, with or without
26237 + * modification, are permitted provided that the following conditions are met:
26238 + * * Redistributions of source code must retain the above copyright
26239 + * notice, this list of conditions and the following disclaimer.
26240 + * * Redistributions in binary form must reproduce the above copyright
26241 + * notice, this list of conditions and the following disclaimer in the
26242 + * documentation and/or other materials provided with the distribution.
26243 + * * Neither the name of Freescale Semiconductor nor the
26244 + * names of its contributors may be used to endorse or promote products
26245 + * derived from this software without specific prior written permission.
26246 + *
26247 + *
26248 + * ALTERNATIVELY, this software may be distributed under the terms of the
26249 + * GNU General Public License ("GPL") as published by the Free Software
26250 + * Foundation, either version 2 of that License or (at your option) any
26251 + * later version.
26252 + *
26253 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26254 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26255 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26256 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26257 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26258 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26259 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26260 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26261 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26262 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26263 + */
26264 +
26265 +/******************************************************************************
26266 + @File fm_macsec_master.h
26267 +
26268 + @Description FM MACSEC internal structures and definitions.
26269 +*//***************************************************************************/
26270 +#ifndef __FM_MACSEC_MASTER_H
26271 +#define __FM_MACSEC_MASTER_H
26272 +
26273 +#include "error_ext.h"
26274 +#include "std_ext.h"
26275 +
26276 +#include "fm_macsec.h"
26277 +
26278 +
26279 +#define MACSEC_ICV_SIZE 16
26280 +#define MACSEC_SECTAG_SIZE 16
26281 +#define MACSEC_SCI_SIZE 8
26282 +#define MACSEC_FCS_SIZE 4
26283 +
26284 +/**************************************************************************//**
26285 + @Description Exceptions
26286 +*//***************************************************************************/
26287 +
26288 +#define FM_MACSEC_EX_TX_SC_0 0x80000000
26289 +#define FM_MACSEC_EX_TX_SC(sc) (FM_MACSEC_EX_TX_SC_0 >> (sc))
26290 +#define FM_MACSEC_EX_ECC 0x00000001
26291 +
26292 +#define GET_EXCEPTION_FLAG(bitMask, exception, id) switch (exception){ \
26293 + case e_FM_MACSEC_EX_TX_SC: \
26294 + bitMask = FM_MACSEC_EX_TX_SC(id); break; \
26295 + case e_FM_MACSEC_EX_ECC: \
26296 + bitMask = FM_MACSEC_EX_ECC; break; \
26297 + default: bitMask = 0;break;}
26298 +
26299 +#define FM_MACSEC_USER_EX_SINGLE_BIT_ECC 0x80000000
26300 +#define FM_MACSEC_USER_EX_MULTI_BIT_ECC 0x40000000
26301 +
26302 +#define GET_USER_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
26303 + case e_FM_MACSEC_EX_SINGLE_BIT_ECC: \
26304 + bitMask = FM_MACSEC_USER_EX_SINGLE_BIT_ECC; break; \
26305 + case e_FM_MACSEC_EX_MULTI_BIT_ECC: \
26306 + bitMask = FM_MACSEC_USER_EX_MULTI_BIT_ECC; break; \
26307 + default: bitMask = 0;break;}
26308 +
26309 +/**************************************************************************//**
26310 + @Description Events
26311 +*//***************************************************************************/
26312 +
26313 +#define FM_MACSEC_EV_TX_SC_0_NEXT_PN 0x80000000
26314 +#define FM_MACSEC_EV_TX_SC_NEXT_PN(sc) (FM_MACSEC_EV_TX_SC_0_NEXT_PN >> (sc))
26315 +
26316 +#define GET_EVENT_FLAG(bitMask, event, id) switch (event){ \
26317 + case e_FM_MACSEC_EV_TX_SC_NEXT_PN: \
26318 + bitMask = FM_MACSEC_EV_TX_SC_NEXT_PN(id); break; \
26319 + default: bitMask = 0;break;}
26320 +
26321 +/**************************************************************************//**
26322 + @Description Defaults
26323 +*//***************************************************************************/
26324 +#define DEFAULT_userExceptions (FM_MACSEC_USER_EX_SINGLE_BIT_ECC |\
26325 + FM_MACSEC_USER_EX_MULTI_BIT_ECC)
26326 +
26327 +#define DEFAULT_exceptions (FM_MACSEC_EX_TX_SC(0) |\
26328 + FM_MACSEC_EX_TX_SC(1) |\
26329 + FM_MACSEC_EX_TX_SC(2) |\
26330 + FM_MACSEC_EX_TX_SC(3) |\
26331 + FM_MACSEC_EX_TX_SC(4) |\
26332 + FM_MACSEC_EX_TX_SC(5) |\
26333 + FM_MACSEC_EX_TX_SC(6) |\
26334 + FM_MACSEC_EX_TX_SC(7) |\
26335 + FM_MACSEC_EX_TX_SC(8) |\
26336 + FM_MACSEC_EX_TX_SC(9) |\
26337 + FM_MACSEC_EX_TX_SC(10) |\
26338 + FM_MACSEC_EX_TX_SC(11) |\
26339 + FM_MACSEC_EX_TX_SC(12) |\
26340 + FM_MACSEC_EX_TX_SC(13) |\
26341 + FM_MACSEC_EX_TX_SC(14) |\
26342 + FM_MACSEC_EX_TX_SC(15) |\
26343 + FM_MACSEC_EX_ECC )
26344 +
26345 +#define DEFAULT_events (FM_MACSEC_EV_TX_SC_NEXT_PN(0) |\
26346 + FM_MACSEC_EV_TX_SC_NEXT_PN(1) |\
26347 + FM_MACSEC_EV_TX_SC_NEXT_PN(2) |\
26348 + FM_MACSEC_EV_TX_SC_NEXT_PN(3) |\
26349 + FM_MACSEC_EV_TX_SC_NEXT_PN(4) |\
26350 + FM_MACSEC_EV_TX_SC_NEXT_PN(5) |\
26351 + FM_MACSEC_EV_TX_SC_NEXT_PN(6) |\
26352 + FM_MACSEC_EV_TX_SC_NEXT_PN(7) |\
26353 + FM_MACSEC_EV_TX_SC_NEXT_PN(8) |\
26354 + FM_MACSEC_EV_TX_SC_NEXT_PN(9) |\
26355 + FM_MACSEC_EV_TX_SC_NEXT_PN(10) |\
26356 + FM_MACSEC_EV_TX_SC_NEXT_PN(11) |\
26357 + FM_MACSEC_EV_TX_SC_NEXT_PN(12) |\
26358 + FM_MACSEC_EV_TX_SC_NEXT_PN(13) |\
26359 + FM_MACSEC_EV_TX_SC_NEXT_PN(14) |\
26360 + FM_MACSEC_EV_TX_SC_NEXT_PN(15) )
26361 +
26362 +#define DEFAULT_unknownSciFrameTreatment e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH
26363 +#define DEFAULT_invalidTagsFrameTreatment FALSE
26364 +#define DEFAULT_encryptWithNoChangedTextFrameTreatment FALSE
26365 +#define DEFAULT_untagFrameTreatment e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED
26366 +#define DEFAULT_changedTextWithNoEncryptFrameTreatment FALSE
26367 +#define DEFAULT_onlyScbIsSetFrameTreatment FALSE
26368 +#define DEFAULT_keysUnreadable FALSE
26369 +#define DEFAULT_normalMode TRUE
26370 +#define DEFAULT_sc0ReservedForPTP FALSE
26371 +#define DEFAULT_initNextPn 1
26372 +#define DEFAULT_pnExhThr 0xffffffff
26373 +#define DEFAULT_sectagOverhead (MACSEC_ICV_SIZE + MACSEC_SECTAG_SIZE)
26374 +#define DEFAULT_mflSubtract MACSEC_FCS_SIZE
26375 +
26376 +
26377 +/**************************************************************************//**
26378 + @Description Memory Mapped Registers
26379 +*//***************************************************************************/
26380 +
26381 +#if defined(__MWERKS__) && !defined(__GNUC__)
26382 +#pragma pack(push,1)
26383 +#endif /* defined(__MWERKS__) && ... */
26384 +
26385 +typedef _Packed struct
26386 +{
26387 + /* MACsec configuration */
26388 + volatile uint32_t cfg; /**< MACsec configuration */
26389 + volatile uint32_t et; /**< MACsec EtherType */
26390 + volatile uint8_t res1[56]; /**< reserved */
26391 + volatile uint32_t mfl; /**< Maximum Frame Length */
26392 + volatile uint32_t tpnet; /**< TX Packet Number exhaustion threshold */
26393 + volatile uint8_t res2[56]; /**< reserved */
26394 + volatile uint32_t rxsca; /**< RX SC access select */
26395 + volatile uint8_t res3[60]; /**< reserved */
26396 + volatile uint32_t txsca; /**< TX SC access select */
26397 + volatile uint8_t res4[60]; /**< reserved */
26398 +
26399 + /* RX configuration, status and statistic */
26400 + volatile uint32_t rxsci1h; /**< RX Secure Channel Identifier first half */
26401 + volatile uint32_t rxsci2h; /**< RX Secure Channel Identifier second half */
26402 + volatile uint8_t res5[8]; /**< reserved */
26403 + volatile uint32_t ifio1hs; /**< ifInOctets first half Statistic */
26404 + volatile uint32_t ifio2hs; /**< ifInOctets second half Statistic */
26405 + volatile uint32_t ifiups; /**< ifInUcastPkts Statistic */
26406 + volatile uint8_t res6[4]; /**< reserved */
26407 + volatile uint32_t ifimps; /**< ifInMulticastPkts Statistic */
26408 + volatile uint32_t ifibps; /**< ifInBroadcastPkts Statistic */
26409 + volatile uint32_t rxsccfg; /**< RX Secure Channel configuration */
26410 + volatile uint32_t rpw; /**< replayWindow */
26411 + volatile uint8_t res7[16]; /**< reserved */
26412 + volatile uint32_t inov1hs; /**< InOctetsValidated first half Statistic */
26413 + volatile uint32_t inov2hs; /**< InOctetsValidated second half Statistic */
26414 + volatile uint32_t inod1hs; /**< InOctetsDecrypted first half Statistic */
26415 + volatile uint32_t inod2hs; /**< InOctetsDecrypted second half Statistic */
26416 + volatile uint32_t rxscipus; /**< RX Secure Channel InPktsUnchecked Statistic */
26417 + volatile uint32_t rxscipds; /**< RX Secure Channel InPktsDelayed Statistic */
26418 + volatile uint32_t rxscipls; /**< RX Secure Channel InPktsLate Statistic */
26419 + volatile uint8_t res8[4]; /**< reserved */
26420 + volatile uint32_t rxaninuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InNotUsingSA Statistic */
26421 + volatile uint32_t rxanipuss[MAX_NUM_OF_SA_PER_SC]; /**< RX AN 0-3 InPktsUnusedSA Statistic */
26422 + _Packed struct
26423 + {
26424 + volatile uint32_t rxsacs; /**< RX Security Association configuration and status */
26425 + volatile uint32_t rxsanpn; /**< RX Security Association nextPN */
26426 + volatile uint32_t rxsalpn; /**< RX Security Association lowestPN */
26427 + volatile uint32_t rxsaipos; /**< RX Security Association InPktsOK Statistic */
26428 + volatile uint32_t rxsak[4]; /**< RX Security Association key (128 bit) */
26429 + volatile uint32_t rxsah[4]; /**< RX Security Association hash (128 bit) */
26430 + volatile uint32_t rxsaipis; /**< RX Security Association InPktsInvalid Statistic */
26431 + volatile uint32_t rxsaipnvs; /**< RX Security Association InPktsNotValid Statistic */
26432 + volatile uint8_t res9[8]; /**< reserved */
26433 + } _PackedType fmMacsecRxScSa[NUM_OF_SA_PER_RX_SC];
26434 +
26435 + /* TX configuration, status and statistic */
26436 + volatile uint32_t txsci1h; /**< TX Secure Channel Identifier first half */
26437 + volatile uint32_t txsci2h; /**< TX Secure Channel Identifier second half */
26438 + volatile uint8_t res10[8]; /**< reserved */
26439 + volatile uint32_t ifoo1hs; /**< ifOutOctets first half Statistic */
26440 + volatile uint32_t ifoo2hs; /**< ifOutOctets second half Statistic */
26441 + volatile uint32_t ifoups; /**< ifOutUcastPkts Statistic */
26442 + volatile uint32_t opus; /**< OutPktsUntagged Statistic */
26443 + volatile uint32_t ifomps; /**< ifOutMulticastPkts Statistic */
26444 + volatile uint32_t ifobps; /**< ifOutBroadcastPkts Statistic */
26445 + volatile uint32_t txsccfg; /**< TX Secure Channel configuration */
26446 + volatile uint32_t optls; /**< OutPktsTooLong Statistic */
26447 + volatile uint8_t res11[16]; /**< reserved */
26448 + volatile uint32_t oop1hs; /**< OutOctetsProtected first half Statistic */
26449 + volatile uint32_t oop2hs; /**< OutOctetsProtected second half Statistic */
26450 + volatile uint32_t ooe1hs; /**< OutOctetsEncrypted first half Statistic */
26451 + volatile uint32_t ooe2hs; /**< OutOctetsEncrypted second half Statistic */
26452 + volatile uint8_t res12[48]; /**< reserved */
26453 + _Packed struct
26454 + {
26455 + volatile uint32_t txsacs; /**< TX Security Association configuration and status */
26456 + volatile uint32_t txsanpn; /**< TX Security Association nextPN */
26457 + volatile uint32_t txsaopps; /**< TX Security Association OutPktsProtected Statistic */
26458 + volatile uint32_t txsaopes; /**< TX Security Association OutPktsEncrypted Statistic */
26459 + volatile uint32_t txsak[4]; /**< TX Security Association key (128 bit) */
26460 + volatile uint32_t txsah[4]; /**< TX Security Association hash (128 bit) */
26461 + volatile uint8_t res13[16]; /**< reserved */
26462 + } _PackedType fmMacsecTxScSa[NUM_OF_SA_PER_TX_SC];
26463 + volatile uint8_t res14[248]; /**< reserved */
26464 +
26465 + /* Global configuration and status */
26466 + volatile uint32_t ip_rev1; /**< MACsec IP Block Revision 1 register */
26467 + volatile uint32_t ip_rev2; /**< MACsec IP Block Revision 2 register */
26468 + volatile uint32_t evr; /**< MACsec Event Register */
26469 + volatile uint32_t ever; /**< MACsec Event Enable Register */
26470 + volatile uint32_t evfr; /**< MACsec Event Force Register */
26471 + volatile uint32_t err; /**< MACsec Error Register */
26472 + volatile uint32_t erer; /**< MACsec Error Enable Register */
26473 + volatile uint32_t erfr; /**< MACsec Error Force Register */
26474 + volatile uint8_t res15[40]; /**< reserved */
26475 + volatile uint32_t meec; /**< MACsec Memory ECC Error Capture Register */
26476 + volatile uint32_t idle; /**< MACsec Idle status Register */
26477 + volatile uint8_t res16[184]; /**< reserved */
26478 + /* DEBUG */
26479 + volatile uint32_t rxec; /**< MACsec RX error capture Register */
26480 + volatile uint8_t res17[28]; /**< reserved */
26481 + volatile uint32_t txec; /**< MACsec TX error capture Register */
26482 + volatile uint8_t res18[220]; /**< reserved */
26483 +
26484 + /* Macsec Rx global statistic */
26485 + volatile uint32_t ifiocp1hs; /**< ifInOctetsCp first half Statistic */
26486 + volatile uint32_t ifiocp2hs; /**< ifInOctetsCp second half Statistic */
26487 + volatile uint32_t ifiupcps; /**< ifInUcastPktsCp Statistic */
26488 + volatile uint8_t res19[4]; /**< reserved */
26489 + volatile uint32_t ifioup1hs; /**< ifInOctetsUp first half Statistic */
26490 + volatile uint32_t ifioup2hs; /**< ifInOctetsUp second half Statistic */
26491 + volatile uint32_t ifiupups; /**< ifInUcastPktsUp Statistic */
26492 + volatile uint8_t res20[4]; /**< reserved */
26493 + volatile uint32_t ifimpcps; /**< ifInMulticastPktsCp Statistic */
26494 + volatile uint32_t ifibpcps; /**< ifInBroadcastPktsCp Statistic */
26495 + volatile uint32_t ifimpups; /**< ifInMulticastPktsUp Statistic */
26496 + volatile uint32_t ifibpups; /**< ifInBroadcastPktsUp Statistic */
26497 + volatile uint32_t ipwts; /**< InPktsWithoutTag Statistic */
26498 + volatile uint32_t ipkays; /**< InPktsKaY Statistic */
26499 + volatile uint32_t ipbts; /**< InPktsBadTag Statistic */
26500 + volatile uint32_t ipsnfs; /**< InPktsSCINotFound Statistic */
26501 + volatile uint32_t ipuecs; /**< InPktsUnsupportedEC Statistic */
26502 + volatile uint32_t ipescbs; /**< InPktsEponSingleCopyBroadcast Statistic */
26503 + volatile uint32_t iptls; /**< InPktsTooLong Statistic */
26504 + volatile uint8_t res21[52]; /**< reserved */
26505 +
26506 + /* Macsec Tx global statistic */
26507 + volatile uint32_t opds; /**< OutPktsDiscarded Statistic */
26508 +#if (DPAA_VERSION >= 11)
26509 + volatile uint8_t res22[124]; /**< reserved */
26510 + _Packed struct
26511 + {
26512 + volatile uint32_t rxsak[8]; /**< RX Security Association key (128/256 bit) */
26513 + volatile uint8_t res23[32]; /**< reserved */
26514 + } _PackedType rxScSaKey[NUM_OF_SA_PER_RX_SC];
26515 + _Packed struct
26516 + {
26517 + volatile uint32_t txsak[8]; /**< TX Security Association key (128/256 bit) */
26518 + volatile uint8_t res24[32]; /**< reserved */
26519 + } _PackedType txScSaKey[NUM_OF_SA_PER_TX_SC];
26520 +#endif /* (DPAA_VERSION >= 11) */
26521 +} _PackedType t_FmMacsecRegs;
26522 +
26523 +#if defined(__MWERKS__) && !defined(__GNUC__)
26524 +#pragma pack(pop)
26525 +#endif /* defined(__MWERKS__) && ... */
26526 +
26527 +
26528 +/**************************************************************************//**
26529 + @Description General defines
26530 +*//***************************************************************************/
26531 +
26532 +#define SCI_HIGH_MASK 0xffffffff00000000LL
26533 +#define SCI_LOW_MASK 0x00000000ffffffffLL
26534 +
26535 +#define LONG_SHIFT 32
26536 +
26537 +#define GET_SCI_FIRST_HALF(sci) (uint32_t)((macsecSCI_t)((macsecSCI_t)(sci) & SCI_HIGH_MASK) >> LONG_SHIFT)
26538 +#define GET_SCI_SECOND_HALF(sci) (uint32_t)((macsecSCI_t)(sci) & SCI_LOW_MASK)
26539 +
26540 +/**************************************************************************//**
26541 + @Description Configuration defines
26542 +*//***************************************************************************/
26543 +
26544 +/* masks */
26545 +#define CFG_UECT 0x00000800
26546 +#define CFG_ESCBT 0x00000400
26547 +#define CFG_USFT 0x00000300
26548 +#define CFG_ITT 0x00000080
26549 +#define CFG_KFT 0x00000040
26550 +#define CFG_UFT 0x00000030
26551 +#define CFG_KSS 0x00000004
26552 +#define CFG_BYPN 0x00000002
26553 +#define CFG_S0I 0x00000001
26554 +
26555 +#define ET_TYPE 0x0000ffff
26556 +
26557 +#define MFL_MAX_LEN 0x0000ffff
26558 +
26559 +#define RXSCA_SC_SEL 0x0000000f
26560 +
26561 +#define TXSCA_SC_SEL 0x0000000f
26562 +
26563 +#define IP_REV_1_IP_ID 0xffff0000
26564 +#define IP_REV_1_IP_MJ 0x0000ff00
26565 +#define IP_REV_1_IP_MM 0x000000ff
26566 +
26567 +#define IP_REV_2_IP_INT 0x00ff0000
26568 +#define IP_REV_2_IP_ERR 0x0000ff00
26569 +#define IP_REV_2_IP_CFG 0x000000ff
26570 +
26571 +#define MECC_CAP 0x80000000
26572 +#define MECC_CET 0x40000000
26573 +#define MECC_SERCNT 0x00ff0000
26574 +#define MECC_MEMADDR 0x000001ff
26575 +
26576 +/* shifts */
26577 +#define CFG_UECT_SHIFT (31-20)
26578 +#define CFG_ESCBT_SHIFT (31-21)
26579 +#define CFG_USFT_SHIFT (31-23)
26580 +#define CFG_ITT_SHIFT (31-24)
26581 +#define CFG_KFT_SHIFT (31-25)
26582 +#define CFG_UFT_SHIFT (31-27)
26583 +#define CFG_KSS_SHIFT (31-29)
26584 +#define CFG_BYPN_SHIFT (31-30)
26585 +#define CFG_S0I_SHIFT (31-31)
26586 +
26587 +#define IP_REV_1_IP_ID_SHIFT (31-15)
26588 +#define IP_REV_1_IP_MJ_SHIFT (31-23)
26589 +#define IP_REV_1_IP_MM_SHIFT (31-31)
26590 +
26591 +#define IP_REV_2_IP_INT_SHIFT (31-15)
26592 +#define IP_REV_2_IP_ERR_SHIFT (31-23)
26593 +#define IP_REV_2_IP_CFG_SHIFT (31-31)
26594 +
26595 +#define MECC_CAP_SHIFT (31-0)
26596 +#define MECC_CET_SHIFT (31-1)
26597 +#define MECC_SERCNT_SHIFT (31-15)
26598 +#define MECC_MEMADDR_SHIFT (31-31)
26599 +
26600 +/**************************************************************************//**
26601 + @Description RX SC defines
26602 +*//***************************************************************************/
26603 +
26604 +/* masks */
26605 +#define RX_SCCFG_SCI_EN_MASK 0x00000800
26606 +#define RX_SCCFG_RP_MASK 0x00000400
26607 +#define RX_SCCFG_VF_MASK 0x00000300
26608 +#define RX_SCCFG_CO_MASK 0x0000003f
26609 +
26610 +/* shifts */
26611 +#define RX_SCCFG_SCI_EN_SHIFT (31-20)
26612 +#define RX_SCCFG_RP_SHIFT (31-21)
26613 +#define RX_SCCFG_VF_SHIFT (31-23)
26614 +#define RX_SCCFG_CO_SHIFT (31-31)
26615 +#define RX_SCCFG_CS_SHIFT (31-7)
26616 +
26617 +/**************************************************************************//**
26618 + @Description RX SA defines
26619 +*//***************************************************************************/
26620 +
26621 +/* masks */
26622 +#define RX_SACFG_ACTIVE 0x80000000
26623 +#define RX_SACFG_AN_MASK 0x00000006
26624 +#define RX_SACFG_EN_MASK 0x00000001
26625 +
26626 +/* shifts */
26627 +#define RX_SACFG_AN_SHIFT (31-30)
26628 +#define RX_SACFG_EN_SHIFT (31-31)
26629 +
26630 +/**************************************************************************//**
26631 + @Description TX SC defines
26632 +*//***************************************************************************/
26633 +
26634 +/* masks */
26635 +#define TX_SCCFG_AN_MASK 0x000c0000
26636 +#define TX_SCCFG_ASA_MASK 0x00020000
26637 +#define TX_SCCFG_SCE_MASK 0x00010000
26638 +#define TX_SCCFG_CO_MASK 0x00003f00
26639 +#define TX_SCCFG_CE_MASK 0x00000010
26640 +#define TX_SCCFG_PF_MASK 0x00000008
26641 +#define TX_SCCFG_AIS_MASK 0x00000004
26642 +#define TX_SCCFG_UES_MASK 0x00000002
26643 +#define TX_SCCFG_USCB_MASK 0x00000001
26644 +
26645 +/* shifts */
26646 +#define TX_SCCFG_AN_SHIFT (31-13)
26647 +#define TX_SCCFG_ASA_SHIFT (31-14)
26648 +#define TX_SCCFG_SCE_SHIFT (31-15)
26649 +#define TX_SCCFG_CO_SHIFT (31-23)
26650 +#define TX_SCCFG_CE_SHIFT (31-27)
26651 +#define TX_SCCFG_PF_SHIFT (31-28)
26652 +#define TX_SCCFG_AIS_SHIFT (31-29)
26653 +#define TX_SCCFG_UES_SHIFT (31-30)
26654 +#define TX_SCCFG_USCB_SHIFT (31-31)
26655 +#define TX_SCCFG_CS_SHIFT (31-7)
26656 +
26657 +/**************************************************************************//**
26658 + @Description TX SA defines
26659 +*//***************************************************************************/
26660 +
26661 +/* masks */
26662 +#define TX_SACFG_ACTIVE 0x80000000
26663 +
26664 +
26665 +typedef struct
26666 +{
26667 + void (*f_Isr) (t_Handle h_Arg, uint32_t id);
26668 + t_Handle h_SrcHandle;
26669 +} t_FmMacsecIntrSrc;
26670 +
26671 +typedef struct
26672 +{
26673 + e_FmMacsecUnknownSciFrameTreatment unknownSciTreatMode;
26674 + bool invalidTagsDeliverUncontrolled;
26675 + bool changedTextWithNoEncryptDeliverUncontrolled;
26676 + bool onlyScbIsSetDeliverUncontrolled;
26677 + bool encryptWithNoChangedTextDiscardUncontrolled;
26678 + e_FmMacsecUntagFrameTreatment untagTreatMode;
26679 + uint32_t pnExhThr;
26680 + bool keysUnreadable;
26681 + bool byPassMode;
26682 + bool reservedSc0;
26683 + uint32_t sectagOverhead;
26684 + uint32_t mflSubtract;
26685 +} t_FmMacsecDriverParam;
26686 +
26687 +typedef struct
26688 +{
26689 + t_FmMacsecControllerDriver fmMacsecControllerDriver;
26690 + t_Handle h_Fm;
26691 + t_FmMacsecRegs *p_FmMacsecRegs;
26692 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
26693 + char fmMacsecModuleName[MODULE_NAME_SIZE];
26694 + t_FmMacsecIntrSrc intrMng[NUM_OF_INTER_MODULE_EVENTS];
26695 + uint32_t events;
26696 + uint32_t exceptions;
26697 + uint32_t userExceptions;
26698 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
26699 + t_Handle h_App; /**< A handle to an application layer object; This handle will
26700 + be passed by the driver upon calling the above callbacks */
26701 + bool rxScTable[NUM_OF_RX_SC];
26702 + uint32_t numRxScAvailable;
26703 + bool txScTable[NUM_OF_TX_SC];
26704 + uint32_t numTxScAvailable;
26705 + t_Handle rxScSpinLock;
26706 + t_Handle txScSpinLock;
26707 + t_FmMacsecDriverParam *p_FmMacsecDriverParam;
26708 +} t_FmMacsec;
26709 +
26710 +
26711 +#endif /* __FM_MACSEC_MASTER_H */
26712 --- /dev/null
26713 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.c
26714 @@ -0,0 +1,883 @@
26715 +/*
26716 + * Copyright 2008-2015 Freescale Semiconductor Inc.
26717 + *
26718 + * Redistribution and use in source and binary forms, with or without
26719 + * modification, are permitted provided that the following conditions are met:
26720 + * * Redistributions of source code must retain the above copyright
26721 + * notice, this list of conditions and the following disclaimer.
26722 + * * Redistributions in binary form must reproduce the above copyright
26723 + * notice, this list of conditions and the following disclaimer in the
26724 + * documentation and/or other materials provided with the distribution.
26725 + * * Neither the name of Freescale Semiconductor nor the
26726 + * names of its contributors may be used to endorse or promote products
26727 + * derived from this software without specific prior written permission.
26728 + *
26729 + *
26730 + * ALTERNATIVELY, this software may be distributed under the terms of the
26731 + * GNU General Public License ("GPL") as published by the Free Software
26732 + * Foundation, either version 2 of that License or (at your option) any
26733 + * later version.
26734 + *
26735 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
26736 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26737 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26738 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
26739 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26740 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26741 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26742 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26743 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26744 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26745 + */
26746 +
26747 +/******************************************************************************
26748 + @File fm_macsec_secy.c
26749 +
26750 + @Description FM MACSEC SECY driver routines implementation.
26751 +*//***************************************************************************/
26752 +
26753 +#include "std_ext.h"
26754 +#include "error_ext.h"
26755 +#include "xx_ext.h"
26756 +#include "string_ext.h"
26757 +#include "sprint_ext.h"
26758 +
26759 +#include "fm_macsec_secy.h"
26760 +
26761 +
26762 +/****************************************/
26763 +/* static functions */
26764 +/****************************************/
26765 +static void FmMacsecSecYExceptionsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
26766 +{
26767 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26768 +
26769 + UNUSED(id);
26770 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
26771 +
26772 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
26773 + p_FmMacsecSecY->f_Exception(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EX_FRAME_DISCARDED);
26774 +}
26775 +
26776 +static void FmMacsecSecYEventsIsr(t_Handle h_FmMacsecSecY, uint32_t id)
26777 +{
26778 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26779 +
26780 + UNUSED(id);
26781 + SANITY_CHECK_RETURN(p_FmMacsecSecY, E_INVALID_HANDLE);
26782 +
26783 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
26784 + p_FmMacsecSecY->f_Event(p_FmMacsecSecY->h_App, e_FM_MACSEC_SECY_EV_NEXT_PN);
26785 +}
26786 +
26787 +static t_Error CheckFmMacsecSecYParameters(t_FmMacsecSecY *p_FmMacsecSecY)
26788 +{
26789 + if (!p_FmMacsecSecY->f_Exception)
26790 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
26791 +
26792 + if (!p_FmMacsecSecY->f_Event)
26793 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Events callback not provided"));
26794 +
26795 + if (!p_FmMacsecSecY->numOfRxSc)
26796 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Num of Rx Scs must be greater than '0'"));
26797 +
26798 +
26799 + return E_OK;
26800 +}
26801 +
26802 +static t_Handle FmMacsecSecYCreateSc(t_FmMacsecSecY *p_FmMacsecSecY,
26803 + macsecSCI_t sci,
26804 + e_FmMacsecSecYCipherSuite cipherSuite,
26805 + e_ScType type)
26806 +{
26807 + t_SecYSc *p_ScTable;
26808 + void *p_Params;
26809 + uint32_t numOfSc,i;
26810 + t_Error err = E_OK;
26811 + t_RxScParams rxScParams;
26812 + t_TxScParams txScParams;
26813 +
26814 + ASSERT_COND(p_FmMacsecSecY);
26815 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
26816 +
26817 + if (type == e_SC_RX)
26818 + {
26819 + memset(&rxScParams, 0, sizeof(rxScParams));
26820 + i = (NUM_OF_RX_SC - 1);
26821 + p_ScTable = p_FmMacsecSecY->p_RxSc;
26822 + numOfSc = p_FmMacsecSecY->numOfRxSc;
26823 + rxScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
26824 + rxScParams.replayProtect = p_FmMacsecSecY->replayProtect;
26825 + rxScParams.replayWindow = p_FmMacsecSecY->replayWindow;
26826 + rxScParams.validateFrames = p_FmMacsecSecY->validateFrames;
26827 + rxScParams.cipherSuite = cipherSuite;
26828 + p_Params = &rxScParams;
26829 + }
26830 + else
26831 + {
26832 + memset(&txScParams, 0, sizeof(txScParams));
26833 + i = (NUM_OF_TX_SC - 1);
26834 + p_ScTable = p_FmMacsecSecY->p_TxSc;
26835 + numOfSc = p_FmMacsecSecY->numOfTxSc;
26836 + txScParams.sciInsertionMode = p_FmMacsecSecY->sciInsertionMode;
26837 + txScParams.protectFrames = p_FmMacsecSecY->protectFrames;
26838 + txScParams.confidentialityEnable = p_FmMacsecSecY->confidentialityEnable;
26839 + txScParams.confidentialityOffset = p_FmMacsecSecY->confidentialityOffset;
26840 + txScParams.cipherSuite = cipherSuite;
26841 + p_Params = &txScParams;
26842 + }
26843 +
26844 + for (i=0;i<numOfSc;i++)
26845 + if (!p_ScTable[i].inUse)
26846 + break;
26847 + if (i == numOfSc)
26848 + {
26849 + REPORT_ERROR(MAJOR, E_FULL, ("FM MACSEC SECY SC"));
26850 + return NULL;
26851 + }
26852 +
26853 + if (type == e_SC_RX)
26854 + {
26855 + ((t_RxScParams *)p_Params)->scId = p_ScTable[i].scId;
26856 + ((t_RxScParams *)p_Params)->sci = sci;
26857 + if ((err = FmMacsecCreateRxSc(p_FmMacsecSecY->h_FmMacsec, (t_RxScParams *)p_Params)) != E_OK)
26858 + {
26859 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
26860 + return NULL;
26861 + }
26862 + }
26863 + else
26864 + {
26865 + ((t_TxScParams *)p_Params)->scId = p_ScTable[i].scId;
26866 + ((t_TxScParams *)p_Params)->sci = sci;
26867 + if ((err = FmMacsecCreateTxSc(p_FmMacsecSecY->h_FmMacsec, (t_TxScParams *)p_Params)) != E_OK)
26868 + {
26869 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
26870 + return NULL;
26871 + }
26872 + }
26873 +
26874 + p_ScTable[i].inUse = TRUE;
26875 + return &p_ScTable[i];
26876 +}
26877 +
26878 +static t_Error FmMacsecSecYDeleteSc(t_FmMacsecSecY *p_FmMacsecSecY, t_SecYSc *p_FmSecYSc, e_ScType type)
26879 +{
26880 + t_Error err = E_OK;
26881 +
26882 + ASSERT_COND(p_FmMacsecSecY);
26883 + ASSERT_COND(p_FmMacsecSecY->h_FmMacsec);
26884 + ASSERT_COND(p_FmSecYSc);
26885 +
26886 + if (type == e_SC_RX)
26887 + {
26888 + if ((err = FmMacsecDeleteRxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
26889 + RETURN_ERROR(MINOR, err, NO_MSG);
26890 + }
26891 + else
26892 + if ((err = FmMacsecDeleteTxSc(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId)) != E_OK)
26893 + RETURN_ERROR(MINOR, err, NO_MSG);
26894 +
26895 + p_FmSecYSc->inUse = FALSE;
26896 +
26897 + return err;
26898 +}
26899 +
26900 +/****************************************/
26901 +/* API Init unit functions */
26902 +/****************************************/
26903 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam)
26904 +{
26905 + t_FmMacsecSecY *p_FmMacsecSecY;
26906 +
26907 + /* Allocate FM MACSEC structure */
26908 + p_FmMacsecSecY = (t_FmMacsecSecY *) XX_Malloc(sizeof(t_FmMacsecSecY));
26909 + if (!p_FmMacsecSecY)
26910 + {
26911 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver structure"));
26912 + return NULL;
26913 + }
26914 + memset(p_FmMacsecSecY, 0, sizeof(t_FmMacsecSecY));
26915 +
26916 + /* Allocate the FM MACSEC driver's parameters structure */
26917 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = (t_FmMacsecSecYDriverParam *)XX_Malloc(sizeof(t_FmMacsecSecYDriverParam));
26918 + if (!p_FmMacsecSecY->p_FmMacsecSecYDriverParam)
26919 + {
26920 + XX_Free(p_FmMacsecSecY);
26921 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY driver parameters"));
26922 + return NULL;
26923 + }
26924 + memset(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, 0, sizeof(t_FmMacsecSecYDriverParam));
26925 +
26926 + /* Initialize FM MACSEC SECY parameters which will be kept by the driver */
26927 + p_FmMacsecSecY->h_FmMacsec = p_FmMacsecSecYParam->h_FmMacsec;
26928 + p_FmMacsecSecY->f_Event = p_FmMacsecSecYParam->f_Event;
26929 + p_FmMacsecSecY->f_Exception = p_FmMacsecSecYParam->f_Exception;
26930 + p_FmMacsecSecY->h_App = p_FmMacsecSecYParam->h_App;
26931 + p_FmMacsecSecY->confidentialityEnable = DEFAULT_confidentialityEnable;
26932 + p_FmMacsecSecY->confidentialityOffset = DEFAULT_confidentialityOffset;
26933 + p_FmMacsecSecY->validateFrames = DEFAULT_validateFrames;
26934 + p_FmMacsecSecY->replayProtect = DEFAULT_replayEnable;
26935 + p_FmMacsecSecY->replayWindow = DEFAULT_replayWindow;
26936 + p_FmMacsecSecY->protectFrames = DEFAULT_protectFrames;
26937 + p_FmMacsecSecY->sciInsertionMode = DEFAULT_sciInsertionMode;
26938 + p_FmMacsecSecY->isPointToPoint = DEFAULT_ptp;
26939 + p_FmMacsecSecY->numOfRxSc = p_FmMacsecSecYParam->numReceiveChannels;
26940 + p_FmMacsecSecY->numOfTxSc = DEFAULT_numOfTxSc;
26941 + p_FmMacsecSecY->exceptions = DEFAULT_exceptions;
26942 + p_FmMacsecSecY->events = DEFAULT_events;
26943 +
26944 + memcpy(&p_FmMacsecSecY->p_FmMacsecSecYDriverParam->txScParams,
26945 + &p_FmMacsecSecYParam->txScParams,
26946 + sizeof(t_FmMacsecSecYSCParams));
26947 + return p_FmMacsecSecY;
26948 +}
26949 +
26950 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY)
26951 +{
26952 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
26953 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam = NULL;
26954 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i, j;
26955 + t_Error err;
26956 +
26957 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
26958 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_HANDLE);
26959 +
26960 + CHECK_INIT_PARAMETERS(p_FmMacsecSecY, CheckFmMacsecSecYParameters);
26961 +
26962 + p_FmMacsecSecYDriverParam = p_FmMacsecSecY->p_FmMacsecSecYDriverParam;
26963 +
26964 + if ((p_FmMacsecSecY->isPointToPoint) &&
26965 + ((err = FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, TRUE)) != E_OK))
26966 + RETURN_ERROR(MAJOR, err, ("Can't set Poin-to-Point"));
26967 +
26968 + /* Rx Sc Allocation */
26969 + p_FmMacsecSecY->p_RxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
26970 + if (!p_FmMacsecSecY->p_RxSc)
26971 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY RX SC"));
26972 + memset(p_FmMacsecSecY->p_RxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfRxSc);
26973 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
26974 + {
26975 + if (p_FmMacsecSecY->p_TxSc)
26976 + XX_Free(p_FmMacsecSecY->p_TxSc);
26977 + if (p_FmMacsecSecY->p_RxSc)
26978 + XX_Free(p_FmMacsecSecY->p_RxSc);
26979 + return ERROR_CODE(err);
26980 + }
26981 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
26982 + {
26983 + p_FmMacsecSecY->p_RxSc[i].scId = rxScIds[i];
26984 + p_FmMacsecSecY->p_RxSc[i].type = e_SC_RX;
26985 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
26986 + p_FmMacsecSecY->p_RxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
26987 + }
26988 +
26989 + /* Tx Sc Allocation */
26990 + p_FmMacsecSecY->p_TxSc = (t_SecYSc *)XX_Malloc(sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
26991 + if (!p_FmMacsecSecY->p_TxSc)
26992 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM MACSEC SECY TX SC"));
26993 + memset(p_FmMacsecSecY->p_TxSc, 0, sizeof(t_SecYSc) * p_FmMacsecSecY->numOfTxSc);
26994 +
26995 + if ((err = FmMacsecAllocScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->isPointToPoint, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
26996 + {
26997 + if (p_FmMacsecSecY->p_TxSc)
26998 + XX_Free(p_FmMacsecSecY->p_TxSc);
26999 + if (p_FmMacsecSecY->p_RxSc)
27000 + XX_Free(p_FmMacsecSecY->p_RxSc);
27001 + return ERROR_CODE(err);
27002 + }
27003 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++)
27004 + {
27005 + p_FmMacsecSecY->p_TxSc[i].scId = txScIds[i];
27006 + p_FmMacsecSecY->p_TxSc[i].type = e_SC_TX;
27007 + for (j=0; j<MAX_NUM_OF_SA_PER_SC;j++)
27008 + p_FmMacsecSecY->p_TxSc[i].sa[j].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
27009 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
27010 + e_FM_MACSEC_MOD_SC_TX,
27011 + (uint8_t)txScIds[i],
27012 + e_FM_INTR_TYPE_ERR,
27013 + FmMacsecSecYExceptionsIsr,
27014 + p_FmMacsecSecY);
27015 + FmMacsecRegisterIntr(p_FmMacsecSecY->h_FmMacsec,
27016 + e_FM_MACSEC_MOD_SC_TX,
27017 + (uint8_t)txScIds[i],
27018 + e_FM_INTR_TYPE_NORMAL,
27019 + FmMacsecSecYEventsIsr,
27020 + p_FmMacsecSecY);
27021 +
27022 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
27023 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], TRUE);
27024 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
27025 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], TRUE);
27026 + }
27027 +
27028 + FmMacsecSecYCreateSc(p_FmMacsecSecY,
27029 + p_FmMacsecSecYDriverParam->txScParams.sci,
27030 + p_FmMacsecSecYDriverParam->txScParams.cipherSuite,
27031 + e_SC_TX);
27032 + XX_Free(p_FmMacsecSecYDriverParam);
27033 + p_FmMacsecSecY->p_FmMacsecSecYDriverParam = NULL;
27034 +
27035 + return E_OK;
27036 +}
27037 +
27038 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY)
27039 +{
27040 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27041 + t_Error err = E_OK;
27042 + uint32_t rxScIds[NUM_OF_RX_SC], txScIds[NUM_OF_TX_SC], i;
27043 +
27044 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27045 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27046 +
27047 + if (p_FmMacsecSecY->isPointToPoint)
27048 + FmMacsecSetPTP(p_FmMacsecSecY->h_FmMacsec, FALSE);
27049 + if (p_FmMacsecSecY->p_RxSc)
27050 + {
27051 + for (i=0; i<p_FmMacsecSecY->numOfRxSc; i++)
27052 + rxScIds[i] = p_FmMacsecSecY->p_RxSc[i].scId;
27053 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_RX, p_FmMacsecSecY->numOfRxSc, rxScIds)) != E_OK)
27054 + return ERROR_CODE(err);
27055 + XX_Free(p_FmMacsecSecY->p_RxSc);
27056 + }
27057 + if (p_FmMacsecSecY->p_TxSc)
27058 + {
27059 + FmMacsecSecYDeleteSc(p_FmMacsecSecY, &p_FmMacsecSecY->p_TxSc[0], e_SC_TX);
27060 +
27061 + for (i=0; i<p_FmMacsecSecY->numOfTxSc; i++) {
27062 + txScIds[i] = p_FmMacsecSecY->p_TxSc[i].scId;
27063 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
27064 + e_FM_MACSEC_MOD_SC_TX,
27065 + (uint8_t)txScIds[i],
27066 + e_FM_INTR_TYPE_ERR);
27067 + FmMacsecUnregisterIntr(p_FmMacsecSecY->h_FmMacsec,
27068 + e_FM_MACSEC_MOD_SC_TX,
27069 + (uint8_t)txScIds[i],
27070 + e_FM_INTR_TYPE_NORMAL);
27071 +
27072 + if (p_FmMacsecSecY->exceptions & FM_MACSEC_SECY_EX_FRAME_DISCARDED)
27073 + FmMacsecSetException(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EX_TX_SC, txScIds[i], FALSE);
27074 + if (p_FmMacsecSecY->events & FM_MACSEC_SECY_EV_NEXT_PN)
27075 + FmMacsecSetEvent(p_FmMacsecSecY->h_FmMacsec, e_FM_MACSEC_EV_TX_SC_NEXT_PN, txScIds[i], FALSE);
27076 + }
27077 +
27078 + if ((err = FmMacsecFreeScs(p_FmMacsecSecY->h_FmMacsec, e_SC_TX, p_FmMacsecSecY->numOfTxSc, txScIds)) != E_OK)
27079 + return ERROR_CODE(err);
27080 + XX_Free(p_FmMacsecSecY->p_TxSc);
27081 + }
27082 +
27083 + XX_Free(p_FmMacsecSecY);
27084 +
27085 + return err;
27086 +}
27087 +
27088 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode)
27089 +{
27090 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27091 +
27092 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27093 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27094 +
27095 + p_FmMacsecSecY->sciInsertionMode = sciInsertionMode;
27096 +
27097 + return E_OK;
27098 +}
27099 +
27100 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames)
27101 +{
27102 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27103 +
27104 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27105 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27106 +
27107 + p_FmMacsecSecY->protectFrames = protectFrames;
27108 +
27109 + return E_OK;
27110 +}
27111 +
27112 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow)
27113 +{
27114 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27115 +
27116 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27117 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27118 +
27119 + p_FmMacsecSecY->replayProtect = replayProtect;
27120 + p_FmMacsecSecY->replayWindow = replayWindow;
27121 +
27122 + return E_OK;
27123 +}
27124 +
27125 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames)
27126 +{
27127 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27128 +
27129 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27130 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27131 +
27132 + p_FmMacsecSecY->validateFrames = validateFrames;
27133 +
27134 + return E_OK;
27135 +}
27136 +
27137 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset)
27138 +{
27139 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27140 +
27141 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27142 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27143 +
27144 + p_FmMacsecSecY->confidentialityEnable = confidentialityEnable;
27145 + p_FmMacsecSecY->confidentialityOffset = confidentialityOffset;
27146 +
27147 + return E_OK;
27148 +}
27149 +
27150 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY)
27151 +{
27152 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27153 +
27154 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27155 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27156 +
27157 + p_FmMacsecSecY->numOfRxSc = 1;
27158 + p_FmMacsecSecY->isPointToPoint = TRUE;
27159 + p_FmMacsecSecY->sciInsertionMode = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP;
27160 +
27161 + return E_OK;
27162 +}
27163 +
27164 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable)
27165 +{
27166 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27167 + uint32_t bitMask = 0;
27168 +
27169 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27170 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27171 +
27172 + GET_EXCEPTION_FLAG(bitMask, exception);
27173 + if (bitMask)
27174 + {
27175 + if (enable)
27176 + p_FmMacsecSecY->exceptions |= bitMask;
27177 + else
27178 + p_FmMacsecSecY->exceptions &= ~bitMask;
27179 + }
27180 + else
27181 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
27182 +
27183 + return E_OK;
27184 +}
27185 +
27186 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
27187 +{
27188 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27189 + uint32_t bitMask = 0;
27190 +
27191 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27192 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27193 +
27194 + GET_EVENT_FLAG(bitMask, event);
27195 + if (bitMask)
27196 + {
27197 + if (enable)
27198 + p_FmMacsecSecY->events |= bitMask;
27199 + else
27200 + p_FmMacsecSecY->events &= ~bitMask;
27201 + }
27202 + else
27203 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined event"));
27204 +
27205 + return E_OK;
27206 +}
27207 +
27208 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams)
27209 +{
27210 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27211 +
27212 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY, E_INVALID_HANDLE, NULL);
27213 + SANITY_CHECK_RETURN_VALUE(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE, NULL);
27214 + SANITY_CHECK_RETURN_VALUE(p_ScParams, E_NULL_POINTER, NULL);
27215 + SANITY_CHECK_RETURN_VALUE(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE, NULL);
27216 +
27217 + return FmMacsecSecYCreateSc(p_FmMacsecSecY, p_ScParams->sci, p_ScParams->cipherSuite, e_SC_RX);
27218 +}
27219 +
27220 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc)
27221 +{
27222 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27223 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27224 +
27225 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27226 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27227 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27228 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27229 +
27230 + return FmMacsecSecYDeleteSc(p_FmMacsecSecY, p_FmSecYSc, e_SC_RX);
27231 +}
27232 +
27233 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key)
27234 +{
27235 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27236 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27237 + t_Error err = E_OK;
27238 +
27239 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27240 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27241 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27242 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27243 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27244 +
27245 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
27246 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already assigned",an));
27247 +
27248 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, an, lowestPn, key)) != E_OK)
27249 + RETURN_ERROR(MINOR, err, NO_MSG);
27250 +
27251 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
27252 + return err;
27253 +}
27254 +
27255 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
27256 +{
27257 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27258 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27259 + t_Error err = E_OK;
27260 +
27261 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27262 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27263 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27264 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27265 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27266 +
27267 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27268 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
27269 +
27270 + if ((err = FmMacsecDeleteRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
27271 + RETURN_ERROR(MINOR, err, NO_MSG);
27272 +
27273 + p_FmSecYSc->numOfSa--;
27274 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
27275 + /* TODO - check if statistics need to be read*/
27276 + return err;
27277 +}
27278 +
27279 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
27280 +{
27281 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27282 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27283 + t_Error err = E_OK;
27284 +
27285 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27286 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27287 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27288 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27289 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27290 +
27291 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27292 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
27293 +
27294 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
27295 + RETURN_ERROR(MINOR, err, NO_MSG);
27296 +
27297 + p_FmSecYSc->sa[an].active = TRUE;
27298 + return err;
27299 +}
27300 +
27301 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an)
27302 +{
27303 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27304 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27305 + t_Error err = E_OK;
27306 +
27307 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27308 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27309 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27310 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27311 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27312 +
27313 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27314 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
27315 +
27316 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
27317 + RETURN_ERROR(MINOR, err, NO_MSG);
27318 +
27319 + p_FmSecYSc->sa[an].active = FALSE;
27320 + return err;
27321 +}
27322 +
27323 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN)
27324 +{
27325 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27326 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27327 + t_Error err = E_OK;
27328 +
27329 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27330 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27331 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27332 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27333 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27334 +
27335 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27336 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
27337 +
27338 + if ((err = FmMacsecRxSaUpdateNextPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtNextPN)) != E_OK)
27339 + RETURN_ERROR(MINOR, err, NO_MSG);
27340 +
27341 + return err;
27342 +}
27343 +
27344 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN)
27345 +{
27346 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27347 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27348 + t_Error err = E_OK;
27349 +
27350 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27351 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27352 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27353 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27354 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27355 +
27356 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27357 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
27358 +
27359 + if ((err = FmMacsecRxSaUpdateLowestPn(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, updtLowestPN)) != E_OK)
27360 + RETURN_ERROR(MINOR, err, NO_MSG);
27361 +
27362 + return err;
27363 +}
27364 +
27365 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key)
27366 +{
27367 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27368 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27369 + t_Error err = E_OK;
27370 +
27371 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27372 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27373 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27374 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27375 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27376 +
27377 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27378 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
27379 +
27380 + if (p_FmSecYSc->sa[an].active)
27381 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, FALSE)) != E_OK)
27382 + RETURN_ERROR(MINOR, err, NO_MSG);
27383 +
27384 + /* TODO - statistics should be read */
27385 +
27386 + if ((err = FmMacsecCreateRxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, an, 1, key)) != E_OK)
27387 + RETURN_ERROR(MINOR, err, NO_MSG);
27388 +
27389 + if (p_FmSecYSc->sa[an].active)
27390 + if ((err = FmMacsecRxSaSetReceive(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId, TRUE)) != E_OK)
27391 + RETURN_ERROR(MINOR, err, NO_MSG);
27392 + return err;
27393 +}
27394 +
27395 +
27396 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key)
27397 +{
27398 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27399 + t_SecYSc *p_FmSecYSc;
27400 + t_Error err = E_OK;
27401 +
27402 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27403 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27404 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27405 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27406 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27407 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27408 +
27409 + if (p_FmSecYSc->sa[an].saId != SECY_AN_FREE_VALUE)
27410 + RETURN_ERROR(MINOR, err, ("An %d is already assigned",an));
27411 +
27412 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec,p_FmSecYSc->scId, (e_ScSaId)p_FmSecYSc->numOfSa, key)) != E_OK)
27413 + RETURN_ERROR(MINOR, err, NO_MSG);
27414 +
27415 + p_FmSecYSc->sa[an].saId = (e_ScSaId)p_FmSecYSc->numOfSa++;
27416 + return err;
27417 +}
27418 +
27419 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an)
27420 +{
27421 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27422 + t_SecYSc *p_FmSecYSc;
27423 + t_Error err = E_OK;
27424 +
27425 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27426 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27427 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27428 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27429 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27430 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27431 +
27432 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27433 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is already deleted",an));
27434 +
27435 + if ((err = FmMacsecDeleteTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[an].saId)) != E_OK)
27436 + RETURN_ERROR(MINOR, err, NO_MSG);
27437 +
27438 + p_FmSecYSc->numOfSa--;
27439 + p_FmSecYSc->sa[an].saId = (e_ScSaId)SECY_AN_FREE_VALUE;
27440 + /* TODO - check if statistics need to be read*/
27441 + return err;
27442 +}
27443 +
27444 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key)
27445 +{
27446 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27447 + t_SecYSc *p_FmSecYSc;
27448 + macsecAN_t currentAn;
27449 + t_Error err = E_OK;
27450 +
27451 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27452 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27453 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27454 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27455 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27456 + SANITY_CHECK_RETURN_ERROR(nextActiveAn < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27457 +
27458 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
27459 + p_FmSecYSc->scId,
27460 + &currentAn)) != E_OK)
27461 + RETURN_ERROR(MINOR, err, NO_MSG);
27462 +
27463 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
27464 + p_FmSecYSc->scId,
27465 + p_FmSecYSc->sa[nextActiveAn].saId,
27466 + nextActiveAn)) != E_OK)
27467 + RETURN_ERROR(MINOR, err, NO_MSG);
27468 +
27469 + /* TODO - statistics should be read */
27470 +
27471 + if ((err = FmMacsecCreateTxSa(p_FmMacsecSecY->h_FmMacsec, p_FmSecYSc->scId, p_FmSecYSc->sa[currentAn].saId, key)) != E_OK)
27472 + RETURN_ERROR(MINOR, err, NO_MSG);
27473 +
27474 + return err;
27475 +}
27476 +
27477 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an)
27478 +{
27479 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27480 + t_SecYSc *p_FmSecYSc;
27481 + t_Error err = E_OK;
27482 +
27483 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27484 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27485 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27486 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27487 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27488 + SANITY_CHECK_RETURN_ERROR(an < MAX_NUM_OF_SA_PER_SC, E_INVALID_STATE);
27489 +
27490 + if (p_FmSecYSc->sa[an].saId == SECY_AN_FREE_VALUE)
27491 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("An %d is not configured",an));
27492 +
27493 + if ((err = FmMacsecTxSaSetActive(p_FmMacsecSecY->h_FmMacsec,
27494 + p_FmSecYSc->scId,
27495 + p_FmSecYSc->sa[an].saId,
27496 + an)) != E_OK)
27497 + RETURN_ERROR(MINOR, err, NO_MSG);
27498 +
27499 + return err;
27500 +}
27501 +
27502 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An)
27503 +{
27504 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27505 + t_SecYSc *p_FmSecYSc;
27506 + t_Error err = E_OK;
27507 +
27508 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27509 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27510 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27511 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27512 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27513 + SANITY_CHECK_RETURN_ERROR(p_An, E_INVALID_HANDLE);
27514 +
27515 + if ((err = FmMacsecTxSaGetActive(p_FmMacsecSecY->h_FmMacsec,
27516 + p_FmSecYSc->scId,
27517 + p_An)) != E_OK)
27518 + RETURN_ERROR(MINOR, err, NO_MSG);
27519 +
27520 + return err;
27521 +}
27522 +
27523 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId)
27524 +{
27525 + t_SecYSc *p_FmSecYSc = (t_SecYSc *)h_Sc;
27526 + t_Error err = E_OK;
27527 +
27528 + SANITY_CHECK_RETURN_ERROR(h_FmMacsecSecY, E_INVALID_HANDLE);
27529 + SANITY_CHECK_RETURN_ERROR(((t_FmMacsecSecY *)h_FmMacsecSecY)->h_FmMacsec, E_INVALID_HANDLE);
27530 + SANITY_CHECK_RETURN_ERROR(!((t_FmMacsecSecY *)h_FmMacsecSecY)->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27531 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27532 +#ifdef DISABLE_SANITY_CHECKS
27533 + UNUSED(h_FmMacsecSecY);
27534 +#endif /* DISABLE_SANITY_CHECKS */
27535 +
27536 + *p_ScPhysId = p_FmSecYSc->scId;
27537 + return err;
27538 +}
27539 +
27540 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId)
27541 +{
27542 + t_FmMacsecSecY *p_FmMacsecSecY = (t_FmMacsecSecY *)h_FmMacsecSecY;
27543 + t_SecYSc *p_FmSecYSc;
27544 + t_Error err = E_OK;
27545 +
27546 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY, E_INVALID_HANDLE);
27547 + SANITY_CHECK_RETURN_ERROR(p_FmMacsecSecY->h_FmMacsec, E_INVALID_HANDLE);
27548 + SANITY_CHECK_RETURN_ERROR(!p_FmMacsecSecY->p_FmMacsecSecYDriverParam, E_INVALID_STATE);
27549 + p_FmSecYSc = &p_FmMacsecSecY->p_TxSc[0];
27550 + SANITY_CHECK_RETURN_ERROR(p_FmSecYSc, E_INVALID_HANDLE);
27551 +
27552 + *p_ScPhysId = p_FmSecYSc->scId;
27553 + return err;
27554 +}
27555 +
27556 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable)
27557 +{
27558 + UNUSED(h_FmMacsecSecY);UNUSED(exception);UNUSED(enable);
27559 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27560 +}
27561 +
27562 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable)
27563 +{
27564 + UNUSED(h_FmMacsecSecY);UNUSED(event);UNUSED(enable);
27565 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27566 +}
27567 +
27568 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics)
27569 +{
27570 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
27571 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27572 +}
27573 +
27574 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics)
27575 +{
27576 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(p_Statistics);
27577 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27578 +}
27579 +
27580 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics)
27581 +{
27582 + UNUSED(h_FmMacsecSecY);UNUSED(h_Sc);UNUSED(an);UNUSED(p_Statistics);
27583 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27584 +}
27585 +
27586 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics)
27587 +{
27588 + UNUSED(h_FmMacsecSecY);UNUSED(p_Statistics);
27589 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27590 +}
27591 +
27592 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics)
27593 +{
27594 + UNUSED(h_FmMacsecSecY);UNUSED(an);UNUSED(p_Statistics);
27595 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
27596 +}
27597 +
27598 --- /dev/null
27599 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/MACSEC/fm_macsec_secy.h
27600 @@ -0,0 +1,144 @@
27601 +/*
27602 + * Copyright 2008-2015 Freescale Semiconductor Inc.
27603 + *
27604 + * Redistribution and use in source and binary forms, with or without
27605 + * modification, are permitted provided that the following conditions are met:
27606 + * * Redistributions of source code must retain the above copyright
27607 + * notice, this list of conditions and the following disclaimer.
27608 + * * Redistributions in binary form must reproduce the above copyright
27609 + * notice, this list of conditions and the following disclaimer in the
27610 + * documentation and/or other materials provided with the distribution.
27611 + * * Neither the name of Freescale Semiconductor nor the
27612 + * names of its contributors may be used to endorse or promote products
27613 + * derived from this software without specific prior written permission.
27614 + *
27615 + *
27616 + * ALTERNATIVELY, this software may be distributed under the terms of the
27617 + * GNU General Public License ("GPL") as published by the Free Software
27618 + * Foundation, either version 2 of that License or (at your option) any
27619 + * later version.
27620 + *
27621 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
27622 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27623 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27624 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27625 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27626 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27627 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27628 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27629 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27630 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27631 + */
27632 +
27633 +/******************************************************************************
27634 + @File fm_macsec_secy.h
27635 +
27636 + @Description FM MACSEC SecY internal structures and definitions.
27637 +*//***************************************************************************/
27638 +#ifndef __FM_MACSEC_SECY_H
27639 +#define __FM_MACSEC_SECY_H
27640 +
27641 +#include "error_ext.h"
27642 +#include "std_ext.h"
27643 +
27644 +#include "fm_macsec.h"
27645 +
27646 +
27647 +/**************************************************************************//**
27648 + @Description Exceptions
27649 +*//***************************************************************************/
27650 +
27651 +#define FM_MACSEC_SECY_EX_FRAME_DISCARDED 0x80000000
27652 +
27653 +#define GET_EXCEPTION_FLAG(bitMask, exception) switch (exception){ \
27654 + case e_FM_MACSEC_SECY_EX_FRAME_DISCARDED: \
27655 + bitMask = FM_MACSEC_SECY_EX_FRAME_DISCARDED; break; \
27656 + default: bitMask = 0;break;}
27657 +
27658 +/**************************************************************************//**
27659 + @Description Events
27660 +*//***************************************************************************/
27661 +
27662 +#define FM_MACSEC_SECY_EV_NEXT_PN 0x80000000
27663 +
27664 +#define GET_EVENT_FLAG(bitMask, event) switch (event){ \
27665 + case e_FM_MACSEC_SECY_EV_NEXT_PN: \
27666 + bitMask = FM_MACSEC_SECY_EV_NEXT_PN; break; \
27667 + default: bitMask = 0;break;}
27668 +
27669 +/**************************************************************************//**
27670 + @Description Defaults
27671 +*//***************************************************************************/
27672 +
27673 +#define DEFAULT_exceptions (FM_MACSEC_SECY_EX_FRAME_DISCARDED)
27674 +#define DEFAULT_events (FM_MACSEC_SECY_EV_NEXT_PN)
27675 +#define DEFAULT_numOfTxSc 1
27676 +#define DEFAULT_confidentialityEnable FALSE
27677 +#define DEFAULT_confidentialityOffset 0
27678 +#define DEFAULT_sciInsertionMode e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG
27679 +#define DEFAULT_validateFrames e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
27680 +#define DEFAULT_replayEnable FALSE
27681 +#define DEFAULT_replayWindow 0
27682 +#define DEFAULT_protectFrames TRUE
27683 +#define DEFAULT_ptp FALSE
27684 +
27685 +/**************************************************************************//**
27686 + @Description General defines
27687 +*//***************************************************************************/
27688 +
27689 +#define SECY_AN_FREE_VALUE MAX_NUM_OF_SA_PER_SC
27690 +
27691 +
27692 +typedef struct {
27693 + e_ScSaId saId;
27694 + bool active;
27695 + union {
27696 + t_FmMacsecSecYRxSaStatistics rxSaStatistics;
27697 + t_FmMacsecSecYTxSaStatistics txSaStatistics;
27698 + };
27699 +} t_SecYSa;
27700 +
27701 +typedef struct {
27702 + bool inUse;
27703 + uint32_t scId;
27704 + e_ScType type;
27705 + uint8_t numOfSa;
27706 + t_SecYSa sa[MAX_NUM_OF_SA_PER_SC];
27707 + union {
27708 + t_FmMacsecSecYRxScStatistics rxScStatistics;
27709 + t_FmMacsecSecYTxScStatistics txScStatistics;
27710 + };
27711 +} t_SecYSc;
27712 +
27713 +typedef struct {
27714 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
27715 +} t_FmMacsecSecYDriverParam;
27716 +
27717 +typedef struct {
27718 + t_Handle h_FmMacsec;
27719 + bool confidentialityEnable; /**< TRUE - confidentiality protection and integrity protection
27720 + FALSE - no confidentiality protection, only integrity protection*/
27721 + uint16_t confidentialityOffset; /**< The number of initial octets of each MSDU without confidentiality protection
27722 + common values are 0, 30, and 50 */
27723 + bool replayProtect; /**< replay protection function mode */
27724 + uint32_t replayWindow; /**< the size of the replay window */
27725 + e_FmMacsecValidFrameBehavior validateFrames; /**< validation function mode */
27726 + e_FmMacsecSciInsertionMode sciInsertionMode;
27727 + bool protectFrames;
27728 + bool isPointToPoint;
27729 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for this SecY */
27730 + uint32_t numOfRxSc; /**< Number of receive channels */
27731 + uint32_t numOfTxSc; /**< Number of transmit channels */
27732 + t_SecYSc *p_RxSc;
27733 + t_SecYSc *p_TxSc;
27734 + uint32_t events;
27735 + uint32_t exceptions;
27736 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< TODO */
27737 + t_FmMacsecSecYEventsCallback *f_Event; /**< TODO */
27738 + t_Handle h_App;
27739 + t_FmMacsecSecYStatistics statistics;
27740 + t_FmMacsecSecYDriverParam *p_FmMacsecSecYDriverParam;
27741 +} t_FmMacsecSecY;
27742 +
27743 +
27744 +#endif /* __FM_MACSEC_SECY_H */
27745 --- /dev/null
27746 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Makefile
27747 @@ -0,0 +1,23 @@
27748 +#
27749 +# Makefile for the Freescale Ethernet controllers
27750 +#
27751 +ccflags-y += -DVERSION=\"\"
27752 +#
27753 +#Include netcomm SW specific definitions
27754 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
27755 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
27756 +
27757 +ccflags-y += -I$(NCSW_FM_INC)
27758 +
27759 +
27760 +obj-y += fsl-ncsw-PFM1.o
27761 +
27762 +fsl-ncsw-PFM1-objs := fm.o fm_muram.o fman.o
27763 +
27764 +obj-y += MAC/
27765 +obj-y += Pcd/
27766 +obj-y += SP/
27767 +obj-y += Port/
27768 +obj-y += HC/
27769 +obj-y += Rtc/
27770 +obj-y += MACSEC/
27771 --- /dev/null
27772 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/Makefile
27773 @@ -0,0 +1,26 @@
27774 +#
27775 +# Makefile for the Freescale Ethernet controllers
27776 +#
27777 +ccflags-y += -DVERSION=\"\"
27778 +#
27779 +#Include netcomm SW specific definitions
27780 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
27781 +
27782 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
27783 +
27784 +ccflags-y += -I$(NCSW_FM_INC)
27785 +
27786 +obj-y += fsl-ncsw-Pcd.o
27787 +
27788 +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
27789 +
27790 +ifeq ($(CONFIG_FMAN_V3H),y)
27791 +fsl-ncsw-Pcd-objs += fm_replic.o
27792 +endif
27793 +ifeq ($(CONFIG_FMAN_V3L),y)
27794 +fsl-ncsw-Pcd-objs += fm_replic.o
27795 +endif
27796 +ifeq ($(CONFIG_FMAN_ARM),y)
27797 +fsl-ncsw-Pcd-objs += fm_replic.o
27798 +endif
27799 +
27800 --- /dev/null
27801 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/crc64.h
27802 @@ -0,0 +1,360 @@
27803 +/*
27804 + * Copyright 2008-2012 Freescale Semiconductor Inc.
27805 + *
27806 + * Redistribution and use in source and binary forms, with or without
27807 + * modification, are permitted provided that the following conditions are met:
27808 + * * Redistributions of source code must retain the above copyright
27809 + * notice, this list of conditions and the following disclaimer.
27810 + * * Redistributions in binary form must reproduce the above copyright
27811 + * notice, this list of conditions and the following disclaimer in the
27812 + * documentation and/or other materials provided with the distribution.
27813 + * * Neither the name of Freescale Semiconductor nor the
27814 + * names of its contributors may be used to endorse or promote products
27815 + * derived from this software without specific prior written permission.
27816 + *
27817 + *
27818 + * ALTERNATIVELY, this software may be distributed under the terms of the
27819 + * GNU General Public License ("GPL") as published by the Free Software
27820 + * Foundation, either version 2 of that License or (at your option) any
27821 + * later version.
27822 + *
27823 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
27824 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27825 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27826 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27827 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27828 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27829 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27830 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27831 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27832 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27833 + */
27834 +
27835 +
27836 + /**************************************************************************//**
27837 + @File crc64.h
27838 +
27839 + @Description brief This file contains the CRC64 Table, and __inline__
27840 + functions used for calculating crc.
27841 +*//***************************************************************************/
27842 +#ifndef __CRC64_H
27843 +#define __CRC64_H
27844 +
27845 +#include "std_ext.h"
27846 +
27847 +
27848 +#define BITS_PER_BYTE 8
27849 +
27850 +#define CRC64_EXPON_ECMA_182 0xC96C5795D7870F42ULL
27851 +#define CRC64_DEFAULT_INITVAL 0xFFFFFFFFFFFFFFFFULL
27852 +
27853 +#define CRC64_BYTE_MASK 0xFF
27854 +#define CRC64_TABLE_ENTRIES ( 1 << BITS_PER_BYTE )
27855 +#define CRC64_ODD_MASK 1
27856 +
27857 +
27858 +/**
27859 + \brief '64 bit crc' Table
27860 + */
27861 +struct crc64_t {
27862 + uint64_t initial; /**< Initial seed */
27863 + uint64_t table[CRC64_TABLE_ENTRIES]; /**< CRC table entries */
27864 +};
27865 +
27866 +
27867 +static struct crc64_t CRC64_ECMA_182 = {
27868 + CRC64_DEFAULT_INITVAL,
27869 + {
27870 + 0x0000000000000000ULL,
27871 + 0xb32e4cbe03a75f6fULL,
27872 + 0xf4843657a840a05bULL,
27873 + 0x47aa7ae9abe7ff34ULL,
27874 + 0x7bd0c384ff8f5e33ULL,
27875 + 0xc8fe8f3afc28015cULL,
27876 + 0x8f54f5d357cffe68ULL,
27877 + 0x3c7ab96d5468a107ULL,
27878 + 0xf7a18709ff1ebc66ULL,
27879 + 0x448fcbb7fcb9e309ULL,
27880 + 0x0325b15e575e1c3dULL,
27881 + 0xb00bfde054f94352ULL,
27882 + 0x8c71448d0091e255ULL,
27883 + 0x3f5f08330336bd3aULL,
27884 + 0x78f572daa8d1420eULL,
27885 + 0xcbdb3e64ab761d61ULL,
27886 + 0x7d9ba13851336649ULL,
27887 + 0xceb5ed8652943926ULL,
27888 + 0x891f976ff973c612ULL,
27889 + 0x3a31dbd1fad4997dULL,
27890 + 0x064b62bcaebc387aULL,
27891 + 0xb5652e02ad1b6715ULL,
27892 + 0xf2cf54eb06fc9821ULL,
27893 + 0x41e11855055bc74eULL,
27894 + 0x8a3a2631ae2dda2fULL,
27895 + 0x39146a8fad8a8540ULL,
27896 + 0x7ebe1066066d7a74ULL,
27897 + 0xcd905cd805ca251bULL,
27898 + 0xf1eae5b551a2841cULL,
27899 + 0x42c4a90b5205db73ULL,
27900 + 0x056ed3e2f9e22447ULL,
27901 + 0xb6409f5cfa457b28ULL,
27902 + 0xfb374270a266cc92ULL,
27903 + 0x48190ecea1c193fdULL,
27904 + 0x0fb374270a266cc9ULL,
27905 + 0xbc9d3899098133a6ULL,
27906 + 0x80e781f45de992a1ULL,
27907 + 0x33c9cd4a5e4ecdceULL,
27908 + 0x7463b7a3f5a932faULL,
27909 + 0xc74dfb1df60e6d95ULL,
27910 + 0x0c96c5795d7870f4ULL,
27911 + 0xbfb889c75edf2f9bULL,
27912 + 0xf812f32ef538d0afULL,
27913 + 0x4b3cbf90f69f8fc0ULL,
27914 + 0x774606fda2f72ec7ULL,
27915 + 0xc4684a43a15071a8ULL,
27916 + 0x83c230aa0ab78e9cULL,
27917 + 0x30ec7c140910d1f3ULL,
27918 + 0x86ace348f355aadbULL,
27919 + 0x3582aff6f0f2f5b4ULL,
27920 + 0x7228d51f5b150a80ULL,
27921 + 0xc10699a158b255efULL,
27922 + 0xfd7c20cc0cdaf4e8ULL,
27923 + 0x4e526c720f7dab87ULL,
27924 + 0x09f8169ba49a54b3ULL,
27925 + 0xbad65a25a73d0bdcULL,
27926 + 0x710d64410c4b16bdULL,
27927 + 0xc22328ff0fec49d2ULL,
27928 + 0x85895216a40bb6e6ULL,
27929 + 0x36a71ea8a7ace989ULL,
27930 + 0x0adda7c5f3c4488eULL,
27931 + 0xb9f3eb7bf06317e1ULL,
27932 + 0xfe5991925b84e8d5ULL,
27933 + 0x4d77dd2c5823b7baULL,
27934 + 0x64b62bcaebc387a1ULL,
27935 + 0xd7986774e864d8ceULL,
27936 + 0x90321d9d438327faULL,
27937 + 0x231c512340247895ULL,
27938 + 0x1f66e84e144cd992ULL,
27939 + 0xac48a4f017eb86fdULL,
27940 + 0xebe2de19bc0c79c9ULL,
27941 + 0x58cc92a7bfab26a6ULL,
27942 + 0x9317acc314dd3bc7ULL,
27943 + 0x2039e07d177a64a8ULL,
27944 + 0x67939a94bc9d9b9cULL,
27945 + 0xd4bdd62abf3ac4f3ULL,
27946 + 0xe8c76f47eb5265f4ULL,
27947 + 0x5be923f9e8f53a9bULL,
27948 + 0x1c4359104312c5afULL,
27949 + 0xaf6d15ae40b59ac0ULL,
27950 + 0x192d8af2baf0e1e8ULL,
27951 + 0xaa03c64cb957be87ULL,
27952 + 0xeda9bca512b041b3ULL,
27953 + 0x5e87f01b11171edcULL,
27954 + 0x62fd4976457fbfdbULL,
27955 + 0xd1d305c846d8e0b4ULL,
27956 + 0x96797f21ed3f1f80ULL,
27957 + 0x2557339fee9840efULL,
27958 + 0xee8c0dfb45ee5d8eULL,
27959 + 0x5da24145464902e1ULL,
27960 + 0x1a083bacedaefdd5ULL,
27961 + 0xa9267712ee09a2baULL,
27962 + 0x955cce7fba6103bdULL,
27963 + 0x267282c1b9c65cd2ULL,
27964 + 0x61d8f8281221a3e6ULL,
27965 + 0xd2f6b4961186fc89ULL,
27966 + 0x9f8169ba49a54b33ULL,
27967 + 0x2caf25044a02145cULL,
27968 + 0x6b055fede1e5eb68ULL,
27969 + 0xd82b1353e242b407ULL,
27970 + 0xe451aa3eb62a1500ULL,
27971 + 0x577fe680b58d4a6fULL,
27972 + 0x10d59c691e6ab55bULL,
27973 + 0xa3fbd0d71dcdea34ULL,
27974 + 0x6820eeb3b6bbf755ULL,
27975 + 0xdb0ea20db51ca83aULL,
27976 + 0x9ca4d8e41efb570eULL,
27977 + 0x2f8a945a1d5c0861ULL,
27978 + 0x13f02d374934a966ULL,
27979 + 0xa0de61894a93f609ULL,
27980 + 0xe7741b60e174093dULL,
27981 + 0x545a57dee2d35652ULL,
27982 + 0xe21ac88218962d7aULL,
27983 + 0x5134843c1b317215ULL,
27984 + 0x169efed5b0d68d21ULL,
27985 + 0xa5b0b26bb371d24eULL,
27986 + 0x99ca0b06e7197349ULL,
27987 + 0x2ae447b8e4be2c26ULL,
27988 + 0x6d4e3d514f59d312ULL,
27989 + 0xde6071ef4cfe8c7dULL,
27990 + 0x15bb4f8be788911cULL,
27991 + 0xa6950335e42fce73ULL,
27992 + 0xe13f79dc4fc83147ULL,
27993 + 0x521135624c6f6e28ULL,
27994 + 0x6e6b8c0f1807cf2fULL,
27995 + 0xdd45c0b11ba09040ULL,
27996 + 0x9aefba58b0476f74ULL,
27997 + 0x29c1f6e6b3e0301bULL,
27998 + 0xc96c5795d7870f42ULL,
27999 + 0x7a421b2bd420502dULL,
28000 + 0x3de861c27fc7af19ULL,
28001 + 0x8ec62d7c7c60f076ULL,
28002 + 0xb2bc941128085171ULL,
28003 + 0x0192d8af2baf0e1eULL,
28004 + 0x4638a2468048f12aULL,
28005 + 0xf516eef883efae45ULL,
28006 + 0x3ecdd09c2899b324ULL,
28007 + 0x8de39c222b3eec4bULL,
28008 + 0xca49e6cb80d9137fULL,
28009 + 0x7967aa75837e4c10ULL,
28010 + 0x451d1318d716ed17ULL,
28011 + 0xf6335fa6d4b1b278ULL,
28012 + 0xb199254f7f564d4cULL,
28013 + 0x02b769f17cf11223ULL,
28014 + 0xb4f7f6ad86b4690bULL,
28015 + 0x07d9ba1385133664ULL,
28016 + 0x4073c0fa2ef4c950ULL,
28017 + 0xf35d8c442d53963fULL,
28018 + 0xcf273529793b3738ULL,
28019 + 0x7c0979977a9c6857ULL,
28020 + 0x3ba3037ed17b9763ULL,
28021 + 0x888d4fc0d2dcc80cULL,
28022 + 0x435671a479aad56dULL,
28023 + 0xf0783d1a7a0d8a02ULL,
28024 + 0xb7d247f3d1ea7536ULL,
28025 + 0x04fc0b4dd24d2a59ULL,
28026 + 0x3886b22086258b5eULL,
28027 + 0x8ba8fe9e8582d431ULL,
28028 + 0xcc0284772e652b05ULL,
28029 + 0x7f2cc8c92dc2746aULL,
28030 + 0x325b15e575e1c3d0ULL,
28031 + 0x8175595b76469cbfULL,
28032 + 0xc6df23b2dda1638bULL,
28033 + 0x75f16f0cde063ce4ULL,
28034 + 0x498bd6618a6e9de3ULL,
28035 + 0xfaa59adf89c9c28cULL,
28036 + 0xbd0fe036222e3db8ULL,
28037 + 0x0e21ac88218962d7ULL,
28038 + 0xc5fa92ec8aff7fb6ULL,
28039 + 0x76d4de52895820d9ULL,
28040 + 0x317ea4bb22bfdfedULL,
28041 + 0x8250e80521188082ULL,
28042 + 0xbe2a516875702185ULL,
28043 + 0x0d041dd676d77eeaULL,
28044 + 0x4aae673fdd3081deULL,
28045 + 0xf9802b81de97deb1ULL,
28046 + 0x4fc0b4dd24d2a599ULL,
28047 + 0xfceef8632775faf6ULL,
28048 + 0xbb44828a8c9205c2ULL,
28049 + 0x086ace348f355aadULL,
28050 + 0x34107759db5dfbaaULL,
28051 + 0x873e3be7d8faa4c5ULL,
28052 + 0xc094410e731d5bf1ULL,
28053 + 0x73ba0db070ba049eULL,
28054 + 0xb86133d4dbcc19ffULL,
28055 + 0x0b4f7f6ad86b4690ULL,
28056 + 0x4ce50583738cb9a4ULL,
28057 + 0xffcb493d702be6cbULL,
28058 + 0xc3b1f050244347ccULL,
28059 + 0x709fbcee27e418a3ULL,
28060 + 0x3735c6078c03e797ULL,
28061 + 0x841b8ab98fa4b8f8ULL,
28062 + 0xadda7c5f3c4488e3ULL,
28063 + 0x1ef430e13fe3d78cULL,
28064 + 0x595e4a08940428b8ULL,
28065 + 0xea7006b697a377d7ULL,
28066 + 0xd60abfdbc3cbd6d0ULL,
28067 + 0x6524f365c06c89bfULL,
28068 + 0x228e898c6b8b768bULL,
28069 + 0x91a0c532682c29e4ULL,
28070 + 0x5a7bfb56c35a3485ULL,
28071 + 0xe955b7e8c0fd6beaULL,
28072 + 0xaeffcd016b1a94deULL,
28073 + 0x1dd181bf68bdcbb1ULL,
28074 + 0x21ab38d23cd56ab6ULL,
28075 + 0x9285746c3f7235d9ULL,
28076 + 0xd52f0e859495caedULL,
28077 + 0x6601423b97329582ULL,
28078 + 0xd041dd676d77eeaaULL,
28079 + 0x636f91d96ed0b1c5ULL,
28080 + 0x24c5eb30c5374ef1ULL,
28081 + 0x97eba78ec690119eULL,
28082 + 0xab911ee392f8b099ULL,
28083 + 0x18bf525d915feff6ULL,
28084 + 0x5f1528b43ab810c2ULL,
28085 + 0xec3b640a391f4fadULL,
28086 + 0x27e05a6e926952ccULL,
28087 + 0x94ce16d091ce0da3ULL,
28088 + 0xd3646c393a29f297ULL,
28089 + 0x604a2087398eadf8ULL,
28090 + 0x5c3099ea6de60cffULL,
28091 + 0xef1ed5546e415390ULL,
28092 + 0xa8b4afbdc5a6aca4ULL,
28093 + 0x1b9ae303c601f3cbULL,
28094 + 0x56ed3e2f9e224471ULL,
28095 + 0xe5c372919d851b1eULL,
28096 + 0xa26908783662e42aULL,
28097 + 0x114744c635c5bb45ULL,
28098 + 0x2d3dfdab61ad1a42ULL,
28099 + 0x9e13b115620a452dULL,
28100 + 0xd9b9cbfcc9edba19ULL,
28101 + 0x6a978742ca4ae576ULL,
28102 + 0xa14cb926613cf817ULL,
28103 + 0x1262f598629ba778ULL,
28104 + 0x55c88f71c97c584cULL,
28105 + 0xe6e6c3cfcadb0723ULL,
28106 + 0xda9c7aa29eb3a624ULL,
28107 + 0x69b2361c9d14f94bULL,
28108 + 0x2e184cf536f3067fULL,
28109 + 0x9d36004b35545910ULL,
28110 + 0x2b769f17cf112238ULL,
28111 + 0x9858d3a9ccb67d57ULL,
28112 + 0xdff2a94067518263ULL,
28113 + 0x6cdce5fe64f6dd0cULL,
28114 + 0x50a65c93309e7c0bULL,
28115 + 0xe388102d33392364ULL,
28116 + 0xa4226ac498dedc50ULL,
28117 + 0x170c267a9b79833fULL,
28118 + 0xdcd7181e300f9e5eULL,
28119 + 0x6ff954a033a8c131ULL,
28120 + 0x28532e49984f3e05ULL,
28121 + 0x9b7d62f79be8616aULL,
28122 + 0xa707db9acf80c06dULL,
28123 + 0x14299724cc279f02ULL,
28124 + 0x5383edcd67c06036ULL,
28125 + 0xe0ada17364673f59ULL
28126 + }
28127 +};
28128 +
28129 +
28130 +/**
28131 + \brief Initializes the crc seed
28132 + */
28133 +static __inline__ uint64_t crc64_init(void)
28134 +{
28135 + return CRC64_ECMA_182.initial;
28136 +}
28137 +
28138 +/**
28139 + \brief Computes 64 bit the crc
28140 + \param[in] data Pointer to the Data in the frame
28141 + \param[in] len Length of the Data
28142 + \param[in] crc seed
28143 + \return calculated crc
28144 + */
28145 +static __inline__ uint64_t crc64_compute(void const *data,
28146 + uint32_t len,
28147 + uint64_t seed)
28148 +{
28149 + uint32_t i;
28150 + uint64_t crc = seed;
28151 + uint8_t *bdata = (uint8_t *) data;
28152 +
28153 + for (i = 0; i < len; i++)
28154 + crc =
28155 + CRC64_ECMA_182.
28156 + table[(crc ^ *bdata++) & CRC64_BYTE_MASK] ^ (crc >> 8);
28157 +
28158 + return crc;
28159 +}
28160 +
28161 +
28162 +#endif /* __CRC64_H */
28163 --- /dev/null
28164 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.c
28165 @@ -0,0 +1,7582 @@
28166 +/*
28167 + * Copyright 2008-2012 Freescale Semiconductor Inc.
28168 + *
28169 + * Redistribution and use in source and binary forms, with or without
28170 + * modification, are permitted provided that the following conditions are met:
28171 + * * Redistributions of source code must retain the above copyright
28172 + * notice, this list of conditions and the following disclaimer.
28173 + * * Redistributions in binary form must reproduce the above copyright
28174 + * notice, this list of conditions and the following disclaimer in the
28175 + * documentation and/or other materials provided with the distribution.
28176 + * * Neither the name of Freescale Semiconductor nor the
28177 + * names of its contributors may be used to endorse or promote products
28178 + * derived from this software without specific prior written permission.
28179 + *
28180 + *
28181 + * ALTERNATIVELY, this software may be distributed under the terms of the
28182 + * GNU General Public License ("GPL") as published by the Free Software
28183 + * Foundation, either version 2 of that License or (at your option) any
28184 + * later version.
28185 + *
28186 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
28187 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28188 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28189 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
28190 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28191 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28192 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28193 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28194 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28195 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28196 + */
28197 +
28198 +
28199 +/******************************************************************************
28200 + @File fm_cc.c
28201 +
28202 + @Description FM Coarse Classifier implementation
28203 + *//***************************************************************************/
28204 +#include <linux/math64.h>
28205 +#include "std_ext.h"
28206 +#include "error_ext.h"
28207 +#include "string_ext.h"
28208 +#include "debug_ext.h"
28209 +#include "fm_pcd_ext.h"
28210 +#include "fm_muram_ext.h"
28211 +
28212 +#include "fm_common.h"
28213 +#include "fm_pcd.h"
28214 +#include "fm_hc.h"
28215 +#include "fm_cc.h"
28216 +#include "crc64.h"
28217 +
28218 +/****************************************/
28219 +/* static functions */
28220 +/****************************************/
28221 +
28222 +
28223 +static t_Error CcRootTryLock(t_Handle h_FmPcdCcTree)
28224 +{
28225 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
28226 +
28227 + ASSERT_COND(h_FmPcdCcTree);
28228 +
28229 + if (FmPcdLockTryLock(p_FmPcdCcTree->p_Lock))
28230 + return E_OK;
28231 +
28232 + return ERROR_CODE(E_BUSY);
28233 +}
28234 +
28235 +static void CcRootReleaseLock(t_Handle h_FmPcdCcTree)
28236 +{
28237 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
28238 +
28239 + ASSERT_COND(h_FmPcdCcTree);
28240 +
28241 + FmPcdLockUnlock(p_FmPcdCcTree->p_Lock);
28242 +}
28243 +
28244 +static void UpdateNodeOwner(t_FmPcdCcNode *p_CcNode, bool add)
28245 +{
28246 + uint32_t intFlags;
28247 +
28248 + ASSERT_COND(p_CcNode);
28249 +
28250 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
28251 +
28252 + if (add)
28253 + p_CcNode->owners++;
28254 + else
28255 + {
28256 + ASSERT_COND(p_CcNode->owners);
28257 + p_CcNode->owners--;
28258 + }
28259 +
28260 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
28261 +}
28262 +
28263 +static __inline__ t_FmPcdStatsObj* DequeueStatsObj(t_List *p_List)
28264 +{
28265 + t_FmPcdStatsObj *p_StatsObj = NULL;
28266 + t_List *p_Next;
28267 +
28268 + if (!LIST_IsEmpty(p_List))
28269 + {
28270 + p_Next = LIST_FIRST(p_List);
28271 + p_StatsObj = LIST_OBJECT(p_Next, t_FmPcdStatsObj, node);
28272 + ASSERT_COND(p_StatsObj);
28273 + LIST_DelAndInit(p_Next);
28274 + }
28275 +
28276 + return p_StatsObj;
28277 +}
28278 +
28279 +static __inline__ void EnqueueStatsObj(t_List *p_List,
28280 + t_FmPcdStatsObj *p_StatsObj)
28281 +{
28282 + LIST_AddToTail(&p_StatsObj->node, p_List);
28283 +}
28284 +
28285 +static void FreeStatObjects(t_List *p_List, t_Handle h_FmMuram)
28286 +{
28287 + t_FmPcdStatsObj *p_StatsObj;
28288 +
28289 + while (!LIST_IsEmpty(p_List))
28290 + {
28291 + p_StatsObj = DequeueStatsObj(p_List);
28292 + ASSERT_COND(p_StatsObj);
28293 +
28294 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
28295 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
28296 +
28297 + XX_Free(p_StatsObj);
28298 + }
28299 +}
28300 +
28301 +static t_FmPcdStatsObj* GetStatsObj(t_FmPcdCcNode *p_CcNode)
28302 +{
28303 + t_FmPcdStatsObj* p_StatsObj;
28304 + t_Handle h_FmMuram;
28305 +
28306 + ASSERT_COND(p_CcNode);
28307 +
28308 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
28309 + upon node initialization */
28310 + if (p_CcNode->maxNumOfKeys)
28311 + {
28312 + p_StatsObj = DequeueStatsObj(&p_CcNode->availableStatsLst);
28313 +
28314 + /* Clean statistics counters & ADs */
28315 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
28316 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
28317 + }
28318 + else
28319 + {
28320 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
28321 + ASSERT_COND(h_FmMuram);
28322 +
28323 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
28324 + if (!p_StatsObj)
28325 + {
28326 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("statistics object"));
28327 + return NULL;
28328 + }
28329 +
28330 + p_StatsObj->h_StatsAd = (t_Handle)FM_MURAM_AllocMem(
28331 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
28332 + if (!p_StatsObj->h_StatsAd)
28333 + {
28334 + XX_Free(p_StatsObj);
28335 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics ADs"));
28336 + return NULL;
28337 + }
28338 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
28339 +
28340 + p_StatsObj->h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
28341 + h_FmMuram, p_CcNode->countersArraySize,
28342 + FM_PCD_CC_AD_TABLE_ALIGN);
28343 + if (!p_StatsObj->h_StatsCounters)
28344 + {
28345 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
28346 + XX_Free(p_StatsObj);
28347 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics counters"));
28348 + return NULL;
28349 + }
28350 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
28351 + }
28352 +
28353 + return p_StatsObj;
28354 +}
28355 +
28356 +static void PutStatsObj(t_FmPcdCcNode *p_CcNode, t_FmPcdStatsObj *p_StatsObj)
28357 +{
28358 + t_Handle h_FmMuram;
28359 +
28360 + ASSERT_COND(p_CcNode);
28361 + ASSERT_COND(p_StatsObj);
28362 +
28363 + /* If 'maxNumOfKeys' was passed, all statistics object were preallocated
28364 + upon node initialization and now will be enqueued back to the list */
28365 + if (p_CcNode->maxNumOfKeys)
28366 + {
28367 + /* Clean statistics counters */
28368 + MemSet8(p_StatsObj->h_StatsCounters, 0, p_CcNode->countersArraySize);
28369 +
28370 + /* Clean statistics ADs */
28371 + MemSet8(p_StatsObj->h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
28372 +
28373 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
28374 + }
28375 + else
28376 + {
28377 + h_FmMuram = ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram;
28378 + ASSERT_COND(h_FmMuram);
28379 +
28380 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsAd);
28381 + FM_MURAM_FreeMem(h_FmMuram, p_StatsObj->h_StatsCounters);
28382 +
28383 + XX_Free(p_StatsObj);
28384 + }
28385 +}
28386 +
28387 +static void SetStatsCounters(t_AdOfTypeStats *p_StatsAd,
28388 + uint32_t statsCountersAddr)
28389 +{
28390 + uint32_t tmp = (statsCountersAddr & FM_PCD_AD_STATS_COUNTERS_ADDR_MASK);
28391 +
28392 + WRITE_UINT32(p_StatsAd->statsTableAddr, tmp);
28393 +}
28394 +
28395 +
28396 +static void UpdateStatsAd(t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28397 + t_Handle h_Ad, uint64_t physicalMuramBase)
28398 +{
28399 + t_AdOfTypeStats *p_StatsAd;
28400 + uint32_t statsCountersAddr, nextActionAddr, tmp;
28401 +#if (DPAA_VERSION >= 11)
28402 + uint32_t frameLengthRangesAddr;
28403 +#endif /* (DPAA_VERSION >= 11) */
28404 +
28405 + p_StatsAd = (t_AdOfTypeStats *)p_FmPcdCcStatsParams->h_StatsAd;
28406 +
28407 + tmp = FM_PCD_AD_STATS_TYPE;
28408 +
28409 +#if (DPAA_VERSION >= 11)
28410 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
28411 + {
28412 + frameLengthRangesAddr = (uint32_t)((XX_VirtToPhys(
28413 + p_FmPcdCcStatsParams->h_StatsFLRs) - physicalMuramBase));
28414 + tmp |= (frameLengthRangesAddr & FM_PCD_AD_STATS_FLR_ADDR_MASK);
28415 + }
28416 +#endif /* (DPAA_VERSION >= 11) */
28417 + WRITE_UINT32(p_StatsAd->profileTableAddr, tmp);
28418 +
28419 + nextActionAddr = (uint32_t)((XX_VirtToPhys(h_Ad) - physicalMuramBase));
28420 + tmp = 0;
28421 + tmp |= (uint32_t)((nextActionAddr << FM_PCD_AD_STATS_NEXT_ACTION_SHIFT)
28422 + & FM_PCD_AD_STATS_NEXT_ACTION_MASK);
28423 + tmp |= (FM_PCD_AD_STATS_NAD_EN | FM_PCD_AD_STATS_OP_CODE);
28424 +
28425 +#if (DPAA_VERSION >= 11)
28426 + if (p_FmPcdCcStatsParams->h_StatsFLRs)
28427 + tmp |= FM_PCD_AD_STATS_FLR_EN;
28428 +#endif /* (DPAA_VERSION >= 11) */
28429 +
28430 + WRITE_UINT32(p_StatsAd->nextActionIndx, tmp);
28431 +
28432 + statsCountersAddr = (uint32_t)((XX_VirtToPhys(
28433 + p_FmPcdCcStatsParams->h_StatsCounters) - physicalMuramBase));
28434 + SetStatsCounters(p_StatsAd, statsCountersAddr);
28435 +}
28436 +
28437 +static void FillAdOfTypeContLookup(t_Handle h_Ad,
28438 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
28439 + t_Handle h_FmPcd, t_Handle p_CcNode,
28440 + t_Handle h_Manip, t_Handle h_FrmReplic)
28441 +{
28442 + t_FmPcdCcNode *p_Node = (t_FmPcdCcNode *)p_CcNode;
28443 + t_AdOfTypeContLookup *p_AdContLookup = (t_AdOfTypeContLookup *)h_Ad;
28444 + t_Handle h_TmpAd;
28445 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
28446 + uint32_t tmpReg32;
28447 + t_Handle p_AdNewPtr = NULL;
28448 +
28449 + UNUSED(h_Manip);
28450 + UNUSED(h_FrmReplic);
28451 +
28452 + /* there are 3 cases handled in this routine of building a "Continue lookup" type AD.
28453 + * Case 1: No Manip. The action descriptor is built within the match table.
28454 + * p_AdResult = p_AdNewPtr;
28455 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
28456 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
28457 + * initialized and returned here.
28458 + * p_AdResult (within the match table) will be initialized after
28459 + * this routine returns and point to the existing AD.
28460 + * Case 3: Manip exists. The action descriptor is built within the match table.
28461 + * FmPcdManipUpdateAdContLookupForCc returns a NULL p_AdNewPtr.
28462 + */
28463 +
28464 + /* As default, the "new" ptr is the current one. i.e. the content of the result
28465 + * AD will be written into the match table itself (case (1))*/
28466 + p_AdNewPtr = p_AdContLookup;
28467 +
28468 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
28469 + if (p_FmPcdCcStatsParams)
28470 + {
28471 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
28472 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
28473 +
28474 + /* Swapping addresses between statistics Ad and the current lookup AD */
28475 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
28476 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
28477 + h_Ad = h_TmpAd;
28478 +
28479 + p_AdNewPtr = h_Ad;
28480 + p_AdContLookup = h_Ad;
28481 +
28482 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
28483 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
28484 + }
28485 +
28486 +#if DPAA_VERSION >= 11
28487 + if (h_Manip && h_FrmReplic)
28488 + FmPcdManipUpdateAdContLookupForCc(
28489 + h_Manip,
28490 + h_Ad,
28491 + &p_AdNewPtr,
28492 + (uint32_t)((XX_VirtToPhys(
28493 + FrmReplicGroupGetSourceTableDescriptor(h_FrmReplic))
28494 + - p_FmPcd->physicalMuramBase)));
28495 + else
28496 + if (h_FrmReplic)
28497 + FrmReplicGroupUpdateAd(h_FrmReplic, h_Ad, &p_AdNewPtr);
28498 + else
28499 +#endif /* (DPAA_VERSION >= 11) */
28500 + if (h_Manip)
28501 + FmPcdManipUpdateAdContLookupForCc(
28502 + h_Manip,
28503 + h_Ad,
28504 + &p_AdNewPtr,
28505 +
28506 +#ifdef FM_CAPWAP_SUPPORT
28507 + /*no check for opcode of manip - this step can be reached only with capwap_applic_specific*/
28508 + (uint32_t)((XX_VirtToPhys(p_Node->h_AdTable) - p_FmPcd->physicalMuramBase))
28509 +#else /* not FM_CAPWAP_SUPPORT */
28510 + (uint32_t)((XX_VirtToPhys(p_Node->h_Ad)
28511 + - p_FmPcd->physicalMuramBase))
28512 +#endif /* not FM_CAPWAP_SUPPORT */
28513 + );
28514 +
28515 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
28516 + if (p_AdNewPtr)
28517 + {
28518 + /* cases (1) & (2) */
28519 + tmpReg32 = 0;
28520 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
28521 + tmpReg32 |=
28522 + p_Node->sizeOfExtraction ? ((p_Node->sizeOfExtraction - 1) << 24) :
28523 + 0;
28524 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Node->h_AdTable)
28525 + - p_FmPcd->physicalMuramBase);
28526 + WRITE_UINT32(p_AdContLookup->ccAdBase, tmpReg32);
28527 +
28528 + tmpReg32 = 0;
28529 + tmpReg32 |= p_Node->numOfKeys << 24;
28530 + tmpReg32 |= (p_Node->lclMask ? FM_PCD_AD_CONT_LOOKUP_LCL_MASK : 0);
28531 + tmpReg32 |=
28532 + p_Node->h_KeysMatchTable ? (uint32_t)(XX_VirtToPhys(
28533 + p_Node->h_KeysMatchTable) - p_FmPcd->physicalMuramBase) :
28534 + 0;
28535 + WRITE_UINT32(p_AdContLookup->matchTblPtr, tmpReg32);
28536 +
28537 + tmpReg32 = 0;
28538 + tmpReg32 |= p_Node->prsArrayOffset << 24;
28539 + tmpReg32 |= p_Node->offset << 16;
28540 + tmpReg32 |= p_Node->parseCode;
28541 + WRITE_UINT32(p_AdContLookup->pcAndOffsets, tmpReg32);
28542 +
28543 + MemCpy8((void*)&p_AdContLookup->gmask, p_Node->p_GlblMask,
28544 + CC_GLBL_MASK_SIZE);
28545 + }
28546 +}
28547 +
28548 +static t_Error AllocAndFillAdForContLookupManip(t_Handle h_CcNode)
28549 +{
28550 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
28551 + uint32_t intFlags;
28552 +
28553 + ASSERT_COND(p_CcNode);
28554 +
28555 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
28556 +
28557 + if (!p_CcNode->h_Ad)
28558 + {
28559 + if (p_CcNode->maxNumOfKeys)
28560 + p_CcNode->h_Ad = p_CcNode->h_TmpAd;
28561 + else
28562 + p_CcNode->h_Ad = (t_Handle)FM_MURAM_AllocMem(
28563 + ((t_FmPcd *)(p_CcNode->h_FmPcd))->h_FmMuram,
28564 + FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
28565 +
28566 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
28567 +
28568 + if (!p_CcNode->h_Ad)
28569 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
28570 + ("MURAM allocation for CC action descriptor"));
28571 +
28572 + MemSet8(p_CcNode->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
28573 +
28574 + FillAdOfTypeContLookup(p_CcNode->h_Ad, NULL, p_CcNode->h_FmPcd,
28575 + p_CcNode, NULL, NULL);
28576 + }
28577 + else
28578 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
28579 +
28580 + return E_OK;
28581 +}
28582 +
28583 +static t_Error SetRequiredAction1(
28584 + t_Handle h_FmPcd, uint32_t requiredAction,
28585 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
28586 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
28587 +{
28588 + t_AdOfTypeResult *p_AdTmp = (t_AdOfTypeResult *)h_AdTmp;
28589 + uint32_t tmpReg32;
28590 + t_Error err;
28591 + t_FmPcdCcNode *p_CcNode;
28592 + int i = 0;
28593 + uint16_t tmp = 0;
28594 + uint16_t profileId;
28595 + uint8_t relativeSchemeId, physicalSchemeId;
28596 + t_CcNodeInformation ccNodeInfo;
28597 +
28598 + for (i = 0; i < numOfEntries; i++)
28599 + {
28600 + if (i == 0)
28601 + h_AdTmp = PTR_MOVE(h_AdTmp, i*FM_PCD_CC_AD_ENTRY_SIZE);
28602 + else
28603 + h_AdTmp = PTR_MOVE(h_AdTmp, FM_PCD_CC_AD_ENTRY_SIZE);
28604 +
28605 + switch (p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.nextEngine)
28606 + {
28607 + case (e_FM_PCD_CC):
28608 + if (requiredAction)
28609 + {
28610 + p_CcNode =
28611 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.ccParams.h_CcNode;
28612 + ASSERT_COND(p_CcNode);
28613 + if (p_CcNode->shadowAction == requiredAction)
28614 + break;
28615 + if ((requiredAction & UPDATE_CC_WITH_TREE)
28616 + && !(p_CcNode->shadowAction & UPDATE_CC_WITH_TREE))
28617 + {
28618 +
28619 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
28620 + ccNodeInfo.h_CcNode = h_Tree;
28621 + EnqueueNodeInfoToRelevantLst(&p_CcNode->ccTreesLst,
28622 + &ccNodeInfo, NULL);
28623 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28624 + UPDATE_CC_WITH_TREE;
28625 + }
28626 + if ((requiredAction & UPDATE_CC_SHADOW_CLEAR)
28627 + && !(p_CcNode->shadowAction & UPDATE_CC_SHADOW_CLEAR))
28628 + {
28629 +
28630 + p_CcNode->shadowAction = 0;
28631 + }
28632 +
28633 + if ((requiredAction & UPDATE_CC_WITH_DELETE_TREE)
28634 + && !(p_CcNode->shadowAction
28635 + & UPDATE_CC_WITH_DELETE_TREE))
28636 + {
28637 + DequeueNodeInfoFromRelevantLst(&p_CcNode->ccTreesLst,
28638 + h_Tree, NULL);
28639 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28640 + UPDATE_CC_WITH_DELETE_TREE;
28641 + }
28642 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
28643 + != e_FM_PCD_INVALID)
28644 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
28645 + else
28646 + tmp = p_CcNode->numOfKeys;
28647 + err = SetRequiredAction1(h_FmPcd, requiredAction,
28648 + p_CcNode->keyAndNextEngineParams,
28649 + p_CcNode->h_AdTable, tmp, h_Tree);
28650 + if (err != E_OK)
28651 + return err;
28652 + if (requiredAction != UPDATE_CC_SHADOW_CLEAR)
28653 + p_CcNode->shadowAction |= requiredAction;
28654 + }
28655 + break;
28656 +
28657 + case (e_FM_PCD_KG):
28658 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
28659 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
28660 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
28661 + {
28662 + physicalSchemeId =
28663 + FmPcdKgGetSchemeId(
28664 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme);
28665 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(
28666 + h_FmPcd, physicalSchemeId);
28667 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
28668 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
28669 + if (!FmPcdKgIsSchemeValidSw(
28670 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme))
28671 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
28672 + ("Invalid direct scheme."));
28673 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
28674 + RETURN_ERROR(
28675 + MAJOR, E_INVALID_STATE,
28676 + ("For this action scheme has to be direct."));
28677 + err =
28678 + FmPcdKgCcGetSetParams(
28679 + h_FmPcd,
28680 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.kgParams.h_DirectScheme,
28681 + requiredAction, 0);
28682 + if (err != E_OK)
28683 + RETURN_ERROR(MAJOR, err, NO_MSG);
28684 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28685 + requiredAction;
28686 + }
28687 + break;
28688 +
28689 + case (e_FM_PCD_PLCR):
28690 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
28691 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
28692 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
28693 + {
28694 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.overrideParams)
28695 + RETURN_ERROR(
28696 + MAJOR,
28697 + E_NOT_SUPPORTED,
28698 + ("In this initialization only overrideFqid can be initialized"));
28699 + if (!p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.sharedProfile)
28700 + RETURN_ERROR(
28701 + MAJOR,
28702 + E_NOT_SUPPORTED,
28703 + ("In this initialization only overrideFqid can be initialized"));
28704 + err =
28705 + FmPcdPlcrGetAbsoluteIdByProfileParams(
28706 + h_FmPcd,
28707 + e_FM_PCD_PLCR_SHARED,
28708 + NULL,
28709 + p_CcKeyAndNextEngineParamsTmp[i].nextEngineParams.params.plcrParams.newRelativeProfileId,
28710 + &profileId);
28711 + if (err != E_OK)
28712 + RETURN_ERROR(MAJOR, err, NO_MSG);
28713 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, profileId,
28714 + requiredAction);
28715 + if (err != E_OK)
28716 + RETURN_ERROR(MAJOR, err, NO_MSG);
28717 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28718 + requiredAction;
28719 + }
28720 + break;
28721 +
28722 + case (e_FM_PCD_DONE):
28723 + if ((requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
28724 + && !(p_CcKeyAndNextEngineParamsTmp[i].shadowAction
28725 + & UPDATE_NIA_ENQ_WITHOUT_DMA))
28726 + {
28727 + tmpReg32 = GET_UINT32(p_AdTmp->nia);
28728 + if ((tmpReg32 & GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
28729 + != GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd))
28730 + RETURN_ERROR(
28731 + MAJOR,
28732 + E_INVALID_STATE,
28733 + ("Next engine was previously assigned not as PCD_DONE"));
28734 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
28735 + WRITE_UINT32(p_AdTmp->nia, tmpReg32);
28736 + p_CcKeyAndNextEngineParamsTmp[i].shadowAction |=
28737 + requiredAction;
28738 + }
28739 + break;
28740 +
28741 + default:
28742 + break;
28743 + }
28744 + }
28745 +
28746 + return E_OK;
28747 +}
28748 +
28749 +static t_Error SetRequiredAction(
28750 + t_Handle h_FmPcd, uint32_t requiredAction,
28751 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParamsTmp,
28752 + t_Handle h_AdTmp, uint16_t numOfEntries, t_Handle h_Tree)
28753 +{
28754 + t_Error err = SetRequiredAction1(h_FmPcd, requiredAction,
28755 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
28756 + numOfEntries, h_Tree);
28757 + if (err != E_OK)
28758 + return err;
28759 + return SetRequiredAction1(h_FmPcd, UPDATE_CC_SHADOW_CLEAR,
28760 + p_CcKeyAndNextEngineParamsTmp, h_AdTmp,
28761 + numOfEntries, h_Tree);
28762 +}
28763 +
28764 +static t_Error ReleaseModifiedDataStructure(
28765 + t_Handle h_FmPcd, t_List *h_FmPcdOldPointersLst,
28766 + t_List *h_FmPcdNewPointersLst,
28767 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
28768 + bool useShadowStructs)
28769 +{
28770 + t_List *p_Pos;
28771 + t_Error err = E_OK;
28772 + t_CcNodeInformation ccNodeInfo, *p_CcNodeInformation;
28773 + t_Handle h_Muram;
28774 + t_FmPcdCcNode *p_FmPcdCcNextNode, *p_FmPcdCcWorkingOnNode;
28775 + t_List *p_UpdateLst;
28776 + uint32_t intFlags;
28777 +
28778 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
28779 + SANITY_CHECK_RETURN_ERROR(p_AdditionalParams->h_CurrentNode,
28780 + E_INVALID_HANDLE);
28781 + SANITY_CHECK_RETURN_ERROR(h_FmPcdOldPointersLst, E_INVALID_HANDLE);
28782 + SANITY_CHECK_RETURN_ERROR(h_FmPcdNewPointersLst, E_INVALID_HANDLE);
28783 +
28784 + /* We don't update subtree of the new node with new tree because it was done in the previous stage */
28785 + if (p_AdditionalParams->h_NodeForAdd)
28786 + {
28787 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForAdd;
28788 +
28789 + if (!p_AdditionalParams->tree)
28790 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
28791 + else
28792 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
28793 +
28794 + p_CcNodeInformation = FindNodeInfoInReleventLst(
28795 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
28796 + p_FmPcdCcNextNode->h_Spinlock);
28797 +
28798 + if (p_CcNodeInformation)
28799 + p_CcNodeInformation->index++;
28800 + else
28801 + {
28802 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
28803 + ccNodeInfo.h_CcNode = (t_Handle)p_AdditionalParams->h_CurrentNode;
28804 + ccNodeInfo.index = 1;
28805 + EnqueueNodeInfoToRelevantLst(p_UpdateLst, &ccNodeInfo,
28806 + p_FmPcdCcNextNode->h_Spinlock);
28807 + }
28808 + if (p_AdditionalParams->h_ManipForAdd)
28809 + {
28810 + p_CcNodeInformation = FindNodeInfoInReleventLst(
28811 + FmPcdManipGetNodeLstPointedOnThisManip(
28812 + p_AdditionalParams->h_ManipForAdd),
28813 + p_AdditionalParams->h_CurrentNode,
28814 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForAdd));
28815 +
28816 + if (p_CcNodeInformation)
28817 + p_CcNodeInformation->index++;
28818 + else
28819 + {
28820 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
28821 + ccNodeInfo.h_CcNode =
28822 + (t_Handle)p_AdditionalParams->h_CurrentNode;
28823 + ccNodeInfo.index = 1;
28824 + EnqueueNodeInfoToRelevantLst(
28825 + FmPcdManipGetNodeLstPointedOnThisManip(
28826 + p_AdditionalParams->h_ManipForAdd),
28827 + &ccNodeInfo,
28828 + FmPcdManipGetSpinlock(
28829 + p_AdditionalParams->h_ManipForAdd));
28830 + }
28831 + }
28832 + }
28833 +
28834 + if (p_AdditionalParams->h_NodeForRmv)
28835 + {
28836 + p_FmPcdCcNextNode = (t_FmPcdCcNode*)p_AdditionalParams->h_NodeForRmv;
28837 +
28838 + if (!p_AdditionalParams->tree)
28839 + {
28840 + p_UpdateLst = &p_FmPcdCcNextNode->ccPrevNodesLst;
28841 + p_FmPcdCcWorkingOnNode =
28842 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
28843 +
28844 + for (p_Pos = LIST_FIRST(&p_FmPcdCcWorkingOnNode->ccTreesLst);
28845 + p_Pos != (&p_FmPcdCcWorkingOnNode->ccTreesLst); p_Pos =
28846 + LIST_NEXT(p_Pos))
28847 + {
28848 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
28849 +
28850 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
28851 +
28852 + err =
28853 + SetRequiredAction(
28854 + h_FmPcd,
28855 + UPDATE_CC_WITH_DELETE_TREE,
28856 + &((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
28857 + PTR_MOVE(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable, p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
28858 + 1, p_CcNodeInformation->h_CcNode);
28859 + }
28860 + }
28861 + else
28862 + {
28863 + p_UpdateLst = &p_FmPcdCcNextNode->ccTreeIdLst;
28864 +
28865 + err =
28866 + SetRequiredAction(
28867 + h_FmPcd,
28868 + UPDATE_CC_WITH_DELETE_TREE,
28869 + &((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams[p_AdditionalParams->savedKeyIndex],
28870 + UINT_TO_PTR(((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->ccTreeBaseAddr + p_AdditionalParams->savedKeyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
28871 + 1, p_AdditionalParams->h_CurrentNode);
28872 + }
28873 + if (err)
28874 + return err;
28875 +
28876 + /* We remove from the subtree of the removed node tree because it wasn't done in the previous stage
28877 + Update ccPrevNodesLst or ccTreeIdLst of the removed node
28878 + Update of the node owner */
28879 + p_CcNodeInformation = FindNodeInfoInReleventLst(
28880 + p_UpdateLst, p_AdditionalParams->h_CurrentNode,
28881 + p_FmPcdCcNextNode->h_Spinlock);
28882 +
28883 + ASSERT_COND(p_CcNodeInformation);
28884 + ASSERT_COND(p_CcNodeInformation->index);
28885 +
28886 + p_CcNodeInformation->index--;
28887 +
28888 + if (p_CcNodeInformation->index == 0)
28889 + DequeueNodeInfoFromRelevantLst(p_UpdateLst,
28890 + p_AdditionalParams->h_CurrentNode,
28891 + p_FmPcdCcNextNode->h_Spinlock);
28892 +
28893 + UpdateNodeOwner(p_FmPcdCcNextNode, FALSE);
28894 +
28895 + if (p_AdditionalParams->h_ManipForRmv)
28896 + {
28897 + p_CcNodeInformation = FindNodeInfoInReleventLst(
28898 + FmPcdManipGetNodeLstPointedOnThisManip(
28899 + p_AdditionalParams->h_ManipForRmv),
28900 + p_AdditionalParams->h_CurrentNode,
28901 + FmPcdManipGetSpinlock(p_AdditionalParams->h_ManipForRmv));
28902 +
28903 + ASSERT_COND(p_CcNodeInformation);
28904 + ASSERT_COND(p_CcNodeInformation->index);
28905 +
28906 + p_CcNodeInformation->index--;
28907 +
28908 + if (p_CcNodeInformation->index == 0)
28909 + DequeueNodeInfoFromRelevantLst(
28910 + FmPcdManipGetNodeLstPointedOnThisManip(
28911 + p_AdditionalParams->h_ManipForRmv),
28912 + p_AdditionalParams->h_CurrentNode,
28913 + FmPcdManipGetSpinlock(
28914 + p_AdditionalParams->h_ManipForRmv));
28915 + }
28916 + }
28917 +
28918 + if (p_AdditionalParams->h_ManipForRmv)
28919 + FmPcdManipUpdateOwner(p_AdditionalParams->h_ManipForRmv, FALSE);
28920 +
28921 + if (p_AdditionalParams->p_StatsObjForRmv)
28922 + PutStatsObj((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode),
28923 + p_AdditionalParams->p_StatsObjForRmv);
28924 +
28925 +#if (DPAA_VERSION >= 11)
28926 + if (p_AdditionalParams->h_FrmReplicForRmv)
28927 + FrmReplicGroupUpdateOwner(p_AdditionalParams->h_FrmReplicForRmv,
28928 + FALSE/* remove */);
28929 +#endif /* (DPAA_VERSION >= 11) */
28930 +
28931 + if (!useShadowStructs)
28932 + {
28933 + h_Muram = FmPcdGetMuramHandle(h_FmPcd);
28934 + ASSERT_COND(h_Muram);
28935 +
28936 + if ((p_AdditionalParams->tree && !((t_FmPcd *)h_FmPcd)->p_CcShadow)
28937 + || (!p_AdditionalParams->tree
28938 + && !((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->maxNumOfKeys))
28939 + {
28940 + /* We release new AD which was allocated and updated for copy from to actual AD */
28941 + for (p_Pos = LIST_FIRST(h_FmPcdNewPointersLst);
28942 + p_Pos != (h_FmPcdNewPointersLst); p_Pos = LIST_NEXT(p_Pos))
28943 + {
28944 +
28945 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
28946 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
28947 + FM_MURAM_FreeMem(h_Muram, p_CcNodeInformation->h_CcNode);
28948 + }
28949 + }
28950 +
28951 + /* Free Old data structure if it has to be freed - new data structure was allocated*/
28952 + if (p_AdditionalParams->p_AdTableOld)
28953 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_AdTableOld);
28954 +
28955 + if (p_AdditionalParams->p_KeysMatchTableOld)
28956 + FM_MURAM_FreeMem(h_Muram, p_AdditionalParams->p_KeysMatchTableOld);
28957 + }
28958 +
28959 + /* Update current modified node with changed fields if it's required*/
28960 + if (!p_AdditionalParams->tree)
28961 + {
28962 + if (p_AdditionalParams->p_AdTableNew)
28963 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_AdTable =
28964 + p_AdditionalParams->p_AdTableNew;
28965 +
28966 + if (p_AdditionalParams->p_KeysMatchTableNew)
28967 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_KeysMatchTable =
28968 + p_AdditionalParams->p_KeysMatchTableNew;
28969 +
28970 + /* Locking node's spinlock before updating 'keys and next engine' structure,
28971 + as it maybe used to retrieve keys statistics */
28972 + intFlags =
28973 + XX_LockIntrSpinlock(
28974 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock);
28975 +
28976 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->numOfKeys =
28977 + p_AdditionalParams->numOfKeys;
28978 +
28979 + memcpy(((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
28980 + &p_AdditionalParams->keyAndNextEngineParams,
28981 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (CC_MAX_NUM_OF_KEYS));
28982 +
28983 + XX_UnlockIntrSpinlock(
28984 + ((t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode))->h_Spinlock,
28985 + intFlags);
28986 + }
28987 + else
28988 + {
28989 + uint8_t numEntries =
28990 + ((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->numOfEntries;
28991 + ASSERT_COND(numEntries < FM_PCD_MAX_NUM_OF_CC_GROUPS);
28992 + memcpy(&((t_FmPcdCcTree *)(p_AdditionalParams->h_CurrentNode))->keyAndNextEngineParams,
28993 + &p_AdditionalParams->keyAndNextEngineParams,
28994 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * numEntries);
28995 + }
28996 +
28997 + ReleaseLst(h_FmPcdOldPointersLst);
28998 + ReleaseLst(h_FmPcdNewPointersLst);
28999 +
29000 + XX_Free(p_AdditionalParams);
29001 +
29002 + return E_OK;
29003 +}
29004 +
29005 +static t_Handle BuildNewAd(
29006 + t_Handle h_Ad,
29007 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
29008 + t_FmPcdCcNode *p_CcNode,
29009 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
29010 +{
29011 + t_FmPcdCcNode *p_FmPcdCcNodeTmp;
29012 + t_Handle h_OrigAd = NULL;
29013 +
29014 + p_FmPcdCcNodeTmp = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
29015 + if (!p_FmPcdCcNodeTmp)
29016 + {
29017 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcNodeTmp"));
29018 + return NULL;
29019 + }
29020 + memset(p_FmPcdCcNodeTmp, 0, sizeof(t_FmPcdCcNode));
29021 +
29022 + p_FmPcdCcNodeTmp->numOfKeys = p_FmPcdModifyCcKeyAdditionalParams->numOfKeys;
29023 + p_FmPcdCcNodeTmp->h_KeysMatchTable =
29024 + p_FmPcdModifyCcKeyAdditionalParams->p_KeysMatchTableNew;
29025 + p_FmPcdCcNodeTmp->h_AdTable =
29026 + p_FmPcdModifyCcKeyAdditionalParams->p_AdTableNew;
29027 +
29028 + p_FmPcdCcNodeTmp->lclMask = p_CcNode->lclMask;
29029 + p_FmPcdCcNodeTmp->parseCode = p_CcNode->parseCode;
29030 + p_FmPcdCcNodeTmp->offset = p_CcNode->offset;
29031 + p_FmPcdCcNodeTmp->prsArrayOffset = p_CcNode->prsArrayOffset;
29032 + p_FmPcdCcNodeTmp->ctrlFlow = p_CcNode->ctrlFlow;
29033 + p_FmPcdCcNodeTmp->ccKeySizeAccExtraction = p_CcNode->ccKeySizeAccExtraction;
29034 + p_FmPcdCcNodeTmp->sizeOfExtraction = p_CcNode->sizeOfExtraction;
29035 + p_FmPcdCcNodeTmp->glblMaskSize = p_CcNode->glblMaskSize;
29036 + p_FmPcdCcNodeTmp->p_GlblMask = p_CcNode->p_GlblMask;
29037 +
29038 + if (p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
29039 + {
29040 + if (p_FmPcdCcNextEngineParams->h_Manip)
29041 + {
29042 + h_OrigAd = p_CcNode->h_Ad;
29043 + if (AllocAndFillAdForContLookupManip(
29044 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
29045 + != E_OK)
29046 + {
29047 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
29048 + XX_Free(p_FmPcdCcNodeTmp);
29049 + return NULL;
29050 + }
29051 + }
29052 + FillAdOfTypeContLookup(h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
29053 + h_OrigAd ? NULL : p_FmPcdCcNextEngineParams->h_Manip, NULL);
29054 + }
29055 +
29056 +#if (DPAA_VERSION >= 11)
29057 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_FR)
29058 + && (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic))
29059 + {
29060 + FillAdOfTypeContLookup(
29061 + h_Ad, NULL, p_CcNode->h_FmPcd, p_FmPcdCcNodeTmp,
29062 + p_FmPcdCcNextEngineParams->h_Manip,
29063 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
29064 + }
29065 +#endif /* (DPAA_VERSION >= 11) */
29066 +
29067 + XX_Free(p_FmPcdCcNodeTmp);
29068 +
29069 + return E_OK;
29070 +}
29071 +
29072 +static t_Error DynamicChangeHc(
29073 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
29074 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
29075 + bool useShadowStructs)
29076 +{
29077 + t_List *p_PosOld, *p_PosNew;
29078 + uint32_t oldAdAddrOffset, newAdAddrOffset;
29079 + uint16_t i = 0;
29080 + t_Error err = E_OK;
29081 + uint8_t numOfModifiedPtr;
29082 +
29083 + ASSERT_COND(h_FmPcd);
29084 + ASSERT_COND(h_OldPointersLst);
29085 + ASSERT_COND(h_NewPointersLst);
29086 +
29087 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
29088 +
29089 + if (numOfModifiedPtr)
29090 + {
29091 + p_PosNew = LIST_FIRST(h_NewPointersLst);
29092 + p_PosOld = LIST_FIRST(h_OldPointersLst);
29093 +
29094 + /* Retrieve address of new AD */
29095 + newAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
29096 + p_PosNew);
29097 + if (newAdAddrOffset == (uint32_t)ILLEGAL_BASE)
29098 + {
29099 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
29100 + h_NewPointersLst,
29101 + p_AdditionalParams, useShadowStructs);
29102 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("New AD address"));
29103 + }
29104 +
29105 + for (i = 0; i < numOfModifiedPtr; i++)
29106 + {
29107 + /* Retrieve address of current AD */
29108 + oldAdAddrOffset = FmPcdCcGetNodeAddrOffsetFromNodeInfo(h_FmPcd,
29109 + p_PosOld);
29110 + if (oldAdAddrOffset == (uint32_t)ILLEGAL_BASE)
29111 + {
29112 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
29113 + h_NewPointersLst,
29114 + p_AdditionalParams,
29115 + useShadowStructs);
29116 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old AD address"));
29117 + }
29118 +
29119 + /* Invoke host command to copy from new AD to old AD */
29120 + err = FmHcPcdCcDoDynamicChange(((t_FmPcd *)h_FmPcd)->h_Hc,
29121 + oldAdAddrOffset, newAdAddrOffset);
29122 + if (err)
29123 + {
29124 + ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
29125 + h_NewPointersLst,
29126 + p_AdditionalParams,
29127 + useShadowStructs);
29128 + RETURN_ERROR(
29129 + MAJOR,
29130 + err,
29131 + ("For part of nodes changes are done - situation is danger"));
29132 + }
29133 +
29134 + p_PosOld = LIST_NEXT(p_PosOld);
29135 + }
29136 + }
29137 + return E_OK;
29138 +}
29139 +
29140 +static t_Error DoDynamicChange(
29141 + t_Handle h_FmPcd, t_List *h_OldPointersLst, t_List *h_NewPointersLst,
29142 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalParams,
29143 + bool useShadowStructs)
29144 +{
29145 + t_FmPcdCcNode *p_CcNode =
29146 + (t_FmPcdCcNode *)(p_AdditionalParams->h_CurrentNode);
29147 + t_List *p_PosNew;
29148 + t_CcNodeInformation *p_CcNodeInfo;
29149 + t_FmPcdCcNextEngineParams nextEngineParams;
29150 + t_Handle h_Ad;
29151 + uint32_t keySize;
29152 + t_Error err = E_OK;
29153 + uint8_t numOfModifiedPtr;
29154 +
29155 + ASSERT_COND(h_FmPcd);
29156 +
29157 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
29158 +
29159 + numOfModifiedPtr = (uint8_t)LIST_NumOfObjs(h_OldPointersLst);
29160 +
29161 + if (numOfModifiedPtr)
29162 + {
29163 +
29164 + p_PosNew = LIST_FIRST(h_NewPointersLst);
29165 +
29166 + /* Invoke host-command to copy from the new Ad to existing Ads */
29167 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
29168 + p_AdditionalParams, useShadowStructs);
29169 + if (err)
29170 + RETURN_ERROR(MAJOR, err, NO_MSG);
29171 +
29172 + if (useShadowStructs)
29173 + {
29174 + /* When the host-command above has ended, the old structures are 'free'and we can update
29175 + them by copying from the new shadow structures. */
29176 + if (p_CcNode->lclMask)
29177 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
29178 + else
29179 + keySize = p_CcNode->ccKeySizeAccExtraction;
29180 +
29181 + MemCpy8(p_AdditionalParams->p_KeysMatchTableOld,
29182 + p_AdditionalParams->p_KeysMatchTableNew,
29183 + p_CcNode->maxNumOfKeys * keySize * sizeof(uint8_t));
29184 +
29185 + MemCpy8(
29186 + p_AdditionalParams->p_AdTableOld,
29187 + p_AdditionalParams->p_AdTableNew,
29188 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
29189 + * FM_PCD_CC_AD_ENTRY_SIZE));
29190 +
29191 + /* Retrieve the address of the allocated Ad */
29192 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_PosNew);
29193 + h_Ad = p_CcNodeInfo->h_CcNode;
29194 +
29195 + /* Build a new Ad that holds the old (now updated) structures */
29196 + p_AdditionalParams->p_KeysMatchTableNew =
29197 + p_AdditionalParams->p_KeysMatchTableOld;
29198 + p_AdditionalParams->p_AdTableNew = p_AdditionalParams->p_AdTableOld;
29199 +
29200 + nextEngineParams.nextEngine = e_FM_PCD_CC;
29201 + nextEngineParams.params.ccParams.h_CcNode = (t_Handle)p_CcNode;
29202 +
29203 + BuildNewAd(h_Ad, p_AdditionalParams, p_CcNode, &nextEngineParams);
29204 +
29205 + /* HC to copy from the new Ad (old updated structures) to current Ad (uses shadow structures) */
29206 + err = DynamicChangeHc(h_FmPcd, h_OldPointersLst, h_NewPointersLst,
29207 + p_AdditionalParams, useShadowStructs);
29208 + if (err)
29209 + RETURN_ERROR(MAJOR, err, NO_MSG);
29210 + }
29211 + }
29212 +
29213 + err = ReleaseModifiedDataStructure(h_FmPcd, h_OldPointersLst,
29214 + h_NewPointersLst,
29215 + p_AdditionalParams, useShadowStructs);
29216 + if (err)
29217 + RETURN_ERROR(MAJOR, err, NO_MSG);
29218 +
29219 + return E_OK;
29220 +}
29221 +
29222 +#ifdef FM_CAPWAP_SUPPORT
29223 +static bool IsCapwapApplSpecific(t_Handle h_Node)
29224 +{
29225 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_Node;
29226 + bool isManipForCapwapApplSpecificBuild = FALSE;
29227 + int i = 0;
29228 +
29229 + ASSERT_COND(h_Node);
29230 + /* assumption that this function called only for INDEXED_FLOW_ID - so no miss*/
29231 + for (i = 0; i < p_CcNode->numOfKeys; i++)
29232 + {
29233 + if ( p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip &&
29234 + FmPcdManipIsCapwapApplSpecific(p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip))
29235 + {
29236 + isManipForCapwapApplSpecificBuild = TRUE;
29237 + break;
29238 + }
29239 + }
29240 + return isManipForCapwapApplSpecificBuild;
29241 +
29242 +}
29243 +#endif /* FM_CAPWAP_SUPPORT */
29244 +
29245 +static t_Error CcUpdateParam(
29246 + t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_FmPort,
29247 + t_FmPcdCcKeyAndNextEngineParams *p_CcKeyAndNextEngineParams,
29248 + uint16_t numOfEntries, t_Handle h_Ad, bool validate, uint16_t level,
29249 + t_Handle h_FmTree, bool modify)
29250 +{
29251 + t_FmPcdCcNode *p_CcNode;
29252 + t_Error err;
29253 + uint16_t tmp = 0;
29254 + int i = 0;
29255 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
29256 +
29257 + level++;
29258 +
29259 + if (p_CcTree->h_IpReassemblyManip)
29260 + {
29261 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
29262 + p_CcTree->h_IpReassemblyManip, NULL, validate,
29263 + level, h_FmTree, modify);
29264 + if (err)
29265 + RETURN_ERROR(MAJOR, err, NO_MSG);
29266 + }
29267 +
29268 + if (p_CcTree->h_CapwapReassemblyManip)
29269 + {
29270 + err = FmPcdManipUpdate(h_FmPcd, h_PcdParams, h_FmPort,
29271 + p_CcTree->h_CapwapReassemblyManip, NULL, validate,
29272 + level, h_FmTree, modify);
29273 + if (err)
29274 + RETURN_ERROR(MAJOR, err, NO_MSG);
29275 + }
29276 +
29277 + if (numOfEntries)
29278 + {
29279 + for (i = 0; i < numOfEntries; i++)
29280 + {
29281 + if (i == 0)
29282 + h_Ad = PTR_MOVE(h_Ad, i*FM_PCD_CC_AD_ENTRY_SIZE);
29283 + else
29284 + h_Ad = PTR_MOVE(h_Ad, FM_PCD_CC_AD_ENTRY_SIZE);
29285 +
29286 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.nextEngine
29287 + == e_FM_PCD_CC)
29288 + {
29289 + p_CcNode =
29290 + p_CcKeyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
29291 + ASSERT_COND(p_CcNode);
29292 +
29293 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
29294 + {
29295 + err =
29296 + FmPcdManipUpdate(
29297 + h_FmPcd,
29298 + NULL,
29299 + h_FmPort,
29300 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
29301 + h_Ad, validate, level, h_FmTree, modify);
29302 + if (err)
29303 + RETURN_ERROR(MAJOR, err, NO_MSG);
29304 + }
29305 +
29306 + if (p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
29307 + != e_FM_PCD_INVALID)
29308 + tmp = (uint8_t)(p_CcNode->numOfKeys + 1);
29309 + else
29310 + tmp = p_CcNode->numOfKeys;
29311 +
29312 + err = CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
29313 + p_CcNode->keyAndNextEngineParams, tmp,
29314 + p_CcNode->h_AdTable, validate, level,
29315 + h_FmTree, modify);
29316 + if (err)
29317 + RETURN_ERROR(MAJOR, err, NO_MSG);
29318 + }
29319 + else
29320 + {
29321 + if (p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip)
29322 + {
29323 + err =
29324 + FmPcdManipUpdate(
29325 + h_FmPcd,
29326 + NULL,
29327 + h_FmPort,
29328 + p_CcKeyAndNextEngineParams[i].nextEngineParams.h_Manip,
29329 + h_Ad, validate, level, h_FmTree, modify);
29330 + if (err)
29331 + RETURN_ERROR(MAJOR, err, NO_MSG);
29332 + }
29333 + }
29334 + }
29335 + }
29336 +
29337 + return E_OK;
29338 +}
29339 +
29340 +static ccPrivateInfo_t IcDefineCode(t_FmPcdCcNodeParams *p_CcNodeParam)
29341 +{
29342 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.action)
29343 + {
29344 + case (e_FM_PCD_ACTION_EXACT_MATCH):
29345 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
29346 + {
29347 + case (e_FM_PCD_EXTRACT_FROM_KEY):
29348 + return CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH;
29349 + case (e_FM_PCD_EXTRACT_FROM_HASH):
29350 + return CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH;
29351 + default:
29352 + return CC_PRIVATE_INFO_NONE;
29353 + }
29354 +
29355 + case (e_FM_PCD_ACTION_INDEXED_LOOKUP):
29356 + switch (p_CcNodeParam->extractCcParams.extractNonHdr.src)
29357 + {
29358 + case (e_FM_PCD_EXTRACT_FROM_HASH):
29359 + return CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP;
29360 + case (e_FM_PCD_EXTRACT_FROM_FLOW_ID):
29361 + return CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP;
29362 + default:
29363 + return CC_PRIVATE_INFO_NONE;
29364 + }
29365 +
29366 + default:
29367 + break;
29368 + }
29369 +
29370 + return CC_PRIVATE_INFO_NONE;
29371 +}
29372 +
29373 +static t_CcNodeInformation * DequeueAdditionalInfoFromRelevantLst(
29374 + t_List *p_List)
29375 +{
29376 + t_CcNodeInformation *p_CcNodeInfo = NULL;
29377 +
29378 + if (!LIST_IsEmpty(p_List))
29379 + {
29380 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_List->p_Next);
29381 + LIST_DelAndInit(&p_CcNodeInfo->node);
29382 + }
29383 +
29384 + return p_CcNodeInfo;
29385 +}
29386 +
29387 +void ReleaseLst(t_List *p_List)
29388 +{
29389 + t_CcNodeInformation *p_CcNodeInfo = NULL;
29390 +
29391 + if (!LIST_IsEmpty(p_List))
29392 + {
29393 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
29394 + while (p_CcNodeInfo)
29395 + {
29396 + XX_Free(p_CcNodeInfo);
29397 + p_CcNodeInfo = DequeueAdditionalInfoFromRelevantLst(p_List);
29398 + }
29399 + }
29400 +
29401 + LIST_Del(p_List);
29402 +}
29403 +
29404 +static void DeleteNode(t_FmPcdCcNode *p_CcNode)
29405 +{
29406 + uint32_t i;
29407 +
29408 + if (!p_CcNode)
29409 + return;
29410 +
29411 + if (p_CcNode->p_GlblMask)
29412 + {
29413 + XX_Free(p_CcNode->p_GlblMask);
29414 + p_CcNode->p_GlblMask = NULL;
29415 + }
29416 +
29417 + if (p_CcNode->h_KeysMatchTable)
29418 + {
29419 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29420 + p_CcNode->h_KeysMatchTable);
29421 + p_CcNode->h_KeysMatchTable = NULL;
29422 + }
29423 +
29424 + if (p_CcNode->h_AdTable)
29425 + {
29426 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29427 + p_CcNode->h_AdTable);
29428 + p_CcNode->h_AdTable = NULL;
29429 + }
29430 +
29431 + if (p_CcNode->h_Ad)
29432 + {
29433 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29434 + p_CcNode->h_Ad);
29435 + p_CcNode->h_Ad = NULL;
29436 + p_CcNode->h_TmpAd = NULL;
29437 + }
29438 +
29439 + if (p_CcNode->h_StatsFLRs)
29440 + {
29441 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
29442 + p_CcNode->h_StatsFLRs);
29443 + p_CcNode->h_StatsFLRs = NULL;
29444 + }
29445 +
29446 + if (p_CcNode->h_Spinlock)
29447 + {
29448 + XX_FreeSpinlock(p_CcNode->h_Spinlock);
29449 + p_CcNode->h_Spinlock = NULL;
29450 + }
29451 +
29452 + /* Restore the original counters pointer instead of the mutual pointer (mutual to all hash buckets) */
29453 + if (p_CcNode->isHashBucket
29454 + && (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE))
29455 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].p_StatsObj->h_StatsCounters =
29456 + p_CcNode->h_PrivMissStatsCounters;
29457 +
29458 + /* Releasing all currently used statistics objects, including 'miss' entry */
29459 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
29460 + if (p_CcNode->keyAndNextEngineParams[i].p_StatsObj)
29461 + PutStatsObj(p_CcNode,
29462 + p_CcNode->keyAndNextEngineParams[i].p_StatsObj);
29463 +
29464 + if (!LIST_IsEmpty(&p_CcNode->availableStatsLst))
29465 + {
29466 + t_Handle h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
29467 + ASSERT_COND(h_FmMuram);
29468 +
29469 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
29470 + }
29471 +
29472 + LIST_Del(&p_CcNode->availableStatsLst);
29473 +
29474 + ReleaseLst(&p_CcNode->availableStatsLst);
29475 + ReleaseLst(&p_CcNode->ccPrevNodesLst);
29476 + ReleaseLst(&p_CcNode->ccTreeIdLst);
29477 + ReleaseLst(&p_CcNode->ccTreesLst);
29478 +
29479 + XX_Free(p_CcNode);
29480 +}
29481 +
29482 +static void DeleteTree(t_FmPcdCcTree *p_FmPcdTree, t_FmPcd *p_FmPcd)
29483 +{
29484 + if (p_FmPcdTree)
29485 + {
29486 + if (p_FmPcdTree->ccTreeBaseAddr)
29487 + {
29488 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd),
29489 + UINT_TO_PTR(p_FmPcdTree->ccTreeBaseAddr));
29490 + p_FmPcdTree->ccTreeBaseAddr = 0;
29491 + }
29492 +
29493 + ReleaseLst(&p_FmPcdTree->fmPortsLst);
29494 +
29495 + XX_Free(p_FmPcdTree);
29496 + }
29497 +}
29498 +
29499 +static void GetCcExtractKeySize(uint8_t parseCodeRealSize,
29500 + uint8_t *parseCodeCcSize)
29501 +{
29502 + if ((parseCodeRealSize > 0) && (parseCodeRealSize < 2))
29503 + *parseCodeCcSize = 1;
29504 + else
29505 + if (parseCodeRealSize == 2)
29506 + *parseCodeCcSize = 2;
29507 + else
29508 + if ((parseCodeRealSize > 2) && (parseCodeRealSize <= 4))
29509 + *parseCodeCcSize = 4;
29510 + else
29511 + if ((parseCodeRealSize > 4) && (parseCodeRealSize <= 8))
29512 + *parseCodeCcSize = 8;
29513 + else
29514 + if ((parseCodeRealSize > 8) && (parseCodeRealSize <= 16))
29515 + *parseCodeCcSize = 16;
29516 + else
29517 + if ((parseCodeRealSize > 16)
29518 + && (parseCodeRealSize <= 24))
29519 + *parseCodeCcSize = 24;
29520 + else
29521 + if ((parseCodeRealSize > 24)
29522 + && (parseCodeRealSize <= 32))
29523 + *parseCodeCcSize = 32;
29524 + else
29525 + if ((parseCodeRealSize > 32)
29526 + && (parseCodeRealSize <= 40))
29527 + *parseCodeCcSize = 40;
29528 + else
29529 + if ((parseCodeRealSize > 40)
29530 + && (parseCodeRealSize <= 48))
29531 + *parseCodeCcSize = 48;
29532 + else
29533 + if ((parseCodeRealSize > 48)
29534 + && (parseCodeRealSize <= 56))
29535 + *parseCodeCcSize = 56;
29536 + else
29537 + *parseCodeCcSize = 0;
29538 +}
29539 +
29540 +static void GetSizeHeaderField(e_NetHeaderType hdr, t_FmPcdFields field,
29541 + uint8_t *parseCodeRealSize)
29542 +{
29543 + switch (hdr)
29544 + {
29545 + case (HEADER_TYPE_ETH):
29546 + switch (field.eth)
29547 + {
29548 + case (NET_HEADER_FIELD_ETH_DA):
29549 + *parseCodeRealSize = 6;
29550 + break;
29551 +
29552 + case (NET_HEADER_FIELD_ETH_SA):
29553 + *parseCodeRealSize = 6;
29554 + break;
29555 +
29556 + case (NET_HEADER_FIELD_ETH_TYPE):
29557 + *parseCodeRealSize = 2;
29558 + break;
29559 +
29560 + default:
29561 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
29562 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29563 + break;
29564 + }
29565 + break;
29566 +
29567 + case (HEADER_TYPE_PPPoE):
29568 + switch (field.pppoe)
29569 + {
29570 + case (NET_HEADER_FIELD_PPPoE_PID):
29571 + *parseCodeRealSize = 2;
29572 + break;
29573 +
29574 + default:
29575 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported1"));
29576 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29577 + break;
29578 + }
29579 + break;
29580 +
29581 + case (HEADER_TYPE_VLAN):
29582 + switch (field.vlan)
29583 + {
29584 + case (NET_HEADER_FIELD_VLAN_TCI):
29585 + *parseCodeRealSize = 2;
29586 + break;
29587 +
29588 + default:
29589 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported2"));
29590 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29591 + break;
29592 + }
29593 + break;
29594 +
29595 + case (HEADER_TYPE_MPLS):
29596 + switch (field.mpls)
29597 + {
29598 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
29599 + *parseCodeRealSize = 4;
29600 + break;
29601 +
29602 + default:
29603 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported3"));
29604 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29605 + break;
29606 + }
29607 + break;
29608 +
29609 + case (HEADER_TYPE_IPv4):
29610 + switch (field.ipv4)
29611 + {
29612 + case (NET_HEADER_FIELD_IPv4_DST_IP):
29613 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
29614 + *parseCodeRealSize = 4;
29615 + break;
29616 +
29617 + case (NET_HEADER_FIELD_IPv4_TOS):
29618 + case (NET_HEADER_FIELD_IPv4_PROTO):
29619 + *parseCodeRealSize = 1;
29620 + break;
29621 +
29622 + case (NET_HEADER_FIELD_IPv4_DST_IP
29623 + | NET_HEADER_FIELD_IPv4_SRC_IP):
29624 + *parseCodeRealSize = 8;
29625 + break;
29626 +
29627 + case (NET_HEADER_FIELD_IPv4_TTL):
29628 + *parseCodeRealSize = 1;
29629 + break;
29630 +
29631 + default:
29632 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported4"));
29633 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29634 + break;
29635 + }
29636 + break;
29637 +
29638 + case (HEADER_TYPE_IPv6):
29639 + switch (field.ipv6)
29640 + {
29641 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
29642 + | NET_HEADER_FIELD_IPv6_TC):
29643 + *parseCodeRealSize = 4;
29644 + break;
29645 +
29646 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
29647 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
29648 + *parseCodeRealSize = 1;
29649 + break;
29650 +
29651 + case (NET_HEADER_FIELD_IPv6_DST_IP):
29652 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
29653 + *parseCodeRealSize = 16;
29654 + break;
29655 +
29656 + default:
29657 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
29658 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29659 + break;
29660 + }
29661 + break;
29662 +
29663 + case (HEADER_TYPE_IP):
29664 + switch (field.ip)
29665 + {
29666 + case (NET_HEADER_FIELD_IP_DSCP):
29667 + case (NET_HEADER_FIELD_IP_PROTO):
29668 + *parseCodeRealSize = 1;
29669 + break;
29670 +
29671 + default:
29672 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported5"));
29673 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29674 + break;
29675 + }
29676 + break;
29677 +
29678 + case (HEADER_TYPE_GRE):
29679 + switch (field.gre)
29680 + {
29681 + case (NET_HEADER_FIELD_GRE_TYPE):
29682 + *parseCodeRealSize = 2;
29683 + break;
29684 +
29685 + default:
29686 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported6"));
29687 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29688 + break;
29689 + }
29690 + break;
29691 +
29692 + case (HEADER_TYPE_MINENCAP):
29693 + switch (field.minencap)
29694 + {
29695 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
29696 + *parseCodeRealSize = 1;
29697 + break;
29698 +
29699 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
29700 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
29701 + *parseCodeRealSize = 4;
29702 + break;
29703 +
29704 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
29705 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
29706 + *parseCodeRealSize = 8;
29707 + break;
29708 +
29709 + default:
29710 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported7"));
29711 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29712 + break;
29713 + }
29714 + break;
29715 +
29716 + case (HEADER_TYPE_TCP):
29717 + switch (field.tcp)
29718 + {
29719 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
29720 + case (NET_HEADER_FIELD_TCP_PORT_DST):
29721 + *parseCodeRealSize = 2;
29722 + break;
29723 +
29724 + case (NET_HEADER_FIELD_TCP_PORT_SRC
29725 + | NET_HEADER_FIELD_TCP_PORT_DST):
29726 + *parseCodeRealSize = 4;
29727 + break;
29728 +
29729 + default:
29730 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported8"));
29731 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29732 + break;
29733 + }
29734 + break;
29735 +
29736 + case (HEADER_TYPE_UDP):
29737 + switch (field.udp)
29738 + {
29739 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
29740 + case (NET_HEADER_FIELD_UDP_PORT_DST):
29741 + *parseCodeRealSize = 2;
29742 + break;
29743 +
29744 + case (NET_HEADER_FIELD_UDP_PORT_SRC
29745 + | NET_HEADER_FIELD_UDP_PORT_DST):
29746 + *parseCodeRealSize = 4;
29747 + break;
29748 +
29749 + default:
29750 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported9"));
29751 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29752 + break;
29753 + }
29754 + break;
29755 +
29756 + default:
29757 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported10"));
29758 + *parseCodeRealSize = CC_SIZE_ILLEGAL;
29759 + break;
29760 + }
29761 +}
29762 +
29763 +t_Error ValidateNextEngineParams(
29764 + t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
29765 + e_FmPcdCcStatsMode statsMode)
29766 +{
29767 + uint16_t absoluteProfileId;
29768 + t_Error err = E_OK;
29769 + uint8_t relativeSchemeId;
29770 +
29771 + if ((statsMode == e_FM_PCD_CC_STATS_MODE_NONE)
29772 + && (p_FmPcdCcNextEngineParams->statisticsEn))
29773 + RETURN_ERROR(
29774 + MAJOR,
29775 + E_CONFLICT,
29776 + ("Statistics are requested for a key, but statistics mode was set"
29777 + "to 'NONE' upon initialization"));
29778 +
29779 + switch (p_FmPcdCcNextEngineParams->nextEngine)
29780 + {
29781 + case (e_FM_PCD_INVALID):
29782 + err = E_NOT_SUPPORTED;
29783 + break;
29784 +
29785 + case (e_FM_PCD_DONE):
29786 + if ((p_FmPcdCcNextEngineParams->params.enqueueParams.action
29787 + == e_FM_PCD_ENQ_FRAME)
29788 + && p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
29789 + {
29790 + if (!p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid)
29791 + RETURN_ERROR(
29792 + MAJOR,
29793 + E_CONFLICT,
29794 + ("When overrideFqid is set, newFqid must not be zero"));
29795 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.newFqid
29796 + & ~0x00FFFFFF)
29797 + RETURN_ERROR(
29798 + MAJOR, E_INVALID_VALUE,
29799 + ("fqidForCtrlFlow must be between 1 and 2^24-1"));
29800 + }
29801 + break;
29802 +
29803 + case (e_FM_PCD_KG):
29804 + relativeSchemeId =
29805 + FmPcdKgGetRelativeSchemeId(
29806 + h_FmPcd,
29807 + FmPcdKgGetSchemeId(
29808 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme));
29809 + if (relativeSchemeId == FM_PCD_KG_NUM_OF_SCHEMES)
29810 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
29811 + if (!FmPcdKgIsSchemeValidSw(
29812 + p_FmPcdCcNextEngineParams->params.kgParams.h_DirectScheme))
29813 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
29814 + ("not valid schemeIndex in KG next engine param"));
29815 + if (!KgIsSchemeAlwaysDirect(h_FmPcd, relativeSchemeId))
29816 + RETURN_ERROR(
29817 + MAJOR,
29818 + E_INVALID_STATE,
29819 + ("CC Node may point only to a scheme that is always direct."));
29820 + break;
29821 +
29822 + case (e_FM_PCD_PLCR):
29823 + if (p_FmPcdCcNextEngineParams->params.plcrParams.overrideParams)
29824 + {
29825 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
29826 + if (p_FmPcdCcNextEngineParams->params.plcrParams.sharedProfile)
29827 + {
29828 + err =
29829 + FmPcdPlcrGetAbsoluteIdByProfileParams(
29830 + h_FmPcd,
29831 + e_FM_PCD_PLCR_SHARED,
29832 + NULL,
29833 + p_FmPcdCcNextEngineParams->params.plcrParams.newRelativeProfileId,
29834 + &absoluteProfileId);
29835 + if (err)
29836 + RETURN_ERROR(MAJOR, err,
29837 + ("Shared profile offset is out of range"));
29838 + if (!FmPcdPlcrIsProfileValid(h_FmPcd, absoluteProfileId))
29839 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
29840 + ("Invalid profile"));
29841 + }
29842 + }
29843 + break;
29844 +
29845 + case (e_FM_PCD_HASH):
29846 + p_FmPcdCcNextEngineParams->nextEngine = e_FM_PCD_CC;
29847 + case (e_FM_PCD_CC):
29848 + if (!p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
29849 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
29850 + ("handler to next Node is NULL"));
29851 + break;
29852 +
29853 +#if (DPAA_VERSION >= 11)
29854 + case (e_FM_PCD_FR):
29855 + if (!p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
29856 + err = E_NOT_SUPPORTED;
29857 + break;
29858 +#endif /* (DPAA_VERSION >= 11) */
29859 +
29860 + default:
29861 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
29862 + ("Next engine is not correct"));
29863 + }
29864 +
29865 +
29866 + return err;
29867 +}
29868 +
29869 +static uint8_t GetGenParseCode(e_FmPcdExtractFrom src,
29870 + uint32_t offset, bool glblMask,
29871 + uint8_t *parseArrayOffset, bool fromIc,
29872 + ccPrivateInfo_t icCode)
29873 +{
29874 + if (!fromIc)
29875 + {
29876 + switch (src)
29877 + {
29878 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
29879 + if (glblMask)
29880 + return CC_PC_GENERIC_WITH_MASK;
29881 + else
29882 + return CC_PC_GENERIC_WITHOUT_MASK;
29883 +
29884 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
29885 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
29886 + if (offset)
29887 + return CC_PR_OFFSET;
29888 + else
29889 + return CC_PR_WITHOUT_OFFSET;
29890 +
29891 + default:
29892 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
29893 + return CC_PC_ILLEGAL;
29894 + }
29895 + }
29896 + else
29897 + {
29898 + switch (icCode)
29899 + {
29900 + case (CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH):
29901 + *parseArrayOffset = 0x50;
29902 + return CC_PC_GENERIC_IC_GMASK;
29903 +
29904 + case (CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH):
29905 + *parseArrayOffset = 0x48;
29906 + return CC_PC_GENERIC_IC_GMASK;
29907 +
29908 + case (CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP):
29909 + *parseArrayOffset = 0x48;
29910 + return CC_PC_GENERIC_IC_HASH_INDEXED;
29911 +
29912 + case (CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP):
29913 + *parseArrayOffset = 0x16;
29914 + return CC_PC_GENERIC_IC_HASH_INDEXED;
29915 +
29916 + default:
29917 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
29918 + break;
29919 + }
29920 + }
29921 +
29922 + return CC_PC_ILLEGAL;
29923 +}
29924 +
29925 +static uint8_t GetFullFieldParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex index,
29926 + t_FmPcdFields field)
29927 +{
29928 + switch (hdr)
29929 + {
29930 + case (HEADER_TYPE_NONE):
29931 + ASSERT_COND(FALSE);
29932 + return CC_PC_ILLEGAL;
29933 +
29934 + case (HEADER_TYPE_ETH):
29935 + switch (field.eth)
29936 + {
29937 + case (NET_HEADER_FIELD_ETH_DA):
29938 + return CC_PC_FF_MACDST;
29939 + case (NET_HEADER_FIELD_ETH_SA):
29940 + return CC_PC_FF_MACSRC;
29941 + case (NET_HEADER_FIELD_ETH_TYPE):
29942 + return CC_PC_FF_ETYPE;
29943 + default:
29944 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29945 + return CC_PC_ILLEGAL;
29946 + }
29947 +
29948 + case (HEADER_TYPE_VLAN):
29949 + switch (field.vlan)
29950 + {
29951 + case (NET_HEADER_FIELD_VLAN_TCI):
29952 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29953 + || (index == e_FM_PCD_HDR_INDEX_1))
29954 + return CC_PC_FF_TCI1;
29955 + if (index == e_FM_PCD_HDR_INDEX_LAST)
29956 + return CC_PC_FF_TCI2;
29957 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29958 + return CC_PC_ILLEGAL;
29959 + default:
29960 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29961 + return CC_PC_ILLEGAL;
29962 + }
29963 +
29964 + case (HEADER_TYPE_MPLS):
29965 + switch (field.mpls)
29966 + {
29967 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
29968 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29969 + || (index == e_FM_PCD_HDR_INDEX_1))
29970 + return CC_PC_FF_MPLS1;
29971 + if (index == e_FM_PCD_HDR_INDEX_LAST)
29972 + return CC_PC_FF_MPLS_LAST;
29973 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
29974 + return CC_PC_ILLEGAL;
29975 + default:
29976 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
29977 + return CC_PC_ILLEGAL;
29978 + }
29979 +
29980 + case (HEADER_TYPE_IPv4):
29981 + switch (field.ipv4)
29982 + {
29983 + case (NET_HEADER_FIELD_IPv4_DST_IP):
29984 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29985 + || (index == e_FM_PCD_HDR_INDEX_1))
29986 + return CC_PC_FF_IPV4DST1;
29987 + if (index == e_FM_PCD_HDR_INDEX_2)
29988 + return CC_PC_FF_IPV4DST2;
29989 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
29990 + return CC_PC_ILLEGAL;
29991 + case (NET_HEADER_FIELD_IPv4_TOS):
29992 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
29993 + || (index == e_FM_PCD_HDR_INDEX_1))
29994 + return CC_PC_FF_IPV4IPTOS_TC1;
29995 + if (index == e_FM_PCD_HDR_INDEX_2)
29996 + return CC_PC_FF_IPV4IPTOS_TC2;
29997 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
29998 + return CC_PC_ILLEGAL;
29999 + case (NET_HEADER_FIELD_IPv4_PROTO):
30000 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
30001 + || (index == e_FM_PCD_HDR_INDEX_1))
30002 + return CC_PC_FF_IPV4PTYPE1;
30003 + if (index == e_FM_PCD_HDR_INDEX_2)
30004 + return CC_PC_FF_IPV4PTYPE2;
30005 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
30006 + return CC_PC_ILLEGAL;
30007 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
30008 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
30009 + || (index == e_FM_PCD_HDR_INDEX_1))
30010 + return CC_PC_FF_IPV4SRC1;
30011 + if (index == e_FM_PCD_HDR_INDEX_2)
30012 + return CC_PC_FF_IPV4SRC2;
30013 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
30014 + return CC_PC_ILLEGAL;
30015 + case (NET_HEADER_FIELD_IPv4_SRC_IP
30016 + | NET_HEADER_FIELD_IPv4_DST_IP):
30017 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
30018 + || (index == e_FM_PCD_HDR_INDEX_1))
30019 + return CC_PC_FF_IPV4SRC1_IPV4DST1;
30020 + if (index == e_FM_PCD_HDR_INDEX_2)
30021 + return CC_PC_FF_IPV4SRC2_IPV4DST2;
30022 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
30023 + return CC_PC_ILLEGAL;
30024 + case (NET_HEADER_FIELD_IPv4_TTL):
30025 + return CC_PC_FF_IPV4TTL;
30026 + default:
30027 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30028 + return CC_PC_ILLEGAL;
30029 + }
30030 +
30031 + case (HEADER_TYPE_IPv6):
30032 + switch (field.ipv6)
30033 + {
30034 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL
30035 + | NET_HEADER_FIELD_IPv6_TC):
30036 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
30037 + || (index == e_FM_PCD_HDR_INDEX_1))
30038 + return CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1;
30039 + if (index == e_FM_PCD_HDR_INDEX_2)
30040 + return CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2;
30041 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
30042 + return CC_PC_ILLEGAL;
30043 +
30044 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
30045 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
30046 + || (index == e_FM_PCD_HDR_INDEX_1))
30047 + return CC_PC_FF_IPV6PTYPE1;
30048 + if (index == e_FM_PCD_HDR_INDEX_2)
30049 + return CC_PC_FF_IPV6PTYPE2;
30050 + if (index == e_FM_PCD_HDR_INDEX_LAST)
30051 + return CC_PC_FF_IPPID;
30052 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
30053 + return CC_PC_ILLEGAL;
30054 +
30055 + case (NET_HEADER_FIELD_IPv6_DST_IP):
30056 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
30057 + || (index == e_FM_PCD_HDR_INDEX_1))
30058 + return CC_PC_FF_IPV6DST1;
30059 + if (index == e_FM_PCD_HDR_INDEX_2)
30060 + return CC_PC_FF_IPV6DST2;
30061 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
30062 + return CC_PC_ILLEGAL;
30063 +
30064 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
30065 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
30066 + || (index == e_FM_PCD_HDR_INDEX_1))
30067 + return CC_PC_FF_IPV6SRC1;
30068 + if (index == e_FM_PCD_HDR_INDEX_2)
30069 + return CC_PC_FF_IPV6SRC2;
30070 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
30071 + return CC_PC_ILLEGAL;
30072 +
30073 + case (NET_HEADER_FIELD_IPv6_HOP_LIMIT):
30074 + return CC_PC_FF_IPV6HOP_LIMIT;
30075 +
30076 + default:
30077 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30078 + return CC_PC_ILLEGAL;
30079 + }
30080 +
30081 + case (HEADER_TYPE_IP):
30082 + switch (field.ip)
30083 + {
30084 + case (NET_HEADER_FIELD_IP_DSCP):
30085 + if ((index == e_FM_PCD_HDR_INDEX_NONE)
30086 + || (index == e_FM_PCD_HDR_INDEX_1))
30087 + return CC_PC_FF_IPDSCP;
30088 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
30089 + return CC_PC_ILLEGAL;
30090 +
30091 + case (NET_HEADER_FIELD_IP_PROTO):
30092 + if (index == e_FM_PCD_HDR_INDEX_LAST)
30093 + return CC_PC_FF_IPPID;
30094 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP index"));
30095 + return CC_PC_ILLEGAL;
30096 +
30097 + default:
30098 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30099 + return CC_PC_ILLEGAL;
30100 + }
30101 +
30102 + case (HEADER_TYPE_GRE):
30103 + switch (field.gre)
30104 + {
30105 + case (NET_HEADER_FIELD_GRE_TYPE):
30106 + return CC_PC_FF_GREPTYPE;
30107 +
30108 + default:
30109 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30110 + return CC_PC_ILLEGAL;
30111 + }
30112 +
30113 + case (HEADER_TYPE_MINENCAP):
30114 + switch (field.minencap)
30115 + {
30116 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
30117 + return CC_PC_FF_MINENCAP_PTYPE;
30118 +
30119 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
30120 + return CC_PC_FF_MINENCAP_IPDST;
30121 +
30122 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
30123 + return CC_PC_FF_MINENCAP_IPSRC;
30124 +
30125 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP
30126 + | NET_HEADER_FIELD_MINENCAP_DST_IP):
30127 + return CC_PC_FF_MINENCAP_IPSRC_IPDST;
30128 +
30129 + default:
30130 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30131 + return CC_PC_ILLEGAL;
30132 + }
30133 +
30134 + case (HEADER_TYPE_TCP):
30135 + switch (field.tcp)
30136 + {
30137 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
30138 + return CC_PC_FF_L4PSRC;
30139 +
30140 + case (NET_HEADER_FIELD_TCP_PORT_DST):
30141 + return CC_PC_FF_L4PDST;
30142 +
30143 + case (NET_HEADER_FIELD_TCP_PORT_DST
30144 + | NET_HEADER_FIELD_TCP_PORT_SRC):
30145 + return CC_PC_FF_L4PSRC_L4PDST;
30146 +
30147 + default:
30148 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30149 + return CC_PC_ILLEGAL;
30150 + }
30151 +
30152 + case (HEADER_TYPE_PPPoE):
30153 + switch (field.pppoe)
30154 + {
30155 + case (NET_HEADER_FIELD_PPPoE_PID):
30156 + return CC_PC_FF_PPPPID;
30157 +
30158 + default:
30159 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30160 + return CC_PC_ILLEGAL;
30161 + }
30162 +
30163 + case (HEADER_TYPE_UDP):
30164 + switch (field.udp)
30165 + {
30166 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
30167 + return CC_PC_FF_L4PSRC;
30168 +
30169 + case (NET_HEADER_FIELD_UDP_PORT_DST):
30170 + return CC_PC_FF_L4PDST;
30171 +
30172 + case (NET_HEADER_FIELD_UDP_PORT_DST
30173 + | NET_HEADER_FIELD_UDP_PORT_SRC):
30174 + return CC_PC_FF_L4PSRC_L4PDST;
30175 +
30176 + default:
30177 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30178 + return CC_PC_ILLEGAL;
30179 + }
30180 +
30181 + default:
30182 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30183 + return CC_PC_ILLEGAL;
30184 + }
30185 +}
30186 +
30187 +static uint8_t GetPrParseCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex,
30188 + uint32_t offset, bool glblMask,
30189 + uint8_t *parseArrayOffset)
30190 +{
30191 + bool offsetRelevant = FALSE;
30192 +
30193 + if (offset)
30194 + offsetRelevant = TRUE;
30195 +
30196 + switch (hdr)
30197 + {
30198 + case (HEADER_TYPE_NONE):
30199 + ASSERT_COND(FALSE);
30200 + return CC_PC_ILLEGAL;
30201 +
30202 + case (HEADER_TYPE_ETH):
30203 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
30204 + break;
30205 +
30206 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
30207 + if (offset || glblMask)
30208 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
30209 + else
30210 + return CC_PC_PR_SHIM1;
30211 + break;
30212 +
30213 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
30214 + if (offset || glblMask)
30215 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
30216 + else
30217 + return CC_PC_PR_SHIM2;
30218 + break;
30219 +
30220 + case (HEADER_TYPE_LLC_SNAP):
30221 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
30222 + break;
30223 +
30224 + case (HEADER_TYPE_PPPoE):
30225 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
30226 + break;
30227 +
30228 + case (HEADER_TYPE_MPLS):
30229 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
30230 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
30231 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
30232 + else
30233 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
30234 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
30235 + else
30236 + {
30237 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
30238 + return CC_PC_ILLEGAL;
30239 + }
30240 + break;
30241 +
30242 + case (HEADER_TYPE_IPv4):
30243 + case (HEADER_TYPE_IPv6):
30244 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
30245 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
30246 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
30247 + else
30248 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
30249 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
30250 + else
30251 + {
30252 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
30253 + return CC_PC_ILLEGAL;
30254 + }
30255 + break;
30256 +
30257 + case (HEADER_TYPE_MINENCAP):
30258 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
30259 + break;
30260 +
30261 + case (HEADER_TYPE_GRE):
30262 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
30263 + break;
30264 +
30265 + case (HEADER_TYPE_TCP):
30266 + case (HEADER_TYPE_UDP):
30267 + case (HEADER_TYPE_IPSEC_AH):
30268 + case (HEADER_TYPE_IPSEC_ESP):
30269 + case (HEADER_TYPE_DCCP):
30270 + case (HEADER_TYPE_SCTP):
30271 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
30272 + break;
30273 +
30274 + default:
30275 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header for this type of operation"));
30276 + return CC_PC_ILLEGAL;
30277 + }
30278 +
30279 + if (offsetRelevant)
30280 + return CC_PR_OFFSET;
30281 + else
30282 + return CC_PR_WITHOUT_OFFSET;
30283 +}
30284 +
30285 +static uint8_t GetFieldParseCode(e_NetHeaderType hdr, t_FmPcdFields field,
30286 + uint32_t offset, uint8_t *parseArrayOffset,
30287 + e_FmPcdHdrIndex hdrIndex)
30288 +{
30289 + bool offsetRelevant = FALSE;
30290 +
30291 + if (offset)
30292 + offsetRelevant = TRUE;
30293 +
30294 + switch (hdr)
30295 + {
30296 + case (HEADER_TYPE_NONE):
30297 + ASSERT_COND(FALSE);
30298 + break;
30299 + case (HEADER_TYPE_ETH):
30300 + switch (field.eth)
30301 + {
30302 + case (NET_HEADER_FIELD_ETH_TYPE):
30303 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
30304 + break;
30305 +
30306 + default:
30307 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30308 + return CC_PC_ILLEGAL;
30309 + }
30310 + break;
30311 +
30312 + case (HEADER_TYPE_VLAN):
30313 + switch (field.vlan)
30314 + {
30315 + case (NET_HEADER_FIELD_VLAN_TCI):
30316 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
30317 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
30318 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
30319 + else
30320 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
30321 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
30322 + break;
30323 +
30324 + default:
30325 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
30326 + return CC_PC_ILLEGAL;
30327 + }
30328 + break;
30329 +
30330 + default:
30331 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal header "));
30332 + return CC_PC_ILLEGAL;
30333 + }
30334 +
30335 + if (offsetRelevant)
30336 + return CC_PR_OFFSET;
30337 + else
30338 + return CC_PR_WITHOUT_OFFSET;
30339 +}
30340 +
30341 +static void FillAdOfTypeResult(t_Handle h_Ad,
30342 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
30343 + t_FmPcd *p_FmPcd,
30344 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams)
30345 +{
30346 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult *)h_Ad;
30347 + t_Handle h_TmpAd;
30348 + uint32_t tmp = 0, tmpNia = 0;
30349 + uint16_t profileId;
30350 + t_Handle p_AdNewPtr = NULL;
30351 + t_Error err = E_OK;
30352 +
30353 + /* There are 3 cases handled in this routine of building a "result" type AD.
30354 + * Case 1: No Manip. The action descriptor is built within the match table.
30355 + * Case 2: Manip exists. A new AD is created - p_AdNewPtr. It is initialized
30356 + * either in the FmPcdManipUpdateAdResultForCc routine or it was already
30357 + * initialized and returned here.
30358 + * p_AdResult (within the match table) will be initialized after
30359 + * this routine returns and point to the existing AD.
30360 + * Case 3: Manip exists. The action descriptor is built within the match table.
30361 + * FmPcdManipUpdateAdResultForCc returns a NULL p_AdNewPtr.
30362 + *
30363 + * If statistics were enabled and the statistics mode of this node requires
30364 + * a statistics Ad, it will be placed after the result Ad and before the
30365 + * manip Ad, if manip Ad exists here.
30366 + */
30367 +
30368 + /* As default, the "new" ptr is the current one. i.e. the content of the result
30369 + * AD will be written into the match table itself (case (1))*/
30370 + p_AdNewPtr = p_AdResult;
30371 +
30372 + /* Initialize an action descriptor, if current statistics mode requires an Ad */
30373 + if (p_FmPcdCcStatsParams)
30374 + {
30375 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsAd);
30376 + ASSERT_COND(p_FmPcdCcStatsParams->h_StatsCounters);
30377 +
30378 + /* Swapping addresses between statistics Ad and the current lookup AD addresses */
30379 + h_TmpAd = p_FmPcdCcStatsParams->h_StatsAd;
30380 + p_FmPcdCcStatsParams->h_StatsAd = h_Ad;
30381 + h_Ad = h_TmpAd;
30382 +
30383 + p_AdNewPtr = h_Ad;
30384 + p_AdResult = h_Ad;
30385 +
30386 + /* Init statistics Ad and connect current lookup AD as 'next action' from statistics Ad */
30387 + UpdateStatsAd(p_FmPcdCcStatsParams, h_Ad, p_FmPcd->physicalMuramBase);
30388 + }
30389 +
30390 + /* Create manip and return p_AdNewPtr to either a new descriptor or NULL */
30391 + if (p_CcNextEngineParams->h_Manip)
30392 + FmPcdManipUpdateAdResultForCc(p_CcNextEngineParams->h_Manip,
30393 + p_CcNextEngineParams, h_Ad, &p_AdNewPtr);
30394 +
30395 + /* if (p_AdNewPtr = NULL) --> Done. (case (3)) */
30396 + if (p_AdNewPtr)
30397 + {
30398 + /* case (1) and (2) */
30399 + switch (p_CcNextEngineParams->nextEngine)
30400 + {
30401 + case (e_FM_PCD_DONE):
30402 + if (p_CcNextEngineParams->params.enqueueParams.action
30403 + == e_FM_PCD_ENQ_FRAME)
30404 + {
30405 + if (p_CcNextEngineParams->params.enqueueParams.overrideFqid)
30406 + {
30407 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
30408 + tmp |=
30409 + p_CcNextEngineParams->params.enqueueParams.newFqid;
30410 +#if (DPAA_VERSION >= 11)
30411 + tmp |=
30412 + (p_CcNextEngineParams->params.enqueueParams.newRelativeStorageProfileId
30413 + & FM_PCD_AD_RESULT_VSP_MASK)
30414 + << FM_PCD_AD_RESULT_VSP_SHIFT;
30415 +#endif /* (DPAA_VERSION >= 11) */
30416 + }
30417 + else
30418 + {
30419 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
30420 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
30421 + }
30422 + }
30423 +
30424 + if (p_CcNextEngineParams->params.enqueueParams.action
30425 + == e_FM_PCD_DROP_FRAME)
30426 + tmpNia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
30427 + else
30428 + tmpNia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
30429 + break;
30430 +
30431 + case (e_FM_PCD_KG):
30432 + if (p_CcNextEngineParams->params.kgParams.overrideFqid)
30433 + {
30434 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
30435 + tmp |= p_CcNextEngineParams->params.kgParams.newFqid;
30436 +#if (DPAA_VERSION >= 11)
30437 + tmp |=
30438 + (p_CcNextEngineParams->params.kgParams.newRelativeStorageProfileId
30439 + & FM_PCD_AD_RESULT_VSP_MASK)
30440 + << FM_PCD_AD_RESULT_VSP_SHIFT;
30441 +#endif /* (DPAA_VERSION >= 11) */
30442 + }
30443 + else
30444 + {
30445 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
30446 + tmp |= FM_PCD_AD_RESULT_PLCR_DIS;
30447 + }
30448 + tmpNia = NIA_KG_DIRECT;
30449 + tmpNia |= NIA_ENG_KG;
30450 + tmpNia |= NIA_KG_CC_EN;
30451 + tmpNia |= FmPcdKgGetSchemeId(
30452 + p_CcNextEngineParams->params.kgParams.h_DirectScheme);
30453 + break;
30454 +
30455 + case (e_FM_PCD_PLCR):
30456 + if (p_CcNextEngineParams->params.plcrParams.overrideParams)
30457 + {
30458 + tmp = FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE;
30459 +
30460 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
30461 + if (p_CcNextEngineParams->params.plcrParams.sharedProfile)
30462 + {
30463 + tmpNia |= NIA_PLCR_ABSOLUTE;
30464 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(
30465 + (t_Handle)p_FmPcd,
30466 + e_FM_PCD_PLCR_SHARED,
30467 + NULL,
30468 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId,
30469 + &profileId);
30470 +
30471 + if (err != E_OK) {
30472 + REPORT_ERROR(MAJOR, err, NO_MSG);
30473 + return;
30474 + }
30475 +
30476 + }
30477 + else
30478 + profileId =
30479 + p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
30480 +
30481 + tmp |= p_CcNextEngineParams->params.plcrParams.newFqid;
30482 +#if (DPAA_VERSION >= 11)
30483 + tmp |=
30484 + (p_CcNextEngineParams->params.plcrParams.newRelativeStorageProfileId
30485 + & FM_PCD_AD_RESULT_VSP_MASK)
30486 + << FM_PCD_AD_RESULT_VSP_SHIFT;
30487 +#endif /* (DPAA_VERSION >= 11) */
30488 + WRITE_UINT32(
30489 + p_AdResult->plcrProfile,
30490 + (uint32_t)((uint32_t)profileId << FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT));
30491 + }
30492 + else
30493 + tmp = FM_PCD_AD_RESULT_DATA_FLOW_TYPE;
30494 +
30495 + tmpNia |=
30496 + NIA_ENG_PLCR
30497 + | p_CcNextEngineParams->params.plcrParams.newRelativeProfileId;
30498 + break;
30499 +
30500 + default:
30501 + return;
30502 + }WRITE_UINT32(p_AdResult->fqid, tmp);
30503 +
30504 + if (p_CcNextEngineParams->h_Manip)
30505 + {
30506 + tmp = GET_UINT32(p_AdResult->plcrProfile);
30507 + tmp |= (uint32_t)(XX_VirtToPhys(p_AdNewPtr)
30508 + - (p_FmPcd->physicalMuramBase)) >> 4;
30509 + WRITE_UINT32(p_AdResult->plcrProfile, tmp);
30510 +
30511 + tmpNia |= FM_PCD_AD_RESULT_EXTENDED_MODE;
30512 + tmpNia |= FM_PCD_AD_RESULT_NADEN;
30513 + }
30514 +
30515 +#if (DPAA_VERSION >= 11)
30516 + tmpNia |= FM_PCD_AD_RESULT_NO_OM_VSPE;
30517 +#endif /* (DPAA_VERSION >= 11) */
30518 + WRITE_UINT32(p_AdResult->nia, tmpNia);
30519 + }
30520 +}
30521 +
30522 +static t_Error CcUpdateParams(t_Handle h_FmPcd, t_Handle h_PcdParams,
30523 + t_Handle h_FmPort, t_Handle h_FmTree,
30524 + bool validate)
30525 +{
30526 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_FmTree;
30527 +
30528 + return CcUpdateParam(h_FmPcd, h_PcdParams, h_FmPort,
30529 + p_CcTree->keyAndNextEngineParams,
30530 + p_CcTree->numOfEntries,
30531 + UINT_TO_PTR(p_CcTree->ccTreeBaseAddr), validate, 0,
30532 + h_FmTree, FALSE);
30533 +}
30534 +
30535 +
30536 +static void ReleaseNewNodeCommonPart(
30537 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
30538 +{
30539 + if (p_AdditionalInfo->p_AdTableNew)
30540 + FM_MURAM_FreeMem(
30541 + FmPcdGetMuramHandle(
30542 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
30543 + p_AdditionalInfo->p_AdTableNew);
30544 +
30545 + if (p_AdditionalInfo->p_KeysMatchTableNew)
30546 + FM_MURAM_FreeMem(
30547 + FmPcdGetMuramHandle(
30548 + ((t_FmPcdCcNode *)(p_AdditionalInfo->h_CurrentNode))->h_FmPcd),
30549 + p_AdditionalInfo->p_KeysMatchTableNew);
30550 +}
30551 +
30552 +static t_Error UpdateGblMask(t_FmPcdCcNode *p_CcNode, uint8_t keySize,
30553 + uint8_t *p_Mask)
30554 +{
30555 + uint8_t prvGlblMaskSize = p_CcNode->glblMaskSize;
30556 +
30557 + if (p_Mask && !p_CcNode->glblMaskUpdated && (keySize <= 4)
30558 + && !p_CcNode->lclMask)
30559 + {
30560 + if (p_CcNode->parseCode && (p_CcNode->parseCode != CC_PC_FF_TCI1)
30561 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
30562 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
30563 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
30564 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
30565 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
30566 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
30567 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
30568 + && (p_CcNode->parseCode != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2))
30569 + {
30570 + p_CcNode->glblMaskSize = 0;
30571 + p_CcNode->lclMask = TRUE;
30572 + }
30573 + else
30574 + {
30575 + memcpy(p_CcNode->p_GlblMask, p_Mask, (sizeof(uint8_t)) * keySize);
30576 + p_CcNode->glblMaskUpdated = TRUE;
30577 + p_CcNode->glblMaskSize = 4;
30578 + }
30579 + }
30580 + else
30581 + if (p_Mask && (keySize <= 4) && !p_CcNode->lclMask)
30582 + {
30583 + if (memcmp(p_CcNode->p_GlblMask, p_Mask, keySize) != 0)
30584 + {
30585 + p_CcNode->lclMask = TRUE;
30586 + p_CcNode->glblMaskSize = 0;
30587 + }
30588 + }
30589 + else
30590 + if (!p_Mask && p_CcNode->glblMaskUpdated && (keySize <= 4))
30591 + {
30592 + uint32_t tmpMask = 0xffffffff;
30593 + if (memcmp(p_CcNode->p_GlblMask, &tmpMask, 4) != 0)
30594 + {
30595 + p_CcNode->lclMask = TRUE;
30596 + p_CcNode->glblMaskSize = 0;
30597 + }
30598 + }
30599 + else
30600 + if (p_Mask)
30601 + {
30602 + p_CcNode->lclMask = TRUE;
30603 + p_CcNode->glblMaskSize = 0;
30604 + }
30605 +
30606 + /* In static mode (maxNumOfKeys > 0), local mask is supported
30607 + only is mask support was enabled at initialization */
30608 + if (p_CcNode->maxNumOfKeys && (!p_CcNode->maskSupport) && p_CcNode->lclMask)
30609 + {
30610 + p_CcNode->lclMask = FALSE;
30611 + p_CcNode->glblMaskSize = prvGlblMaskSize;
30612 + return ERROR_CODE(E_NOT_SUPPORTED);
30613 + }
30614 +
30615 + return E_OK;
30616 +}
30617 +
30618 +static __inline__ t_Handle GetNewAd(t_Handle h_FmPcdCcNodeOrTree, bool isTree)
30619 +{
30620 + t_FmPcd *p_FmPcd;
30621 + t_Handle h_Ad;
30622 +
30623 + if (isTree)
30624 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcTree *)h_FmPcdCcNodeOrTree)->h_FmPcd);
30625 + else
30626 + p_FmPcd = (t_FmPcd *)(((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_FmPcd);
30627 +
30628 + if ((isTree && p_FmPcd->p_CcShadow)
30629 + || (!isTree && ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->maxNumOfKeys))
30630 + {
30631 + /* The allocated shadow is divided as follows:
30632 + 0 . . . 16 . . .
30633 + ---------------------------------------------------
30634 + | Shadow | Shadow Keys | Shadow Next |
30635 + | Ad | Match Table | Engine Table |
30636 + | (16 bytes) | (maximal size) | (maximal size) |
30637 + ---------------------------------------------------
30638 + */
30639 + if (!p_FmPcd->p_CcShadow)
30640 + {
30641 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
30642 + return NULL;
30643 + }
30644 +
30645 + h_Ad = p_FmPcd->p_CcShadow;
30646 + }
30647 + else
30648 + {
30649 + h_Ad = (t_Handle)FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
30650 + FM_PCD_CC_AD_ENTRY_SIZE,
30651 + FM_PCD_CC_AD_TABLE_ALIGN);
30652 + if (!h_Ad)
30653 + {
30654 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node action descriptor"));
30655 + return NULL;
30656 + }
30657 + }
30658 +
30659 + return h_Ad;
30660 +}
30661 +
30662 +static t_Error BuildNewNodeCommonPart(
30663 + t_FmPcdCcNode *p_CcNode, int *size,
30664 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
30665 +{
30666 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
30667 +
30668 + if (p_CcNode->lclMask)
30669 + *size = 2 * p_CcNode->ccKeySizeAccExtraction;
30670 + else
30671 + *size = p_CcNode->ccKeySizeAccExtraction;
30672 +
30673 + if (p_CcNode->maxNumOfKeys == 0)
30674 + {
30675 + p_AdditionalInfo->p_AdTableNew = (t_Handle)FM_MURAM_AllocMem(
30676 + FmPcdGetMuramHandle(p_FmPcd),
30677 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
30678 + * FM_PCD_CC_AD_ENTRY_SIZE),
30679 + FM_PCD_CC_AD_TABLE_ALIGN);
30680 + if (!p_AdditionalInfo->p_AdTableNew)
30681 + RETURN_ERROR(
30682 + MAJOR, E_NO_MEMORY,
30683 + ("MURAM allocation for CC node action descriptors table"));
30684 +
30685 + p_AdditionalInfo->p_KeysMatchTableNew = (t_Handle)FM_MURAM_AllocMem(
30686 + FmPcdGetMuramHandle(p_FmPcd),
30687 + (uint32_t)(*size * sizeof(uint8_t)
30688 + * (p_AdditionalInfo->numOfKeys + 1)),
30689 + FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
30690 + if (!p_AdditionalInfo->p_KeysMatchTableNew)
30691 + {
30692 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_CcNode->h_FmPcd),
30693 + p_AdditionalInfo->p_AdTableNew);
30694 + p_AdditionalInfo->p_AdTableNew = NULL;
30695 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
30696 + ("MURAM allocation for CC node key match table"));
30697 + }
30698 +
30699 + MemSet8(
30700 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
30701 + 0,
30702 + (uint32_t)((p_AdditionalInfo->numOfKeys + 1)
30703 + * FM_PCD_CC_AD_ENTRY_SIZE));
30704 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
30705 + *size * sizeof(uint8_t) * (p_AdditionalInfo->numOfKeys + 1));
30706 + }
30707 + else
30708 + {
30709 + /* The allocated shadow is divided as follows:
30710 + 0 . . . 16 . . .
30711 + ---------------------------------------------------
30712 + | Shadow | Shadow Keys | Shadow Next |
30713 + | Ad | Match Table | Engine Table |
30714 + | (16 bytes) | (maximal size) | (maximal size) |
30715 + ---------------------------------------------------
30716 + */
30717 +
30718 + if (!p_FmPcd->p_CcShadow)
30719 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
30720 +
30721 + p_AdditionalInfo->p_KeysMatchTableNew =
30722 + PTR_MOVE(p_FmPcd->p_CcShadow, FM_PCD_CC_AD_ENTRY_SIZE);
30723 + p_AdditionalInfo->p_AdTableNew =
30724 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, p_CcNode->keysMatchTableMaxSize);
30725 +
30726 + MemSet8(
30727 + (uint8_t*)p_AdditionalInfo->p_AdTableNew,
30728 + 0,
30729 + (uint32_t)((p_CcNode->maxNumOfKeys + 1)
30730 + * FM_PCD_CC_AD_ENTRY_SIZE));
30731 + MemSet8((uint8_t*)p_AdditionalInfo->p_KeysMatchTableNew, 0,
30732 + (*size) * sizeof(uint8_t) * (p_CcNode->maxNumOfKeys));
30733 + }
30734 +
30735 + p_AdditionalInfo->p_AdTableOld = p_CcNode->h_AdTable;
30736 + p_AdditionalInfo->p_KeysMatchTableOld = p_CcNode->h_KeysMatchTable;
30737 +
30738 + return E_OK;
30739 +}
30740 +
30741 +static t_Error BuildNewNodeAddOrMdfyKeyAndNextEngine(
30742 + t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
30743 + t_FmPcdCcKeyParams *p_KeyParams,
30744 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo, bool add)
30745 +{
30746 + t_Error err = E_OK;
30747 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
30748 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
30749 + int size;
30750 + int i = 0, j = 0;
30751 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
30752 + uint32_t requiredAction = 0;
30753 + bool prvLclMask;
30754 + t_CcNodeInformation *p_CcNodeInformation;
30755 + t_FmPcdCcStatsParams statsParams = { 0 };
30756 + t_List *p_Pos;
30757 + t_FmPcdStatsObj *p_StatsObj;
30758 +
30759 + /* Check that new NIA is legal */
30760 + err = ValidateNextEngineParams(h_FmPcd, &p_KeyParams->ccNextEngineParams,
30761 + p_CcNode->statisticsMode);
30762 + if (err)
30763 + RETURN_ERROR(MAJOR, err, NO_MSG);
30764 +
30765 + prvLclMask = p_CcNode->lclMask;
30766 +
30767 + /* Check that new key is not require update of localMask */
30768 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction,
30769 + p_KeyParams->p_Mask);
30770 + if (err)
30771 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30772 +
30773 + /* Update internal data structure with new next engine for the given index */
30774 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
30775 + &p_KeyParams->ccNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
30776 +
30777 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key,
30778 + p_KeyParams->p_Key, p_CcNode->userSizeOfExtraction);
30779 +
30780 + if ((p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
30781 + == e_FM_PCD_CC)
30782 + && p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
30783 + {
30784 + err =
30785 + AllocAndFillAdForContLookupManip(
30786 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode);
30787 + if (err)
30788 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30789 + }
30790 +
30791 + if (p_KeyParams->p_Mask)
30792 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask,
30793 + p_KeyParams->p_Mask, p_CcNode->userSizeOfExtraction);
30794 + else
30795 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
30796 + p_CcNode->userSizeOfExtraction);
30797 +
30798 + /* Update numOfKeys */
30799 + if (add)
30800 + p_AdditionalInfo->numOfKeys = (uint8_t)(p_CcNode->numOfKeys + 1);
30801 + else
30802 + p_AdditionalInfo->numOfKeys = (uint8_t)p_CcNode->numOfKeys;
30803 +
30804 + /* Allocate new tables in MURAM: keys match table and action descriptors table */
30805 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
30806 + if (err)
30807 + RETURN_ERROR(MAJOR, err, NO_MSG);
30808 +
30809 + /* Check that manip is legal and what requiredAction is necessary for this manip */
30810 + if (p_KeyParams->ccNextEngineParams.h_Manip)
30811 + {
30812 + err = FmPcdManipCheckParamsForCcNextEngine(
30813 + &p_KeyParams->ccNextEngineParams, &requiredAction);
30814 + if (err)
30815 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30816 + }
30817 +
30818 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
30819 + requiredAction;
30820 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
30821 + UPDATE_CC_WITH_TREE;
30822 +
30823 + /* Update new Ad and new Key Table according to new requirement */
30824 + i = 0;
30825 + for (j = 0; j < p_AdditionalInfo->numOfKeys; j++)
30826 + {
30827 + p_AdTableNewTmp =
30828 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
30829 +
30830 + if (j == keyIndex)
30831 + {
30832 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
30833 + {
30834 + /* Allocate a statistics object that holds statistics AD and counters.
30835 + - For added key - New statistics AD and counters pointer need to be allocated
30836 + new statistics object. If statistics were enabled, we need to replace the
30837 + existing descriptor with a new descriptor with nullified counters.
30838 + */
30839 + p_StatsObj = GetStatsObj(p_CcNode);
30840 + ASSERT_COND(p_StatsObj);
30841 +
30842 + /* Store allocated statistics object */
30843 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
30844 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
30845 + p_StatsObj;
30846 +
30847 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
30848 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
30849 +#if (DPAA_VERSION >= 11)
30850 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
30851 +
30852 +#endif /* (DPAA_VERSION >= 11) */
30853 +
30854 + /* Building action descriptor for the received new key */
30855 + NextStepAd(p_AdTableNewTmp, &statsParams,
30856 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
30857 + }
30858 + else
30859 + {
30860 + /* Building action descriptor for the received new key */
30861 + NextStepAd(p_AdTableNewTmp, NULL,
30862 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
30863 + }
30864 +
30865 + /* Copy the received new key into keys match table */
30866 + p_KeysMatchTableNewTmp =
30867 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j*size*sizeof(uint8_t));
30868 +
30869 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeyParams->p_Key,
30870 + p_CcNode->userSizeOfExtraction);
30871 +
30872 + /* Update mask for the received new key */
30873 + if (p_CcNode->lclMask)
30874 + {
30875 + if (p_KeyParams->p_Mask)
30876 + {
30877 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
30878 + p_CcNode->ccKeySizeAccExtraction),
30879 + p_KeyParams->p_Mask,
30880 + p_CcNode->userSizeOfExtraction);
30881 + }
30882 + else
30883 + if (p_CcNode->ccKeySizeAccExtraction > 4)
30884 + {
30885 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
30886 + p_CcNode->ccKeySizeAccExtraction),
30887 + 0xff, p_CcNode->userSizeOfExtraction);
30888 + }
30889 + else
30890 + {
30891 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
30892 + p_CcNode->ccKeySizeAccExtraction),
30893 + p_CcNode->p_GlblMask,
30894 + p_CcNode->userSizeOfExtraction);
30895 + }
30896 + }
30897 +
30898 + /* If key modification requested, the old entry is omitted and replaced by the new parameters */
30899 + if (!add)
30900 + i++;
30901 + }
30902 + else
30903 + {
30904 + /* Copy existing action descriptors to the newly allocated Ad table */
30905 + p_AdTableOldTmp =
30906 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
30907 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp,
30908 + FM_PCD_CC_AD_ENTRY_SIZE);
30909 +
30910 + /* Copy existing keys and their masks to the newly allocated keys match table */
30911 + p_KeysMatchTableNewTmp =
30912 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
30913 + p_KeysMatchTableOldTmp =
30914 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, i * size * sizeof(uint8_t));
30915 +
30916 + if (p_CcNode->lclMask)
30917 + {
30918 + if (prvLclMask)
30919 + {
30920 + MemCpy8(
30921 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
30922 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
30923 + p_CcNode->ccKeySizeAccExtraction);
30924 + }
30925 + else
30926 + {
30927 + p_KeysMatchTableOldTmp =
30928 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
30929 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
30930 +
30931 + if (p_CcNode->ccKeySizeAccExtraction > 4)
30932 + {
30933 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
30934 + p_CcNode->ccKeySizeAccExtraction),
30935 + 0xff, p_CcNode->userSizeOfExtraction);
30936 + }
30937 + else
30938 + {
30939 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
30940 + p_CcNode->ccKeySizeAccExtraction),
30941 + p_CcNode->p_GlblMask,
30942 + p_CcNode->userSizeOfExtraction);
30943 + }
30944 + }
30945 + }
30946 +
30947 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
30948 + p_CcNode->ccKeySizeAccExtraction);
30949 +
30950 + i++;
30951 + }
30952 + }
30953 +
30954 + /* Miss action descriptor */
30955 + p_AdTableNewTmp =
30956 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
30957 + p_AdTableOldTmp =
30958 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i * FM_PCD_CC_AD_ENTRY_SIZE);
30959 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
30960 +
30961 + if (!LIST_IsEmpty(&p_CcNode->ccTreesLst))
30962 + {
30963 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
30964 + {
30965 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
30966 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
30967 + /* Update the manipulation which has to be updated from parameters of the port */
30968 + /* It's has to be updated with restrictions defined in the function */
30969 + err =
30970 + SetRequiredAction(
30971 + p_CcNode->h_FmPcd,
30972 + p_CcNode->shadowAction
30973 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
30974 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
30975 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
30976 + 1, p_CcNodeInformation->h_CcNode);
30977 + if (err)
30978 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30979 +
30980 + err =
30981 + CcUpdateParam(
30982 + p_CcNode->h_FmPcd,
30983 + NULL,
30984 + NULL,
30985 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
30986 + 1,
30987 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, keyIndex*FM_PCD_CC_AD_ENTRY_SIZE),
30988 + TRUE, p_CcNodeInformation->index,
30989 + p_CcNodeInformation->h_CcNode, TRUE);
30990 + if (err)
30991 + RETURN_ERROR(MAJOR, err, (NO_MSG));
30992 + }
30993 + }
30994 +
30995 + if (p_CcNode->lclMask)
30996 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
30997 +
30998 + if (p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_CC)
30999 + p_AdditionalInfo->h_NodeForAdd =
31000 + p_KeyParams->ccNextEngineParams.params.ccParams.h_CcNode;
31001 + if (p_KeyParams->ccNextEngineParams.h_Manip)
31002 + p_AdditionalInfo->h_ManipForAdd =
31003 + p_KeyParams->ccNextEngineParams.h_Manip;
31004 +
31005 +#if (DPAA_VERSION >= 11)
31006 + if ((p_KeyParams->ccNextEngineParams.nextEngine == e_FM_PCD_FR)
31007 + && (p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic))
31008 + p_AdditionalInfo->h_FrmReplicForAdd =
31009 + p_KeyParams->ccNextEngineParams.params.frParams.h_FrmReplic;
31010 +#endif /* (DPAA_VERSION >= 11) */
31011 +
31012 + if (!add)
31013 + {
31014 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
31015 + == e_FM_PCD_CC)
31016 + p_AdditionalInfo->h_NodeForRmv =
31017 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
31018 +
31019 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
31020 + p_AdditionalInfo->h_ManipForRmv =
31021 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
31022 +
31023 + /* If statistics were previously enabled, store the old statistics object to be released */
31024 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
31025 + {
31026 + p_AdditionalInfo->p_StatsObjForRmv =
31027 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
31028 + }
31029 +
31030 +#if (DPAA_VERSION >= 11)
31031 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
31032 + == e_FM_PCD_FR)
31033 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
31034 + p_AdditionalInfo->h_FrmReplicForRmv =
31035 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
31036 +#endif /* (DPAA_VERSION >= 11) */
31037 + }
31038 +
31039 + return E_OK;
31040 +}
31041 +
31042 +static t_Error BuildNewNodeRemoveKey(
31043 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
31044 + t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
31045 +{
31046 + int i = 0, j = 0;
31047 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
31048 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
31049 + int size;
31050 + t_Error err = E_OK;
31051 +
31052 + /*save new numOfKeys*/
31053 + p_AdditionalInfo->numOfKeys = (uint16_t)(p_CcNode->numOfKeys - 1);
31054 +
31055 + /*function which allocates in the memory new KeyTbl, AdTbl*/
31056 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
31057 + if (err)
31058 + RETURN_ERROR(MAJOR, err, NO_MSG);
31059 +
31060 + /*update new Ad and new Key Table according to new requirement*/
31061 + for (i = 0, j = 0; j < p_CcNode->numOfKeys; i++, j++)
31062 + {
31063 + if (j == keyIndex)
31064 + j++;
31065 +
31066 + if (j == p_CcNode->numOfKeys)
31067 + break;
31068 + p_AdTableNewTmp =
31069 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
31070 + p_AdTableOldTmp =
31071 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
31072 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31073 +
31074 + p_KeysMatchTableOldTmp =
31075 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableOld, j * size * sizeof(uint8_t));
31076 + p_KeysMatchTableNewTmp =
31077 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, i * size * sizeof(uint8_t));
31078 + MemCpy8(p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
31079 + size * sizeof(uint8_t));
31080 + }
31081 +
31082 + p_AdTableNewTmp =
31083 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, i * FM_PCD_CC_AD_ENTRY_SIZE);
31084 + p_AdTableOldTmp =
31085 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, j * FM_PCD_CC_AD_ENTRY_SIZE);
31086 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31087 +
31088 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
31089 + == e_FM_PCD_CC)
31090 + p_AdditionalInfo->h_NodeForRmv =
31091 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
31092 +
31093 + if (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
31094 + p_AdditionalInfo->h_ManipForRmv =
31095 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
31096 +
31097 + /* If statistics were previously enabled, store the old statistics object to be released */
31098 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
31099 + {
31100 + p_AdditionalInfo->p_StatsObjForRmv =
31101 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
31102 + }
31103 +
31104 +#if (DPAA_VERSION >= 11)
31105 + if ((p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
31106 + == e_FM_PCD_FR)
31107 + && (p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
31108 + p_AdditionalInfo->h_FrmReplicForRmv =
31109 + p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
31110 +#endif /* (DPAA_VERSION >= 11) */
31111 +
31112 + return E_OK;
31113 +}
31114 +
31115 +static t_Error BuildNewNodeModifyKey(
31116 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex, uint8_t *p_Key,
31117 + uint8_t *p_Mask, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
31118 +{
31119 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
31120 + t_Error err = E_OK;
31121 + t_Handle p_AdTableNewTmp, p_KeysMatchTableNewTmp;
31122 + t_Handle p_KeysMatchTableOldTmp, p_AdTableOldTmp;
31123 + int size;
31124 + int i = 0, j = 0;
31125 + bool prvLclMask;
31126 + t_FmPcdStatsObj *p_StatsObj, tmpStatsObj;
31127 + p_AdditionalInfo->numOfKeys = p_CcNode->numOfKeys;
31128 +
31129 + prvLclMask = p_CcNode->lclMask;
31130 +
31131 + /* Check that new key is not require update of localMask */
31132 + err = UpdateGblMask(p_CcNode, p_CcNode->ccKeySizeAccExtraction, p_Mask);
31133 + if (err)
31134 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31135 +
31136 + /* Update internal data structure with new next engine for the given index */
31137 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].key, p_Key,
31138 + p_CcNode->userSizeOfExtraction);
31139 +
31140 + if (p_Mask)
31141 + memcpy(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, p_Mask,
31142 + p_CcNode->userSizeOfExtraction);
31143 + else
31144 + memset(p_AdditionalInfo->keyAndNextEngineParams[keyIndex].mask, 0xFF,
31145 + p_CcNode->userSizeOfExtraction);
31146 +
31147 + /*function which build in the memory new KeyTbl, AdTbl*/
31148 + err = BuildNewNodeCommonPart(p_CcNode, &size, p_AdditionalInfo);
31149 + if (err)
31150 + RETURN_ERROR(MAJOR, err, NO_MSG);
31151 +
31152 + /*fill the New AdTable and New KeyTable*/
31153 + for (j = 0, i = 0; j < p_AdditionalInfo->numOfKeys; j++, i++)
31154 + {
31155 + p_AdTableNewTmp =
31156 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j*FM_PCD_CC_AD_ENTRY_SIZE);
31157 + p_AdTableOldTmp =
31158 + PTR_MOVE(p_AdditionalInfo->p_AdTableOld, i*FM_PCD_CC_AD_ENTRY_SIZE);
31159 +
31160 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31161 +
31162 + if (j == keyIndex)
31163 + {
31164 + ASSERT_COND(keyIndex < CC_MAX_NUM_OF_KEYS);
31165 + if (p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
31166 + {
31167 + /* As statistics were enabled, we need to update the existing
31168 + statistics descriptor with a new nullified counters. */
31169 + p_StatsObj = GetStatsObj(p_CcNode);
31170 + ASSERT_COND(p_StatsObj);
31171 +
31172 + SetStatsCounters(
31173 + p_AdTableNewTmp,
31174 + (uint32_t)((XX_VirtToPhys(p_StatsObj->h_StatsCounters)
31175 + - p_FmPcd->physicalMuramBase)));
31176 +
31177 + tmpStatsObj.h_StatsAd = p_StatsObj->h_StatsAd;
31178 + tmpStatsObj.h_StatsCounters = p_StatsObj->h_StatsCounters;
31179 +
31180 + /* As we need to replace only the counters, we build a new statistics
31181 + object that holds the old AD and the new counters - this will be the
31182 + currently used statistics object.
31183 + The newly allocated AD is not required and may be released back to
31184 + the available objects with the previous counters pointer. */
31185 + p_StatsObj->h_StatsAd =
31186 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
31187 +
31188 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd =
31189 + tmpStatsObj.h_StatsAd;
31190 +
31191 + /* Store allocated statistics object */
31192 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
31193 + p_StatsObj;
31194 +
31195 + /* As statistics were previously enabled, store the old statistics object to be released */
31196 + p_AdditionalInfo->p_StatsObjForRmv =
31197 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj;
31198 + }
31199 +
31200 + p_KeysMatchTableNewTmp =
31201 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
31202 +
31203 + MemCpy8(p_KeysMatchTableNewTmp, p_Key,
31204 + p_CcNode->userSizeOfExtraction);
31205 +
31206 + if (p_CcNode->lclMask)
31207 + {
31208 + if (p_Mask)
31209 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
31210 + p_CcNode->ccKeySizeAccExtraction),
31211 + p_Mask, p_CcNode->userSizeOfExtraction);
31212 + else
31213 + if (p_CcNode->ccKeySizeAccExtraction > 4)
31214 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
31215 + p_CcNode->ccKeySizeAccExtraction),
31216 + 0xff, p_CcNode->userSizeOfExtraction);
31217 + else
31218 + MemCpy8(PTR_MOVE(p_KeysMatchTableNewTmp,
31219 + p_CcNode->ccKeySizeAccExtraction),
31220 + p_CcNode->p_GlblMask,
31221 + p_CcNode->userSizeOfExtraction);
31222 + }
31223 + }
31224 + else
31225 + {
31226 + p_KeysMatchTableNewTmp =
31227 + PTR_MOVE(p_AdditionalInfo->p_KeysMatchTableNew, j * size * sizeof(uint8_t));
31228 + p_KeysMatchTableOldTmp =
31229 + PTR_MOVE(p_CcNode->h_KeysMatchTable, i * size * sizeof(uint8_t));
31230 +
31231 + if (p_CcNode->lclMask)
31232 + {
31233 + if (prvLclMask)
31234 + MemCpy8(
31235 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
31236 + PTR_MOVE(p_KeysMatchTableOldTmp, p_CcNode->ccKeySizeAccExtraction),
31237 + p_CcNode->userSizeOfExtraction);
31238 + else
31239 + {
31240 + p_KeysMatchTableOldTmp =
31241 + PTR_MOVE(p_CcNode->h_KeysMatchTable,
31242 + i * (int)p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t));
31243 +
31244 + if (p_CcNode->ccKeySizeAccExtraction > 4)
31245 + MemSet8(PTR_MOVE(p_KeysMatchTableNewTmp,
31246 + p_CcNode->ccKeySizeAccExtraction),
31247 + 0xff, p_CcNode->userSizeOfExtraction);
31248 + else
31249 + MemCpy8(
31250 + PTR_MOVE(p_KeysMatchTableNewTmp, p_CcNode->ccKeySizeAccExtraction),
31251 + p_CcNode->p_GlblMask,
31252 + p_CcNode->userSizeOfExtraction);
31253 + }
31254 + }
31255 + MemCpy8((void*)p_KeysMatchTableNewTmp, p_KeysMatchTableOldTmp,
31256 + p_CcNode->ccKeySizeAccExtraction);
31257 + }
31258 + }
31259 +
31260 + p_AdTableNewTmp =
31261 + PTR_MOVE(p_AdditionalInfo->p_AdTableNew, j * FM_PCD_CC_AD_ENTRY_SIZE);
31262 + p_AdTableOldTmp = PTR_MOVE(p_CcNode->h_AdTable, i * FM_PCD_CC_AD_ENTRY_SIZE);
31263 +
31264 + MemCpy8(p_AdTableNewTmp, p_AdTableOldTmp, FM_PCD_CC_AD_ENTRY_SIZE);
31265 +
31266 + return E_OK;
31267 +}
31268 +
31269 +static t_Error BuildNewNodeModifyNextEngine(
31270 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
31271 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams, t_List *h_OldLst,
31272 + t_List *h_NewLst, t_FmPcdModifyCcKeyAdditionalParams *p_AdditionalInfo)
31273 +{
31274 + t_Error err = E_OK;
31275 + uint32_t requiredAction = 0;
31276 + t_List *p_Pos;
31277 + t_CcNodeInformation *p_CcNodeInformation, ccNodeInfo;
31278 + t_Handle p_Ad;
31279 + t_FmPcdCcNode *p_FmPcdCcNode1 = NULL;
31280 + t_FmPcdCcTree *p_FmPcdCcTree = NULL;
31281 + t_FmPcdStatsObj *p_StatsObj;
31282 + t_FmPcdCcStatsParams statsParams = { 0 };
31283 +
31284 + ASSERT_COND(p_CcNextEngineParams);
31285 +
31286 + /* check that new NIA is legal */
31287 + if (!p_AdditionalInfo->tree)
31288 + err = ValidateNextEngineParams(
31289 + h_FmPcd, p_CcNextEngineParams,
31290 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->statisticsMode);
31291 + else
31292 + /* Statistics are not supported for CC root */
31293 + err = ValidateNextEngineParams(h_FmPcd, p_CcNextEngineParams,
31294 + e_FM_PCD_CC_STATS_MODE_NONE);
31295 + if (err)
31296 + RETURN_ERROR(MAJOR, err, NO_MSG);
31297 +
31298 + /* Update internal data structure for next engine per index (index - key) */
31299 + memcpy(&p_AdditionalInfo->keyAndNextEngineParams[keyIndex].nextEngineParams,
31300 + p_CcNextEngineParams, sizeof(t_FmPcdCcNextEngineParams));
31301 +
31302 + /* Check that manip is legal and what requiredAction is necessary for this manip */
31303 + if (p_CcNextEngineParams->h_Manip)
31304 + {
31305 + err = FmPcdManipCheckParamsForCcNextEngine(p_CcNextEngineParams,
31306 + &requiredAction);
31307 + if (err)
31308 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31309 + }
31310 +
31311 + if (!p_AdditionalInfo->tree)
31312 + {
31313 + p_FmPcdCcNode1 = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
31314 + p_AdditionalInfo->numOfKeys = p_FmPcdCcNode1->numOfKeys;
31315 + p_Ad = p_FmPcdCcNode1->h_AdTable;
31316 +
31317 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
31318 + == e_FM_PCD_CC)
31319 + p_AdditionalInfo->h_NodeForRmv =
31320 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
31321 +
31322 + if (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
31323 + p_AdditionalInfo->h_ManipForRmv =
31324 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
31325 +
31326 +#if (DPAA_VERSION >= 11)
31327 + if ((p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
31328 + == e_FM_PCD_FR)
31329 + && (p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
31330 + p_AdditionalInfo->h_FrmReplicForRmv =
31331 + p_FmPcdCcNode1->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
31332 +#endif /* (DPAA_VERSION >= 11) */
31333 + }
31334 + else
31335 + {
31336 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
31337 + p_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
31338 +
31339 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
31340 + == e_FM_PCD_CC)
31341 + p_AdditionalInfo->h_NodeForRmv =
31342 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.ccParams.h_CcNode;
31343 +
31344 + if (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip)
31345 + p_AdditionalInfo->h_ManipForRmv =
31346 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.h_Manip;
31347 +
31348 +#if (DPAA_VERSION >= 11)
31349 + if ((p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.nextEngine
31350 + == e_FM_PCD_FR)
31351 + && (p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic))
31352 + p_AdditionalInfo->h_FrmReplicForRmv =
31353 + p_FmPcdCcTree->keyAndNextEngineParams[keyIndex].nextEngineParams.params.frParams.h_FrmReplic;
31354 +#endif /* (DPAA_VERSION >= 11) */
31355 + }
31356 +
31357 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
31358 + && p_CcNextEngineParams->h_Manip)
31359 + {
31360 + err = AllocAndFillAdForContLookupManip(
31361 + p_CcNextEngineParams->params.ccParams.h_CcNode);
31362 + if (err)
31363 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31364 + }
31365 +
31366 + ASSERT_COND(p_Ad);
31367 +
31368 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31369 + ccNodeInfo.h_CcNode = PTR_MOVE(p_Ad, keyIndex * FM_PCD_CC_AD_ENTRY_SIZE);
31370 +
31371 + /* If statistics were enabled, this Ad is the statistics Ad. Need to follow its
31372 + nextAction to retrieve the actual Nia-Ad. If statistics should remain enabled,
31373 + only the actual Nia-Ad should be modified. */
31374 + if ((!p_AdditionalInfo->tree)
31375 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
31376 + && (p_CcNextEngineParams->statisticsEn))
31377 + ccNodeInfo.h_CcNode =
31378 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsAd;
31379 +
31380 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
31381 +
31382 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31383 + p_Ad = GetNewAd(h_FmPcdCcNodeOrTree, p_AdditionalInfo->tree);
31384 + if (!p_Ad)
31385 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
31386 + ("MURAM allocation for CC node action descriptor"));
31387 + MemSet8((uint8_t *)p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
31388 +
31389 + /* If statistics were not enabled before, but requested now - Allocate a statistics
31390 + object that holds statistics AD and counters. */
31391 + if ((!p_AdditionalInfo->tree)
31392 + && (!((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
31393 + && (p_CcNextEngineParams->statisticsEn))
31394 + {
31395 + p_StatsObj = GetStatsObj((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree);
31396 + ASSERT_COND(p_StatsObj);
31397 +
31398 + /* Store allocated statistics object */
31399 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj =
31400 + p_StatsObj;
31401 +
31402 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
31403 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
31404 +
31405 +#if (DPAA_VERSION >= 11)
31406 + statsParams.h_StatsFLRs =
31407 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->h_StatsFLRs;
31408 +
31409 +#endif /* (DPAA_VERSION >= 11) */
31410 +
31411 + NextStepAd(p_Ad, &statsParams, p_CcNextEngineParams, h_FmPcd);
31412 + }
31413 + else
31414 + NextStepAd(p_Ad, NULL, p_CcNextEngineParams, h_FmPcd);
31415 +
31416 + ccNodeInfo.h_CcNode = p_Ad;
31417 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
31418 +
31419 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction =
31420 + requiredAction;
31421 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction |=
31422 + UPDATE_CC_WITH_TREE;
31423 +
31424 + if (!p_AdditionalInfo->tree)
31425 + {
31426 + ASSERT_COND(p_FmPcdCcNode1);
31427 + if (!LIST_IsEmpty(&p_FmPcdCcNode1->ccTreesLst))
31428 + {
31429 + LIST_FOR_EACH(p_Pos, &p_FmPcdCcNode1->ccTreesLst)
31430 + {
31431 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
31432 +
31433 + ASSERT_COND(p_CcNodeInformation->h_CcNode);
31434 + /* Update the manipulation which has to be updated from parameters of the port
31435 + it's has to be updated with restrictions defined in the function */
31436 +
31437 + err =
31438 + SetRequiredAction(
31439 + p_FmPcdCcNode1->h_FmPcd,
31440 + p_FmPcdCcNode1->shadowAction
31441 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
31442 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
31443 + p_Ad, 1, p_CcNodeInformation->h_CcNode);
31444 + if (err)
31445 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31446 +
31447 + err = CcUpdateParam(
31448 + p_FmPcdCcNode1->h_FmPcd, NULL, NULL,
31449 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex], 1,
31450 + p_Ad, TRUE, p_CcNodeInformation->index,
31451 + p_CcNodeInformation->h_CcNode, TRUE);
31452 + if (err)
31453 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31454 + }
31455 + }
31456 + }
31457 + else
31458 + {
31459 + ASSERT_COND(p_FmPcdCcTree);
31460 +
31461 + err =
31462 + SetRequiredAction(
31463 + h_FmPcd,
31464 + p_FmPcdCcTree->requiredAction
31465 + | p_AdditionalInfo->keyAndNextEngineParams[keyIndex].requiredAction,
31466 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
31467 + p_Ad, 1, (t_Handle)p_FmPcdCcTree);
31468 + if (err)
31469 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31470 +
31471 + err = CcUpdateParam(h_FmPcd, NULL, NULL,
31472 + &p_AdditionalInfo->keyAndNextEngineParams[keyIndex],
31473 + 1, p_Ad, TRUE, 0, (t_Handle)p_FmPcdCcTree, TRUE);
31474 + if (err)
31475 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31476 + }
31477 +
31478 + if (p_CcNextEngineParams->nextEngine == e_FM_PCD_CC)
31479 + p_AdditionalInfo->h_NodeForAdd =
31480 + p_CcNextEngineParams->params.ccParams.h_CcNode;
31481 + if (p_CcNextEngineParams->h_Manip)
31482 + p_AdditionalInfo->h_ManipForAdd = p_CcNextEngineParams->h_Manip;
31483 +
31484 + /* If statistics were previously enabled, but now are disabled,
31485 + store the old statistics object to be released */
31486 + if ((!p_AdditionalInfo->tree)
31487 + && (((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj)
31488 + && (!p_CcNextEngineParams->statisticsEn))
31489 + {
31490 + p_AdditionalInfo->p_StatsObjForRmv =
31491 + ((t_FmPcdCcNode *)h_FmPcdCcNodeOrTree)->keyAndNextEngineParams[keyIndex].p_StatsObj;
31492 +
31493 +
31494 + p_AdditionalInfo->keyAndNextEngineParams[keyIndex].p_StatsObj = NULL;
31495 + }
31496 +#if (DPAA_VERSION >= 11)
31497 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_FR)
31498 + && (p_CcNextEngineParams->params.frParams.h_FrmReplic))
31499 + p_AdditionalInfo->h_FrmReplicForAdd =
31500 + p_CcNextEngineParams->params.frParams.h_FrmReplic;
31501 +#endif /* (DPAA_VERSION >= 11) */
31502 +
31503 + return E_OK;
31504 +}
31505 +
31506 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(
31507 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
31508 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
31509 +{
31510 + t_CcNodeInformation *p_CcNodeInformation;
31511 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfNode = NULL;
31512 + t_List *p_Pos;
31513 + int i = 0;
31514 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
31515 + t_CcNodeInformation ccNodeInfo;
31516 +
31517 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccPrevNodesLst)
31518 + {
31519 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
31520 + p_NodePtrOnCurrentMdfNode =
31521 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
31522 +
31523 + ASSERT_COND(p_NodePtrOnCurrentMdfNode);
31524 +
31525 + /* Search in the previous node which exact index points on this current modified node for getting AD */
31526 + for (i = 0; i < p_NodePtrOnCurrentMdfNode->numOfKeys + 1; i++)
31527 + {
31528 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
31529 + == e_FM_PCD_CC)
31530 + {
31531 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
31532 + == (t_Handle)p_CrntMdfNode)
31533 + {
31534 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
31535 + p_AdTablePtOnCrntCurrentMdfNode = p_CrntMdfNode->h_Ad;
31536 + else
31537 + if (p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj)
31538 + p_AdTablePtOnCrntCurrentMdfNode =
31539 + p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
31540 + else
31541 + p_AdTablePtOnCrntCurrentMdfNode =
31542 + PTR_MOVE(p_NodePtrOnCurrentMdfNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
31543 +
31544 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31545 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
31546 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
31547 +
31548 + if (!(*p_NextEngineParams))
31549 + *p_NextEngineParams =
31550 + &p_NodePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
31551 + }
31552 + }
31553 + }
31554 +
31555 + ASSERT_COND(i != p_NodePtrOnCurrentMdfNode->numOfKeys);
31556 + }
31557 +}
31558 +
31559 +static void UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(
31560 + t_FmPcdCcNode *p_CrntMdfNode, t_List *h_OldLst,
31561 + t_FmPcdCcNextEngineParams **p_NextEngineParams)
31562 +{
31563 + t_CcNodeInformation *p_CcNodeInformation;
31564 + t_FmPcdCcTree *p_TreePtrOnCurrentMdfNode = NULL;
31565 + t_List *p_Pos;
31566 + int i = 0;
31567 + t_Handle p_AdTableTmp;
31568 + t_CcNodeInformation ccNodeInfo;
31569 +
31570 + LIST_FOR_EACH(p_Pos, &p_CrntMdfNode->ccTreeIdLst)
31571 + {
31572 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
31573 + p_TreePtrOnCurrentMdfNode =
31574 + (t_FmPcdCcTree *)p_CcNodeInformation->h_CcNode;
31575 +
31576 + ASSERT_COND(p_TreePtrOnCurrentMdfNode);
31577 +
31578 + /*search in the trees which exact index points on this current modified node for getting AD */
31579 + for (i = 0; i < p_TreePtrOnCurrentMdfNode->numOfEntries; i++)
31580 + {
31581 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
31582 + == e_FM_PCD_CC)
31583 + {
31584 + if (p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode
31585 + == (t_Handle)p_CrntMdfNode)
31586 + {
31587 + p_AdTableTmp =
31588 + UINT_TO_PTR(p_TreePtrOnCurrentMdfNode->ccTreeBaseAddr + i*FM_PCD_CC_AD_ENTRY_SIZE);
31589 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
31590 + ccNodeInfo.h_CcNode = p_AdTableTmp;
31591 + EnqueueNodeInfoToRelevantLst(h_OldLst, &ccNodeInfo, NULL);
31592 +
31593 + if (!(*p_NextEngineParams))
31594 + *p_NextEngineParams =
31595 + &p_TreePtrOnCurrentMdfNode->keyAndNextEngineParams[i].nextEngineParams;
31596 + }
31597 + }
31598 + }
31599 +
31600 + ASSERT_COND(i == p_TreePtrOnCurrentMdfNode->numOfEntries);
31601 + }
31602 +}
31603 +
31604 +static t_FmPcdModifyCcKeyAdditionalParams * ModifyNodeCommonPart(
31605 + t_Handle h_FmPcdCcNodeOrTree, uint16_t keyIndex,
31606 + e_ModifyState modifyState, bool ttlCheck, bool hashCheck, bool tree)
31607 +{
31608 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams;
31609 + int i = 0, j = 0;
31610 + bool wasUpdate = FALSE;
31611 + t_FmPcdCcNode *p_CcNode = NULL;
31612 + t_FmPcdCcTree *p_FmPcdCcTree;
31613 + uint16_t numOfKeys;
31614 + t_FmPcdCcKeyAndNextEngineParams *p_KeyAndNextEngineParams;
31615 +
31616 + SANITY_CHECK_RETURN_VALUE(h_FmPcdCcNodeOrTree, E_INVALID_HANDLE, NULL);
31617 +
31618 + if (!tree)
31619 + {
31620 + p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNodeOrTree;
31621 + numOfKeys = p_CcNode->numOfKeys;
31622 +
31623 + /* node has to be pointed by another node or tree */
31624 +
31625 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
31626 + sizeof(t_FmPcdCcKeyAndNextEngineParams) * (numOfKeys + 1));
31627 + if (!p_KeyAndNextEngineParams)
31628 + {
31629 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
31630 + return NULL;
31631 + }
31632 + memcpy(p_KeyAndNextEngineParams, p_CcNode->keyAndNextEngineParams,
31633 + (numOfKeys + 1) * sizeof(t_FmPcdCcKeyAndNextEngineParams));
31634 +
31635 + if (ttlCheck)
31636 + {
31637 + if ((p_CcNode->parseCode == CC_PC_FF_IPV4TTL)
31638 + || (p_CcNode->parseCode == CC_PC_FF_IPV6HOP_LIMIT))
31639 + {
31640 + XX_Free(p_KeyAndNextEngineParams);
31641 + 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"));
31642 + return NULL;
31643 + }
31644 + }
31645 +
31646 + if (hashCheck)
31647 + {
31648 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
31649 + {
31650 + XX_Free(p_KeyAndNextEngineParams);
31651 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("nodeId of CC_PC_GENERIC_IC_HASH_INDEXED can not be used for this operation"));
31652 + return NULL;
31653 + }
31654 + }
31655 + }
31656 + else
31657 + {
31658 + p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcNodeOrTree;
31659 + numOfKeys = p_FmPcdCcTree->numOfEntries;
31660 +
31661 + p_KeyAndNextEngineParams = (t_FmPcdCcKeyAndNextEngineParams *)XX_Malloc(
31662 + sizeof(t_FmPcdCcKeyAndNextEngineParams)
31663 + * FM_PCD_MAX_NUM_OF_CC_GROUPS);
31664 + if (!p_KeyAndNextEngineParams)
31665 + {
31666 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Next engine and required action structure"));
31667 + return NULL;
31668 + }
31669 + memcpy(p_KeyAndNextEngineParams,
31670 + p_FmPcdCcTree->keyAndNextEngineParams,
31671 + FM_PCD_MAX_NUM_OF_CC_GROUPS
31672 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
31673 + }
31674 +
31675 + p_FmPcdModifyCcKeyAdditionalParams =
31676 + (t_FmPcdModifyCcKeyAdditionalParams *)XX_Malloc(
31677 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
31678 + if (!p_FmPcdModifyCcKeyAdditionalParams)
31679 + {
31680 + XX_Free(p_KeyAndNextEngineParams);
31681 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of internal data structure FAILED"));
31682 + return NULL;
31683 + }
31684 + memset(p_FmPcdModifyCcKeyAdditionalParams, 0,
31685 + sizeof(t_FmPcdModifyCcKeyAdditionalParams));
31686 +
31687 + p_FmPcdModifyCcKeyAdditionalParams->h_CurrentNode = h_FmPcdCcNodeOrTree;
31688 + p_FmPcdModifyCcKeyAdditionalParams->savedKeyIndex = keyIndex;
31689 +
31690 + while (i < numOfKeys)
31691 + {
31692 + if ((j == keyIndex) && !wasUpdate)
31693 + {
31694 + if (modifyState == e_MODIFY_STATE_ADD)
31695 + j++;
31696 + else
31697 + if (modifyState == e_MODIFY_STATE_REMOVE)
31698 + i++;
31699 + wasUpdate = TRUE;
31700 + }
31701 + else
31702 + {
31703 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
31704 + p_KeyAndNextEngineParams + i,
31705 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
31706 + i++;
31707 + j++;
31708 + }
31709 + }
31710 +
31711 + if (keyIndex == numOfKeys)
31712 + {
31713 + if (modifyState == e_MODIFY_STATE_ADD)
31714 + j++;
31715 + }
31716 +
31717 + memcpy(&p_FmPcdModifyCcKeyAdditionalParams->keyAndNextEngineParams[j],
31718 + p_KeyAndNextEngineParams + numOfKeys,
31719 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
31720 +
31721 + XX_Free(p_KeyAndNextEngineParams);
31722 +
31723 + return p_FmPcdModifyCcKeyAdditionalParams;
31724 +}
31725 +
31726 +static t_Error UpdatePtrWhichPointOnCrntMdfNode(
31727 + t_FmPcdCcNode *p_CcNode,
31728 + t_FmPcdModifyCcKeyAdditionalParams *p_FmPcdModifyCcKeyAdditionalParams,
31729 + t_List *h_OldLst, t_List *h_NewLst)
31730 +{
31731 + t_FmPcdCcNextEngineParams *p_NextEngineParams = NULL;
31732 + t_CcNodeInformation ccNodeInfo = { 0 };
31733 + t_Handle h_NewAd;
31734 + t_Handle h_OrigAd = NULL;
31735 +
31736 + /* Building a list of all action descriptors that point to the previous node */
31737 + if (!LIST_IsEmpty(&p_CcNode->ccPrevNodesLst))
31738 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
31739 + &p_NextEngineParams);
31740 +
31741 + if (!LIST_IsEmpty(&p_CcNode->ccTreeIdLst))
31742 + UpdateAdPtrOfTreesWhichPointsOnCrntMdfNode(p_CcNode, h_OldLst,
31743 + &p_NextEngineParams);
31744 +
31745 + /* This node must be found as next engine of one of its previous nodes or trees*/
31746 + if (p_NextEngineParams)
31747 + {
31748 + /* Building a new action descriptor that points to the modified node */
31749 + h_NewAd = GetNewAd(p_CcNode, FALSE);
31750 + if (!h_NewAd)
31751 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
31752 + MemSet8(h_NewAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
31753 +
31754 + h_OrigAd = p_CcNode->h_Ad;
31755 + BuildNewAd(h_NewAd, p_FmPcdModifyCcKeyAdditionalParams, p_CcNode,
31756 + p_NextEngineParams);
31757 +
31758 + ccNodeInfo.h_CcNode = h_NewAd;
31759 + EnqueueNodeInfoToRelevantLst(h_NewLst, &ccNodeInfo, NULL);
31760 +
31761 + if (p_NextEngineParams->h_Manip && !h_OrigAd)
31762 + FmPcdManipUpdateOwner(p_NextEngineParams->h_Manip, FALSE);
31763 + }
31764 + return E_OK;
31765 +}
31766 +
31767 +static void UpdateCcRootOwner(t_FmPcdCcTree *p_FmPcdCcTree, bool add)
31768 +{
31769 + ASSERT_COND(p_FmPcdCcTree);
31770 +
31771 + /* this routine must be protected by the calling routine! */
31772 +
31773 + if (add)
31774 + p_FmPcdCcTree->owners++;
31775 + else
31776 + {
31777 + ASSERT_COND(p_FmPcdCcTree->owners);
31778 + p_FmPcdCcTree->owners--;
31779 + }
31780 +}
31781 +
31782 +static t_Error CheckAndSetManipParamsWithCcNodeParams(t_FmPcdCcNode *p_CcNode)
31783 +{
31784 + t_Error err = E_OK;
31785 + int i = 0;
31786 +
31787 + for (i = 0; i < p_CcNode->numOfKeys; i++)
31788 + {
31789 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
31790 + {
31791 + err =
31792 + FmPcdManipCheckParamsWithCcNodeParams(
31793 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
31794 + (t_Handle)p_CcNode);
31795 + if (err)
31796 + return err;
31797 + }
31798 + }
31799 +
31800 + return err;
31801 +}
31802 +static t_Error ValidateAndCalcStatsParams(t_FmPcdCcNode *p_CcNode,
31803 + t_FmPcdCcNodeParams *p_CcNodeParam,
31804 + uint32_t *p_NumOfRanges,
31805 + uint32_t *p_CountersArraySize)
31806 +{
31807 + e_FmPcdCcStatsMode statisticsMode = p_CcNode->statisticsMode;
31808 + uint32_t i;
31809 +
31810 + UNUSED(p_CcNodeParam);
31811 +
31812 + switch (statisticsMode)
31813 + {
31814 + case e_FM_PCD_CC_STATS_MODE_NONE:
31815 + for (i = 0; i < p_CcNode->numOfKeys; i++)
31816 + if (p_CcNodeParam->keysParams.keyParams[i].ccNextEngineParams.statisticsEn)
31817 + RETURN_ERROR(
31818 + MAJOR,
31819 + E_INVALID_VALUE,
31820 + ("Statistics cannot be enabled for key %d when statistics mode was set to 'NONE'", i));
31821 + return E_OK;
31822 +
31823 + case e_FM_PCD_CC_STATS_MODE_FRAME:
31824 + case e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME:
31825 + *p_NumOfRanges = 1;
31826 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
31827 + return E_OK;
31828 +
31829 +#if (DPAA_VERSION >= 11)
31830 + case e_FM_PCD_CC_STATS_MODE_RMON:
31831 + {
31832 + uint16_t *p_FrameLengthRanges =
31833 + p_CcNodeParam->keysParams.frameLengthRanges;
31834 + uint32_t i;
31835 +
31836 + if (p_FrameLengthRanges[0] <= 0)
31837 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
31838 +
31839 + if (p_FrameLengthRanges[0] == 0xFFFF)
31840 + {
31841 + *p_NumOfRanges = 1;
31842 + *p_CountersArraySize = 2 * FM_PCD_CC_STATS_COUNTER_SIZE;
31843 + return E_OK;
31844 + }
31845 +
31846 + for (i = 1; i < FM_PCD_CC_STATS_MAX_NUM_OF_FLR; i++)
31847 + {
31848 + if (p_FrameLengthRanges[i - 1] >= p_FrameLengthRanges[i])
31849 + RETURN_ERROR(
31850 + MAJOR,
31851 + E_INVALID_VALUE,
31852 + ("Frame length range must be larger at least by 1 from preceding range"));
31853 +
31854 + /* Stop when last range is reached */
31855 + if (p_FrameLengthRanges[i] == 0xFFFF)
31856 + break;
31857 + }
31858 +
31859 + if ((i >= FM_PCD_CC_STATS_MAX_NUM_OF_FLR)
31860 + || (p_FrameLengthRanges[i] != 0xFFFF))
31861 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
31862 + ("Last Frame length range must be 0xFFFF"));
31863 +
31864 + *p_NumOfRanges = i + 1;
31865 +
31866 + /* Allocate an extra counter for byte count, as counters
31867 + array always begins with byte count */
31868 + *p_CountersArraySize = (*p_NumOfRanges + 1)
31869 + * FM_PCD_CC_STATS_COUNTER_SIZE;
31870 +
31871 + }
31872 + return E_OK;
31873 +#endif /* (DPAA_VERSION >= 11) */
31874 +
31875 + default:
31876 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Statistics mode"));
31877 + }
31878 +}
31879 +
31880 +static t_Error CheckParams(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
31881 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
31882 +{
31883 + int tmp = 0;
31884 + t_FmPcdCcKeyParams *p_KeyParams;
31885 + t_Error err;
31886 + uint32_t requiredAction = 0;
31887 +
31888 + /* Validate statistics parameters */
31889 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
31890 + &(p_CcNode->numOfStatsFLRs),
31891 + &(p_CcNode->countersArraySize));
31892 + if (err)
31893 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
31894 +
31895 + /* Validate next engine parameters on Miss */
31896 + err = ValidateNextEngineParams(
31897 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31898 + p_CcNode->statisticsMode);
31899 + if (err)
31900 + RETURN_ERROR(MAJOR, err,
31901 + ("For this node MissNextEngineParams are not valid"));
31902 +
31903 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
31904 + {
31905 + err = FmPcdManipCheckParamsForCcNextEngine(
31906 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31907 + &requiredAction);
31908 + if (err)
31909 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31910 + }
31911 +
31912 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
31913 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
31914 + sizeof(t_FmPcdCcNextEngineParams));
31915 +
31916 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
31917 + requiredAction;
31918 +
31919 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
31920 + == e_FM_PCD_CC)
31921 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
31922 + {
31923 + err =
31924 + AllocAndFillAdForContLookupManip(
31925 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
31926 + if (err)
31927 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31928 + }
31929 +
31930 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
31931 + {
31932 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
31933 +
31934 + if (!p_KeyParams->p_Key)
31935 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_Key is not initialized"));
31936 +
31937 + err = ValidateNextEngineParams(h_FmPcd,
31938 + &p_KeyParams->ccNextEngineParams,
31939 + p_CcNode->statisticsMode);
31940 + if (err)
31941 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31942 +
31943 + err = UpdateGblMask(p_CcNode, p_CcNodeParam->keysParams.keySize,
31944 + p_KeyParams->p_Mask);
31945 + if (err)
31946 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31947 +
31948 + if (p_KeyParams->ccNextEngineParams.h_Manip)
31949 + {
31950 + err = FmPcdManipCheckParamsForCcNextEngine(
31951 + &p_KeyParams->ccNextEngineParams, &requiredAction);
31952 + if (err)
31953 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31954 + }
31955 +
31956 + /* Store 'key' parameters - key, mask (if passed by the user) */
31957 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].key, p_KeyParams->p_Key,
31958 + p_CcNodeParam->keysParams.keySize);
31959 +
31960 + if (p_KeyParams->p_Mask)
31961 + memcpy(p_CcNode->keyAndNextEngineParams[tmp].mask,
31962 + p_KeyParams->p_Mask, p_CcNodeParam->keysParams.keySize);
31963 + else
31964 + memset((void *)(p_CcNode->keyAndNextEngineParams[tmp].mask), 0xFF,
31965 + p_CcNodeParam->keysParams.keySize);
31966 +
31967 + /* Store next engine parameters */
31968 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
31969 + &p_KeyParams->ccNextEngineParams,
31970 + sizeof(t_FmPcdCcNextEngineParams));
31971 +
31972 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
31973 +
31974 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
31975 + == e_FM_PCD_CC)
31976 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
31977 + {
31978 + err =
31979 + AllocAndFillAdForContLookupManip(
31980 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
31981 + if (err)
31982 + RETURN_ERROR(MAJOR, err, (NO_MSG));
31983 + }
31984 + }
31985 +
31986 + if (p_CcNode->maxNumOfKeys)
31987 + {
31988 + if (p_CcNode->maxNumOfKeys < p_CcNode->numOfKeys)
31989 + RETURN_ERROR(
31990 + MAJOR,
31991 + E_INVALID_VALUE,
31992 + ("Number of keys exceed the provided maximal number of keys"));
31993 + }
31994 +
31995 + *isKeyTblAlloc = TRUE;
31996 +
31997 + return E_OK;
31998 +}
31999 +
32000 +static t_Error Ipv4TtlOrIpv6HopLimitCheckParams(
32001 + t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_CcNodeParam,
32002 + t_FmPcdCcNode *p_CcNode, bool *isKeyTblAlloc)
32003 +{
32004 + int tmp = 0;
32005 + t_FmPcdCcKeyParams *p_KeyParams;
32006 + t_Error err;
32007 + uint8_t key = 0x01;
32008 + uint32_t requiredAction = 0;
32009 +
32010 + if (p_CcNode->numOfKeys != 1)
32011 + RETURN_ERROR(
32012 + MAJOR,
32013 + E_INVALID_VALUE,
32014 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'numOfKeys' is 1"));
32015 +
32016 + if ((p_CcNodeParam->keysParams.maxNumOfKeys)
32017 + && (p_CcNodeParam->keysParams.maxNumOfKeys != 1))
32018 + RETURN_ERROR(
32019 + MAJOR,
32020 + E_INVALID_VALUE,
32021 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT the maximal supported 'maxNumOfKeys' is 1"));
32022 +
32023 + /* Validate statistics parameters */
32024 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
32025 + &(p_CcNode->numOfStatsFLRs),
32026 + &(p_CcNode->countersArraySize));
32027 + if (err)
32028 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
32029 +
32030 + err = ValidateNextEngineParams(
32031 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
32032 + p_CcNodeParam->keysParams.statisticsMode);
32033 + if (err)
32034 + RETURN_ERROR(MAJOR, err,
32035 + ("For this node MissNextEngineParams are not valid"));
32036 +
32037 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.h_Manip)
32038 + {
32039 + err = FmPcdManipCheckParamsForCcNextEngine(
32040 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
32041 + &requiredAction);
32042 + if (err)
32043 + RETURN_ERROR(MAJOR, err, (NO_MSG));
32044 + }
32045 +
32046 + memcpy(&p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams,
32047 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
32048 + sizeof(t_FmPcdCcNextEngineParams));
32049 +
32050 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].requiredAction =
32051 + requiredAction;
32052 +
32053 + if ((p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.nextEngine
32054 + == e_FM_PCD_CC)
32055 + && p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.h_Manip)
32056 + {
32057 + err =
32058 + AllocAndFillAdForContLookupManip(
32059 + p_CcNode->keyAndNextEngineParams[p_CcNode->numOfKeys].nextEngineParams.params.ccParams.h_CcNode);
32060 + if (err)
32061 + RETURN_ERROR(MAJOR, err, (NO_MSG));
32062 + }
32063 +
32064 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
32065 + {
32066 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
32067 +
32068 + if (p_KeyParams->p_Mask)
32069 + RETURN_ERROR(
32070 + MAJOR,
32071 + E_INVALID_VALUE,
32072 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Mask can not be initialized"));
32073 +
32074 + if (memcmp(p_KeyParams->p_Key, &key, 1) != 0)
32075 + RETURN_ERROR(
32076 + MAJOR,
32077 + E_INVALID_VALUE,
32078 + ("For node of the type IPV4_TTL or IPV6_HOP_LIMIT p_Key has to be 1"));
32079 +
32080 + err = ValidateNextEngineParams(h_FmPcd,
32081 + &p_KeyParams->ccNextEngineParams,
32082 + p_CcNode->statisticsMode);
32083 + if (err)
32084 + RETURN_ERROR(MAJOR, err, (NO_MSG));
32085 +
32086 + if (p_KeyParams->ccNextEngineParams.h_Manip)
32087 + {
32088 + err = FmPcdManipCheckParamsForCcNextEngine(
32089 + &p_KeyParams->ccNextEngineParams, &requiredAction);
32090 + if (err)
32091 + RETURN_ERROR(MAJOR, err, (NO_MSG));
32092 + }
32093 +
32094 + /* Store 'key' parameters - key (fixed to 0x01), key size of 1 byte and full mask */
32095 + p_CcNode->keyAndNextEngineParams[tmp].key[0] = key;
32096 + p_CcNode->keyAndNextEngineParams[tmp].mask[0] = 0xFF;
32097 +
32098 + /* Store NextEngine parameters */
32099 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
32100 + &p_KeyParams->ccNextEngineParams,
32101 + sizeof(t_FmPcdCcNextEngineParams));
32102 +
32103 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
32104 + == e_FM_PCD_CC)
32105 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
32106 + {
32107 + err =
32108 + AllocAndFillAdForContLookupManip(
32109 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
32110 + if (err)
32111 + RETURN_ERROR(MAJOR, err, (NO_MSG));
32112 + }
32113 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction = requiredAction;
32114 + }
32115 +
32116 + *isKeyTblAlloc = FALSE;
32117 +
32118 + return E_OK;
32119 +}
32120 +
32121 +static t_Error IcHashIndexedCheckParams(t_Handle h_FmPcd,
32122 + t_FmPcdCcNodeParams *p_CcNodeParam,
32123 + t_FmPcdCcNode *p_CcNode,
32124 + bool *isKeyTblAlloc)
32125 +{
32126 + int tmp = 0, countOnes = 0;
32127 + t_FmPcdCcKeyParams *p_KeyParams;
32128 + t_Error err;
32129 + uint16_t glblMask = p_CcNodeParam->extractCcParams.extractNonHdr.icIndxMask;
32130 + uint16_t countMask = (uint16_t)(glblMask >> 4);
32131 + uint32_t requiredAction = 0;
32132 +
32133 + if (glblMask & 0x000f)
32134 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
32135 + ("icIndxMask has to be with last nibble 0"));
32136 +
32137 + while (countMask)
32138 + {
32139 + countOnes++;
32140 + countMask = (uint16_t)(countMask >> 1);
32141 + }
32142 +
32143 + if (!POWER_OF_2(p_CcNode->numOfKeys))
32144 + RETURN_ERROR(
32145 + MAJOR,
32146 + E_INVALID_VALUE,
32147 + ("For Node of the type INDEXED numOfKeys has to be powerOfTwo"));
32148 +
32149 + if (p_CcNode->numOfKeys != ((uint32_t)1 << countOnes))
32150 + RETURN_ERROR(
32151 + MAJOR,
32152 + E_INVALID_VALUE,
32153 + ("For Node of the type IC_HASH_INDEXED numOfKeys has to be powerOfTwo"));
32154 +
32155 + if (p_CcNodeParam->keysParams.maxNumOfKeys
32156 + && (p_CcNodeParam->keysParams.maxNumOfKeys != p_CcNode->numOfKeys))
32157 + RETURN_ERROR(
32158 + MAJOR,
32159 + E_INVALID_VALUE,
32160 + ("For Node of the type INDEXED 'maxNumOfKeys' should be 0 or equal 'numOfKeys'"));
32161 +
32162 + /* Validate statistics parameters */
32163 + err = ValidateAndCalcStatsParams(p_CcNode, p_CcNodeParam,
32164 + &(p_CcNode->numOfStatsFLRs),
32165 + &(p_CcNode->countersArraySize));
32166 + if (err)
32167 + RETURN_ERROR(MAJOR, err, ("Invalid statistics parameters"));
32168 +
32169 + err = ValidateNextEngineParams(
32170 + h_FmPcd, &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
32171 + p_CcNode->statisticsMode);
32172 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
32173 + RETURN_ERROR(
32174 + MAJOR,
32175 + err,
32176 + ("MissNextEngineParams for the node of the type IC_INDEX_HASH has to be UnInitialized"));
32177 +
32178 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
32179 + {
32180 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
32181 +
32182 + if (p_KeyParams->p_Mask || p_KeyParams->p_Key)
32183 + RETURN_ERROR(
32184 + MAJOR,
32185 + E_INVALID_VALUE,
32186 + ("For Node of the type IC_HASH_INDEXED p_Key or p_Mask has to be NULL"));
32187 +
32188 + if ((glblMask & (tmp * 16)) == (tmp * 16))
32189 + {
32190 + err = ValidateNextEngineParams(h_FmPcd,
32191 + &p_KeyParams->ccNextEngineParams,
32192 + p_CcNode->statisticsMode);
32193 + if (err)
32194 + RETURN_ERROR(
32195 + MAJOR,
32196 + err,
32197 + ("This index has to be initialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask "));
32198 +
32199 + if (p_KeyParams->ccNextEngineParams.h_Manip)
32200 + {
32201 + err = FmPcdManipCheckParamsForCcNextEngine(
32202 + &p_KeyParams->ccNextEngineParams, &requiredAction);
32203 + if (err)
32204 + RETURN_ERROR(MAJOR, err, (NO_MSG));
32205 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction =
32206 + requiredAction;
32207 + }
32208 +
32209 + memcpy(&p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams,
32210 + &p_KeyParams->ccNextEngineParams,
32211 + sizeof(t_FmPcdCcNextEngineParams));
32212 +
32213 + if ((p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
32214 + == e_FM_PCD_CC)
32215 + && p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
32216 + {
32217 + err =
32218 + AllocAndFillAdForContLookupManip(
32219 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode);
32220 + if (err)
32221 + RETURN_ERROR(MAJOR, err, (NO_MSG));
32222 + }
32223 + }
32224 + else
32225 + {
32226 + err = ValidateNextEngineParams(h_FmPcd,
32227 + &p_KeyParams->ccNextEngineParams,
32228 + p_CcNode->statisticsMode);
32229 + if (GET_ERROR_TYPE(err) != E_NOT_SUPPORTED)
32230 + RETURN_ERROR(
32231 + MAJOR,
32232 + err,
32233 + ("This index has to be UnInitialized for the node of the type IC_INDEX_HASH according to settings of GlobalMask"));
32234 + }
32235 + }
32236 +
32237 + *isKeyTblAlloc = FALSE;
32238 + cpu_to_be16s(&glblMask);
32239 + memcpy(PTR_MOVE(p_CcNode->p_GlblMask, 2), &glblMask, 2);
32240 +
32241 + return E_OK;
32242 +}
32243 +
32244 +static t_Error ModifyNextEngineParamNode(
32245 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex,
32246 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
32247 +{
32248 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
32249 + t_FmPcd *p_FmPcd;
32250 + t_List h_OldPointersLst, h_NewPointersLst;
32251 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
32252 + t_Error err = E_OK;
32253 +
32254 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_VALUE);
32255 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
32256 +
32257 + if (keyIndex >= p_CcNode->numOfKeys)
32258 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32259 + ("keyIndex > previously cleared last index + 1"));
32260 +
32261 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
32262 +
32263 + INIT_LIST(&h_OldPointersLst);
32264 + INIT_LIST(&h_NewPointersLst);
32265 +
32266 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
32267 + e_MODIFY_STATE_CHANGE, FALSE,
32268 + FALSE, FALSE);
32269 + if (!p_ModifyKeyParams)
32270 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
32271 +
32272 + if (p_CcNode->maxNumOfKeys
32273 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
32274 + {
32275 + XX_Free(p_ModifyKeyParams);
32276 + return ERROR_CODE(E_BUSY);
32277 + }
32278 +
32279 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
32280 + p_FmPcdCcNextEngineParams,
32281 + &h_OldPointersLst, &h_NewPointersLst,
32282 + p_ModifyKeyParams);
32283 + if (err)
32284 + {
32285 + XX_Free(p_ModifyKeyParams);
32286 + if (p_CcNode->maxNumOfKeys)
32287 + RELEASE_LOCK(p_FmPcd->shadowLock);
32288 + RETURN_ERROR(MAJOR, err, NO_MSG);
32289 + }
32290 +
32291 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
32292 + p_ModifyKeyParams, FALSE);
32293 +
32294 + if (p_CcNode->maxNumOfKeys)
32295 + RELEASE_LOCK(p_FmPcd->shadowLock);
32296 +
32297 + ReleaseLst(&h_OldPointersLst);
32298 + ReleaseLst(&h_NewPointersLst);
32299 +
32300 + return err;
32301 +}
32302 +
32303 +static t_Error FindKeyIndex(t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key,
32304 + uint8_t *p_Mask, uint16_t *p_KeyIndex)
32305 +{
32306 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
32307 + uint8_t tmpMask[FM_PCD_MAX_SIZE_OF_KEY];
32308 + uint16_t i;
32309 +
32310 + ASSERT_COND(p_Key);
32311 + ASSERT_COND(p_KeyIndex);
32312 + ASSERT_COND(keySize < FM_PCD_MAX_SIZE_OF_KEY);
32313 +
32314 + if (keySize != p_CcNode->userSizeOfExtraction)
32315 + RETURN_ERROR(
32316 + MINOR, E_INVALID_VALUE,
32317 + ("Key size doesn't match the extraction size of the node"));
32318 +
32319 + /* If user didn't pass a mask for this key, we'll look for full extraction mask */
32320 + if (!p_Mask)
32321 + memset(tmpMask, 0xFF, keySize);
32322 +
32323 + for (i = 0; i < p_CcNode->numOfKeys; i++)
32324 + {
32325 + /* Comparing received key */
32326 + if (memcmp(p_Key, p_CcNode->keyAndNextEngineParams[i].key, keySize)
32327 + == 0)
32328 + {
32329 + if (p_Mask)
32330 + {
32331 + /* If a user passed a mask for this key, it must match to the existing key's mask for a correct match */
32332 + if (memcmp(p_Mask, p_CcNode->keyAndNextEngineParams[i].mask,
32333 + keySize) == 0)
32334 + {
32335 + *p_KeyIndex = i;
32336 + return E_OK;
32337 + }
32338 + }
32339 + else
32340 + {
32341 + /* If user didn't pass a mask for this key, check if the existing key mask is full extraction */
32342 + if (memcmp(tmpMask, p_CcNode->keyAndNextEngineParams[i].mask,
32343 + keySize) == 0)
32344 + {
32345 + *p_KeyIndex = i;
32346 + return E_OK;
32347 + }
32348 + }
32349 + }
32350 + }
32351 +
32352 + return ERROR_CODE(E_NOT_FOUND);
32353 +}
32354 +
32355 +static t_Error CalcAndUpdateCcShadow(t_FmPcdCcNode *p_CcNode,
32356 + bool isKeyTblAlloc,
32357 + uint32_t *p_MatchTableSize,
32358 + uint32_t *p_AdTableSize)
32359 +{
32360 + uint32_t shadowSize;
32361 + t_Error err;
32362 +
32363 + /* Calculate keys table maximal size - each entry consists of a key and a mask,
32364 + (if local mask support is requested) */
32365 + *p_MatchTableSize = p_CcNode->ccKeySizeAccExtraction * sizeof(uint8_t)
32366 + * p_CcNode->maxNumOfKeys;
32367 +
32368 + if (p_CcNode->maskSupport)
32369 + *p_MatchTableSize *= 2;
32370 +
32371 + /* Calculate next action descriptors table, including one more entry for miss */
32372 + *p_AdTableSize = (uint32_t)((p_CcNode->maxNumOfKeys + 1)
32373 + * FM_PCD_CC_AD_ENTRY_SIZE);
32374 +
32375 + /* Calculate maximal shadow size of this node.
32376 + All shadow structures will be used for runtime modifications host command. If
32377 + keys table was allocated for this node, the keys table and next engines table may
32378 + be modified in run time (entries added or removed), so shadow tables are requires.
32379 + Otherwise, the only supported runtime modification is a specific next engine update
32380 + and this requires shadow memory of a single AD */
32381 +
32382 + /* Shadow size should be enough to hold the following 3 structures:
32383 + * 1 - an action descriptor */
32384 + shadowSize = FM_PCD_CC_AD_ENTRY_SIZE;
32385 +
32386 + /* 2 - keys match table, if was allocated for the current node */
32387 + if (isKeyTblAlloc)
32388 + shadowSize += *p_MatchTableSize;
32389 +
32390 + /* 3 - next action descriptors table */
32391 + shadowSize += *p_AdTableSize;
32392 +
32393 + /* Update shadow to the calculated size */
32394 + err = FmPcdUpdateCcShadow(p_CcNode->h_FmPcd, (uint32_t)shadowSize,
32395 + FM_PCD_CC_AD_TABLE_ALIGN);
32396 + if (err != E_OK)
32397 + {
32398 + DeleteNode(p_CcNode);
32399 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC node shadow"));
32400 + }
32401 +
32402 + return E_OK;
32403 +}
32404 +
32405 +static t_Error AllocStatsObjs(t_FmPcdCcNode *p_CcNode)
32406 +{
32407 + t_FmPcdStatsObj *p_StatsObj;
32408 + t_Handle h_FmMuram, h_StatsAd, h_StatsCounters;
32409 + uint32_t i;
32410 +
32411 + h_FmMuram = FmPcdGetMuramHandle(p_CcNode->h_FmPcd);
32412 + if (!h_FmMuram)
32413 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
32414 +
32415 + /* Allocate statistics ADs and statistics counter. An extra pair (AD + counters)
32416 + will be allocated to support runtime modifications */
32417 + for (i = 0; i < p_CcNode->maxNumOfKeys + 2; i++)
32418 + {
32419 + /* Allocate list object structure */
32420 + p_StatsObj = XX_Malloc(sizeof(t_FmPcdStatsObj));
32421 + if (!p_StatsObj)
32422 + {
32423 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
32424 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Statistics object"));
32425 + }
32426 + memset(p_StatsObj, 0, sizeof(t_FmPcdStatsObj));
32427 +
32428 + /* Allocate statistics AD from MURAM */
32429 + h_StatsAd = (t_Handle)FM_MURAM_AllocMem(h_FmMuram,
32430 + FM_PCD_CC_AD_ENTRY_SIZE,
32431 + FM_PCD_CC_AD_TABLE_ALIGN);
32432 + if (!h_StatsAd)
32433 + {
32434 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
32435 + XX_Free(p_StatsObj);
32436 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32437 + ("MURAM allocation for statistics ADs"));
32438 + }
32439 + MemSet8(h_StatsAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
32440 +
32441 + /* Allocate statistics counters from MURAM */
32442 + h_StatsCounters = (t_Handle)FM_MURAM_AllocMem(
32443 + h_FmMuram, p_CcNode->countersArraySize,
32444 + FM_PCD_CC_AD_TABLE_ALIGN);
32445 + if (!h_StatsCounters)
32446 + {
32447 + FreeStatObjects(&p_CcNode->availableStatsLst, h_FmMuram);
32448 + FM_MURAM_FreeMem(h_FmMuram, h_StatsAd);
32449 + XX_Free(p_StatsObj);
32450 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32451 + ("MURAM allocation for statistics counters"));
32452 + }
32453 + MemSet8(h_StatsCounters, 0, p_CcNode->countersArraySize);
32454 +
32455 + p_StatsObj->h_StatsAd = h_StatsAd;
32456 + p_StatsObj->h_StatsCounters = h_StatsCounters;
32457 +
32458 + EnqueueStatsObj(&p_CcNode->availableStatsLst, p_StatsObj);
32459 + }
32460 +
32461 + return E_OK;
32462 +}
32463 +
32464 +static t_Error MatchTableGetKeyStatistics(
32465 + t_FmPcdCcNode *p_CcNode, uint16_t keyIndex,
32466 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
32467 +{
32468 + uint32_t *p_StatsCounters, i;
32469 +
32470 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
32471 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32472 + ("Statistics were not enabled for this match table"));
32473 +
32474 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
32475 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
32476 + ("Statistics were not enabled for this key"));
32477 +
32478 + memset(p_KeyStatistics, 0, sizeof(t_FmPcdCcKeyStatistics));
32479 +
32480 + p_StatsCounters =
32481 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
32482 + ASSERT_COND(p_StatsCounters);
32483 +
32484 + p_KeyStatistics->byteCount = GET_UINT32(*p_StatsCounters);
32485 +
32486 + for (i = 1; i <= p_CcNode->numOfStatsFLRs; i++)
32487 + {
32488 + p_StatsCounters =
32489 + PTR_MOVE(p_StatsCounters, FM_PCD_CC_STATS_COUNTER_SIZE);
32490 +
32491 + p_KeyStatistics->frameCount += GET_UINT32(*p_StatsCounters);
32492 +
32493 +#if (DPAA_VERSION >= 11)
32494 + p_KeyStatistics->frameLengthRangeCount[i - 1] =
32495 + GET_UINT32(*p_StatsCounters);
32496 +#endif /* (DPAA_VERSION >= 11) */
32497 + }
32498 +
32499 + return E_OK;
32500 +}
32501 +
32502 +static t_Error MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNode *p_CcNode,
32503 + t_FmPcdCcNodeParams *p_CcNodeParam)
32504 +{
32505 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
32506 + t_FmPcdCcNode *p_FmPcdCcNextNode;
32507 + t_Error err = E_OK;
32508 + uint32_t tmp, keySize;
32509 + bool glblMask = FALSE;
32510 + t_FmPcdCcKeyParams *p_KeyParams;
32511 + t_Handle h_FmMuram, p_KeysMatchTblTmp, p_AdTableTmp;
32512 +#if (DPAA_VERSION >= 11)
32513 + t_Handle h_StatsFLRs;
32514 +#endif /* (DPAA_VERSION >= 11) */
32515 + bool fullField = FALSE;
32516 + ccPrivateInfo_t icCode = CC_PRIVATE_INFO_NONE;
32517 + bool isKeyTblAlloc, fromIc = FALSE;
32518 + uint32_t matchTableSize, adTableSize;
32519 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
32520 + t_FmPcdStatsObj *p_StatsObj;
32521 + t_FmPcdCcStatsParams statsParams = { 0 };
32522 + t_Handle h_Manip;
32523 +
32524 + ASSERT_COND(h_FmPcd);
32525 + ASSERT_COND(p_CcNode);
32526 + ASSERT_COND(p_CcNodeParam);
32527 +
32528 + p_CcNode->p_GlblMask = (t_Handle)XX_Malloc(
32529 + CC_GLBL_MASK_SIZE * sizeof(uint8_t));
32530 + memset(p_CcNode->p_GlblMask, 0, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
32531 +
32532 + p_CcNode->h_FmPcd = h_FmPcd;
32533 + p_CcNode->numOfKeys = p_CcNodeParam->keysParams.numOfKeys;
32534 + p_CcNode->maxNumOfKeys = p_CcNodeParam->keysParams.maxNumOfKeys;
32535 + p_CcNode->maskSupport = p_CcNodeParam->keysParams.maskSupport;
32536 + p_CcNode->statisticsMode = p_CcNodeParam->keysParams.statisticsMode;
32537 +
32538 + /* For backward compatibility - even if statistics mode is nullified,
32539 + we'll fix it to frame mode so we can support per-key request for
32540 + statistics using 'statisticsEn' in next engine parameters */
32541 + if (!p_CcNode->maxNumOfKeys
32542 + && (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE))
32543 + p_CcNode->statisticsMode = e_FM_PCD_CC_STATS_MODE_FRAME;
32544 +
32545 + h_FmMuram = FmPcdGetMuramHandle(h_FmPcd);
32546 + if (!h_FmMuram)
32547 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM MURAM"));
32548 +
32549 + INIT_LIST(&p_CcNode->ccPrevNodesLst);
32550 + INIT_LIST(&p_CcNode->ccTreeIdLst);
32551 + INIT_LIST(&p_CcNode->ccTreesLst);
32552 + INIT_LIST(&p_CcNode->availableStatsLst);
32553 +
32554 + p_CcNode->h_Spinlock = XX_InitSpinlock();
32555 + if (!p_CcNode->h_Spinlock)
32556 + {
32557 + DeleteNode(p_CcNode);
32558 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC node spinlock"));
32559 + }
32560 +
32561 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_BY_HDR)
32562 + && ((p_CcNodeParam->extractCcParams.extractByHdr.hdr
32563 + == HEADER_TYPE_IPv4)
32564 + || (p_CcNodeParam->extractCcParams.extractByHdr.hdr
32565 + == HEADER_TYPE_IPv6))
32566 + && (p_CcNodeParam->extractCcParams.extractByHdr.type
32567 + == e_FM_PCD_EXTRACT_FULL_FIELD)
32568 + && ((p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv6
32569 + == NET_HEADER_FIELD_IPv6_HOP_LIMIT)
32570 + || (p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField.ipv4
32571 + == NET_HEADER_FIELD_IPv4_TTL)))
32572 + {
32573 + err = Ipv4TtlOrIpv6HopLimitCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
32574 + &isKeyTblAlloc);
32575 + glblMask = FALSE;
32576 + }
32577 + else
32578 + if ((p_CcNodeParam->extractCcParams.type == e_FM_PCD_EXTRACT_NON_HDR)
32579 + && ((p_CcNodeParam->extractCcParams.extractNonHdr.src
32580 + == e_FM_PCD_EXTRACT_FROM_KEY)
32581 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
32582 + == e_FM_PCD_EXTRACT_FROM_HASH)
32583 + || (p_CcNodeParam->extractCcParams.extractNonHdr.src
32584 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)))
32585 + {
32586 + if ((p_CcNodeParam->extractCcParams.extractNonHdr.src
32587 + == e_FM_PCD_EXTRACT_FROM_FLOW_ID)
32588 + && (p_CcNodeParam->extractCcParams.extractNonHdr.offset != 0))
32589 + {
32590 + DeleteNode(p_CcNode);
32591 + RETURN_ERROR(
32592 + MAJOR,
32593 + E_INVALID_VALUE,
32594 + ("In the case of the extraction from e_FM_PCD_EXTRACT_FROM_FLOW_ID offset has to be 0"));
32595 + }
32596 +
32597 + icCode = IcDefineCode(p_CcNodeParam);
32598 + fromIc = TRUE;
32599 + if (icCode == CC_PRIVATE_INFO_NONE)
32600 + {
32601 + DeleteNode(p_CcNode);
32602 + RETURN_ERROR(
32603 + MAJOR,
32604 + E_INVALID_STATE,
32605 + ("user asked extraction from IC and field in internal context or action wasn't initialized in the right way"));
32606 + }
32607 +
32608 + if ((icCode == CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP)
32609 + || (icCode == CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP))
32610 + {
32611 + err = IcHashIndexedCheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
32612 + &isKeyTblAlloc);
32613 + glblMask = TRUE;
32614 + }
32615 + else
32616 + {
32617 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode,
32618 + &isKeyTblAlloc);
32619 + if (p_CcNode->glblMaskSize)
32620 + glblMask = TRUE;
32621 + }
32622 + }
32623 + else
32624 + {
32625 + err = CheckParams(h_FmPcd, p_CcNodeParam, p_CcNode, &isKeyTblAlloc);
32626 + if (p_CcNode->glblMaskSize)
32627 + glblMask = TRUE;
32628 + }
32629 +
32630 + if (err)
32631 + {
32632 + DeleteNode(p_CcNode);
32633 + RETURN_ERROR(MAJOR, err, NO_MSG);
32634 + }
32635 +
32636 + switch (p_CcNodeParam->extractCcParams.type)
32637 + {
32638 + case (e_FM_PCD_EXTRACT_BY_HDR):
32639 + switch (p_CcNodeParam->extractCcParams.extractByHdr.type)
32640 + {
32641 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
32642 + p_CcNode->parseCode =
32643 + GetFullFieldParseCode(
32644 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
32645 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
32646 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField);
32647 + GetSizeHeaderField(
32648 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
32649 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fullField,
32650 + &p_CcNode->sizeOfExtraction);
32651 + fullField = TRUE;
32652 + if ((p_CcNode->parseCode != CC_PC_FF_TCI1)
32653 + && (p_CcNode->parseCode != CC_PC_FF_TCI2)
32654 + && (p_CcNode->parseCode != CC_PC_FF_MPLS1)
32655 + && (p_CcNode->parseCode != CC_PC_FF_MPLS_LAST)
32656 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC1)
32657 + && (p_CcNode->parseCode != CC_PC_FF_IPV4IPTOS_TC2)
32658 + && (p_CcNode->parseCode
32659 + != CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1)
32660 + && (p_CcNode->parseCode != CC_PC_FF_IPDSCP)
32661 + && (p_CcNode->parseCode
32662 + != CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2)
32663 + && glblMask)
32664 + {
32665 + glblMask = FALSE;
32666 + p_CcNode->glblMaskSize = 4;
32667 + p_CcNode->lclMask = TRUE;
32668 + }
32669 + break;
32670 +
32671 + case (e_FM_PCD_EXTRACT_FROM_HDR):
32672 + p_CcNode->sizeOfExtraction =
32673 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.size;
32674 + p_CcNode->offset =
32675 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
32676 + p_CcNode->userOffset =
32677 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromHdr.offset;
32678 + p_CcNode->parseCode =
32679 + GetPrParseCode(
32680 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
32681 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex,
32682 + p_CcNode->offset, glblMask,
32683 + &p_CcNode->prsArrayOffset);
32684 + break;
32685 +
32686 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
32687 + p_CcNode->offset =
32688 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
32689 + p_CcNode->userOffset =
32690 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.offset;
32691 + p_CcNode->sizeOfExtraction =
32692 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.size;
32693 + p_CcNode->parseCode =
32694 + GetFieldParseCode(
32695 + p_CcNodeParam->extractCcParams.extractByHdr.hdr,
32696 + p_CcNodeParam->extractCcParams.extractByHdr.extractByHdrType.fromField.field,
32697 + p_CcNode->offset,
32698 + &p_CcNode->prsArrayOffset,
32699 + p_CcNodeParam->extractCcParams.extractByHdr.hdrIndex);
32700 + break;
32701 +
32702 + default:
32703 + DeleteNode(p_CcNode);
32704 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
32705 + }
32706 + break;
32707 +
32708 + case (e_FM_PCD_EXTRACT_NON_HDR):
32709 + /* get the field code for the generic extract */
32710 + p_CcNode->sizeOfExtraction =
32711 + p_CcNodeParam->extractCcParams.extractNonHdr.size;
32712 + p_CcNode->offset =
32713 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
32714 + p_CcNode->userOffset =
32715 + p_CcNodeParam->extractCcParams.extractNonHdr.offset;
32716 + p_CcNode->parseCode = GetGenParseCode(
32717 + p_CcNodeParam->extractCcParams.extractNonHdr.src,
32718 + p_CcNode->offset, glblMask, &p_CcNode->prsArrayOffset,
32719 + fromIc, icCode);
32720 +
32721 + if (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED)
32722 + {
32723 + if ((p_CcNode->offset + p_CcNode->sizeOfExtraction) > 8)
32724 + {
32725 + DeleteNode(p_CcNode);
32726 + RETURN_ERROR(
32727 + MAJOR,
32728 + E_INVALID_SELECTION,
32729 + ("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)"));
32730 + }
32731 + }
32732 + if ((p_CcNode->parseCode == CC_PC_GENERIC_IC_GMASK)
32733 + || (p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED))
32734 + {
32735 + p_CcNode->offset += p_CcNode->prsArrayOffset;
32736 + p_CcNode->prsArrayOffset = 0;
32737 + }
32738 + break;
32739 +
32740 + default:
32741 + DeleteNode(p_CcNode);
32742 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
32743 + }
32744 +
32745 + if (p_CcNode->parseCode == CC_PC_ILLEGAL)
32746 + {
32747 + DeleteNode(p_CcNode);
32748 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("illegal extraction type"));
32749 + }
32750 +
32751 + if ((p_CcNode->sizeOfExtraction > FM_PCD_MAX_SIZE_OF_KEY)
32752 + || !p_CcNode->sizeOfExtraction)
32753 + {
32754 + DeleteNode(p_CcNode);
32755 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
32756 + ("sizeOfExatrction can not be greater than 56 and not 0"));
32757 + }
32758 +
32759 + if (p_CcNodeParam->keysParams.keySize != p_CcNode->sizeOfExtraction)
32760 + {
32761 + DeleteNode(p_CcNode);
32762 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
32763 + ("keySize has to be equal to sizeOfExtraction"));
32764 + }
32765 +
32766 + p_CcNode->userSizeOfExtraction = p_CcNode->sizeOfExtraction;
32767 +
32768 + if (!glblMask)
32769 + memset(p_CcNode->p_GlblMask, 0xff, CC_GLBL_MASK_SIZE * sizeof(uint8_t));
32770 +
32771 + err = CheckAndSetManipParamsWithCcNodeParams(p_CcNode);
32772 + if (err != E_OK)
32773 + {
32774 + DeleteNode(p_CcNode);
32775 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
32776 + ("keySize has to be equal to sizeOfExtraction"));
32777 + }
32778 +
32779 + /* Calculating matching table entry size by rounding up the user-defined size of extraction to valid entry size */
32780 + GetCcExtractKeySize(p_CcNode->sizeOfExtraction,
32781 + &p_CcNode->ccKeySizeAccExtraction);
32782 +
32783 + /* If local mask is used, it is stored next to each key in the keys match table */
32784 + if (p_CcNode->lclMask)
32785 + keySize = (uint32_t)(2 * p_CcNode->ccKeySizeAccExtraction);
32786 + else
32787 + keySize = p_CcNode->ccKeySizeAccExtraction;
32788 +
32789 + /* Update CC shadow with maximal size required by this node */
32790 + if (p_CcNode->maxNumOfKeys)
32791 + {
32792 + err = CalcAndUpdateCcShadow(p_CcNode, isKeyTblAlloc, &matchTableSize,
32793 + &adTableSize);
32794 + if (err != E_OK)
32795 + {
32796 + DeleteNode(p_CcNode);
32797 + RETURN_ERROR(MAJOR, err, NO_MSG);
32798 + }
32799 +
32800 + p_CcNode->keysMatchTableMaxSize = matchTableSize;
32801 +
32802 + if (p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_NONE)
32803 + {
32804 + err = AllocStatsObjs(p_CcNode);
32805 + if (err != E_OK)
32806 + {
32807 + DeleteNode(p_CcNode);
32808 + RETURN_ERROR(MAJOR, err, NO_MSG);
32809 + }
32810 + }
32811 +
32812 + /* If manipulation will be initialized before this node, it will use the table
32813 + descriptor in the AD table of previous node and this node will need an extra
32814 + AD as his table descriptor. */
32815 + p_CcNode->h_TmpAd = (t_Handle)FM_MURAM_AllocMem(
32816 + h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE, FM_PCD_CC_AD_TABLE_ALIGN);
32817 + if (!p_CcNode->h_TmpAd)
32818 + {
32819 + DeleteNode(p_CcNode);
32820 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32821 + ("MURAM allocation for CC action descriptor"));
32822 + }
32823 + }
32824 + else
32825 + {
32826 + matchTableSize = (uint32_t)(keySize * sizeof(uint8_t)
32827 + * (p_CcNode->numOfKeys + 1));
32828 + adTableSize = (uint32_t)(FM_PCD_CC_AD_ENTRY_SIZE
32829 + * (p_CcNode->numOfKeys + 1));
32830 + }
32831 +
32832 +#if (DPAA_VERSION >= 11)
32833 + switch (p_CcNode->statisticsMode)
32834 + {
32835 +
32836 + case e_FM_PCD_CC_STATS_MODE_RMON:
32837 + /* If RMON statistics or RMON conditional statistics modes are requested,
32838 + allocate frame length ranges array */
32839 + p_CcNode->h_StatsFLRs = FM_MURAM_AllocMem(
32840 + h_FmMuram,
32841 + (uint32_t)(p_CcNode->numOfStatsFLRs)
32842 + * FM_PCD_CC_STATS_FLR_SIZE,
32843 + FM_PCD_CC_AD_TABLE_ALIGN);
32844 +
32845 + if (!p_CcNode->h_StatsFLRs)
32846 + {
32847 + DeleteNode(p_CcNode);
32848 + RETURN_ERROR(
32849 + MAJOR, E_NO_MEMORY,
32850 + ("MURAM allocation for CC frame length ranges array"));
32851 + }
32852 +
32853 + /* Initialize using value received from the user */
32854 + for (tmp = 0; tmp < p_CcNode->numOfStatsFLRs; tmp++)
32855 + {
32856 + uint16_t flr =
32857 + cpu_to_be16(p_CcNodeParam->keysParams.frameLengthRanges[tmp]);
32858 +
32859 + h_StatsFLRs =
32860 + PTR_MOVE(p_CcNode->h_StatsFLRs, tmp * FM_PCD_CC_STATS_FLR_SIZE);
32861 +
32862 + MemCpy8(h_StatsFLRs,
32863 + &flr,
32864 + FM_PCD_CC_STATS_FLR_SIZE);
32865 + }
32866 + break;
32867 +
32868 + default:
32869 + break;
32870 + }
32871 +#endif /* (DPAA_VERSION >= 11) */
32872 +
32873 + /* Allocate keys match table. Not required for some CC nodes, for example for IPv4 TTL
32874 + identification, IPv6 hop count identification, etc. */
32875 + if (isKeyTblAlloc)
32876 + {
32877 + p_CcNode->h_KeysMatchTable = (t_Handle)FM_MURAM_AllocMem(
32878 + h_FmMuram, matchTableSize, FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN);
32879 + if (!p_CcNode->h_KeysMatchTable)
32880 + {
32881 + DeleteNode(p_CcNode);
32882 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32883 + ("MURAM allocation for CC node key match table"));
32884 + }
32885 + MemSet8((uint8_t *)p_CcNode->h_KeysMatchTable, 0, matchTableSize);
32886 + }
32887 +
32888 + /* Allocate action descriptors table */
32889 + p_CcNode->h_AdTable = (t_Handle)FM_MURAM_AllocMem(h_FmMuram, adTableSize,
32890 + FM_PCD_CC_AD_TABLE_ALIGN);
32891 + if (!p_CcNode->h_AdTable)
32892 + {
32893 + DeleteNode(p_CcNode);
32894 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
32895 + ("MURAM allocation for CC node action descriptors table"));
32896 + }
32897 + MemSet8((uint8_t *)p_CcNode->h_AdTable, 0, adTableSize);
32898 +
32899 + p_KeysMatchTblTmp = p_CcNode->h_KeysMatchTable;
32900 + p_AdTableTmp = p_CcNode->h_AdTable;
32901 +
32902 + /* For each key, create the key and the next step AD */
32903 + for (tmp = 0; tmp < p_CcNode->numOfKeys; tmp++)
32904 + {
32905 + p_KeyParams = &p_CcNodeParam->keysParams.keyParams[tmp];
32906 +
32907 + if (p_KeysMatchTblTmp)
32908 + {
32909 + /* Copy the key */
32910 + MemCpy8((void*)p_KeysMatchTblTmp, p_KeyParams->p_Key,
32911 + p_CcNode->sizeOfExtraction);
32912 +
32913 + /* Copy the key mask or initialize it to 0xFF..F */
32914 + if (p_CcNode->lclMask && p_KeyParams->p_Mask)
32915 + {
32916 + MemCpy8(PTR_MOVE(p_KeysMatchTblTmp,
32917 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
32918 + p_KeyParams->p_Mask, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
32919 + }
32920 + else
32921 + if (p_CcNode->lclMask)
32922 + {
32923 + MemSet8(PTR_MOVE(p_KeysMatchTblTmp,
32924 + p_CcNode->ccKeySizeAccExtraction), /* User's size of extraction rounded up to a valid matching table entry size */
32925 + 0xff, p_CcNode->sizeOfExtraction); /* Exact size of extraction as received from the user */
32926 + }
32927 +
32928 + p_KeysMatchTblTmp =
32929 + PTR_MOVE(p_KeysMatchTblTmp, keySize * sizeof(uint8_t));
32930 + }
32931 +
32932 + /* Create the next action descriptor in the match table */
32933 + if (p_KeyParams->ccNextEngineParams.statisticsEn)
32934 + {
32935 + p_StatsObj = GetStatsObj(p_CcNode);
32936 + ASSERT_COND(p_StatsObj);
32937 +
32938 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
32939 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
32940 +#if (DPAA_VERSION >= 11)
32941 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
32942 +
32943 +#endif /* (DPAA_VERSION >= 11) */
32944 + NextStepAd(p_AdTableTmp, &statsParams,
32945 + &p_KeyParams->ccNextEngineParams, p_FmPcd);
32946 +
32947 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
32948 + }
32949 + else
32950 + {
32951 + NextStepAd(p_AdTableTmp, NULL, &p_KeyParams->ccNextEngineParams,
32952 + p_FmPcd);
32953 +
32954 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
32955 + }
32956 +
32957 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
32958 + }
32959 +
32960 + /* Update next engine for the 'miss' entry */
32961 + if (p_CcNodeParam->keysParams.ccNextEngineParamsForMiss.statisticsEn)
32962 + {
32963 + p_StatsObj = GetStatsObj(p_CcNode);
32964 + ASSERT_COND(p_StatsObj);
32965 +
32966 + /* All 'bucket' nodes of a hash table should share the same statistics counters,
32967 + allocated by the hash table. So, if this node is a bucket of a hash table,
32968 + we'll replace the locally allocated counters with the shared counters. */
32969 + if (p_CcNode->isHashBucket)
32970 + {
32971 + ASSERT_COND(p_CcNode->h_MissStatsCounters);
32972 +
32973 + /* Store original counters pointer and replace it with mutual preallocated pointer */
32974 + p_CcNode->h_PrivMissStatsCounters = p_StatsObj->h_StatsCounters;
32975 + p_StatsObj->h_StatsCounters = p_CcNode->h_MissStatsCounters;
32976 + }
32977 +
32978 + statsParams.h_StatsAd = p_StatsObj->h_StatsAd;
32979 + statsParams.h_StatsCounters = p_StatsObj->h_StatsCounters;
32980 +#if (DPAA_VERSION >= 11)
32981 + statsParams.h_StatsFLRs = p_CcNode->h_StatsFLRs;
32982 +
32983 +#endif /* (DPAA_VERSION >= 11) */
32984 +
32985 + NextStepAd(p_AdTableTmp, &statsParams,
32986 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
32987 + p_FmPcd);
32988 +
32989 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = p_StatsObj;
32990 + }
32991 + else
32992 + {
32993 + NextStepAd(p_AdTableTmp, NULL,
32994 + &p_CcNodeParam->keysParams.ccNextEngineParamsForMiss,
32995 + p_FmPcd);
32996 +
32997 + p_CcNode->keyAndNextEngineParams[tmp].p_StatsObj = NULL;
32998 + }
32999 +
33000 + /* This parameter will be used to initialize the "key length" field in the action descriptor
33001 + that points to this node and it should be 0 for full field extraction */
33002 + if (fullField == TRUE)
33003 + p_CcNode->sizeOfExtraction = 0;
33004 +
33005 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
33006 + {
33007 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.nextEngine
33008 + == e_FM_PCD_CC)
33009 + {
33010 + p_FmPcdCcNextNode =
33011 + (t_FmPcdCcNode*)p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.params.ccParams.h_CcNode;
33012 + p_CcInformation = FindNodeInfoInReleventLst(
33013 + &p_FmPcdCcNextNode->ccPrevNodesLst, (t_Handle)p_CcNode,
33014 + p_FmPcdCcNextNode->h_Spinlock);
33015 + if (!p_CcInformation)
33016 + {
33017 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
33018 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
33019 + ccNodeInfo.index = 1;
33020 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccPrevNodesLst,
33021 + &ccNodeInfo,
33022 + p_FmPcdCcNextNode->h_Spinlock);
33023 + }
33024 + else
33025 + p_CcInformation->index++;
33026 +
33027 + if (p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip)
33028 + {
33029 + h_Manip =
33030 + p_CcNode->keyAndNextEngineParams[tmp].nextEngineParams.h_Manip;
33031 + p_CcInformation = FindNodeInfoInReleventLst(
33032 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
33033 + (t_Handle)p_CcNode, FmPcdManipGetSpinlock(h_Manip));
33034 + if (!p_CcInformation)
33035 + {
33036 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
33037 + ccNodeInfo.h_CcNode = (t_Handle)p_CcNode;
33038 + ccNodeInfo.index = 1;
33039 + EnqueueNodeInfoToRelevantLst(
33040 + FmPcdManipGetNodeLstPointedOnThisManip(h_Manip),
33041 + &ccNodeInfo, FmPcdManipGetSpinlock(h_Manip));
33042 + }
33043 + else
33044 + p_CcInformation->index++;
33045 + }
33046 + }
33047 + }
33048 +
33049 + p_AdTableTmp = p_CcNode->h_AdTable;
33050 +
33051 + if (!FmPcdLockTryLockAll(h_FmPcd))
33052 + {
33053 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
33054 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
33055 + return ERROR_CODE(E_BUSY);
33056 + }
33057 +
33058 + /* Required action for each next engine */
33059 + for (tmp = 0; tmp < MIN(p_CcNode->numOfKeys + 1, CC_MAX_NUM_OF_KEYS); tmp++)
33060 + {
33061 + if (p_CcNode->keyAndNextEngineParams[tmp].requiredAction)
33062 + {
33063 + err = SetRequiredAction(
33064 + h_FmPcd,
33065 + p_CcNode->keyAndNextEngineParams[tmp].requiredAction,
33066 + &p_CcNode->keyAndNextEngineParams[tmp], p_AdTableTmp, 1,
33067 + NULL);
33068 + if (err)
33069 + {
33070 + FmPcdLockUnlockAll(h_FmPcd);
33071 + FM_PCD_MatchTableDelete((t_Handle)p_CcNode);
33072 + RETURN_ERROR(MAJOR, err, NO_MSG);
33073 + }
33074 + p_AdTableTmp = PTR_MOVE(p_AdTableTmp, FM_PCD_CC_AD_ENTRY_SIZE);
33075 + }
33076 + }
33077 +
33078 + FmPcdLockUnlockAll(h_FmPcd);
33079 +
33080 + return E_OK;
33081 +}
33082 +/************************** End of static functions **************************/
33083 +
33084 +/*****************************************************************************/
33085 +/* Inter-module API routines */
33086 +/*****************************************************************************/
33087 +
33088 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info,
33089 + t_Handle h_Spinlock)
33090 +{
33091 + t_CcNodeInformation *p_CcInformation;
33092 + t_List *p_Pos;
33093 + uint32_t intFlags;
33094 +
33095 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
33096 +
33097 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
33098 + p_Pos = LIST_NEXT(p_Pos))
33099 + {
33100 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
33101 +
33102 + ASSERT_COND(p_CcInformation->h_CcNode);
33103 +
33104 + if (p_CcInformation->h_CcNode == h_Info)
33105 + {
33106 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
33107 + return p_CcInformation;
33108 + }
33109 + }
33110 +
33111 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
33112 +
33113 + return NULL;
33114 +}
33115 +
33116 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo,
33117 + t_Handle h_Spinlock)
33118 +{
33119 + t_CcNodeInformation *p_CcInformation;
33120 + uint32_t intFlags = 0;
33121 +
33122 + p_CcInformation = (t_CcNodeInformation *)XX_Malloc(
33123 + sizeof(t_CcNodeInformation));
33124 +
33125 + if (p_CcInformation)
33126 + {
33127 + memset(p_CcInformation, 0, sizeof(t_CcNodeInformation));
33128 + memcpy(p_CcInformation, p_CcInfo, sizeof(t_CcNodeInformation));
33129 + INIT_LIST(&p_CcInformation->node);
33130 +
33131 + if (h_Spinlock)
33132 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
33133 +
33134 + LIST_AddToTail(&p_CcInformation->node, p_List);
33135 +
33136 + if (h_Spinlock)
33137 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
33138 + }
33139 + else
33140 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("CC Node Information"));
33141 +}
33142 +
33143 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info,
33144 + t_Handle h_Spinlock)
33145 +{
33146 + t_CcNodeInformation *p_CcInformation = NULL;
33147 + uint32_t intFlags = 0;
33148 + t_List *p_Pos;
33149 +
33150 + if (h_Spinlock)
33151 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
33152 +
33153 + if (LIST_IsEmpty(p_List))
33154 + {
33155 + XX_RestoreAllIntr(intFlags);
33156 + return;
33157 + }
33158 +
33159 + for (p_Pos = LIST_FIRST(p_List); p_Pos != (p_List);
33160 + p_Pos = LIST_NEXT(p_Pos))
33161 + {
33162 + p_CcInformation = CC_NODE_F_OBJECT(p_Pos);
33163 + ASSERT_COND(p_CcInformation);
33164 + ASSERT_COND(p_CcInformation->h_CcNode);
33165 + if (p_CcInformation->h_CcNode == h_Info)
33166 + break;
33167 + }
33168 +
33169 + if (p_CcInformation)
33170 + {
33171 + LIST_DelAndInit(&p_CcInformation->node);
33172 + XX_Free(p_CcInformation);
33173 + }
33174 +
33175 + if (h_Spinlock)
33176 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
33177 +}
33178 +
33179 +void NextStepAd(t_Handle h_Ad, t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
33180 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
33181 + t_FmPcd *p_FmPcd)
33182 +{
33183 + switch (p_FmPcdCcNextEngineParams->nextEngine)
33184 + {
33185 + case (e_FM_PCD_KG):
33186 + case (e_FM_PCD_PLCR):
33187 + case (e_FM_PCD_DONE):
33188 + /* if NIA is not CC, create a "result" type AD */
33189 + FillAdOfTypeResult(h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
33190 + p_FmPcdCcNextEngineParams);
33191 + break;
33192 +#if (DPAA_VERSION >= 11)
33193 + case (e_FM_PCD_FR):
33194 + if (p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic)
33195 + {
33196 + FillAdOfTypeContLookup(
33197 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
33198 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
33199 + p_FmPcdCcNextEngineParams->h_Manip,
33200 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic);
33201 + FrmReplicGroupUpdateOwner(
33202 + p_FmPcdCcNextEngineParams->params.frParams.h_FrmReplic,
33203 + TRUE/* add */);
33204 + }
33205 + break;
33206 +#endif /* (DPAA_VERSION >= 11) */
33207 +
33208 + case (e_FM_PCD_CC):
33209 + /* if NIA is not CC, create a TD to continue the CC lookup */
33210 + FillAdOfTypeContLookup(
33211 + h_Ad, p_FmPcdCcStatsParams, p_FmPcd,
33212 + p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
33213 + p_FmPcdCcNextEngineParams->h_Manip, NULL);
33214 +
33215 + UpdateNodeOwner(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode,
33216 + TRUE);
33217 + break;
33218 +
33219 + default:
33220 + return;
33221 + }
33222 +}
33223 +
33224 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree,
33225 + t_Handle h_NetEnv, t_Handle h_IpReassemblyManip,
33226 + bool createSchemes)
33227 +{
33228 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
33229 + t_FmPcdCcNextEngineParams nextEngineParams;
33230 + t_NetEnvParams netEnvParams;
33231 + t_Handle h_Ad;
33232 + bool isIpv6Present;
33233 + uint8_t ipv4GroupId, ipv6GroupId;
33234 + t_Error err;
33235 +
33236 + ASSERT_COND(p_FmPcdCcTree);
33237 +
33238 + /* this routine must be protected by the calling routine! */
33239 +
33240 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
33241 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
33242 +
33243 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
33244 +
33245 + isIpv6Present = FmPcdManipIpReassmIsIpv6Hdr(h_IpReassemblyManip);
33246 +
33247 + if (isIpv6Present
33248 + && (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2)))
33249 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
33250 +
33251 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
33252 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need two free entries for IPR"));
33253 +
33254 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
33255 + nextEngineParams.h_Manip = h_IpReassemblyManip;
33256 +
33257 + /* Lock tree */
33258 + err = CcRootTryLock(p_FmPcdCcTree);
33259 + if (err)
33260 + return ERROR_CODE(E_BUSY);
33261 +
33262 + if (p_FmPcdCcTree->h_IpReassemblyManip == h_IpReassemblyManip)
33263 + {
33264 + CcRootReleaseLock(p_FmPcdCcTree);
33265 + return E_OK;
33266 + }
33267 +
33268 + if ((p_FmPcdCcTree->h_IpReassemblyManip)
33269 + && (p_FmPcdCcTree->h_IpReassemblyManip != h_IpReassemblyManip))
33270 + {
33271 + CcRootReleaseLock(p_FmPcdCcTree);
33272 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33273 + ("This tree was previously updated with different IPR"));
33274 + }
33275 +
33276 + /* Initialize IPR for the first time for this tree */
33277 + if (isIpv6Present)
33278 + {
33279 + ipv6GroupId = p_FmPcdCcTree->numOfGrps++;
33280 + p_FmPcdCcTree->fmPcdGroupParam[ipv6GroupId].baseGroupEntry =
33281 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 2);
33282 +
33283 + if (createSchemes)
33284 + {
33285 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv,
33286 + p_FmPcdCcTree,
33287 + h_IpReassemblyManip, FALSE,
33288 + ipv6GroupId);
33289 + if (err)
33290 + {
33291 + p_FmPcdCcTree->numOfGrps--;
33292 + CcRootReleaseLock(p_FmPcdCcTree);
33293 + RETURN_ERROR(MAJOR, err, NO_MSG);
33294 + }
33295 + }
33296 +
33297 + NextStepAd(
33298 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-2) * FM_PCD_CC_AD_ENTRY_SIZE),
33299 + NULL, &nextEngineParams, h_FmPcd);
33300 + }
33301 +
33302 + ipv4GroupId = p_FmPcdCcTree->numOfGrps++;
33303 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].totalBitsMask = 0;
33304 + p_FmPcdCcTree->fmPcdGroupParam[ipv4GroupId].baseGroupEntry =
33305 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
33306 +
33307 + if (createSchemes)
33308 + {
33309 + err = FmPcdManipBuildIpReassmScheme(h_FmPcd, h_NetEnv, p_FmPcdCcTree,
33310 + h_IpReassemblyManip, TRUE,
33311 + ipv4GroupId);
33312 + if (err)
33313 + {
33314 + p_FmPcdCcTree->numOfGrps--;
33315 + if (isIpv6Present)
33316 + {
33317 + p_FmPcdCcTree->numOfGrps--;
33318 + FmPcdManipDeleteIpReassmSchemes(h_IpReassemblyManip);
33319 + }
33320 + CcRootReleaseLock(p_FmPcdCcTree);
33321 + RETURN_ERROR(MAJOR, err, NO_MSG);
33322 + }
33323 + }
33324 +
33325 + NextStepAd(
33326 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
33327 + NULL, &nextEngineParams, h_FmPcd);
33328 +
33329 + p_FmPcdCcTree->h_IpReassemblyManip = h_IpReassemblyManip;
33330 +
33331 + CcRootReleaseLock(p_FmPcdCcTree);
33332 +
33333 + return E_OK;
33334 +}
33335 +
33336 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree,
33337 + t_Handle h_NetEnv, t_Handle h_ReassemblyManip,
33338 + bool createSchemes)
33339 +{
33340 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
33341 + t_FmPcdCcNextEngineParams nextEngineParams;
33342 + t_NetEnvParams netEnvParams;
33343 + t_Handle h_Ad;
33344 + uint8_t groupId;
33345 + t_Error err;
33346 +
33347 + ASSERT_COND(p_FmPcdCcTree);
33348 +
33349 + /* this routine must be protected by the calling routine! */
33350 + memset(&nextEngineParams, 0, sizeof(t_FmPcdCcNextEngineParams));
33351 + memset(&netEnvParams, 0, sizeof(t_NetEnvParams));
33352 +
33353 + h_Ad = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
33354 +
33355 + if (p_FmPcdCcTree->numOfEntries > (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1))
33356 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("need one free entries for CPR"));
33357 +
33358 + nextEngineParams.nextEngine = e_FM_PCD_DONE;
33359 + nextEngineParams.h_Manip = h_ReassemblyManip;
33360 +
33361 + /* Lock tree */
33362 + err = CcRootTryLock(p_FmPcdCcTree);
33363 + if (err)
33364 + return ERROR_CODE(E_BUSY);
33365 +
33366 + if (p_FmPcdCcTree->h_CapwapReassemblyManip == h_ReassemblyManip)
33367 + {
33368 + CcRootReleaseLock(p_FmPcdCcTree);
33369 + return E_OK;
33370 + }
33371 +
33372 + if ((p_FmPcdCcTree->h_CapwapReassemblyManip)
33373 + && (p_FmPcdCcTree->h_CapwapReassemblyManip != h_ReassemblyManip))
33374 + {
33375 + CcRootReleaseLock(p_FmPcdCcTree);
33376 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33377 + ("This tree was previously updated with different CPR"));
33378 + }
33379 +
33380 + groupId = p_FmPcdCcTree->numOfGrps++;
33381 + p_FmPcdCcTree->fmPcdGroupParam[groupId].baseGroupEntry =
33382 + (FM_PCD_MAX_NUM_OF_CC_GROUPS - 1);
33383 +
33384 + if (createSchemes)
33385 + {
33386 + err = FmPcdManipBuildCapwapReassmScheme(h_FmPcd, h_NetEnv,
33387 + p_FmPcdCcTree,
33388 + h_ReassemblyManip, groupId);
33389 + if (err)
33390 + {
33391 + p_FmPcdCcTree->numOfGrps--;
33392 + CcRootReleaseLock(p_FmPcdCcTree);
33393 + RETURN_ERROR(MAJOR, err, NO_MSG);
33394 + }
33395 + }
33396 +
33397 + NextStepAd(
33398 + PTR_MOVE(h_Ad, (FM_PCD_MAX_NUM_OF_CC_GROUPS-1) * FM_PCD_CC_AD_ENTRY_SIZE),
33399 + NULL, &nextEngineParams, h_FmPcd);
33400 +
33401 + p_FmPcdCcTree->h_CapwapReassemblyManip = h_ReassemblyManip;
33402 +
33403 + CcRootReleaseLock(p_FmPcdCcTree);
33404 +
33405 + return E_OK;
33406 +}
33407 +
33408 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree)
33409 +{
33410 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
33411 +
33412 + ASSERT_COND(p_FmPcdCcTree);
33413 +
33414 + return p_FmPcdCcTree->h_FmPcdCcSavedManipParams;
33415 +}
33416 +
33417 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree,
33418 + t_Handle h_SavedManipParams)
33419 +{
33420 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmTree;
33421 +
33422 + ASSERT_COND(p_FmPcdCcTree);
33423 +
33424 + p_FmPcdCcTree->h_FmPcdCcSavedManipParams = h_SavedManipParams;
33425 +}
33426 +
33427 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode)
33428 +{
33429 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33430 +
33431 + ASSERT_COND(p_CcNode);
33432 +
33433 + return p_CcNode->parseCode;
33434 +}
33435 +
33436 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode)
33437 +{
33438 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33439 +
33440 + ASSERT_COND(p_CcNode);
33441 +
33442 + return p_CcNode->offset;
33443 +}
33444 +
33445 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode)
33446 +{
33447 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
33448 +
33449 + ASSERT_COND(p_CcNode);
33450 +
33451 + return p_CcNode->numOfKeys;
33452 +}
33453 +
33454 +t_Error FmPcdCcModifyNextEngineParamTree(
33455 + t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index,
33456 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33457 +{
33458 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
33459 + t_FmPcd *p_FmPcd;
33460 + t_List h_OldPointersLst, h_NewPointersLst;
33461 + uint16_t keyIndex;
33462 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33463 + t_Error err = E_OK;
33464 +
33465 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
33466 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
33467 + SANITY_CHECK_RETURN_ERROR((grpId <= 7), E_INVALID_VALUE);
33468 +
33469 + if (grpId >= p_FmPcdCcTree->numOfGrps)
33470 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
33471 + ("grpId you asked > numOfGroup of relevant tree"));
33472 +
33473 + if (index >= p_FmPcdCcTree->fmPcdGroupParam[grpId].numOfEntriesInGroup)
33474 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("index > numOfEntriesInGroup"));
33475 +
33476 + p_FmPcd = (t_FmPcd *)h_FmPcd;
33477 +
33478 + INIT_LIST(&h_OldPointersLst);
33479 + INIT_LIST(&h_NewPointersLst);
33480 +
33481 + keyIndex = (uint16_t)(p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry
33482 + + index);
33483 +
33484 + p_ModifyKeyParams = ModifyNodeCommonPart(p_FmPcdCcTree, keyIndex,
33485 + e_MODIFY_STATE_CHANGE, FALSE,
33486 + FALSE, TRUE);
33487 + if (!p_ModifyKeyParams)
33488 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33489 +
33490 + p_ModifyKeyParams->tree = TRUE;
33491 +
33492 + if (p_FmPcd->p_CcShadow
33493 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33494 + {
33495 + XX_Free(p_ModifyKeyParams);
33496 + return ERROR_CODE(E_BUSY);
33497 + }
33498 +
33499 + err = BuildNewNodeModifyNextEngine(p_FmPcd, p_FmPcdCcTree, keyIndex,
33500 + p_FmPcdCcNextEngineParams,
33501 + &h_OldPointersLst, &h_NewPointersLst,
33502 + p_ModifyKeyParams);
33503 + if (err)
33504 + {
33505 + XX_Free(p_ModifyKeyParams);
33506 + RETURN_ERROR(MAJOR, err, NO_MSG);
33507 + }
33508 +
33509 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33510 + p_ModifyKeyParams, FALSE);
33511 +
33512 + if (p_FmPcd->p_CcShadow)
33513 + RELEASE_LOCK(p_FmPcd->shadowLock);
33514 +
33515 + ReleaseLst(&h_OldPointersLst);
33516 + ReleaseLst(&h_NewPointersLst);
33517 +
33518 + return err;
33519 +
33520 +}
33521 +
33522 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33523 + uint16_t keyIndex)
33524 +{
33525 +
33526 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33527 + t_FmPcd *p_FmPcd;
33528 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33529 + t_List h_OldPointersLst, h_NewPointersLst;
33530 + bool useShadowStructs = FALSE;
33531 + t_Error err = E_OK;
33532 +
33533 + if (keyIndex >= p_CcNode->numOfKeys)
33534 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
33535 + ("impossible to remove key when numOfKeys <= keyIndex"));
33536 +
33537 + if (p_CcNode->h_FmPcd != h_FmPcd)
33538 + RETURN_ERROR(
33539 + MAJOR,
33540 + E_INVALID_VALUE,
33541 + ("handler to FmPcd is different from the handle provided at node initialization time"));
33542 +
33543 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33544 +
33545 + INIT_LIST(&h_OldPointersLst);
33546 + INIT_LIST(&h_NewPointersLst);
33547 +
33548 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33549 + e_MODIFY_STATE_REMOVE, TRUE, TRUE,
33550 + FALSE);
33551 + if (!p_ModifyKeyParams)
33552 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33553 +
33554 + if (p_CcNode->maxNumOfKeys)
33555 + {
33556 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33557 + {
33558 + XX_Free(p_ModifyKeyParams);
33559 + return ERROR_CODE(E_BUSY);
33560 + }
33561 +
33562 + useShadowStructs = TRUE;
33563 + }
33564 +
33565 + err = BuildNewNodeRemoveKey(p_CcNode, keyIndex, p_ModifyKeyParams);
33566 + if (err)
33567 + {
33568 + XX_Free(p_ModifyKeyParams);
33569 + if (p_CcNode->maxNumOfKeys)
33570 + RELEASE_LOCK(p_FmPcd->shadowLock);
33571 + RETURN_ERROR(MAJOR, err, NO_MSG);
33572 + }
33573 +
33574 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
33575 + &h_OldPointersLst,
33576 + &h_NewPointersLst);
33577 + if (err)
33578 + {
33579 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33580 + XX_Free(p_ModifyKeyParams);
33581 + if (p_CcNode->maxNumOfKeys)
33582 + RELEASE_LOCK(p_FmPcd->shadowLock);
33583 + RETURN_ERROR(MAJOR, err, NO_MSG);
33584 + }
33585 +
33586 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33587 + p_ModifyKeyParams, useShadowStructs);
33588 +
33589 + if (p_CcNode->maxNumOfKeys)
33590 + RELEASE_LOCK(p_FmPcd->shadowLock);
33591 +
33592 + ReleaseLst(&h_OldPointersLst);
33593 + ReleaseLst(&h_NewPointersLst);
33594 +
33595 + return err;
33596 +}
33597 +
33598 +t_Error FmPcdCcModifyKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33599 + uint16_t keyIndex, uint8_t keySize, uint8_t *p_Key,
33600 + uint8_t *p_Mask)
33601 +{
33602 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33603 + t_FmPcd *p_FmPcd;
33604 + t_List h_OldPointersLst, h_NewPointersLst;
33605 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33606 + uint16_t tmpKeyIndex;
33607 + bool useShadowStructs = FALSE;
33608 + t_Error err = E_OK;
33609 +
33610 + if (keyIndex >= p_CcNode->numOfKeys)
33611 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33612 + ("keyIndex > previously cleared last index + 1"));
33613 +
33614 + if (keySize != p_CcNode->userSizeOfExtraction)
33615 + RETURN_ERROR(
33616 + MAJOR,
33617 + E_INVALID_VALUE,
33618 + ("size for ModifyKey has to be the same as defined in SetNode"));
33619 +
33620 + if (p_CcNode->h_FmPcd != h_FmPcd)
33621 + RETURN_ERROR(
33622 + MAJOR,
33623 + E_INVALID_VALUE,
33624 + ("handler to FmPcd is different from the handle provided at node initialization time"));
33625 +
33626 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_Key, p_Mask, &tmpKeyIndex);
33627 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
33628 + RETURN_ERROR(
33629 + MINOR,
33630 + E_ALREADY_EXISTS,
33631 + ("The received key and mask pair was already found in the match table of the provided node"));
33632 +
33633 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33634 +
33635 + INIT_LIST(&h_OldPointersLst);
33636 + INIT_LIST(&h_NewPointersLst);
33637 +
33638 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33639 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
33640 + FALSE);
33641 + if (!p_ModifyKeyParams)
33642 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33643 +
33644 + if (p_CcNode->maxNumOfKeys)
33645 + {
33646 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33647 + {
33648 + XX_Free(p_ModifyKeyParams);
33649 + return ERROR_CODE(E_BUSY);
33650 + }
33651 +
33652 + useShadowStructs = TRUE;
33653 + }
33654 +
33655 + err = BuildNewNodeModifyKey(p_CcNode, keyIndex, p_Key, p_Mask,
33656 + p_ModifyKeyParams);
33657 + if (err)
33658 + {
33659 + XX_Free(p_ModifyKeyParams);
33660 + if (p_CcNode->maxNumOfKeys)
33661 + RELEASE_LOCK(p_FmPcd->shadowLock);
33662 + RETURN_ERROR(MAJOR, err, NO_MSG);
33663 + }
33664 +
33665 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
33666 + &h_OldPointersLst,
33667 + &h_NewPointersLst);
33668 + if (err)
33669 + {
33670 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33671 + XX_Free(p_ModifyKeyParams);
33672 + if (p_CcNode->maxNumOfKeys)
33673 + RELEASE_LOCK(p_FmPcd->shadowLock);
33674 + RETURN_ERROR(MAJOR, err, NO_MSG);
33675 + }
33676 +
33677 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33678 + p_ModifyKeyParams, useShadowStructs);
33679 +
33680 + if (p_CcNode->maxNumOfKeys)
33681 + RELEASE_LOCK(p_FmPcd->shadowLock);
33682 +
33683 + ReleaseLst(&h_OldPointersLst);
33684 + ReleaseLst(&h_NewPointersLst);
33685 +
33686 + return err;
33687 +}
33688 +
33689 +t_Error FmPcdCcModifyMissNextEngineParamNode(
33690 + t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33691 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
33692 +{
33693 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33694 + t_FmPcd *p_FmPcd;
33695 + t_List h_OldPointersLst, h_NewPointersLst;
33696 + uint16_t keyIndex;
33697 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33698 + t_Error err = E_OK;
33699 +
33700 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_VALUE);
33701 +
33702 + keyIndex = p_CcNode->numOfKeys;
33703 +
33704 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33705 +
33706 + INIT_LIST(&h_OldPointersLst);
33707 + INIT_LIST(&h_NewPointersLst);
33708 +
33709 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33710 + e_MODIFY_STATE_CHANGE, FALSE, TRUE,
33711 + FALSE);
33712 + if (!p_ModifyKeyParams)
33713 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33714 +
33715 + if (p_CcNode->maxNumOfKeys
33716 + && !TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33717 + {
33718 + XX_Free(p_ModifyKeyParams);
33719 + return ERROR_CODE(E_BUSY);
33720 + }
33721 +
33722 + err = BuildNewNodeModifyNextEngine(h_FmPcd, p_CcNode, keyIndex,
33723 + p_FmPcdCcNextEngineParams,
33724 + &h_OldPointersLst, &h_NewPointersLst,
33725 + p_ModifyKeyParams);
33726 + if (err)
33727 + {
33728 + XX_Free(p_ModifyKeyParams);
33729 + if (p_CcNode->maxNumOfKeys)
33730 + RELEASE_LOCK(p_FmPcd->shadowLock);
33731 + RETURN_ERROR(MAJOR, err, NO_MSG);
33732 + }
33733 +
33734 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33735 + p_ModifyKeyParams, FALSE);
33736 +
33737 + if (p_CcNode->maxNumOfKeys)
33738 + RELEASE_LOCK(p_FmPcd->shadowLock);
33739 +
33740 + ReleaseLst(&h_OldPointersLst);
33741 + ReleaseLst(&h_NewPointersLst);
33742 +
33743 + return err;
33744 +}
33745 +
33746 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33747 + uint16_t keyIndex, uint8_t keySize,
33748 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
33749 +{
33750 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33751 + t_FmPcd *p_FmPcd;
33752 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33753 + t_List h_OldPointersLst, h_NewPointersLst;
33754 + bool useShadowStructs = FALSE;
33755 + uint16_t tmpKeyIndex;
33756 + t_Error err = E_OK;
33757 +
33758 + if (keyIndex > p_CcNode->numOfKeys)
33759 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
33760 + ("keyIndex > previously cleared last index + 1"));
33761 +
33762 + if (keySize != p_CcNode->userSizeOfExtraction)
33763 + RETURN_ERROR(
33764 + MAJOR,
33765 + E_INVALID_VALUE,
33766 + ("keySize has to be defined as it was defined in initialization step"));
33767 +
33768 + if (p_CcNode->h_FmPcd != h_FmPcd)
33769 + RETURN_ERROR(
33770 + MAJOR,
33771 + E_INVALID_VALUE,
33772 + ("handler to FmPcd is different from the handle provided at node initialization time"));
33773 +
33774 + if (p_CcNode->maxNumOfKeys)
33775 + {
33776 + if (p_CcNode->numOfKeys == p_CcNode->maxNumOfKeys)
33777 + RETURN_ERROR(
33778 + MAJOR,
33779 + E_FULL,
33780 + ("number of keys exceeds the maximal number of keys provided at node initialization time"));
33781 + }
33782 + else
33783 + if (p_CcNode->numOfKeys == FM_PCD_MAX_NUM_OF_KEYS)
33784 + RETURN_ERROR(
33785 + MAJOR,
33786 + E_INVALID_VALUE,
33787 + ("number of keys can not be larger than %d", FM_PCD_MAX_NUM_OF_KEYS));
33788 +
33789 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
33790 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
33791 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
33792 + RETURN_ERROR(
33793 + MAJOR,
33794 + E_ALREADY_EXISTS,
33795 + ("The received key and mask pair was already found in the match table of the provided node"));
33796 +
33797 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33798 +
33799 + INIT_LIST(&h_OldPointersLst);
33800 + INIT_LIST(&h_NewPointersLst);
33801 +
33802 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33803 + e_MODIFY_STATE_ADD, TRUE, TRUE,
33804 + FALSE);
33805 + if (!p_ModifyKeyParams)
33806 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33807 +
33808 + if (p_CcNode->maxNumOfKeys)
33809 + {
33810 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33811 + {
33812 + XX_Free(p_ModifyKeyParams);
33813 + return ERROR_CODE(E_BUSY);
33814 + }
33815 +
33816 + useShadowStructs = TRUE;
33817 + }
33818 +
33819 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
33820 + p_FmPcdCcKeyParams,
33821 + p_ModifyKeyParams, TRUE);
33822 + if (err)
33823 + {
33824 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33825 + XX_Free(p_ModifyKeyParams);
33826 + if (p_CcNode->maxNumOfKeys)
33827 + RELEASE_LOCK(p_FmPcd->shadowLock);
33828 + RETURN_ERROR(MAJOR, err, NO_MSG);
33829 + }
33830 +
33831 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
33832 + &h_OldPointersLst,
33833 + &h_NewPointersLst);
33834 + if (err)
33835 + {
33836 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33837 + XX_Free(p_ModifyKeyParams);
33838 + if (p_CcNode->maxNumOfKeys)
33839 + RELEASE_LOCK(p_FmPcd->shadowLock);
33840 + RETURN_ERROR(MAJOR, err, NO_MSG);
33841 + }
33842 +
33843 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33844 + p_ModifyKeyParams, useShadowStructs);
33845 + if (p_CcNode->maxNumOfKeys)
33846 + RELEASE_LOCK(p_FmPcd->shadowLock);
33847 +
33848 + ReleaseLst(&h_OldPointersLst);
33849 + ReleaseLst(&h_NewPointersLst);
33850 +
33851 + return err;
33852 +}
33853 +
33854 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
33855 + uint16_t keyIndex, uint8_t keySize,
33856 + t_FmPcdCcKeyParams *p_FmPcdCcKeyParams)
33857 +{
33858 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
33859 + t_FmPcd *p_FmPcd;
33860 + t_List h_OldPointersLst, h_NewPointersLst;
33861 + t_FmPcdModifyCcKeyAdditionalParams *p_ModifyKeyParams;
33862 + uint16_t tmpKeyIndex;
33863 + bool useShadowStructs = FALSE;
33864 + t_Error err = E_OK;
33865 +
33866 + if (keyIndex > p_CcNode->numOfKeys)
33867 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
33868 + ("keyIndex > previously cleared last index + 1"));
33869 +
33870 + if (keySize != p_CcNode->userSizeOfExtraction)
33871 + RETURN_ERROR(
33872 + MAJOR,
33873 + E_INVALID_VALUE,
33874 + ("keySize has to be defined as it was defined in initialization step"));
33875 +
33876 + if (p_CcNode->h_FmPcd != h_FmPcd)
33877 + RETURN_ERROR(
33878 + MAJOR,
33879 + E_INVALID_VALUE,
33880 + ("handler to FmPcd is different from the handle provided at node initialization time"));
33881 +
33882 + err = FindKeyIndex(h_FmPcdCcNode, keySize, p_FmPcdCcKeyParams->p_Key,
33883 + p_FmPcdCcKeyParams->p_Mask, &tmpKeyIndex);
33884 + if (GET_ERROR_TYPE(err) != E_NOT_FOUND)
33885 + RETURN_ERROR(
33886 + MINOR,
33887 + E_ALREADY_EXISTS,
33888 + ("The received key and mask pair was already found in the match table of the provided node"));
33889 +
33890 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
33891 +
33892 + INIT_LIST(&h_OldPointersLst);
33893 + INIT_LIST(&h_NewPointersLst);
33894 +
33895 + p_ModifyKeyParams = ModifyNodeCommonPart(p_CcNode, keyIndex,
33896 + e_MODIFY_STATE_CHANGE, TRUE, TRUE,
33897 + FALSE);
33898 + if (!p_ModifyKeyParams)
33899 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
33900 +
33901 + if (p_CcNode->maxNumOfKeys)
33902 + {
33903 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
33904 + {
33905 + XX_Free(p_ModifyKeyParams);
33906 + return ERROR_CODE(E_BUSY);
33907 + }
33908 +
33909 + useShadowStructs = TRUE;
33910 + }
33911 +
33912 + err = BuildNewNodeAddOrMdfyKeyAndNextEngine(h_FmPcd, p_CcNode, keyIndex,
33913 + p_FmPcdCcKeyParams,
33914 + p_ModifyKeyParams, FALSE);
33915 + if (err)
33916 + {
33917 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33918 + XX_Free(p_ModifyKeyParams);
33919 + if (p_CcNode->maxNumOfKeys)
33920 + RELEASE_LOCK(p_FmPcd->shadowLock);
33921 + RETURN_ERROR(MAJOR, err, NO_MSG);
33922 + }
33923 +
33924 + err = UpdatePtrWhichPointOnCrntMdfNode(p_CcNode, p_ModifyKeyParams,
33925 + &h_OldPointersLst,
33926 + &h_NewPointersLst);
33927 + if (err)
33928 + {
33929 + ReleaseNewNodeCommonPart(p_ModifyKeyParams);
33930 + XX_Free(p_ModifyKeyParams);
33931 + if (p_CcNode->maxNumOfKeys)
33932 + RELEASE_LOCK(p_FmPcd->shadowLock);
33933 + RETURN_ERROR(MAJOR, err, NO_MSG);
33934 + }
33935 +
33936 + err = DoDynamicChange(p_FmPcd, &h_OldPointersLst, &h_NewPointersLst,
33937 + p_ModifyKeyParams, useShadowStructs);
33938 +
33939 + if (p_CcNode->maxNumOfKeys)
33940 + RELEASE_LOCK(p_FmPcd->shadowLock);
33941 +
33942 + ReleaseLst(&h_OldPointersLst);
33943 + ReleaseLst(&h_NewPointersLst);
33944 +
33945 + return err;
33946 +}
33947 +
33948 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd,
33949 + t_Handle h_Pointer)
33950 +{
33951 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
33952 + t_CcNodeInformation *p_CcNodeInfo;
33953 +
33954 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE,
33955 + (uint32_t)ILLEGAL_BASE);
33956 +
33957 + p_CcNodeInfo = CC_NODE_F_OBJECT(h_Pointer);
33958 +
33959 + return (uint32_t)(XX_VirtToPhys(p_CcNodeInfo->h_CcNode)
33960 + - p_FmPcd->physicalMuramBase);
33961 +}
33962 +
33963 +t_Error FmPcdCcGetGrpParams(t_Handle h_FmPcdCcTree, uint8_t grpId,
33964 + uint32_t *p_GrpBits, uint8_t *p_GrpBase)
33965 +{
33966 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
33967 +
33968 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
33969 +
33970 + if (grpId >= p_FmPcdCcTree->numOfGrps)
33971 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
33972 + ("grpId you asked > numOfGroup of relevant tree"));
33973 +
33974 + *p_GrpBits = p_FmPcdCcTree->fmPcdGroupParam[grpId].totalBitsMask;
33975 + *p_GrpBase = p_FmPcdCcTree->fmPcdGroupParam[grpId].baseGroupEntry;
33976 +
33977 + return E_OK;
33978 +}
33979 +
33980 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams,
33981 + t_Handle h_FmPcdCcTree, uint32_t *p_Offset,
33982 + t_Handle h_FmPort)
33983 +{
33984 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
33985 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
33986 + t_Error err = E_OK;
33987 +
33988 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
33989 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
33990 +
33991 + /* this routine must be protected by the calling routine by locking all PCD modules! */
33992 +
33993 + err = CcUpdateParams(h_FmPcd, h_PcdParams, h_FmPort, h_FmPcdCcTree, TRUE);
33994 +
33995 + if (err == E_OK)
33996 + UpdateCcRootOwner(p_FmPcdCcTree, TRUE);
33997 +
33998 + *p_Offset = (uint32_t)(XX_VirtToPhys(
33999 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr))
34000 + - p_FmPcd->physicalMuramBase);
34001 +
34002 + return err;
34003 +}
34004 +
34005 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree)
34006 +{
34007 + t_FmPcdCcTree *p_FmPcdCcTree = (t_FmPcdCcTree *)h_FmPcdCcTree;
34008 +
34009 + /* this routine must be protected by the calling routine by locking all PCD modules! */
34010 +
34011 + UNUSED(h_FmPcd);
34012 +
34013 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcTree, E_INVALID_HANDLE);
34014 +
34015 + UpdateCcRootOwner(p_FmPcdCcTree, FALSE);
34016 +
34017 + return E_OK;
34018 +}
34019 +
34020 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode,
34021 + t_List *p_List)
34022 +{
34023 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_FmPcdCcNode;
34024 + t_List *p_Pos, *p_Tmp;
34025 + t_CcNodeInformation *p_CcNodeInfo, nodeInfo;
34026 + uint32_t intFlags;
34027 + t_Error err = E_OK;
34028 +
34029 + intFlags = FmPcdLock(h_FmPcd);
34030 +
34031 + LIST_FOR_EACH(p_Pos, &p_CcNode->ccTreesLst)
34032 + {
34033 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
34034 + ASSERT_COND(p_CcNodeInfo->h_CcNode);
34035 +
34036 + err = CcRootTryLock(p_CcNodeInfo->h_CcNode);
34037 +
34038 + if (err)
34039 + {
34040 + LIST_FOR_EACH(p_Tmp, &p_CcNode->ccTreesLst)
34041 + {
34042 + if (p_Tmp == p_Pos)
34043 + break;
34044 +
34045 + CcRootReleaseLock(p_CcNodeInfo->h_CcNode);
34046 + }
34047 + break;
34048 + }
34049 +
34050 + memset(&nodeInfo, 0, sizeof(t_CcNodeInformation));
34051 + nodeInfo.h_CcNode = p_CcNodeInfo->h_CcNode;
34052 + EnqueueNodeInfoToRelevantLst(p_List, &nodeInfo, NULL);
34053 + }
34054 +
34055 + FmPcdUnlock(h_FmPcd, intFlags);
34056 + CORE_MemoryBarrier();
34057 +
34058 + return err;
34059 +}
34060 +
34061 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List)
34062 +{
34063 + t_List *p_Pos;
34064 + t_CcNodeInformation *p_CcNodeInfo;
34065 + t_Handle h_FmPcdCcTree;
34066 + uint32_t intFlags;
34067 +
34068 + intFlags = FmPcdLock(h_FmPcd);
34069 +
34070 + LIST_FOR_EACH(p_Pos, p_List)
34071 + {
34072 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
34073 + h_FmPcdCcTree = p_CcNodeInfo->h_CcNode;
34074 + CcRootReleaseLock(h_FmPcdCcTree);
34075 + }
34076 +
34077 + ReleaseLst(p_List);
34078 +
34079 + FmPcdUnlock(h_FmPcd, intFlags);
34080 + CORE_MemoryBarrier();
34081 +}
34082 +
34083 +t_Error FmPcdUpdateCcShadow(t_FmPcd *p_FmPcd, uint32_t size, uint32_t align)
34084 +{
34085 + uint32_t intFlags;
34086 + uint32_t newSize = 0, newAlign = 0;
34087 + bool allocFail = FALSE;
34088 +
34089 + ASSERT_COND(p_FmPcd);
34090 +
34091 + if (!size)
34092 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("size must be larger then 0"));
34093 +
34094 + if (!POWER_OF_2(align))
34095 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("alignment must be power of 2"));
34096 +
34097 + newSize = p_FmPcd->ccShadowSize;
34098 + newAlign = p_FmPcd->ccShadowAlign;
34099 +
34100 + /* Check if current shadow is large enough to hold the requested size */
34101 + if (size > p_FmPcd->ccShadowSize)
34102 + newSize = size;
34103 +
34104 + /* Check if current shadow matches the requested alignment */
34105 + if (align > p_FmPcd->ccShadowAlign)
34106 + newAlign = align;
34107 +
34108 + /* If a bigger shadow size or bigger shadow alignment are required,
34109 + a new shadow will be allocated */
34110 + if ((newSize != p_FmPcd->ccShadowSize)
34111 + || (newAlign != p_FmPcd->ccShadowAlign))
34112 + {
34113 + intFlags = FmPcdLock(p_FmPcd);
34114 +
34115 + if (p_FmPcd->p_CcShadow)
34116 + {
34117 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->p_CcShadow);
34118 + p_FmPcd->ccShadowSize = 0;
34119 + p_FmPcd->ccShadowAlign = 0;
34120 + }
34121 +
34122 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(FmPcdGetMuramHandle(p_FmPcd),
34123 + newSize, newAlign);
34124 + if (!p_FmPcd->p_CcShadow)
34125 + {
34126 + allocFail = TRUE;
34127 +
34128 + /* If new shadow size allocation failed,
34129 + re-allocate with previous parameters */
34130 + p_FmPcd->p_CcShadow = FM_MURAM_AllocMem(
34131 + FmPcdGetMuramHandle(p_FmPcd), p_FmPcd->ccShadowSize,
34132 + p_FmPcd->ccShadowAlign);
34133 + }
34134 +
34135 + FmPcdUnlock(p_FmPcd, intFlags);
34136 +
34137 + if (allocFail)
34138 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
34139 + ("MURAM allocation for CC Shadow memory"));
34140 +
34141 + p_FmPcd->ccShadowSize = newSize;
34142 + p_FmPcd->ccShadowAlign = newAlign;
34143 + }
34144 +
34145 + return E_OK;
34146 +}
34147 +
34148 +#if (DPAA_VERSION >= 11)
34149 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
34150 + t_Handle h_ReplicGroup,
34151 + t_List *p_AdTables,
34152 + uint32_t *p_NumOfAdTables)
34153 +{
34154 + t_FmPcdCcNode *p_CurrentNode = (t_FmPcdCcNode *)h_Node;
34155 + int i = 0;
34156 + void * p_AdTable;
34157 + t_CcNodeInformation ccNodeInfo;
34158 +
34159 + ASSERT_COND(h_Node);
34160 + *p_NumOfAdTables = 0;
34161 +
34162 + /* search in the current node which exact index points on this current replicator group for getting AD */
34163 + for (i = 0; i < p_CurrentNode->numOfKeys + 1; i++)
34164 + {
34165 + if ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34166 + == e_FM_PCD_FR)
34167 + && ((p_CurrentNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic
34168 + == (t_Handle)h_ReplicGroup)))
34169 + {
34170 + /* save the current ad table in the list */
34171 + /* this entry uses the input replicator group */
34172 + p_AdTable =
34173 + PTR_MOVE(p_CurrentNode->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
34174 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
34175 + ccNodeInfo.h_CcNode = p_AdTable;
34176 + EnqueueNodeInfoToRelevantLst(p_AdTables, &ccNodeInfo, NULL);
34177 + (*p_NumOfAdTables)++;
34178 + }
34179 + }
34180 +
34181 + ASSERT_COND(i != p_CurrentNode->numOfKeys);
34182 +}
34183 +#endif /* (DPAA_VERSION >= 11) */
34184 +/*********************** End of inter-module routines ************************/
34185 +
34186 +/****************************************/
34187 +/* API Init unit functions */
34188 +/****************************************/
34189 +
34190 +t_Handle FM_PCD_CcRootBuild(t_Handle h_FmPcd,
34191 + t_FmPcdCcTreeParams *p_PcdGroupsParam)
34192 +{
34193 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
34194 + t_Error err = E_OK;
34195 + int i = 0, j = 0, k = 0;
34196 + t_FmPcdCcTree *p_FmPcdCcTree;
34197 + uint8_t numOfEntries;
34198 + t_Handle p_CcTreeTmp;
34199 + t_FmPcdCcGrpParams *p_FmPcdCcGroupParams;
34200 + t_FmPcdCcKeyAndNextEngineParams *p_Params, *p_KeyAndNextEngineParams;
34201 + t_NetEnvParams netEnvParams;
34202 + uint8_t lastOne = 0;
34203 + uint32_t requiredAction = 0;
34204 + t_FmPcdCcNode *p_FmPcdCcNextNode;
34205 + t_CcNodeInformation ccNodeInfo, *p_CcInformation;
34206 +
34207 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
34208 + SANITY_CHECK_RETURN_VALUE(p_PcdGroupsParam, E_INVALID_HANDLE, NULL);
34209 +
34210 + if (p_PcdGroupsParam->numOfGrps > FM_PCD_MAX_NUM_OF_CC_GROUPS)
34211 + {
34212 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfGrps should not exceed %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
34213 + return NULL;
34214 + }
34215 +
34216 + p_FmPcdCcTree = (t_FmPcdCcTree*)XX_Malloc(sizeof(t_FmPcdCcTree));
34217 + if (!p_FmPcdCcTree)
34218 + {
34219 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("PCD tree structure"));
34220 + return NULL;
34221 + }
34222 + memset(p_FmPcdCcTree, 0, sizeof(t_FmPcdCcTree));
34223 + p_FmPcdCcTree->h_FmPcd = h_FmPcd;
34224 +
34225 + p_Params = (t_FmPcdCcKeyAndNextEngineParams*)XX_Malloc(
34226 + FM_PCD_MAX_NUM_OF_CC_GROUPS
34227 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
34228 + memset(p_Params,
34229 + 0,
34230 + FM_PCD_MAX_NUM_OF_CC_GROUPS
34231 + * sizeof(t_FmPcdCcKeyAndNextEngineParams));
34232 +
34233 + INIT_LIST(&p_FmPcdCcTree->fmPortsLst);
34234 +
34235 +#ifdef FM_CAPWAP_SUPPORT
34236 + if ((p_PcdGroupsParam->numOfGrps == 1) &&
34237 + (p_PcdGroupsParam->ccGrpParams[0].numOfDistinctionUnits == 0) &&
34238 + (p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].nextEngine == e_FM_PCD_CC) &&
34239 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode &&
34240 + IsCapwapApplSpecific(p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].params.ccParams.h_CcNode))
34241 + {
34242 + p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip = FmPcdManipApplSpecificBuild();
34243 + if (!p_PcdGroupsParam->ccGrpParams[0].nextEnginePerEntriesInGrp[0].h_Manip)
34244 + {
34245 + DeleteTree(p_FmPcdCcTree,p_FmPcd);
34246 + XX_Free(p_Params);
34247 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
34248 + return NULL;
34249 + }
34250 + }
34251 +#endif /* FM_CAPWAP_SUPPORT */
34252 +
34253 + numOfEntries = 0;
34254 + p_FmPcdCcTree->netEnvId = FmPcdGetNetEnvId(p_PcdGroupsParam->h_NetEnv);
34255 +
34256 + for (i = 0; i < p_PcdGroupsParam->numOfGrps; i++)
34257 + {
34258 + p_FmPcdCcGroupParams = &p_PcdGroupsParam->ccGrpParams[i];
34259 +
34260 + if (p_FmPcdCcGroupParams->numOfDistinctionUnits
34261 + > FM_PCD_MAX_NUM_OF_CC_UNITS)
34262 + {
34263 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34264 + XX_Free(p_Params);
34265 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
34266 + ("numOfDistinctionUnits (group %d) should not exceed %d", i, FM_PCD_MAX_NUM_OF_CC_UNITS));
34267 + return NULL;
34268 + }
34269 +
34270 + p_FmPcdCcTree->fmPcdGroupParam[i].baseGroupEntry = numOfEntries;
34271 + p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup = (uint8_t)(0x01
34272 + << p_FmPcdCcGroupParams->numOfDistinctionUnits);
34273 + numOfEntries += p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
34274 + if (numOfEntries > FM_PCD_MAX_NUM_OF_CC_GROUPS)
34275 + {
34276 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34277 + XX_Free(p_Params);
34278 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("numOfEntries can not be larger than %d", FM_PCD_MAX_NUM_OF_CC_GROUPS));
34279 + return NULL;
34280 + }
34281 +
34282 + if (lastOne)
34283 + {
34284 + if (p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup > lastOne)
34285 + {
34286 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34287 + XX_Free(p_Params);
34288 + REPORT_ERROR(MAJOR, E_CONFLICT, ("numOfEntries per group must be set in descending order"));
34289 + return NULL;
34290 + }
34291 + }
34292 +
34293 + lastOne = p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
34294 +
34295 + netEnvParams.netEnvId = p_FmPcdCcTree->netEnvId;
34296 + netEnvParams.numOfDistinctionUnits =
34297 + p_FmPcdCcGroupParams->numOfDistinctionUnits;
34298 +
34299 + memcpy(netEnvParams.unitIds, &p_FmPcdCcGroupParams->unitIds,
34300 + (sizeof(uint8_t)) * p_FmPcdCcGroupParams->numOfDistinctionUnits);
34301 +
34302 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
34303 + if (err)
34304 + {
34305 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34306 + XX_Free(p_Params);
34307 + REPORT_ERROR(MAJOR, err, NO_MSG);
34308 + return NULL;
34309 + }
34310 +
34311 + p_FmPcdCcTree->fmPcdGroupParam[i].totalBitsMask = netEnvParams.vector;
34312 + for (j = 0; j < p_FmPcdCcTree->fmPcdGroupParam[i].numOfEntriesInGroup;
34313 + j++)
34314 + {
34315 + err = ValidateNextEngineParams(
34316 + h_FmPcd,
34317 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
34318 + e_FM_PCD_CC_STATS_MODE_NONE);
34319 + if (err)
34320 + {
34321 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34322 + XX_Free(p_Params);
34323 + REPORT_ERROR(MAJOR, err, (NO_MSG));
34324 + return NULL;
34325 + }
34326 +
34327 + if (p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j].h_Manip)
34328 + {
34329 + err = FmPcdManipCheckParamsForCcNextEngine(
34330 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
34331 + &requiredAction);
34332 + if (err)
34333 + {
34334 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34335 + XX_Free(p_Params);
34336 + REPORT_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
34337 + return NULL;
34338 + }
34339 + }
34340 + p_KeyAndNextEngineParams = p_Params + k;
34341 +
34342 + memcpy(&p_KeyAndNextEngineParams->nextEngineParams,
34343 + &p_FmPcdCcGroupParams->nextEnginePerEntriesInGrp[j],
34344 + sizeof(t_FmPcdCcNextEngineParams));
34345 +
34346 + if ((p_KeyAndNextEngineParams->nextEngineParams.nextEngine
34347 + == e_FM_PCD_CC)
34348 + && p_KeyAndNextEngineParams->nextEngineParams.h_Manip)
34349 + {
34350 + err =
34351 + AllocAndFillAdForContLookupManip(
34352 + p_KeyAndNextEngineParams->nextEngineParams.params.ccParams.h_CcNode);
34353 + if (err)
34354 + {
34355 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34356 + XX_Free(p_Params);
34357 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
34358 + return NULL;
34359 + }
34360 + }
34361 +
34362 + requiredAction |= UPDATE_CC_WITH_TREE;
34363 + p_KeyAndNextEngineParams->requiredAction = requiredAction;
34364 +
34365 + k++;
34366 + }
34367 + }
34368 +
34369 + p_FmPcdCcTree->numOfEntries = (uint8_t)k;
34370 + p_FmPcdCcTree->numOfGrps = p_PcdGroupsParam->numOfGrps;
34371 +
34372 + p_FmPcdCcTree->ccTreeBaseAddr =
34373 + PTR_TO_UINT(FM_MURAM_AllocMem(FmPcdGetMuramHandle(h_FmPcd),
34374 + (uint32_t)( FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE),
34375 + FM_PCD_CC_TREE_ADDR_ALIGN));
34376 + if (!p_FmPcdCcTree->ccTreeBaseAddr)
34377 + {
34378 + DeleteTree(p_FmPcdCcTree, p_FmPcd);
34379 + XX_Free(p_Params);
34380 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CC Tree"));
34381 + return NULL;
34382 + }
34383 + MemSet8(
34384 + UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr), 0,
34385 + (uint32_t)(FM_PCD_MAX_NUM_OF_CC_GROUPS * FM_PCD_CC_AD_ENTRY_SIZE));
34386 +
34387 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
34388 +
34389 + for (i = 0; i < numOfEntries; i++)
34390 + {
34391 + p_KeyAndNextEngineParams = p_Params + i;
34392 +
34393 + NextStepAd(p_CcTreeTmp, NULL,
34394 + &p_KeyAndNextEngineParams->nextEngineParams, p_FmPcd);
34395 +
34396 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
34397 +
34398 + memcpy(&p_FmPcdCcTree->keyAndNextEngineParams[i],
34399 + p_KeyAndNextEngineParams,
34400 + sizeof(t_FmPcdCcKeyAndNextEngineParams));
34401 +
34402 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34403 + == e_FM_PCD_CC)
34404 + {
34405 + p_FmPcdCcNextNode =
34406 + (t_FmPcdCcNode*)p_FmPcdCcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
34407 + p_CcInformation = FindNodeInfoInReleventLst(
34408 + &p_FmPcdCcNextNode->ccTreeIdLst, (t_Handle)p_FmPcdCcTree,
34409 + p_FmPcdCcNextNode->h_Spinlock);
34410 +
34411 + if (!p_CcInformation)
34412 + {
34413 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
34414 + ccNodeInfo.h_CcNode = (t_Handle)p_FmPcdCcTree;
34415 + ccNodeInfo.index = 1;
34416 + EnqueueNodeInfoToRelevantLst(&p_FmPcdCcNextNode->ccTreeIdLst,
34417 + &ccNodeInfo,
34418 + p_FmPcdCcNextNode->h_Spinlock);
34419 + }
34420 + else
34421 + p_CcInformation->index++;
34422 + }
34423 + }
34424 +
34425 + FmPcdIncNetEnvOwners(h_FmPcd, p_FmPcdCcTree->netEnvId);
34426 + p_CcTreeTmp = UINT_TO_PTR(p_FmPcdCcTree->ccTreeBaseAddr);
34427 +
34428 + if (!FmPcdLockTryLockAll(p_FmPcd))
34429 + {
34430 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
34431 + XX_Free(p_Params);
34432 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34433 + return NULL;
34434 + }
34435 +
34436 + for (i = 0; i < numOfEntries; i++)
34437 + {
34438 + if (p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction)
34439 + {
34440 + err = SetRequiredAction(
34441 + h_FmPcd,
34442 + p_FmPcdCcTree->keyAndNextEngineParams[i].requiredAction,
34443 + &p_FmPcdCcTree->keyAndNextEngineParams[i], p_CcTreeTmp, 1,
34444 + p_FmPcdCcTree);
34445 + if (err)
34446 + {
34447 + FmPcdLockUnlockAll(p_FmPcd);
34448 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
34449 + XX_Free(p_Params);
34450 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
34451 + return NULL;
34452 + }
34453 + p_CcTreeTmp = PTR_MOVE(p_CcTreeTmp, FM_PCD_CC_AD_ENTRY_SIZE);
34454 + }
34455 + }
34456 +
34457 + FmPcdLockUnlockAll(p_FmPcd);
34458 + p_FmPcdCcTree->p_Lock = FmPcdAcquireLock(p_FmPcd);
34459 + if (!p_FmPcdCcTree->p_Lock)
34460 + {
34461 + FM_PCD_CcRootDelete(p_FmPcdCcTree);
34462 + XX_Free(p_Params);
34463 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM CC lock"));
34464 + return NULL;
34465 + }
34466 +
34467 + XX_Free(p_Params);
34468 +
34469 + return p_FmPcdCcTree;
34470 +}
34471 +
34472 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree)
34473 +{
34474 + t_FmPcd *p_FmPcd;
34475 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
34476 + int i = 0;
34477 +
34478 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
34479 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
34480 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34481 +
34482 + FmPcdDecNetEnvOwners(p_FmPcd, p_CcTree->netEnvId);
34483 +
34484 + if (p_CcTree->owners)
34485 + RETURN_ERROR(
34486 + MAJOR,
34487 + E_INVALID_SELECTION,
34488 + ("the tree with this ID can not be removed because this tree is occupied, first - unbind this tree"));
34489 +
34490 + /* Delete ip-reassembly schemes if exist */
34491 + if (p_CcTree->h_IpReassemblyManip)
34492 + {
34493 + FmPcdManipDeleteIpReassmSchemes(p_CcTree->h_IpReassemblyManip);
34494 + FmPcdManipUpdateOwner(p_CcTree->h_IpReassemblyManip, FALSE);
34495 + }
34496 +
34497 + /* Delete capwap-reassembly schemes if exist */
34498 + if (p_CcTree->h_CapwapReassemblyManip)
34499 + {
34500 + FmPcdManipDeleteCapwapReassmSchemes(p_CcTree->h_CapwapReassemblyManip);
34501 + FmPcdManipUpdateOwner(p_CcTree->h_CapwapReassemblyManip, FALSE);
34502 + }
34503 +
34504 + for (i = 0; i < p_CcTree->numOfEntries; i++)
34505 + {
34506 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34507 + == e_FM_PCD_CC)
34508 + UpdateNodeOwner(
34509 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
34510 + FALSE);
34511 +
34512 + if (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
34513 + FmPcdManipUpdateOwner(
34514 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
34515 + FALSE);
34516 +
34517 +#ifdef FM_CAPWAP_SUPPORT
34518 + if ((p_CcTree->numOfGrps == 1) &&
34519 + (p_CcTree->fmPcdGroupParam[0].numOfEntriesInGroup == 1) &&
34520 + (p_CcTree->keyAndNextEngineParams[0].nextEngineParams.nextEngine == e_FM_PCD_CC) &&
34521 + p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode &&
34522 + IsCapwapApplSpecific(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode))
34523 + {
34524 + if (FM_PCD_ManipNodeDelete(p_CcTree->keyAndNextEngineParams[0].nextEngineParams.h_Manip) != E_OK)
34525 + return E_INVALID_STATE;
34526 + }
34527 +#endif /* FM_CAPWAP_SUPPORT */
34528 +
34529 +#if (DPAA_VERSION >= 11)
34530 + if ((p_CcTree->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34531 + == e_FM_PCD_FR)
34532 + && (p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
34533 + FrmReplicGroupUpdateOwner(
34534 + p_CcTree->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
34535 + FALSE);
34536 +#endif /* (DPAA_VERSION >= 11) */
34537 + }
34538 +
34539 + if (p_CcTree->p_Lock)
34540 + FmPcdReleaseLock(p_CcTree->h_FmPcd, p_CcTree->p_Lock);
34541 +
34542 + DeleteTree(p_CcTree, p_FmPcd);
34543 +
34544 + return E_OK;
34545 +}
34546 +
34547 +t_Error FM_PCD_CcRootModifyNextEngine(
34548 + t_Handle h_CcTree, uint8_t grpId, uint8_t index,
34549 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34550 +{
34551 + t_FmPcd *p_FmPcd;
34552 + t_FmPcdCcTree *p_CcTree = (t_FmPcdCcTree *)h_CcTree;
34553 + t_Error err = E_OK;
34554 +
34555 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34556 + SANITY_CHECK_RETURN_ERROR(p_CcTree, E_INVALID_STATE);
34557 + p_FmPcd = (t_FmPcd *)p_CcTree->h_FmPcd;
34558 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34559 +
34560 + if (!FmPcdLockTryLockAll(p_FmPcd))
34561 + {
34562 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34563 + return ERROR_CODE(E_BUSY);
34564 + }
34565 +
34566 + err = FmPcdCcModifyNextEngineParamTree(p_FmPcd, p_CcTree, grpId, index,
34567 + p_FmPcdCcNextEngineParams);
34568 + FmPcdLockUnlockAll(p_FmPcd);
34569 +
34570 + if (err)
34571 + {
34572 + RETURN_ERROR(MAJOR, err, NO_MSG);
34573 + }
34574 +
34575 + return E_OK;
34576 +}
34577 +
34578 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd,
34579 + t_FmPcdCcNodeParams *p_CcNodeParam)
34580 +{
34581 + t_FmPcdCcNode *p_CcNode;
34582 + t_Error err;
34583 +
34584 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
34585 + SANITY_CHECK_RETURN_VALUE(p_CcNodeParam, E_NULL_POINTER, NULL);
34586 +
34587 + p_CcNode = (t_FmPcdCcNode*)XX_Malloc(sizeof(t_FmPcdCcNode));
34588 + if (!p_CcNode)
34589 + {
34590 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
34591 + return NULL;
34592 + }
34593 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
34594 +
34595 + err = MatchTableSet(h_FmPcd, p_CcNode, p_CcNodeParam);
34596 +
34597 + switch(GET_ERROR_TYPE(err)
34598 +) {
34599 + case E_OK:
34600 + break;
34601 +
34602 + case E_BUSY:
34603 + DBG(TRACE, ("E_BUSY error"));
34604 + return NULL;
34605 +
34606 + default:
34607 + REPORT_ERROR(MAJOR, err, NO_MSG);
34608 + return NULL;
34609 + }
34610 +
34611 + return p_CcNode;
34612 +}
34613 +
34614 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode)
34615 +{
34616 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34617 + int i = 0;
34618 +
34619 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34620 + SANITY_CHECK_RETURN_ERROR(p_CcNode->h_FmPcd, E_INVALID_HANDLE);
34621 +
34622 + if (p_CcNode->owners)
34623 + RETURN_ERROR(
34624 + MAJOR,
34625 + E_INVALID_STATE,
34626 + ("This node cannot be removed because it is occupied; first unbind this node"));
34627 +
34628 + for (i = 0; i < p_CcNode->numOfKeys; i++)
34629 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34630 + == e_FM_PCD_CC)
34631 + UpdateNodeOwner(
34632 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
34633 + FALSE);
34634 +
34635 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34636 + == e_FM_PCD_CC)
34637 + UpdateNodeOwner(
34638 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode,
34639 + FALSE);
34640 +
34641 + /* Handle also Miss entry */
34642 + for (i = 0; i < p_CcNode->numOfKeys + 1; i++)
34643 + {
34644 + if (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip)
34645 + FmPcdManipUpdateOwner(
34646 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.h_Manip,
34647 + FALSE);
34648 +
34649 +#if (DPAA_VERSION >= 11)
34650 + if ((p_CcNode->keyAndNextEngineParams[i].nextEngineParams.nextEngine
34651 + == e_FM_PCD_FR)
34652 + && (p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic))
34653 + {
34654 + FrmReplicGroupUpdateOwner(
34655 + p_CcNode->keyAndNextEngineParams[i].nextEngineParams.params.frParams.h_FrmReplic,
34656 + FALSE);
34657 + }
34658 +#endif /* (DPAA_VERSION >= 11) */
34659 + }
34660 +
34661 + DeleteNode(p_CcNode);
34662 +
34663 + return E_OK;
34664 +}
34665 +
34666 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode, uint16_t keyIndex,
34667 + uint8_t keySize,
34668 + t_FmPcdCcKeyParams *p_KeyParams)
34669 +{
34670 + t_FmPcd *p_FmPcd;
34671 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34672 + t_Error err = E_OK;
34673 +
34674 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
34675 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34676 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34677 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34678 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34679 +
34680 + if (keyIndex == FM_PCD_LAST_KEY_INDEX)
34681 + keyIndex = p_CcNode->numOfKeys;
34682 +
34683 + if (!FmPcdLockTryLockAll(p_FmPcd))
34684 + {
34685 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34686 + return ERROR_CODE(E_BUSY);
34687 + }
34688 +
34689 + err = FmPcdCcAddKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_KeyParams);
34690 +
34691 + FmPcdLockUnlockAll(p_FmPcd);
34692 +
34693 + switch(GET_ERROR_TYPE(err)
34694 +) {
34695 + case E_OK:
34696 + return E_OK;
34697 +
34698 + case E_BUSY:
34699 + DBG(TRACE, ("E_BUSY error"));
34700 + return ERROR_CODE(E_BUSY);
34701 +
34702 + default:
34703 + RETURN_ERROR(MAJOR, err, NO_MSG);
34704 + }
34705 +}
34706 +
34707 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex)
34708 +{
34709 + t_FmPcd *p_FmPcd;
34710 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34711 + t_Error err = E_OK;
34712 +
34713 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34714 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34715 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34716 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34717 +
34718 + if (!FmPcdLockTryLockAll(p_FmPcd))
34719 + {
34720 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34721 + return ERROR_CODE(E_BUSY);
34722 + }
34723 +
34724 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
34725 +
34726 + FmPcdLockUnlockAll(p_FmPcd);
34727 +
34728 + switch(GET_ERROR_TYPE(err)
34729 +) {
34730 + case E_OK:
34731 + return E_OK;
34732 +
34733 + case E_BUSY:
34734 + DBG(TRACE, ("E_BUSY error"));
34735 + return ERROR_CODE(E_BUSY);
34736 +
34737 + default:
34738 + RETURN_ERROR(MAJOR, err, NO_MSG);
34739 + }
34740 +
34741 + return E_OK;
34742 +}
34743 +
34744 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode, uint16_t keyIndex,
34745 + uint8_t keySize, uint8_t *p_Key,
34746 + uint8_t *p_Mask)
34747 +{
34748 + t_FmPcd *p_FmPcd;
34749 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34750 + t_Error err = E_OK;
34751 +
34752 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34753 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34754 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34755 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34756 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34757 +
34758 +
34759 + if (!FmPcdLockTryLockAll(p_FmPcd))
34760 + {
34761 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34762 + return ERROR_CODE(E_BUSY);
34763 + }
34764 +
34765 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_Key, p_Mask);
34766 +
34767 + FmPcdLockUnlockAll(p_FmPcd);
34768 +
34769 + switch(GET_ERROR_TYPE(err)
34770 +) {
34771 + case E_OK:
34772 + return E_OK;
34773 +
34774 + case E_BUSY:
34775 + DBG(TRACE, ("E_BUSY error"));
34776 + return ERROR_CODE(E_BUSY);
34777 +
34778 + default:
34779 + RETURN_ERROR(MAJOR, err, NO_MSG);
34780 + }
34781 +}
34782 +
34783 +t_Error FM_PCD_MatchTableModifyNextEngine(
34784 + t_Handle h_CcNode, uint16_t keyIndex,
34785 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34786 +{
34787 + t_FmPcd *p_FmPcd;
34788 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34789 + t_Error err = E_OK;
34790 +
34791 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34792 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34793 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34794 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34795 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34796 +
34797 + if (!FmPcdLockTryLockAll(p_FmPcd))
34798 + {
34799 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34800 + return ERROR_CODE(E_BUSY);
34801 + }
34802 +
34803 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
34804 + p_FmPcdCcNextEngineParams);
34805 +
34806 + FmPcdLockUnlockAll(p_FmPcd);
34807 +
34808 + switch(GET_ERROR_TYPE(err)
34809 +) {
34810 + case E_OK:
34811 + return E_OK;
34812 +
34813 + case E_BUSY:
34814 + DBG(TRACE, ("E_BUSY error"));
34815 + return ERROR_CODE(E_BUSY);
34816 +
34817 + default:
34818 + RETURN_ERROR(MAJOR, err, NO_MSG);
34819 + }
34820 +}
34821 +
34822 +t_Error FM_PCD_MatchTableModifyMissNextEngine(
34823 + t_Handle h_CcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34824 +{
34825 + t_FmPcd *p_FmPcd;
34826 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34827 + t_Error err = E_OK;
34828 +
34829 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34830 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34831 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34832 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34833 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34834 +
34835 + if (!FmPcdLockTryLockAll(p_FmPcd))
34836 + {
34837 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34838 + return ERROR_CODE(E_BUSY);
34839 + }
34840 +
34841 + err = FmPcdCcModifyMissNextEngineParamNode(p_FmPcd, p_CcNode,
34842 + p_FmPcdCcNextEngineParams);
34843 +
34844 + FmPcdLockUnlockAll(p_FmPcd);
34845 +
34846 + switch(GET_ERROR_TYPE(err)
34847 +) {
34848 + case E_OK:
34849 + return E_OK;
34850 +
34851 + case E_BUSY:
34852 + DBG(TRACE, ("E_BUSY error"));
34853 + return ERROR_CODE(E_BUSY);
34854 +
34855 + default:
34856 + RETURN_ERROR(MAJOR, err, NO_MSG);
34857 + }
34858 +}
34859 +
34860 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
34861 + uint16_t keyIndex,
34862 + uint8_t keySize,
34863 + t_FmPcdCcKeyParams *p_KeyParams)
34864 +{
34865 + t_FmPcd *p_FmPcd;
34866 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34867 + t_Error err = E_OK;
34868 +
34869 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
34870 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34871 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34872 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34873 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34874 +
34875 + if (!FmPcdLockTryLockAll(p_FmPcd))
34876 + {
34877 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34878 + return ERROR_CODE(E_BUSY);
34879 + }
34880 +
34881 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, p_CcNode, keyIndex, keySize,
34882 + p_KeyParams);
34883 +
34884 + FmPcdLockUnlockAll(p_FmPcd);
34885 +
34886 + switch(GET_ERROR_TYPE(err)
34887 +) {
34888 + case E_OK:
34889 + return E_OK;
34890 +
34891 + case E_BUSY:
34892 + DBG(TRACE, ("E_BUSY error"));
34893 + return ERROR_CODE(E_BUSY);
34894 +
34895 + default:
34896 + RETURN_ERROR(MAJOR, err, NO_MSG);
34897 + }
34898 +}
34899 +
34900 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode, uint8_t keySize,
34901 + uint8_t *p_Key, uint8_t *p_Mask)
34902 +{
34903 + t_FmPcd *p_FmPcd;
34904 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34905 + uint16_t keyIndex;
34906 + t_Error err;
34907 +
34908 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34909 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34910 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34911 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34912 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34913 +
34914 + if (!FmPcdLockTryLockAll(p_FmPcd))
34915 + {
34916 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34917 + return ERROR_CODE(E_BUSY);
34918 + }
34919 +
34920 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
34921 + if (GET_ERROR_TYPE(err) != E_OK)
34922 + {
34923 + FmPcdLockUnlockAll(p_FmPcd);
34924 + RETURN_ERROR(
34925 + MAJOR,
34926 + err,
34927 + ("The received key and mask pair was not found in the match table of the provided node"));
34928 + }
34929 +
34930 + err = FmPcdCcRemoveKey(p_FmPcd, p_CcNode, keyIndex);
34931 +
34932 + FmPcdLockUnlockAll(p_FmPcd);
34933 +
34934 + switch(GET_ERROR_TYPE(err)
34935 +) {
34936 + case E_OK:
34937 + return E_OK;
34938 +
34939 + case E_BUSY:
34940 + DBG(TRACE, ("E_BUSY error"));
34941 + return ERROR_CODE(E_BUSY);
34942 +
34943 + default:
34944 + RETURN_ERROR(MAJOR, err, NO_MSG);
34945 + }
34946 +}
34947 +
34948 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(
34949 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
34950 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
34951 +{
34952 + t_FmPcd *p_FmPcd;
34953 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
34954 + uint16_t keyIndex;
34955 + t_Error err;
34956 +
34957 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
34958 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
34959 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
34960 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
34961 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
34962 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
34963 +
34964 + if (!FmPcdLockTryLockAll(p_FmPcd))
34965 + {
34966 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
34967 + return ERROR_CODE(E_BUSY);
34968 + }
34969 +
34970 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
34971 + if (GET_ERROR_TYPE(err) != E_OK)
34972 + {
34973 + FmPcdLockUnlockAll(p_FmPcd);
34974 + RETURN_ERROR(
34975 + MAJOR,
34976 + err,
34977 + ("The received key and mask pair was not found in the match table of the provided node"));
34978 + }
34979 +
34980 + err = ModifyNextEngineParamNode(p_FmPcd, p_CcNode, keyIndex,
34981 + p_FmPcdCcNextEngineParams);
34982 +
34983 + FmPcdLockUnlockAll(p_FmPcd);
34984 +
34985 + switch(GET_ERROR_TYPE(err)
34986 +) {
34987 + case E_OK:
34988 + return E_OK;
34989 +
34990 + case E_BUSY:
34991 + DBG(TRACE, ("E_BUSY error"));
34992 + return ERROR_CODE(E_BUSY);
34993 +
34994 + default:
34995 + RETURN_ERROR(MAJOR, err, NO_MSG);
34996 + }
34997 +}
34998 +
34999 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(
35000 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
35001 + t_FmPcdCcKeyParams *p_KeyParams)
35002 +{
35003 + t_FmPcd *p_FmPcd;
35004 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
35005 + uint16_t keyIndex;
35006 + t_Error err;
35007 +
35008 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35009 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
35010 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
35011 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
35012 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
35013 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
35014 +
35015 + if (!FmPcdLockTryLockAll(p_FmPcd))
35016 + {
35017 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
35018 + return ERROR_CODE(E_BUSY);
35019 + }
35020 +
35021 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
35022 + if (GET_ERROR_TYPE(err) != E_OK)
35023 + {
35024 + FmPcdLockUnlockAll(p_FmPcd);
35025 + RETURN_ERROR(
35026 + MAJOR,
35027 + err,
35028 + ("The received key and mask pair was not found in the match table of the provided node"));
35029 + }
35030 +
35031 + err = FmPcdCcModifyKeyAndNextEngine(p_FmPcd, h_CcNode, keyIndex, keySize,
35032 + p_KeyParams);
35033 +
35034 + FmPcdLockUnlockAll(p_FmPcd);
35035 +
35036 + switch(GET_ERROR_TYPE(err)
35037 +) {
35038 + case E_OK:
35039 + return E_OK;
35040 +
35041 + case E_BUSY:
35042 + DBG(TRACE, ("E_BUSY error"));
35043 + return ERROR_CODE(E_BUSY);
35044 +
35045 + default:
35046 + RETURN_ERROR(MAJOR, err, NO_MSG);
35047 + }
35048 +}
35049 +
35050 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode, uint8_t keySize,
35051 + uint8_t *p_Key, uint8_t *p_Mask,
35052 + uint8_t *p_NewKey, uint8_t *p_NewMask)
35053 +{
35054 + t_FmPcd *p_FmPcd;
35055 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
35056 + t_List h_List;
35057 + uint16_t keyIndex;
35058 + t_Error err;
35059 +
35060 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35061 + SANITY_CHECK_RETURN_ERROR(p_NewKey, E_NULL_POINTER);
35062 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
35063 + p_FmPcd = (t_FmPcd *)p_CcNode->h_FmPcd;
35064 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
35065 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
35066 +
35067 + INIT_LIST(&h_List);
35068 +
35069 + err = FmPcdCcNodeTreeTryLock(p_FmPcd, p_CcNode, &h_List);
35070 + if (err)
35071 + {
35072 + DBG(TRACE, ("Node's trees lock failed"));
35073 + return ERROR_CODE(E_BUSY);
35074 + }
35075 +
35076 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
35077 + if (GET_ERROR_TYPE(err) != E_OK)
35078 + {
35079 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
35080 + RETURN_ERROR(MAJOR, err,
35081 + ("The received key and mask pair was not found in the "
35082 + "match table of the provided node"));
35083 + }
35084 +
35085 + err = FmPcdCcModifyKey(p_FmPcd, p_CcNode, keyIndex, keySize, p_NewKey,
35086 + p_NewMask);
35087 +
35088 + FmPcdCcNodeTreeReleaseLock(p_FmPcd, &h_List);
35089 +
35090 + switch(GET_ERROR_TYPE(err)
35091 +) {
35092 + case E_OK:
35093 + return E_OK;
35094 +
35095 + case E_BUSY:
35096 + DBG(TRACE, ("E_BUSY error"));
35097 + return ERROR_CODE(E_BUSY);
35098 +
35099 + default:
35100 + RETURN_ERROR(MAJOR, err, NO_MSG);
35101 + }
35102 +}
35103 +
35104 +t_Error FM_PCD_MatchTableGetNextEngine(
35105 + t_Handle h_CcNode, uint16_t keyIndex,
35106 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
35107 +{
35108 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
35109 +
35110 + SANITY_CHECK_RETURN_ERROR(p_CcNode, E_INVALID_HANDLE);
35111 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
35112 +
35113 + if (keyIndex >= p_CcNode->numOfKeys)
35114 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35115 + ("keyIndex exceeds current number of keys"));
35116 +
35117 + if (keyIndex > (FM_PCD_MAX_NUM_OF_KEYS - 1))
35118 + RETURN_ERROR(
35119 + MAJOR,
35120 + E_INVALID_VALUE,
35121 + ("keyIndex can not be larger than %d", (FM_PCD_MAX_NUM_OF_KEYS - 1)));
35122 +
35123 + memcpy(p_FmPcdCcNextEngineParams,
35124 + &p_CcNode->keyAndNextEngineParams[keyIndex].nextEngineParams,
35125 + sizeof(t_FmPcdCcNextEngineParams));
35126 +
35127 + return E_OK;
35128 +}
35129 +
35130 +
35131 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex)
35132 +{
35133 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
35134 + uint32_t *p_StatsCounters, frameCount;
35135 + uint32_t intFlags;
35136 +
35137 + SANITY_CHECK_RETURN_VALUE(p_CcNode, E_INVALID_HANDLE, 0);
35138 +
35139 + if (p_CcNode->statisticsMode == e_FM_PCD_CC_STATS_MODE_NONE)
35140 + {
35141 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this match table"));
35142 + return 0;
35143 + }
35144 +
35145 + if ((p_CcNode->statisticsMode != e_FM_PCD_CC_STATS_MODE_FRAME)
35146 + && (p_CcNode->statisticsMode
35147 + != e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
35148 + {
35149 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Frame count is not supported in the statistics mode of this match table"));
35150 + return 0;
35151 + }
35152 +
35153 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
35154 +
35155 + if (keyIndex >= p_CcNode->numOfKeys)
35156 + {
35157 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
35158 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("The provided keyIndex exceeds the number of keys in this match table"));
35159 + return 0;
35160 + }
35161 +
35162 + if (!p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj)
35163 + {
35164 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
35165 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Statistics were not enabled for this key"));
35166 + return 0;
35167 + }
35168 +
35169 + p_StatsCounters =
35170 + p_CcNode->keyAndNextEngineParams[keyIndex].p_StatsObj->h_StatsCounters;
35171 + ASSERT_COND(p_StatsCounters);
35172 +
35173 + /* The first counter is byte counter, so we need to advance to the next counter */
35174 + frameCount = GET_UINT32(*(uint32_t *)(PTR_MOVE(p_StatsCounters,
35175 + FM_PCD_CC_STATS_COUNTER_SIZE)));
35176 +
35177 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
35178 +
35179 + return frameCount;
35180 +}
35181 +
35182 +t_Error FM_PCD_MatchTableGetKeyStatistics(
35183 + t_Handle h_CcNode, uint16_t keyIndex,
35184 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
35185 +{
35186 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
35187 + uint32_t intFlags;
35188 + t_Error err;
35189 +
35190 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
35191 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
35192 +
35193 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
35194 +
35195 + if (keyIndex >= p_CcNode->numOfKeys)
35196 + RETURN_ERROR(
35197 + MAJOR,
35198 + E_INVALID_STATE,
35199 + ("The provided keyIndex exceeds the number of keys in this match table"));
35200 +
35201 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
35202 +
35203 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
35204 +
35205 + if (err != E_OK)
35206 + RETURN_ERROR(MAJOR, err, NO_MSG);
35207 +
35208 + return E_OK;
35209 +}
35210 +
35211 +t_Error FM_PCD_MatchTableGetMissStatistics(
35212 + t_Handle h_CcNode, t_FmPcdCcKeyStatistics *p_MissStatistics)
35213 +{
35214 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
35215 + uint32_t intFlags;
35216 + t_Error err;
35217 +
35218 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
35219 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
35220 +
35221 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
35222 +
35223 + err = MatchTableGetKeyStatistics(p_CcNode, p_CcNode->numOfKeys,
35224 + p_MissStatistics);
35225 +
35226 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
35227 +
35228 + if (err != E_OK)
35229 + RETURN_ERROR(MAJOR, err, NO_MSG);
35230 +
35231 + return E_OK;
35232 +}
35233 +
35234 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(
35235 + t_Handle h_CcNode, uint8_t keySize, uint8_t *p_Key, uint8_t *p_Mask,
35236 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
35237 +{
35238 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
35239 + uint16_t keyIndex;
35240 + uint32_t intFlags;
35241 + t_Error err;
35242 +
35243 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35244 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
35245 +
35246 + intFlags = XX_LockIntrSpinlock(p_CcNode->h_Spinlock);
35247 +
35248 + err = FindKeyIndex(p_CcNode, keySize, p_Key, p_Mask, &keyIndex);
35249 + if (GET_ERROR_TYPE(err) != E_OK)
35250 + {
35251 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
35252 + RETURN_ERROR(MAJOR, err,
35253 + ("The received key and mask pair was not found in the "
35254 + "match table of the provided node"));
35255 + }
35256 +
35257 + ASSERT_COND(keyIndex < p_CcNode->numOfKeys);
35258 +
35259 + err = MatchTableGetKeyStatistics(p_CcNode, keyIndex, p_KeyStatistics);
35260 +
35261 + XX_UnlockIntrSpinlock(p_CcNode->h_Spinlock, intFlags);
35262 +
35263 + if (err != E_OK)
35264 + RETURN_ERROR(MAJOR, err, NO_MSG);
35265 +
35266 + return E_OK;
35267 +}
35268 +
35269 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
35270 + uint8_t keySize, uint8_t *p_Key,
35271 + uint8_t hashShift,
35272 + t_Handle *p_CcNodeBucketHandle,
35273 + uint8_t *p_BucketIndex,
35274 + uint16_t *p_LastIndex)
35275 +{
35276 + t_FmPcdCcNode *p_CcNode = (t_FmPcdCcNode *)h_CcNode;
35277 + uint16_t glblMask;
35278 + uint64_t crc64 = 0;
35279 +
35280 + SANITY_CHECK_RETURN_ERROR(h_CcNode, E_INVALID_HANDLE);
35281 + SANITY_CHECK_RETURN_ERROR(
35282 + p_CcNode->parseCode == CC_PC_GENERIC_IC_HASH_INDEXED,
35283 + E_INVALID_STATE);
35284 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35285 + SANITY_CHECK_RETURN_ERROR(p_CcNodeBucketHandle, E_NULL_POINTER);
35286 +
35287 + memcpy(&glblMask, PTR_MOVE(p_CcNode->p_GlblMask, 2), 2);
35288 + be16_to_cpus(&glblMask);
35289 +
35290 + crc64 = crc64_init();
35291 + crc64 = crc64_compute(p_Key, keySize, crc64);
35292 + crc64 >>= hashShift;
35293 +
35294 + *p_BucketIndex = (uint8_t)(((crc64 >> (8 * (6 - p_CcNode->userOffset)))
35295 + & glblMask) >> 4);
35296 + if (*p_BucketIndex >= p_CcNode->numOfKeys)
35297 + RETURN_ERROR(MINOR, E_NOT_IN_RANGE, ("bucket index!"));
35298 +
35299 + *p_CcNodeBucketHandle =
35300 + p_CcNode->keyAndNextEngineParams[*p_BucketIndex].nextEngineParams.params.ccParams.h_CcNode;
35301 + if (!*p_CcNodeBucketHandle)
35302 + RETURN_ERROR(MINOR, E_NOT_FOUND, ("bucket!"));
35303 +
35304 + *p_LastIndex = ((t_FmPcdCcNode *)*p_CcNodeBucketHandle)->numOfKeys;
35305 +
35306 + return E_OK;
35307 +}
35308 +
35309 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param)
35310 +{
35311 + t_FmPcdCcNode *p_CcNodeHashTbl;
35312 + t_FmPcdCcNodeParams *p_IndxHashCcNodeParam, *p_ExactMatchCcNodeParam;
35313 + t_FmPcdCcNode *p_CcNode;
35314 + t_Handle h_MissStatsCounters = NULL;
35315 + t_FmPcdCcKeyParams *p_HashKeyParams;
35316 + int i;
35317 + uint16_t numOfSets, numOfWays, countMask, onesCount = 0;
35318 + bool statsEnForMiss = FALSE;
35319 + t_Error err;
35320 +
35321 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
35322 + SANITY_CHECK_RETURN_VALUE(p_Param, E_NULL_POINTER, NULL);
35323 +
35324 + if (p_Param->maxNumOfKeys == 0)
35325 + {
35326 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Max number of keys must be higher then 0"));
35327 + return NULL;
35328 + }
35329 +
35330 + if (p_Param->hashResMask == 0)
35331 + {
35332 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("Hash result mask must differ from 0"));
35333 + return NULL;
35334 + }
35335 +
35336 + /*Fix: QorIQ SDK / QSDK-2131*/
35337 + if (p_Param->ccNextEngineParamsForMiss.nextEngine == e_FM_PCD_INVALID)
35338 + {
35339 + 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."));
35340 + return NULL;
35341 + }
35342 +
35343 +#if (DPAA_VERSION >= 11)
35344 + if (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_RMON)
35345 + {
35346 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
35347 + ("RMON statistics mode is not supported for hash table"));
35348 + return NULL;
35349 + }
35350 +#endif /* (DPAA_VERSION >= 11) */
35351 +
35352 + p_ExactMatchCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
35353 + sizeof(t_FmPcdCcNodeParams));
35354 + if (!p_ExactMatchCcNodeParam)
35355 + {
35356 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_ExactMatchCcNodeParam"));
35357 + return NULL;
35358 + }
35359 + memset(p_ExactMatchCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
35360 +
35361 + p_IndxHashCcNodeParam = (t_FmPcdCcNodeParams*)XX_Malloc(
35362 + sizeof(t_FmPcdCcNodeParams));
35363 + if (!p_IndxHashCcNodeParam)
35364 + {
35365 + XX_Free(p_ExactMatchCcNodeParam);
35366 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_IndxHashCcNodeParam"));
35367 + return NULL;
35368 + }
35369 + memset(p_IndxHashCcNodeParam, 0, sizeof(t_FmPcdCcNodeParams));
35370 +
35371 + /* Calculate number of sets and number of ways of the hash table */
35372 + countMask = (uint16_t)(p_Param->hashResMask >> 4);
35373 + while (countMask)
35374 + {
35375 + onesCount++;
35376 + countMask = (uint16_t)(countMask >> 1);
35377 + }
35378 +
35379 + numOfSets = (uint16_t)(1 << onesCount);
35380 + numOfWays = (uint16_t)DIV_CEIL(p_Param->maxNumOfKeys, numOfSets);
35381 +
35382 + if (p_Param->maxNumOfKeys % numOfSets)
35383 + DBG(INFO, ("'maxNumOfKeys' is not a multiple of hash number of ways, so number of ways will be rounded up"));
35384 +
35385 + if ((p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_FRAME)
35386 + || (p_Param->statisticsMode == e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME))
35387 + {
35388 + /* Allocating a statistics counters table that will be used by all
35389 + 'miss' entries of the hash table */
35390 + h_MissStatsCounters = (t_Handle)FM_MURAM_AllocMem(
35391 + FmPcdGetMuramHandle(h_FmPcd), 2 * FM_PCD_CC_STATS_COUNTER_SIZE,
35392 + FM_PCD_CC_AD_TABLE_ALIGN);
35393 + if (!h_MissStatsCounters)
35394 + {
35395 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for statistics table for hash miss"));
35396 + XX_Free(p_IndxHashCcNodeParam);
35397 + XX_Free(p_ExactMatchCcNodeParam);
35398 + return NULL;
35399 + }
35400 + memset(h_MissStatsCounters, 0, (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
35401 +
35402 + /* Always enable statistics for 'miss', so that a statistics AD will be
35403 + initialized from the start. We'll store the requested 'statistics enable'
35404 + value and it will be used when statistics are read by the user. */
35405 + statsEnForMiss = p_Param->ccNextEngineParamsForMiss.statisticsEn;
35406 + p_Param->ccNextEngineParamsForMiss.statisticsEn = TRUE;
35407 + }
35408 +
35409 + /* Building exact-match node params, will be used to create the hash buckets */
35410 + p_ExactMatchCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
35411 +
35412 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.src =
35413 + e_FM_PCD_EXTRACT_FROM_KEY;
35414 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.action =
35415 + e_FM_PCD_ACTION_EXACT_MATCH;
35416 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.offset = 0;
35417 + p_ExactMatchCcNodeParam->extractCcParams.extractNonHdr.size =
35418 + p_Param->matchKeySize;
35419 +
35420 + p_ExactMatchCcNodeParam->keysParams.maxNumOfKeys = numOfWays;
35421 + p_ExactMatchCcNodeParam->keysParams.maskSupport = FALSE;
35422 + p_ExactMatchCcNodeParam->keysParams.statisticsMode =
35423 + p_Param->statisticsMode;
35424 + p_ExactMatchCcNodeParam->keysParams.numOfKeys = 0;
35425 + p_ExactMatchCcNodeParam->keysParams.keySize = p_Param->matchKeySize;
35426 + p_ExactMatchCcNodeParam->keysParams.ccNextEngineParamsForMiss =
35427 + p_Param->ccNextEngineParamsForMiss;
35428 +
35429 + p_HashKeyParams = p_IndxHashCcNodeParam->keysParams.keyParams;
35430 +
35431 + for (i = 0; i < numOfSets; i++)
35432 + {
35433 + /* Each exact-match node will be marked as a 'bucket' and provided with
35434 + a pointer to statistics counters, to be used for 'miss' entry
35435 + statistics */
35436 + p_CcNode = (t_FmPcdCcNode *)XX_Malloc(sizeof(t_FmPcdCcNode));
35437 + if (!p_CcNode)
35438 + break;
35439 + memset(p_CcNode, 0, sizeof(t_FmPcdCcNode));
35440 +
35441 + p_CcNode->isHashBucket = TRUE;
35442 + p_CcNode->h_MissStatsCounters = h_MissStatsCounters;
35443 +
35444 + err = MatchTableSet(h_FmPcd, p_CcNode, p_ExactMatchCcNodeParam);
35445 + if (err)
35446 + break;
35447 +
35448 + p_HashKeyParams[i].ccNextEngineParams.nextEngine = e_FM_PCD_CC;
35449 + p_HashKeyParams[i].ccNextEngineParams.statisticsEn = FALSE;
35450 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode =
35451 + p_CcNode;
35452 + }
35453 +
35454 + if (i < numOfSets)
35455 + {
35456 + for (i = i - 1; i >= 0; i--)
35457 + FM_PCD_MatchTableDelete(
35458 + p_HashKeyParams[i].ccNextEngineParams.params.ccParams.h_CcNode);
35459 +
35460 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
35461 +
35462 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
35463 + XX_Free(p_IndxHashCcNodeParam);
35464 + XX_Free(p_ExactMatchCcNodeParam);
35465 + return NULL;
35466 + }
35467 +
35468 + /* Creating indexed-hash CC node */
35469 + p_IndxHashCcNodeParam->extractCcParams.type = e_FM_PCD_EXTRACT_NON_HDR;
35470 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.src =
35471 + e_FM_PCD_EXTRACT_FROM_HASH;
35472 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.action =
35473 + e_FM_PCD_ACTION_INDEXED_LOOKUP;
35474 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.icIndxMask =
35475 + p_Param->hashResMask;
35476 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.offset =
35477 + p_Param->hashShift;
35478 + p_IndxHashCcNodeParam->extractCcParams.extractNonHdr.size = 2;
35479 +
35480 + p_IndxHashCcNodeParam->keysParams.maxNumOfKeys = numOfSets;
35481 + p_IndxHashCcNodeParam->keysParams.maskSupport = FALSE;
35482 + p_IndxHashCcNodeParam->keysParams.statisticsMode =
35483 + e_FM_PCD_CC_STATS_MODE_NONE;
35484 + /* Number of keys of this node is number of sets of the hash */
35485 + p_IndxHashCcNodeParam->keysParams.numOfKeys = numOfSets;
35486 + p_IndxHashCcNodeParam->keysParams.keySize = 2;
35487 +
35488 + p_CcNodeHashTbl = FM_PCD_MatchTableSet(h_FmPcd, p_IndxHashCcNodeParam);
35489 +
35490 + if (p_CcNodeHashTbl)
35491 + {
35492 + p_CcNodeHashTbl->kgHashShift = p_Param->kgHashShift;
35493 +
35494 + /* Storing the allocated counters for buckets 'miss' in the hash table
35495 + and if statistics for miss were enabled. */
35496 + p_CcNodeHashTbl->h_MissStatsCounters = h_MissStatsCounters;
35497 + p_CcNodeHashTbl->statsEnForMiss = statsEnForMiss;
35498 + }
35499 +
35500 + XX_Free(p_IndxHashCcNodeParam);
35501 + XX_Free(p_ExactMatchCcNodeParam);
35502 +
35503 + return p_CcNodeHashTbl;
35504 +}
35505 +
35506 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl)
35507 +{
35508 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35509 + t_Handle h_FmPcd;
35510 + t_Handle *p_HashBuckets, h_MissStatsCounters;
35511 + uint16_t i, numOfBuckets;
35512 + t_Error err;
35513 +
35514 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35515 +
35516 + /* Store all hash buckets before the hash is freed */
35517 + numOfBuckets = p_HashTbl->numOfKeys;
35518 +
35519 + p_HashBuckets = (t_Handle *)XX_Malloc(numOfBuckets * sizeof(t_Handle));
35520 + if (!p_HashBuckets)
35521 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
35522 +
35523 + for (i = 0; i < numOfBuckets; i++)
35524 + p_HashBuckets[i] =
35525 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
35526 +
35527 + h_FmPcd = p_HashTbl->h_FmPcd;
35528 + h_MissStatsCounters = p_HashTbl->h_MissStatsCounters;
35529 +
35530 + /* Free the hash */
35531 + err = FM_PCD_MatchTableDelete(p_HashTbl);
35532 +
35533 + /* Free each hash bucket */
35534 + for (i = 0; i < numOfBuckets; i++)
35535 + err |= FM_PCD_MatchTableDelete(p_HashBuckets[i]);
35536 +
35537 + XX_Free(p_HashBuckets);
35538 +
35539 + /* Free statistics counters for 'miss', if these were allocated */
35540 + if (h_MissStatsCounters)
35541 + FM_MURAM_FreeMem(FmPcdGetMuramHandle(h_FmPcd), h_MissStatsCounters);
35542 +
35543 + if (err)
35544 + RETURN_ERROR(MAJOR, err, NO_MSG);
35545 +
35546 + return E_OK;
35547 +}
35548 +
35549 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl, uint8_t keySize,
35550 + t_FmPcdCcKeyParams *p_KeyParams)
35551 +{
35552 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35553 + t_Handle h_HashBucket;
35554 + uint8_t bucketIndex;
35555 + uint16_t lastIndex;
35556 + t_Error err;
35557 +
35558 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35559 + SANITY_CHECK_RETURN_ERROR(p_KeyParams, E_NULL_POINTER);
35560 + SANITY_CHECK_RETURN_ERROR(p_KeyParams->p_Key, E_NULL_POINTER);
35561 +
35562 + if (p_KeyParams->p_Mask)
35563 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
35564 + ("Keys masks not supported for hash table"));
35565 +
35566 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize,
35567 + p_KeyParams->p_Key,
35568 + p_HashTbl->kgHashShift,
35569 + &h_HashBucket, &bucketIndex,
35570 + &lastIndex);
35571 + if (err)
35572 + RETURN_ERROR(MAJOR, err, NO_MSG);
35573 +
35574 + return FM_PCD_MatchTableAddKey(h_HashBucket, FM_PCD_LAST_KEY_INDEX, keySize,
35575 + p_KeyParams);
35576 +}
35577 +
35578 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl, uint8_t keySize,
35579 + uint8_t *p_Key)
35580 +{
35581 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35582 + t_Handle h_HashBucket;
35583 + uint8_t bucketIndex;
35584 + uint16_t lastIndex;
35585 + t_Error err;
35586 +
35587 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35588 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35589 +
35590 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
35591 + p_HashTbl->kgHashShift,
35592 + &h_HashBucket, &bucketIndex,
35593 + &lastIndex);
35594 + if (err)
35595 + RETURN_ERROR(MAJOR, err, NO_MSG);
35596 +
35597 + return FM_PCD_MatchTableFindNRemoveKey(h_HashBucket, keySize, p_Key, NULL);
35598 +}
35599 +
35600 +t_Error FM_PCD_HashTableModifyNextEngine(
35601 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
35602 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
35603 +{
35604 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35605 + t_Handle h_HashBucket;
35606 + uint8_t bucketIndex;
35607 + uint16_t lastIndex;
35608 + t_Error err;
35609 +
35610 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35611 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35612 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
35613 +
35614 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
35615 + p_HashTbl->kgHashShift,
35616 + &h_HashBucket, &bucketIndex,
35617 + &lastIndex);
35618 + if (err)
35619 + RETURN_ERROR(MAJOR, err, NO_MSG);
35620 +
35621 + return FM_PCD_MatchTableFindNModifyNextEngine(h_HashBucket, keySize, p_Key,
35622 + NULL,
35623 + p_FmPcdCcNextEngineParams);
35624 +}
35625 +
35626 +t_Error FM_PCD_HashTableModifyMissNextEngine(
35627 + t_Handle h_HashTbl,
35628 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
35629 +{
35630 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35631 + t_Handle h_HashBucket;
35632 + uint8_t i;
35633 + bool nullifyMissStats = FALSE;
35634 + t_Error err;
35635 +
35636 + SANITY_CHECK_RETURN_ERROR(h_HashTbl, E_INVALID_HANDLE);
35637 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
35638 +
35639 + if ((!p_HashTbl->h_MissStatsCounters)
35640 + && (p_FmPcdCcNextEngineParams->statisticsEn))
35641 + RETURN_ERROR(
35642 + MAJOR,
35643 + E_CONFLICT,
35644 + ("Statistics are requested for a key, but statistics mode was set"
35645 + "to 'NONE' upon initialization"));
35646 +
35647 + if (p_HashTbl->h_MissStatsCounters)
35648 + {
35649 + if ((!p_HashTbl->statsEnForMiss)
35650 + && (p_FmPcdCcNextEngineParams->statisticsEn))
35651 + nullifyMissStats = TRUE;
35652 +
35653 + if ((p_HashTbl->statsEnForMiss)
35654 + && (!p_FmPcdCcNextEngineParams->statisticsEn))
35655 + {
35656 + p_HashTbl->statsEnForMiss = FALSE;
35657 + p_FmPcdCcNextEngineParams->statisticsEn = TRUE;
35658 + }
35659 + }
35660 +
35661 + for (i = 0; i < p_HashTbl->numOfKeys; i++)
35662 + {
35663 + h_HashBucket =
35664 + p_HashTbl->keyAndNextEngineParams[i].nextEngineParams.params.ccParams.h_CcNode;
35665 +
35666 + err = FM_PCD_MatchTableModifyMissNextEngine(h_HashBucket,
35667 + p_FmPcdCcNextEngineParams);
35668 + if (err)
35669 + RETURN_ERROR(MAJOR, err, NO_MSG);
35670 + }
35671 +
35672 + if (nullifyMissStats)
35673 + {
35674 + memset(p_HashTbl->h_MissStatsCounters, 0,
35675 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
35676 + memset(p_HashTbl->h_MissStatsCounters, 0,
35677 + (2 * FM_PCD_CC_STATS_COUNTER_SIZE));
35678 + p_HashTbl->statsEnForMiss = TRUE;
35679 + }
35680 +
35681 + return E_OK;
35682 +}
35683 +
35684 +
35685 +t_Error FM_PCD_HashTableGetMissNextEngine(
35686 + t_Handle h_HashTbl,
35687 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams)
35688 +{
35689 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35690 + t_FmPcdCcNode *p_HashBucket;
35691 +
35692 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35693 +
35694 + /* Miss next engine of each bucket was initialized with the next engine of the hash table */
35695 + p_HashBucket =
35696 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
35697 +
35698 + memcpy(p_FmPcdCcNextEngineParams,
35699 + &p_HashBucket->keyAndNextEngineParams[p_HashBucket->numOfKeys].nextEngineParams,
35700 + sizeof(t_FmPcdCcNextEngineParams));
35701 +
35702 + return E_OK;
35703 +}
35704 +
35705 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(
35706 + t_Handle h_HashTbl, uint8_t keySize, uint8_t *p_Key,
35707 + t_FmPcdCcKeyStatistics *p_KeyStatistics)
35708 +{
35709 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35710 + t_Handle h_HashBucket;
35711 + uint8_t bucketIndex;
35712 + uint16_t lastIndex;
35713 + t_Error err;
35714 +
35715 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35716 + SANITY_CHECK_RETURN_ERROR(p_Key, E_NULL_POINTER);
35717 + SANITY_CHECK_RETURN_ERROR(p_KeyStatistics, E_NULL_POINTER);
35718 +
35719 + err = FM_PCD_MatchTableGetIndexedHashBucket(p_HashTbl, keySize, p_Key,
35720 + p_HashTbl->kgHashShift,
35721 + &h_HashBucket, &bucketIndex,
35722 + &lastIndex);
35723 + if (err)
35724 + RETURN_ERROR(MAJOR, err, NO_MSG);
35725 +
35726 + return FM_PCD_MatchTableFindNGetKeyStatistics(h_HashBucket, keySize, p_Key,
35727 + NULL, p_KeyStatistics);
35728 +}
35729 +
35730 +t_Error FM_PCD_HashTableGetMissStatistics(
35731 + t_Handle h_HashTbl, t_FmPcdCcKeyStatistics *p_MissStatistics)
35732 +{
35733 + t_FmPcdCcNode *p_HashTbl = (t_FmPcdCcNode *)h_HashTbl;
35734 + t_Handle h_HashBucket;
35735 +
35736 + SANITY_CHECK_RETURN_ERROR(p_HashTbl, E_INVALID_HANDLE);
35737 + SANITY_CHECK_RETURN_ERROR(p_MissStatistics, E_NULL_POINTER);
35738 +
35739 + if (!p_HashTbl->statsEnForMiss)
35740 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
35741 + ("Statistics were not enabled for miss"));
35742 +
35743 + h_HashBucket =
35744 + p_HashTbl->keyAndNextEngineParams[0].nextEngineParams.params.ccParams.h_CcNode;
35745 +
35746 + return FM_PCD_MatchTableGetMissStatistics(h_HashBucket, p_MissStatistics);
35747 +}
35748 --- /dev/null
35749 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_cc.h
35750 @@ -0,0 +1,399 @@
35751 +/*
35752 + * Copyright 2008-2012 Freescale Semiconductor Inc.
35753 + *
35754 + * Redistribution and use in source and binary forms, with or without
35755 + * modification, are permitted provided that the following conditions are met:
35756 + * * Redistributions of source code must retain the above copyright
35757 + * notice, this list of conditions and the following disclaimer.
35758 + * * Redistributions in binary form must reproduce the above copyright
35759 + * notice, this list of conditions and the following disclaimer in the
35760 + * documentation and/or other materials provided with the distribution.
35761 + * * Neither the name of Freescale Semiconductor nor the
35762 + * names of its contributors may be used to endorse or promote products
35763 + * derived from this software without specific prior written permission.
35764 + *
35765 + *
35766 + * ALTERNATIVELY, this software may be distributed under the terms of the
35767 + * GNU General Public License ("GPL") as published by the Free Software
35768 + * Foundation, either version 2 of that License or (at your option) any
35769 + * later version.
35770 + *
35771 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
35772 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35773 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35774 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
35775 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35776 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35777 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35778 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35779 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35780 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35781 + */
35782 +
35783 +
35784 +/******************************************************************************
35785 + @File fm_cc.h
35786 +
35787 + @Description FM PCD CC ...
35788 +*//***************************************************************************/
35789 +#ifndef __FM_CC_H
35790 +#define __FM_CC_H
35791 +
35792 +#include "std_ext.h"
35793 +#include "error_ext.h"
35794 +#include "list_ext.h"
35795 +
35796 +#include "fm_pcd.h"
35797 +
35798 +
35799 +/***********************************************************************/
35800 +/* Coarse classification defines */
35801 +/***********************************************************************/
35802 +
35803 +#define CC_MAX_NUM_OF_KEYS (FM_PCD_MAX_NUM_OF_KEYS + 1)
35804 +
35805 +#define CC_PC_FF_MACDST 0x00
35806 +#define CC_PC_FF_MACSRC 0x01
35807 +#define CC_PC_FF_ETYPE 0x02
35808 +
35809 +#define CC_PC_FF_TCI1 0x03
35810 +#define CC_PC_FF_TCI2 0x04
35811 +
35812 +#define CC_PC_FF_MPLS1 0x06
35813 +#define CC_PC_FF_MPLS_LAST 0x07
35814 +
35815 +#define CC_PC_FF_IPV4DST1 0x08
35816 +#define CC_PC_FF_IPV4DST2 0x16
35817 +#define CC_PC_FF_IPV4IPTOS_TC1 0x09
35818 +#define CC_PC_FF_IPV4IPTOS_TC2 0x17
35819 +#define CC_PC_FF_IPV4PTYPE1 0x0A
35820 +#define CC_PC_FF_IPV4PTYPE2 0x18
35821 +#define CC_PC_FF_IPV4SRC1 0x0b
35822 +#define CC_PC_FF_IPV4SRC2 0x19
35823 +#define CC_PC_FF_IPV4SRC1_IPV4DST1 0x0c
35824 +#define CC_PC_FF_IPV4SRC2_IPV4DST2 0x1a
35825 +#define CC_PC_FF_IPV4TTL 0x29
35826 +
35827 +
35828 +#define CC_PC_FF_IPTOS_IPV6TC1_IPV6FLOW1 0x0d /*TODO - CLASS - what is it? TOS*/
35829 +#define CC_PC_FF_IPTOS_IPV6TC2_IPV6FLOW2 0x1b
35830 +#define CC_PC_FF_IPV6PTYPE1 0x0e
35831 +#define CC_PC_FF_IPV6PTYPE2 0x1c
35832 +#define CC_PC_FF_IPV6DST1 0x0f
35833 +#define CC_PC_FF_IPV6DST2 0x1d
35834 +#define CC_PC_FF_IPV6SRC1 0x10
35835 +#define CC_PC_FF_IPV6SRC2 0x1e
35836 +#define CC_PC_FF_IPV6HOP_LIMIT 0x2a
35837 +#define CC_PC_FF_IPPID 0x24
35838 +#define CC_PC_FF_IPDSCP 0x76
35839 +
35840 +#define CC_PC_FF_GREPTYPE 0x11
35841 +
35842 +#define CC_PC_FF_MINENCAP_PTYPE 0x12
35843 +#define CC_PC_FF_MINENCAP_IPDST 0x13
35844 +#define CC_PC_FF_MINENCAP_IPSRC 0x14
35845 +#define CC_PC_FF_MINENCAP_IPSRC_IPDST 0x15
35846 +
35847 +#define CC_PC_FF_L4PSRC 0x1f
35848 +#define CC_PC_FF_L4PDST 0x20
35849 +#define CC_PC_FF_L4PSRC_L4PDST 0x21
35850 +
35851 +#define CC_PC_FF_PPPPID 0x05
35852 +
35853 +#define CC_PC_PR_SHIM1 0x22
35854 +#define CC_PC_PR_SHIM2 0x23
35855 +
35856 +#define CC_PC_GENERIC_WITHOUT_MASK 0x27
35857 +#define CC_PC_GENERIC_WITH_MASK 0x28
35858 +#define CC_PC_GENERIC_IC_GMASK 0x2B
35859 +#define CC_PC_GENERIC_IC_HASH_INDEXED 0x2C
35860 +#define CC_PC_GENERIC_IC_AGING_MASK 0x2D
35861 +
35862 +#define CC_PR_OFFSET 0x25
35863 +#define CC_PR_WITHOUT_OFFSET 0x26
35864 +
35865 +#define CC_PC_PR_ETH_OFFSET 19
35866 +#define CC_PC_PR_USER_DEFINED_SHIM1_OFFSET 16
35867 +#define CC_PC_PR_USER_DEFINED_SHIM2_OFFSET 17
35868 +#define CC_PC_PR_USER_LLC_SNAP_OFFSET 20
35869 +#define CC_PC_PR_VLAN1_OFFSET 21
35870 +#define CC_PC_PR_VLAN2_OFFSET 22
35871 +#define CC_PC_PR_PPPOE_OFFSET 24
35872 +#define CC_PC_PR_MPLS1_OFFSET 25
35873 +#define CC_PC_PR_MPLS_LAST_OFFSET 26
35874 +#define CC_PC_PR_IP1_OFFSET 27
35875 +#define CC_PC_PR_IP_LAST_OFFSET 28
35876 +#define CC_PC_PR_MINENC_OFFSET 28
35877 +#define CC_PC_PR_L4_OFFSET 30
35878 +#define CC_PC_PR_GRE_OFFSET 29
35879 +#define CC_PC_PR_ETYPE_LAST_OFFSET 23
35880 +#define CC_PC_PR_NEXT_HEADER_OFFSET 31
35881 +
35882 +#define CC_PC_ILLEGAL 0xff
35883 +#define CC_SIZE_ILLEGAL 0
35884 +
35885 +#define FM_PCD_CC_KEYS_MATCH_TABLE_ALIGN 16
35886 +#define FM_PCD_CC_AD_TABLE_ALIGN 16
35887 +#define FM_PCD_CC_AD_ENTRY_SIZE 16
35888 +#define FM_PCD_CC_NUM_OF_KEYS 255
35889 +#define FM_PCD_CC_TREE_ADDR_ALIGN 256
35890 +
35891 +#define FM_PCD_AD_RESULT_CONTRL_FLOW_TYPE 0x00000000
35892 +#define FM_PCD_AD_RESULT_DATA_FLOW_TYPE 0x80000000
35893 +#define FM_PCD_AD_RESULT_PLCR_DIS 0x20000000
35894 +#define FM_PCD_AD_RESULT_EXTENDED_MODE 0x80000000
35895 +#define FM_PCD_AD_RESULT_NADEN 0x20000000
35896 +#define FM_PCD_AD_RESULT_STATISTICS_EN 0x40000000
35897 +
35898 +#define FM_PCD_AD_CONT_LOOKUP_TYPE 0x40000000
35899 +#define FM_PCD_AD_CONT_LOOKUP_LCL_MASK 0x00800000
35900 +
35901 +#define FM_PCD_AD_STATS_TYPE 0x40000000
35902 +#define FM_PCD_AD_STATS_FLR_ADDR_MASK 0x00FFFFFF
35903 +#define FM_PCD_AD_STATS_COUNTERS_ADDR_MASK 0x00FFFFFF
35904 +#define FM_PCD_AD_STATS_NEXT_ACTION_MASK 0xFFFF0000
35905 +#define FM_PCD_AD_STATS_NEXT_ACTION_SHIFT 12
35906 +#define FM_PCD_AD_STATS_NAD_EN 0x00008000
35907 +#define FM_PCD_AD_STATS_OP_CODE 0x00000036
35908 +#define FM_PCD_AD_STATS_FLR_EN 0x00004000
35909 +#define FM_PCD_AD_STATS_COND_EN 0x00002000
35910 +
35911 +
35912 +
35913 +#define FM_PCD_AD_BYPASS_TYPE 0xc0000000
35914 +
35915 +#define FM_PCD_AD_TYPE_MASK 0xc0000000
35916 +#define FM_PCD_AD_OPCODE_MASK 0x0000000f
35917 +
35918 +#define FM_PCD_AD_PROFILEID_FOR_CNTRL_SHIFT 16
35919 +#if (DPAA_VERSION >= 11)
35920 +#define FM_PCD_AD_RESULT_VSP_SHIFT 24
35921 +#define FM_PCD_AD_RESULT_NO_OM_VSPE 0x02000000
35922 +#define FM_PCD_AD_RESULT_VSP_MASK 0x3f
35923 +#define FM_PCD_AD_NCSPFQIDM_MASK 0x80000000
35924 +#endif /* (DPAA_VERSION >= 11) */
35925 +
35926 +#define GLBL_MASK_FOR_HASH_INDEXED 0xfff00000
35927 +#define CC_GLBL_MASK_SIZE 4
35928 +#define CC_AGING_MASK_SIZE 4
35929 +
35930 +typedef uint32_t ccPrivateInfo_t; /**< private info of CC: */
35931 +
35932 +#define CC_PRIVATE_INFO_NONE 0
35933 +#define CC_PRIVATE_INFO_IC_HASH_INDEX_LOOKUP 0x80000000
35934 +#define CC_PRIVATE_INFO_IC_HASH_EXACT_MATCH 0x40000000
35935 +#define CC_PRIVATE_INFO_IC_KEY_EXACT_MATCH 0x20000000
35936 +#define CC_PRIVATE_INFO_IC_DEQ_FQID_INDEX_LOOKUP 0x10000000
35937 +
35938 +#define CC_BUILD_AGING_MASK(numOfKeys) ((((1LL << ((numOfKeys) + 1)) - 1)) << (31 - (numOfKeys)))
35939 +/***********************************************************************/
35940 +/* Memory map */
35941 +/***********************************************************************/
35942 +#if defined(__MWERKS__) && !defined(__GNUC__)
35943 +#pragma pack(push,1)
35944 +#endif /* defined(__MWERKS__) && ... */
35945 +
35946 +typedef struct
35947 +{
35948 + volatile uint32_t fqid;
35949 + volatile uint32_t plcrProfile;
35950 + volatile uint32_t nia;
35951 + volatile uint32_t res;
35952 +} t_AdOfTypeResult;
35953 +
35954 +typedef struct
35955 +{
35956 + volatile uint32_t ccAdBase;
35957 + volatile uint32_t matchTblPtr;
35958 + volatile uint32_t pcAndOffsets;
35959 + volatile uint32_t gmask;
35960 +} t_AdOfTypeContLookup;
35961 +
35962 +typedef struct
35963 +{
35964 + volatile uint32_t profileTableAddr;
35965 + volatile uint32_t reserved;
35966 + volatile uint32_t nextActionIndx;
35967 + volatile uint32_t statsTableAddr;
35968 +} t_AdOfTypeStats;
35969 +
35970 +typedef union
35971 +{
35972 + volatile t_AdOfTypeResult adResult;
35973 + volatile t_AdOfTypeContLookup adContLookup;
35974 +} t_Ad;
35975 +
35976 +#if defined(__MWERKS__) && !defined(__GNUC__)
35977 +#pragma pack(pop)
35978 +#endif /* defined(__MWERKS__) && ... */
35979 +
35980 +
35981 +/***********************************************************************/
35982 +/* Driver's internal structures */
35983 +/***********************************************************************/
35984 +
35985 +typedef struct t_FmPcdStatsObj
35986 +{
35987 + t_Handle h_StatsAd;
35988 + t_Handle h_StatsCounters;
35989 + t_List node;
35990 +} t_FmPcdStatsObj;
35991 +
35992 +typedef struct
35993 +{
35994 + uint8_t key[FM_PCD_MAX_SIZE_OF_KEY];
35995 + uint8_t mask[FM_PCD_MAX_SIZE_OF_KEY];
35996 +
35997 + t_FmPcdCcNextEngineParams nextEngineParams;
35998 + uint32_t requiredAction;
35999 + uint32_t shadowAction;
36000 +
36001 + t_FmPcdStatsObj *p_StatsObj;
36002 +
36003 +} t_FmPcdCcKeyAndNextEngineParams;
36004 +
36005 +typedef struct
36006 +{
36007 + t_Handle p_Ad;
36008 + e_FmPcdEngine fmPcdEngine;
36009 + bool adAllocated;
36010 + bool isTree;
36011 +
36012 + uint32_t myInfo;
36013 + t_List *h_CcNextNodesLst;
36014 + t_Handle h_AdditionalInfo;
36015 + t_Handle h_Node;
36016 +} t_FmPcdModifyCcAdditionalParams;
36017 +
36018 +typedef struct
36019 +{
36020 + t_Handle p_AdTableNew;
36021 + t_Handle p_KeysMatchTableNew;
36022 + t_Handle p_AdTableOld;
36023 + t_Handle p_KeysMatchTableOld;
36024 + uint16_t numOfKeys;
36025 + t_Handle h_CurrentNode;
36026 + uint16_t savedKeyIndex;
36027 + t_Handle h_NodeForAdd;
36028 + t_Handle h_NodeForRmv;
36029 + t_Handle h_ManipForRmv;
36030 + t_Handle h_ManipForAdd;
36031 + t_FmPcdStatsObj *p_StatsObjForRmv;
36032 +#if (DPAA_VERSION >= 11)
36033 + t_Handle h_FrmReplicForAdd;
36034 + t_Handle h_FrmReplicForRmv;
36035 +#endif /* (DPAA_VERSION >= 11) */
36036 + bool tree;
36037 +
36038 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
36039 +} t_FmPcdModifyCcKeyAdditionalParams;
36040 +
36041 +typedef struct
36042 +{
36043 + t_Handle h_Manip;
36044 + t_Handle h_CcNode;
36045 +} t_CcNextEngineInfo;
36046 +
36047 +typedef struct
36048 +{
36049 + uint16_t numOfKeys;
36050 + uint16_t maxNumOfKeys;
36051 +
36052 + bool maskSupport;
36053 + uint32_t keysMatchTableMaxSize;
36054 +
36055 + e_FmPcdCcStatsMode statisticsMode;
36056 + uint32_t numOfStatsFLRs;
36057 + uint32_t countersArraySize;
36058 +
36059 + bool isHashBucket; /**< Valid for match table node that is a bucket of a hash table only */
36060 + t_Handle h_MissStatsCounters; /**< Valid for hash table node and match table that is a bucket;
36061 + Holds the statistics counters allocated by the hash table and
36062 + are shared by all hash table buckets; */
36063 + t_Handle h_PrivMissStatsCounters; /**< Valid for match table node that is a bucket of a hash table only;
36064 + Holds the statistics counters that were allocated for this node
36065 + and replaced by the shared counters (allocated by the hash table); */
36066 + bool statsEnForMiss; /**< Valid for hash table node only; TRUE is statistics are currently
36067 + enabled for hash 'miss', FALSE otherwise; This parameter effects the
36068 + returned statistics count to user, statistics AD always present for 'miss'
36069 + for all hash buckets; */
36070 + bool glblMaskUpdated;
36071 + t_Handle p_GlblMask;
36072 + bool lclMask;
36073 + uint8_t parseCode;
36074 + uint8_t offset;
36075 + uint8_t prsArrayOffset;
36076 + bool ctrlFlow;
36077 + uint16_t owners;
36078 +
36079 + uint8_t ccKeySizeAccExtraction;
36080 + uint8_t sizeOfExtraction;
36081 + uint8_t glblMaskSize;
36082 +
36083 + t_Handle h_KeysMatchTable;
36084 + t_Handle h_AdTable;
36085 + t_Handle h_StatsAds;
36086 + t_Handle h_TmpAd;
36087 + t_Handle h_Ad;
36088 + t_Handle h_StatsFLRs;
36089 +
36090 + t_List availableStatsLst;
36091 +
36092 + t_List ccPrevNodesLst;
36093 +
36094 + t_List ccTreeIdLst;
36095 + t_List ccTreesLst;
36096 +
36097 + t_Handle h_FmPcd;
36098 + uint32_t shadowAction;
36099 + uint8_t userSizeOfExtraction;
36100 + uint8_t userOffset;
36101 + uint8_t kgHashShift; /* used in hash-table */
36102 +
36103 + t_Handle h_Spinlock;
36104 +
36105 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[CC_MAX_NUM_OF_KEYS];
36106 +} t_FmPcdCcNode;
36107 +
36108 +typedef struct
36109 +{
36110 + t_FmPcdCcNode *p_FmPcdCcNode;
36111 + bool occupied;
36112 + uint16_t owners;
36113 + volatile bool lock;
36114 +} t_FmPcdCcNodeArray;
36115 +
36116 +typedef struct
36117 +{
36118 + uint8_t numOfEntriesInGroup;
36119 + uint32_t totalBitsMask;
36120 + uint8_t baseGroupEntry;
36121 +} t_FmPcdCcGroupParam;
36122 +
36123 +typedef struct
36124 +{
36125 + t_Handle h_FmPcd;
36126 + uint8_t netEnvId;
36127 + uintptr_t ccTreeBaseAddr;
36128 + uint8_t numOfGrps;
36129 + t_FmPcdCcGroupParam fmPcdGroupParam[FM_PCD_MAX_NUM_OF_CC_GROUPS];
36130 + t_List fmPortsLst;
36131 + t_FmPcdLock *p_Lock;
36132 + uint8_t numOfEntries;
36133 + uint16_t owners;
36134 + t_Handle h_FmPcdCcSavedManipParams;
36135 + bool modifiedState;
36136 + uint32_t requiredAction;
36137 + t_Handle h_IpReassemblyManip;
36138 + t_Handle h_CapwapReassemblyManip;
36139 +
36140 + t_FmPcdCcKeyAndNextEngineParams keyAndNextEngineParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
36141 +} t_FmPcdCcTree;
36142 +
36143 +
36144 +t_Error FmPcdCcNodeTreeTryLock(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_List *p_List);
36145 +void FmPcdCcNodeTreeReleaseLock(t_Handle h_FmPcd, t_List *p_List);
36146 +t_Error FmPcdUpdateCcShadow (t_FmPcd *p_FmPcd, uint32_t size, uint32_t align);
36147 +
36148 +
36149 +#endif /* __FM_CC_H */
36150 --- /dev/null
36151 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.c
36152 @@ -0,0 +1,3242 @@
36153 +/*
36154 + * Copyright 2008-2012 Freescale Semiconductor Inc.
36155 + *
36156 + * Redistribution and use in source and binary forms, with or without
36157 + * modification, are permitted provided that the following conditions are met:
36158 + * * Redistributions of source code must retain the above copyright
36159 + * notice, this list of conditions and the following disclaimer.
36160 + * * Redistributions in binary form must reproduce the above copyright
36161 + * notice, this list of conditions and the following disclaimer in the
36162 + * documentation and/or other materials provided with the distribution.
36163 + * * Neither the name of Freescale Semiconductor nor the
36164 + * names of its contributors may be used to endorse or promote products
36165 + * derived from this software without specific prior written permission.
36166 + *
36167 + *
36168 + * ALTERNATIVELY, this software may be distributed under the terms of the
36169 + * GNU General Public License ("GPL") as published by the Free Software
36170 + * Foundation, either version 2 of that License or (at your option) any
36171 + * later version.
36172 + *
36173 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
36174 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
36175 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36176 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
36177 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36178 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36179 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36180 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36181 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36182 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36183 + */
36184 +
36185 +
36186 +/******************************************************************************
36187 + @File fm_kg.c
36188 +
36189 + @Description FM PCD ...
36190 +*//***************************************************************************/
36191 +#include "std_ext.h"
36192 +#include "error_ext.h"
36193 +#include "string_ext.h"
36194 +#include "debug_ext.h"
36195 +#include "net_ext.h"
36196 +#include "fm_port_ext.h"
36197 +
36198 +#include "fm_common.h"
36199 +#include "fm_pcd.h"
36200 +#include "fm_hc.h"
36201 +#include "fm_pcd_ipc.h"
36202 +#include "fm_kg.h"
36203 +#include "fsl_fman_kg.h"
36204 +
36205 +
36206 +/****************************************/
36207 +/* static functions */
36208 +/****************************************/
36209 +
36210 +static uint32_t KgHwLock(t_Handle h_FmPcdKg)
36211 +{
36212 + ASSERT_COND(h_FmPcdKg);
36213 + return XX_LockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock);
36214 +}
36215 +
36216 +static void KgHwUnlock(t_Handle h_FmPcdKg, uint32_t intFlags)
36217 +{
36218 + ASSERT_COND(h_FmPcdKg);
36219 + XX_UnlockIntrSpinlock(((t_FmPcdKg *)h_FmPcdKg)->h_HwSpinlock, intFlags);
36220 +}
36221 +
36222 +static uint32_t KgSchemeLock(t_Handle h_Scheme)
36223 +{
36224 + ASSERT_COND(h_Scheme);
36225 + return FmPcdLockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
36226 +}
36227 +
36228 +static void KgSchemeUnlock(t_Handle h_Scheme, uint32_t intFlags)
36229 +{
36230 + ASSERT_COND(h_Scheme);
36231 + FmPcdUnlockSpinlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock, intFlags);
36232 +}
36233 +
36234 +static bool KgSchemeFlagTryLock(t_Handle h_Scheme)
36235 +{
36236 + ASSERT_COND(h_Scheme);
36237 + return FmPcdLockTryLock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
36238 +}
36239 +
36240 +static void KgSchemeFlagUnlock(t_Handle h_Scheme)
36241 +{
36242 + ASSERT_COND(h_Scheme);
36243 + FmPcdLockUnlock(((t_FmPcdKgScheme *)h_Scheme)->p_Lock);
36244 +}
36245 +
36246 +static t_Error WriteKgarWait(t_FmPcd *p_FmPcd, uint32_t fmkg_ar)
36247 +{
36248 +
36249 + struct fman_kg_regs *regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36250 +
36251 + if (fman_kg_write_ar_wait(regs, fmkg_ar))
36252 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Keygen scheme access violation"));
36253 +
36254 + return E_OK;
36255 +}
36256 +
36257 +static e_FmPcdKgExtractDfltSelect GetGenericSwDefault(t_FmPcdKgExtractDflt swDefaults[], uint8_t numOfSwDefaults, uint8_t code)
36258 +{
36259 + int i;
36260 +
36261 + switch (code)
36262 + {
36263 + case (KG_SCH_GEN_PARSE_RESULT_N_FQID):
36264 + case (KG_SCH_GEN_DEFAULT):
36265 + case (KG_SCH_GEN_NEXTHDR):
36266 + for (i=0 ; i<numOfSwDefaults ; i++)
36267 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_NOT_FROM_DATA)
36268 + return swDefaults[i].dfltSelect;
36269 + break;
36270 + case (KG_SCH_GEN_SHIM1):
36271 + case (KG_SCH_GEN_SHIM2):
36272 + case (KG_SCH_GEN_IP_PID_NO_V):
36273 + case (KG_SCH_GEN_ETH_NO_V):
36274 + case (KG_SCH_GEN_SNAP_NO_V):
36275 + case (KG_SCH_GEN_VLAN1_NO_V):
36276 + case (KG_SCH_GEN_VLAN2_NO_V):
36277 + case (KG_SCH_GEN_ETH_TYPE_NO_V):
36278 + case (KG_SCH_GEN_PPP_NO_V):
36279 + case (KG_SCH_GEN_MPLS1_NO_V):
36280 + case (KG_SCH_GEN_MPLS_LAST_NO_V):
36281 + case (KG_SCH_GEN_L3_NO_V):
36282 + case (KG_SCH_GEN_IP2_NO_V):
36283 + case (KG_SCH_GEN_GRE_NO_V):
36284 + case (KG_SCH_GEN_L4_NO_V):
36285 + for (i=0 ; i<numOfSwDefaults ; i++)
36286 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V)
36287 + return swDefaults[i].dfltSelect;
36288 + break;
36289 + case (KG_SCH_GEN_START_OF_FRM):
36290 + case (KG_SCH_GEN_ETH):
36291 + case (KG_SCH_GEN_SNAP):
36292 + case (KG_SCH_GEN_VLAN1):
36293 + case (KG_SCH_GEN_VLAN2):
36294 + case (KG_SCH_GEN_ETH_TYPE):
36295 + case (KG_SCH_GEN_PPP):
36296 + case (KG_SCH_GEN_MPLS1):
36297 + case (KG_SCH_GEN_MPLS2):
36298 + case (KG_SCH_GEN_MPLS3):
36299 + case (KG_SCH_GEN_MPLS_LAST):
36300 + case (KG_SCH_GEN_IPV4):
36301 + case (KG_SCH_GEN_IPV6):
36302 + case (KG_SCH_GEN_IPV4_TUNNELED):
36303 + case (KG_SCH_GEN_IPV6_TUNNELED):
36304 + case (KG_SCH_GEN_MIN_ENCAP):
36305 + case (KG_SCH_GEN_GRE):
36306 + case (KG_SCH_GEN_TCP):
36307 + case (KG_SCH_GEN_UDP):
36308 + case (KG_SCH_GEN_IPSEC_AH):
36309 + case (KG_SCH_GEN_SCTP):
36310 + case (KG_SCH_GEN_DCCP):
36311 + case (KG_SCH_GEN_IPSEC_ESP):
36312 + for (i=0 ; i<numOfSwDefaults ; i++)
36313 + if (swDefaults[i].type == e_FM_PCD_KG_GENERIC_FROM_DATA)
36314 + return swDefaults[i].dfltSelect;
36315 + break;
36316 + default:
36317 + break;
36318 + }
36319 +
36320 + return e_FM_PCD_KG_DFLT_ILLEGAL;
36321 +}
36322 +
36323 +static uint8_t GetGenCode(e_FmPcdExtractFrom src, uint8_t *p_Offset)
36324 +{
36325 + *p_Offset = 0;
36326 +
36327 + switch (src)
36328 + {
36329 + case (e_FM_PCD_EXTRACT_FROM_FRAME_START):
36330 + return KG_SCH_GEN_START_OF_FRM;
36331 + case (e_FM_PCD_EXTRACT_FROM_DFLT_VALUE):
36332 + return KG_SCH_GEN_DEFAULT;
36333 + case (e_FM_PCD_EXTRACT_FROM_PARSE_RESULT):
36334 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
36335 + case (e_FM_PCD_EXTRACT_FROM_ENQ_FQID):
36336 + *p_Offset = 32;
36337 + return KG_SCH_GEN_PARSE_RESULT_N_FQID;
36338 + case (e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE):
36339 + return KG_SCH_GEN_NEXTHDR;
36340 + default:
36341 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 'extract from' src"));
36342 + return 0;
36343 + }
36344 +}
36345 +
36346 +static uint8_t GetGenHdrCode(e_NetHeaderType hdr, e_FmPcdHdrIndex hdrIndex, bool ignoreProtocolValidation)
36347 +{
36348 + if (!ignoreProtocolValidation)
36349 + switch (hdr)
36350 + {
36351 + case (HEADER_TYPE_NONE):
36352 + ASSERT_COND(FALSE);
36353 + case (HEADER_TYPE_ETH):
36354 + return KG_SCH_GEN_ETH;
36355 + case (HEADER_TYPE_LLC_SNAP):
36356 + return KG_SCH_GEN_SNAP;
36357 + case (HEADER_TYPE_PPPoE):
36358 + return KG_SCH_GEN_PPP;
36359 + case (HEADER_TYPE_MPLS):
36360 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36361 + return KG_SCH_GEN_MPLS1;
36362 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
36363 + return KG_SCH_GEN_MPLS2;
36364 + if (hdrIndex == e_FM_PCD_HDR_INDEX_3)
36365 + return KG_SCH_GEN_MPLS3;
36366 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
36367 + return KG_SCH_GEN_MPLS_LAST;
36368 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
36369 + return 0;
36370 + case (HEADER_TYPE_IPv4):
36371 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36372 + return KG_SCH_GEN_IPV4;
36373 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
36374 + return KG_SCH_GEN_IPV4_TUNNELED;
36375 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 header index"));
36376 + return 0;
36377 + case (HEADER_TYPE_IPv6):
36378 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36379 + return KG_SCH_GEN_IPV6;
36380 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
36381 + return KG_SCH_GEN_IPV6_TUNNELED;
36382 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 header index"));
36383 + return 0;
36384 + case (HEADER_TYPE_GRE):
36385 + return KG_SCH_GEN_GRE;
36386 + case (HEADER_TYPE_TCP):
36387 + return KG_SCH_GEN_TCP;
36388 + case (HEADER_TYPE_UDP):
36389 + return KG_SCH_GEN_UDP;
36390 + case (HEADER_TYPE_IPSEC_AH):
36391 + return KG_SCH_GEN_IPSEC_AH;
36392 + case (HEADER_TYPE_IPSEC_ESP):
36393 + return KG_SCH_GEN_IPSEC_ESP;
36394 + case (HEADER_TYPE_SCTP):
36395 + return KG_SCH_GEN_SCTP;
36396 + case (HEADER_TYPE_DCCP):
36397 + return KG_SCH_GEN_DCCP;
36398 + default:
36399 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36400 + return 0;
36401 + }
36402 + else
36403 + switch (hdr)
36404 + {
36405 + case (HEADER_TYPE_NONE):
36406 + ASSERT_COND(FALSE);
36407 + case (HEADER_TYPE_ETH):
36408 + return KG_SCH_GEN_ETH_NO_V;
36409 + case (HEADER_TYPE_LLC_SNAP):
36410 + return KG_SCH_GEN_SNAP_NO_V;
36411 + case (HEADER_TYPE_PPPoE):
36412 + return KG_SCH_GEN_PPP_NO_V;
36413 + case (HEADER_TYPE_MPLS):
36414 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36415 + return KG_SCH_GEN_MPLS1_NO_V;
36416 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
36417 + return KG_SCH_GEN_MPLS_LAST_NO_V;
36418 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_3) )
36419 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Indexed MPLS Extraction not supported"));
36420 + else
36421 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS header index"));
36422 + return 0;
36423 + case (HEADER_TYPE_IPv4):
36424 + case (HEADER_TYPE_IPv6):
36425 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36426 + return KG_SCH_GEN_L3_NO_V;
36427 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_2) || (hdrIndex == e_FM_PCD_HDR_INDEX_LAST))
36428 + return KG_SCH_GEN_IP2_NO_V;
36429 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IP header index"));
36430 + case (HEADER_TYPE_MINENCAP):
36431 + return KG_SCH_GEN_IP2_NO_V;
36432 + case (HEADER_TYPE_USER_DEFINED_L3):
36433 + return KG_SCH_GEN_L3_NO_V;
36434 + case (HEADER_TYPE_GRE):
36435 + return KG_SCH_GEN_GRE_NO_V;
36436 + case (HEADER_TYPE_TCP):
36437 + case (HEADER_TYPE_UDP):
36438 + case (HEADER_TYPE_IPSEC_AH):
36439 + case (HEADER_TYPE_IPSEC_ESP):
36440 + case (HEADER_TYPE_SCTP):
36441 + case (HEADER_TYPE_DCCP):
36442 + return KG_SCH_GEN_L4_NO_V;
36443 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
36444 + return KG_SCH_GEN_SHIM1;
36445 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
36446 + return KG_SCH_GEN_SHIM2;
36447 + default:
36448 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36449 + return 0;
36450 + }
36451 +}
36452 +static t_GenericCodes GetGenFieldCode(e_NetHeaderType hdr, t_FmPcdFields field, bool ignoreProtocolValidation, e_FmPcdHdrIndex hdrIndex)
36453 +{
36454 + if (!ignoreProtocolValidation)
36455 + switch (hdr)
36456 + {
36457 + case (HEADER_TYPE_NONE):
36458 + ASSERT_COND(FALSE);
36459 + break;
36460 + case (HEADER_TYPE_ETH):
36461 + switch (field.eth)
36462 + {
36463 + case (NET_HEADER_FIELD_ETH_TYPE):
36464 + return KG_SCH_GEN_ETH_TYPE;
36465 + default:
36466 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36467 + return 0;
36468 + }
36469 + break;
36470 + case (HEADER_TYPE_VLAN):
36471 + switch (field.vlan)
36472 + {
36473 + case (NET_HEADER_FIELD_VLAN_TCI):
36474 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36475 + return KG_SCH_GEN_VLAN1;
36476 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
36477 + return KG_SCH_GEN_VLAN2;
36478 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
36479 + return 0;
36480 + }
36481 + break;
36482 + case (HEADER_TYPE_MPLS):
36483 + case (HEADER_TYPE_IPSEC_AH):
36484 + case (HEADER_TYPE_IPSEC_ESP):
36485 + case (HEADER_TYPE_LLC_SNAP):
36486 + case (HEADER_TYPE_PPPoE):
36487 + case (HEADER_TYPE_IPv4):
36488 + case (HEADER_TYPE_IPv6):
36489 + case (HEADER_TYPE_GRE):
36490 + case (HEADER_TYPE_MINENCAP):
36491 + case (HEADER_TYPE_USER_DEFINED_L3):
36492 + case (HEADER_TYPE_TCP):
36493 + case (HEADER_TYPE_UDP):
36494 + case (HEADER_TYPE_SCTP):
36495 + case (HEADER_TYPE_DCCP):
36496 + case (HEADER_TYPE_USER_DEFINED_L4):
36497 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36498 + return 0;
36499 + default:
36500 + break;
36501 +
36502 + }
36503 + else
36504 + switch (hdr)
36505 + {
36506 + case (HEADER_TYPE_NONE):
36507 + ASSERT_COND(FALSE);
36508 + break;
36509 + case (HEADER_TYPE_ETH):
36510 + switch (field.eth)
36511 + {
36512 + case (NET_HEADER_FIELD_ETH_TYPE):
36513 + return KG_SCH_GEN_ETH_TYPE_NO_V;
36514 + default:
36515 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36516 + return 0;
36517 + }
36518 + break;
36519 + case (HEADER_TYPE_VLAN):
36520 + switch (field.vlan)
36521 + {
36522 + case (NET_HEADER_FIELD_VLAN_TCI) :
36523 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE) || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
36524 + return KG_SCH_GEN_VLAN1_NO_V;
36525 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
36526 + return KG_SCH_GEN_VLAN2_NO_V;
36527 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal VLAN header index"));
36528 + return 0;
36529 + }
36530 + break;
36531 + case (HEADER_TYPE_IPv4):
36532 + switch (field.ipv4)
36533 + {
36534 + case (NET_HEADER_FIELD_IPv4_PROTO):
36535 + return KG_SCH_GEN_IP_PID_NO_V;
36536 + default:
36537 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36538 + return 0;
36539 + }
36540 + break;
36541 + case (HEADER_TYPE_IPv6):
36542 + switch (field.ipv6)
36543 + {
36544 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
36545 + return KG_SCH_GEN_IP_PID_NO_V;
36546 + default:
36547 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36548 + return 0;
36549 + }
36550 + break;
36551 + case (HEADER_TYPE_MPLS):
36552 + case (HEADER_TYPE_LLC_SNAP):
36553 + case (HEADER_TYPE_PPPoE):
36554 + case (HEADER_TYPE_GRE):
36555 + case (HEADER_TYPE_MINENCAP):
36556 + case (HEADER_TYPE_USER_DEFINED_L3):
36557 + case (HEADER_TYPE_TCP):
36558 + case (HEADER_TYPE_UDP):
36559 + case (HEADER_TYPE_IPSEC_AH):
36560 + case (HEADER_TYPE_IPSEC_ESP):
36561 + case (HEADER_TYPE_SCTP):
36562 + case (HEADER_TYPE_DCCP):
36563 + case (HEADER_TYPE_USER_DEFINED_L4):
36564 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36565 + return 0;
36566 + default:
36567 + break;
36568 + }
36569 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Header not supported"));
36570 + return 0;
36571 +}
36572 +
36573 +static t_KnownFieldsMasks GetKnownProtMask(t_FmPcd *p_FmPcd, e_NetHeaderType hdr, e_FmPcdHdrIndex index, t_FmPcdFields field)
36574 +{
36575 + UNUSED(p_FmPcd);
36576 +
36577 + switch (hdr)
36578 + {
36579 + case (HEADER_TYPE_NONE):
36580 + ASSERT_COND(FALSE);
36581 + break;
36582 + case (HEADER_TYPE_ETH):
36583 + switch (field.eth)
36584 + {
36585 + case (NET_HEADER_FIELD_ETH_DA):
36586 + return KG_SCH_KN_MACDST;
36587 + case (NET_HEADER_FIELD_ETH_SA):
36588 + return KG_SCH_KN_MACSRC;
36589 + case (NET_HEADER_FIELD_ETH_TYPE):
36590 + return KG_SCH_KN_ETYPE;
36591 + default:
36592 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36593 + return 0;
36594 + }
36595 + case (HEADER_TYPE_LLC_SNAP):
36596 + switch (field.llcSnap)
36597 + {
36598 + case (NET_HEADER_FIELD_LLC_SNAP_TYPE):
36599 + return KG_SCH_KN_ETYPE;
36600 + default:
36601 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36602 + return 0;
36603 + }
36604 + case (HEADER_TYPE_VLAN):
36605 + switch (field.vlan)
36606 + {
36607 + case (NET_HEADER_FIELD_VLAN_TCI):
36608 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36609 + return KG_SCH_KN_TCI1;
36610 + if (index == e_FM_PCD_HDR_INDEX_LAST)
36611 + return KG_SCH_KN_TCI2;
36612 + else
36613 + {
36614 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36615 + return 0;
36616 + }
36617 + default:
36618 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36619 + return 0;
36620 + }
36621 + case (HEADER_TYPE_MPLS):
36622 + switch (field.mpls)
36623 + {
36624 + case (NET_HEADER_FIELD_MPLS_LABEL_STACK):
36625 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36626 + return KG_SCH_KN_MPLS1;
36627 + if (index == e_FM_PCD_HDR_INDEX_2)
36628 + return KG_SCH_KN_MPLS2;
36629 + if (index == e_FM_PCD_HDR_INDEX_LAST)
36630 + return KG_SCH_KN_MPLS_LAST;
36631 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal MPLS index"));
36632 + return 0;
36633 + default:
36634 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36635 + return 0;
36636 + }
36637 + case (HEADER_TYPE_IPv4):
36638 + switch (field.ipv4)
36639 + {
36640 + case (NET_HEADER_FIELD_IPv4_SRC_IP):
36641 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36642 + return KG_SCH_KN_IPSRC1;
36643 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36644 + return KG_SCH_KN_IPSRC2;
36645 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
36646 + return 0;
36647 + case (NET_HEADER_FIELD_IPv4_DST_IP):
36648 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36649 + return KG_SCH_KN_IPDST1;
36650 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36651 + return KG_SCH_KN_IPDST2;
36652 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
36653 + return 0;
36654 + case (NET_HEADER_FIELD_IPv4_PROTO):
36655 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36656 + return KG_SCH_KN_PTYPE1;
36657 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36658 + return KG_SCH_KN_PTYPE2;
36659 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
36660 + return 0;
36661 + case (NET_HEADER_FIELD_IPv4_TOS):
36662 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36663 + return KG_SCH_KN_IPTOS_TC1;
36664 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36665 + return KG_SCH_KN_IPTOS_TC2;
36666 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv4 index"));
36667 + return 0;
36668 + default:
36669 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36670 + return 0;
36671 + }
36672 + case (HEADER_TYPE_IPv6):
36673 + switch (field.ipv6)
36674 + {
36675 + case (NET_HEADER_FIELD_IPv6_SRC_IP):
36676 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36677 + return KG_SCH_KN_IPSRC1;
36678 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36679 + return KG_SCH_KN_IPSRC2;
36680 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36681 + return 0;
36682 + case (NET_HEADER_FIELD_IPv6_DST_IP):
36683 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36684 + return KG_SCH_KN_IPDST1;
36685 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36686 + return KG_SCH_KN_IPDST2;
36687 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36688 + return 0;
36689 + case (NET_HEADER_FIELD_IPv6_NEXT_HDR):
36690 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36691 + return KG_SCH_KN_PTYPE1;
36692 + if (index == e_FM_PCD_HDR_INDEX_2)
36693 + return KG_SCH_KN_PTYPE2;
36694 + if (index == e_FM_PCD_HDR_INDEX_LAST)
36695 +#ifdef FM_KG_NO_IPPID_SUPPORT
36696 + if (p_FmPcd->fmRevInfo.majorRev < 6)
36697 + return KG_SCH_KN_PTYPE2;
36698 +#endif /* FM_KG_NO_IPPID_SUPPORT */
36699 + return KG_SCH_KN_IPPID;
36700 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36701 + return 0;
36702 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC):
36703 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36704 + return (KG_SCH_KN_IPV6FL1 | KG_SCH_KN_IPTOS_TC1);
36705 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36706 + return (KG_SCH_KN_IPV6FL2 | KG_SCH_KN_IPTOS_TC2);
36707 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36708 + return 0;
36709 + case (NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_TC):
36710 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36711 + return KG_SCH_KN_IPTOS_TC1;
36712 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36713 + return KG_SCH_KN_IPTOS_TC2;
36714 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36715 + return 0;
36716 + case (NET_HEADER_FIELD_IPv6_FL):
36717 + if ((index == e_FM_PCD_HDR_INDEX_NONE) || (index == e_FM_PCD_HDR_INDEX_1))
36718 + return KG_SCH_KN_IPV6FL1;
36719 + if ((index == e_FM_PCD_HDR_INDEX_2) || (index == e_FM_PCD_HDR_INDEX_LAST))
36720 + return KG_SCH_KN_IPV6FL2;
36721 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal IPv6 index"));
36722 + return 0;
36723 + default:
36724 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36725 + return 0;
36726 + }
36727 + case (HEADER_TYPE_GRE):
36728 + switch (field.gre)
36729 + {
36730 + case (NET_HEADER_FIELD_GRE_TYPE):
36731 + return KG_SCH_KN_GREPTYPE;
36732 + default:
36733 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36734 + return 0;
36735 + }
36736 + case (HEADER_TYPE_MINENCAP):
36737 + switch (field.minencap)
36738 + {
36739 + case (NET_HEADER_FIELD_MINENCAP_SRC_IP):
36740 + return KG_SCH_KN_IPSRC2;
36741 + case (NET_HEADER_FIELD_MINENCAP_DST_IP):
36742 + return KG_SCH_KN_IPDST2;
36743 + case (NET_HEADER_FIELD_MINENCAP_TYPE):
36744 + return KG_SCH_KN_PTYPE2;
36745 + default:
36746 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36747 + return 0;
36748 + }
36749 + case (HEADER_TYPE_TCP):
36750 + switch (field.tcp)
36751 + {
36752 + case (NET_HEADER_FIELD_TCP_PORT_SRC):
36753 + return KG_SCH_KN_L4PSRC;
36754 + case (NET_HEADER_FIELD_TCP_PORT_DST):
36755 + return KG_SCH_KN_L4PDST;
36756 + case (NET_HEADER_FIELD_TCP_FLAGS):
36757 + return KG_SCH_KN_TFLG;
36758 + default:
36759 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36760 + return 0;
36761 + }
36762 + case (HEADER_TYPE_UDP):
36763 + switch (field.udp)
36764 + {
36765 + case (NET_HEADER_FIELD_UDP_PORT_SRC):
36766 + return KG_SCH_KN_L4PSRC;
36767 + case (NET_HEADER_FIELD_UDP_PORT_DST):
36768 + return KG_SCH_KN_L4PDST;
36769 + default:
36770 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36771 + return 0;
36772 + }
36773 + case (HEADER_TYPE_IPSEC_AH):
36774 + switch (field.ipsecAh)
36775 + {
36776 + case (NET_HEADER_FIELD_IPSEC_AH_SPI):
36777 + return KG_SCH_KN_IPSEC_SPI;
36778 + case (NET_HEADER_FIELD_IPSEC_AH_NH):
36779 + return KG_SCH_KN_IPSEC_NH;
36780 + default:
36781 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36782 + return 0;
36783 + }
36784 + case (HEADER_TYPE_IPSEC_ESP):
36785 + switch (field.ipsecEsp)
36786 + {
36787 + case (NET_HEADER_FIELD_IPSEC_ESP_SPI):
36788 + return KG_SCH_KN_IPSEC_SPI;
36789 + default:
36790 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36791 + return 0;
36792 + }
36793 + case (HEADER_TYPE_SCTP):
36794 + switch (field.sctp)
36795 + {
36796 + case (NET_HEADER_FIELD_SCTP_PORT_SRC):
36797 + return KG_SCH_KN_L4PSRC;
36798 + case (NET_HEADER_FIELD_SCTP_PORT_DST):
36799 + return KG_SCH_KN_L4PDST;
36800 + default:
36801 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36802 + return 0;
36803 + }
36804 + case (HEADER_TYPE_DCCP):
36805 + switch (field.dccp)
36806 + {
36807 + case (NET_HEADER_FIELD_DCCP_PORT_SRC):
36808 + return KG_SCH_KN_L4PSRC;
36809 + case (NET_HEADER_FIELD_DCCP_PORT_DST):
36810 + return KG_SCH_KN_L4PDST;
36811 + default:
36812 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36813 + return 0;
36814 + }
36815 + case (HEADER_TYPE_PPPoE):
36816 + switch (field.pppoe)
36817 + {
36818 + case (NET_HEADER_FIELD_PPPoE_PID):
36819 + return KG_SCH_KN_PPPID;
36820 + case (NET_HEADER_FIELD_PPPoE_SID):
36821 + return KG_SCH_KN_PPPSID;
36822 + default:
36823 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36824 + return 0;
36825 + }
36826 + default:
36827 + break;
36828 +
36829 + }
36830 +
36831 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Extraction not supported"));
36832 + return 0;
36833 +}
36834 +
36835 +
36836 +static uint8_t GetKnownFieldId(uint32_t bitMask)
36837 +{
36838 + uint8_t cnt = 0;
36839 +
36840 + while (bitMask)
36841 + if (bitMask & 0x80000000)
36842 + break;
36843 + else
36844 + {
36845 + cnt++;
36846 + bitMask <<= 1;
36847 + }
36848 + return cnt;
36849 +
36850 +}
36851 +
36852 +static uint8_t GetExtractedOrMask(uint8_t bitOffset, bool fqid)
36853 +{
36854 + uint8_t i, mask, numOfOnesToClear, walking1Mask = 1;
36855 +
36856 + /* bitOffset 1-7 --> mask 0x1-0x7F */
36857 + if (bitOffset<8)
36858 + {
36859 + mask = 0;
36860 + for (i = 0 ; i < bitOffset ; i++, walking1Mask <<= 1)
36861 + mask |= walking1Mask;
36862 + }
36863 + else
36864 + {
36865 + mask = 0xFF;
36866 + numOfOnesToClear = 0;
36867 + if (fqid && bitOffset>24)
36868 + /* bitOffset 25-31 --> mask 0xFE-0x80 */
36869 + numOfOnesToClear = (uint8_t)(bitOffset-24);
36870 + else
36871 + /* bitOffset 9-15 --> mask 0xFE-0x80 */
36872 + if (!fqid && bitOffset>8)
36873 + numOfOnesToClear = (uint8_t)(bitOffset-8);
36874 + for (i = 0 ; i < numOfOnesToClear ; i++, walking1Mask <<= 1)
36875 + mask &= ~walking1Mask;
36876 + /* bitOffset 8-24 for FQID, 8 for PP --> no mask (0xFF)*/
36877 + }
36878 + return mask;
36879 +}
36880 +
36881 +static void IncSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
36882 +{
36883 + t_FmPcdKg *p_FmPcdKg;
36884 + t_FmPcdKgScheme *p_Scheme;
36885 + uint32_t intFlags;
36886 + uint8_t relativeSchemeId;
36887 + int i;
36888 +
36889 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
36890 +
36891 + /* for each scheme - update owners counters */
36892 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
36893 + {
36894 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36895 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
36896 +
36897 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
36898 +
36899 + /* increment owners number */
36900 + intFlags = KgSchemeLock(p_Scheme);
36901 + p_Scheme->owners++;
36902 + KgSchemeUnlock(p_Scheme, intFlags);
36903 + }
36904 +}
36905 +
36906 +static void DecSchemeOwners(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort)
36907 +{
36908 + t_FmPcdKg *p_FmPcdKg;
36909 + t_FmPcdKgScheme *p_Scheme;
36910 + uint32_t intFlags;
36911 + uint8_t relativeSchemeId;
36912 + int i;
36913 +
36914 + p_FmPcdKg = p_FmPcd->p_FmPcdKg;
36915 +
36916 + /* for each scheme - update owners counters */
36917 + for (i = 0; i < p_BindPort->numOfSchemes; i++)
36918 + {
36919 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
36920 + ASSERT_COND(relativeSchemeId < FM_PCD_KG_NUM_OF_SCHEMES);
36921 +
36922 + p_Scheme = &p_FmPcdKg->schemes[relativeSchemeId];
36923 +
36924 + /* increment owners number */
36925 + ASSERT_COND(p_Scheme->owners);
36926 + intFlags = KgSchemeLock(p_Scheme);
36927 + p_Scheme->owners--;
36928 + KgSchemeUnlock(p_Scheme, intFlags);
36929 + }
36930 +}
36931 +
36932 +static void UpdateRequiredActionFlag(t_FmPcdKgScheme *p_Scheme, bool set)
36933 +{
36934 + /* this routine is locked by the calling routine */
36935 + ASSERT_COND(p_Scheme);
36936 + ASSERT_COND(p_Scheme->valid);
36937 +
36938 + if (set)
36939 + p_Scheme->requiredActionFlag = TRUE;
36940 + else
36941 + {
36942 + p_Scheme->requiredAction = 0;
36943 + p_Scheme->requiredActionFlag = FALSE;
36944 + }
36945 +}
36946 +
36947 +static t_Error KgWriteSp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t spReg, bool add)
36948 +{
36949 + struct fman_kg_regs *p_KgRegs;
36950 +
36951 + uint32_t tmpKgarReg = 0, intFlags;
36952 + t_Error err = E_OK;
36953 +
36954 + /* The calling routine had locked the port, so for each port only one core can access
36955 + * (so we don't need a lock here) */
36956 +
36957 + if (p_FmPcd->h_Hc)
36958 + return FmHcKgWriteSp(p_FmPcd->h_Hc, hardwarePortId, spReg, add);
36959 +
36960 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36961 +
36962 + tmpKgarReg = FmPcdKgBuildReadPortSchemeBindActionReg(hardwarePortId);
36963 + /* lock a common KG reg */
36964 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36965 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
36966 + if (err)
36967 + {
36968 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36969 + RETURN_ERROR(MINOR, err, NO_MSG);
36970 + }
36971 +
36972 + fman_kg_write_sp(p_KgRegs, spReg, add);
36973 +
36974 + tmpKgarReg = FmPcdKgBuildWritePortSchemeBindActionReg(hardwarePortId);
36975 +
36976 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
36977 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
36978 + return err;
36979 +}
36980 +
36981 +static t_Error KgWriteCpp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint32_t cppReg)
36982 +{
36983 + struct fman_kg_regs *p_KgRegs;
36984 + uint32_t tmpKgarReg, intFlags;
36985 + t_Error err;
36986 +
36987 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
36988 +
36989 + if (p_FmPcd->h_Hc)
36990 + {
36991 + err = FmHcKgWriteCpp(p_FmPcd->h_Hc, hardwarePortId, cppReg);
36992 + return err;
36993 + }
36994 +
36995 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
36996 + fman_kg_write_cpp(p_KgRegs, cppReg);
36997 + tmpKgarReg = FmPcdKgBuildWritePortClsPlanBindActionReg(hardwarePortId);
36998 + err = WriteKgarWait(p_FmPcd, tmpKgarReg);
36999 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
37000 +
37001 + return err;
37002 +}
37003 +
37004 +static uint32_t BuildCppReg(t_FmPcd *p_FmPcd, uint8_t clsPlanGrpId)
37005 +{
37006 + uint32_t tmpKgpeCpp;
37007 +
37008 + tmpKgpeCpp = (uint32_t)(p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry / 8);
37009 + tmpKgpeCpp |= (uint32_t)(((p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp / 8) - 1) << FM_KG_PE_CPP_MASK_SHIFT);
37010 +
37011 + return tmpKgpeCpp;
37012 +}
37013 +
37014 +static t_Error BindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
37015 +{
37016 + uint32_t tmpKgpeCpp = 0;
37017 +
37018 + tmpKgpeCpp = BuildCppReg(p_FmPcd, clsPlanGrpId);
37019 + return KgWriteCpp(p_FmPcd, hardwarePortId, tmpKgpeCpp);
37020 +}
37021 +
37022 +static void UnbindPortToClsPlanGrp(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
37023 +{
37024 + KgWriteCpp(p_FmPcd, hardwarePortId, 0);
37025 +}
37026 +
37027 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
37028 +static uint32_t __attribute__((unused)) ReadClsPlanBlockActionReg(uint8_t grpId)
37029 +{
37030 + return (uint32_t)(FM_KG_KGAR_GO |
37031 + FM_KG_KGAR_READ |
37032 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
37033 + DUMMY_PORT_ID |
37034 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
37035 + FM_PCD_KG_KGAR_WSEL_MASK);
37036 +
37037 + /* if we ever want to write 1 by 1, use:
37038 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
37039 + */
37040 +}
37041 +#endif /* (defined(DEBUG_ERRORS) && ... */
37042 +
37043 +static void PcdKgErrorException(t_Handle h_FmPcd)
37044 +{
37045 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
37046 + uint32_t event,schemeIndexes = 0, index = 0;
37047 + struct fman_kg_regs *p_KgRegs;
37048 +
37049 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
37050 + p_KgRegs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37051 + fman_kg_get_event(p_KgRegs, &event, &schemeIndexes);
37052 +
37053 + if (event & FM_EX_KG_DOUBLE_ECC)
37054 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC);
37055 + if (event & FM_EX_KG_KEYSIZE_OVERFLOW)
37056 + {
37057 + if (schemeIndexes)
37058 + {
37059 + while (schemeIndexes)
37060 + {
37061 + if (schemeIndexes & 0x1)
37062 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, (uint16_t)(31 - index));
37063 + schemeIndexes >>= 1;
37064 + index+=1;
37065 + }
37066 + }
37067 + else /* this should happen only when interrupt is forced. */
37068 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW);
37069 + }
37070 +}
37071 +
37072 +static t_Error KgInitGuest(t_FmPcd *p_FmPcd)
37073 +{
37074 + t_Error err = E_OK;
37075 + t_FmPcdIpcKgSchemesParams kgAlloc;
37076 + uint32_t replyLength;
37077 + t_FmPcdIpcReply reply;
37078 + t_FmPcdIpcMsg msg;
37079 +
37080 + ASSERT_COND(p_FmPcd->guestId != NCSW_MASTER_ID);
37081 +
37082 + /* in GUEST_PARTITION, we use the IPC */
37083 + memset(&reply, 0, sizeof(reply));
37084 + memset(&msg, 0, sizeof(msg));
37085 + memset(&kgAlloc, 0, sizeof(t_FmPcdIpcKgSchemesParams));
37086 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
37087 + kgAlloc.guestId = p_FmPcd->guestId;
37088 + msg.msgId = FM_PCD_ALLOC_KG_SCHEMES;
37089 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
37090 + replyLength = sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t);
37091 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
37092 + (uint8_t*)&msg,
37093 + sizeof(msg.msgId) + sizeof(kgAlloc),
37094 + (uint8_t*)&reply,
37095 + &replyLength,
37096 + NULL,
37097 + NULL)) != E_OK)
37098 + RETURN_ERROR(MAJOR, err, NO_MSG);
37099 + if (replyLength != (sizeof(uint32_t) + p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t)))
37100 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
37101 + memcpy(p_FmPcd->p_FmPcdKg->schemesIds, (uint8_t*)(reply.replyBody),p_FmPcd->p_FmPcdKg->numOfSchemes*sizeof(uint8_t));
37102 +
37103 + return (t_Error)reply.error;
37104 +}
37105 +
37106 +static t_Error KgInitMaster(t_FmPcd *p_FmPcd)
37107 +{
37108 + t_Error err = E_OK;
37109 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
37110 +
37111 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
37112 +
37113 + if (p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC)
37114 + FmEnableRamsEcc(p_FmPcd->h_Fm);
37115 +
37116 + fman_kg_init(p_Regs, p_FmPcd->exceptions, GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd));
37117 +
37118 + /* register even if no interrupts enabled, to allow future enablement */
37119 + FmRegisterIntr(p_FmPcd->h_Fm,
37120 + e_FM_MOD_KG,
37121 + 0,
37122 + e_FM_INTR_TYPE_ERR,
37123 + PcdKgErrorException,
37124 + p_FmPcd);
37125 +
37126 + fman_kg_enable_scheme_interrupts(p_Regs);
37127 +
37128 + if (p_FmPcd->p_FmPcdKg->numOfSchemes)
37129 + {
37130 + err = FmPcdKgAllocSchemes(p_FmPcd,
37131 + p_FmPcd->p_FmPcdKg->numOfSchemes,
37132 + p_FmPcd->guestId,
37133 + p_FmPcd->p_FmPcdKg->schemesIds);
37134 + if (err)
37135 + RETURN_ERROR(MINOR, err, NO_MSG);
37136 + }
37137 +
37138 + return E_OK;
37139 +}
37140 +
37141 +static void ValidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
37142 +{
37143 + ASSERT_COND(!p_Scheme->valid);
37144 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
37145 + FmPcdIncNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
37146 + p_Scheme->valid = TRUE;
37147 +}
37148 +
37149 +static t_Error InvalidateSchemeSw(t_FmPcdKgScheme *p_Scheme)
37150 +{
37151 + if (p_Scheme->owners)
37152 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a scheme that has ports bound to"));
37153 +
37154 + if (p_Scheme->netEnvId != ILLEGAL_NETENV)
37155 + FmPcdDecNetEnvOwners(p_Scheme->h_FmPcd, p_Scheme->netEnvId);
37156 + p_Scheme->valid = FALSE;
37157 +
37158 + return E_OK;
37159 +}
37160 +
37161 +static t_Error BuildSchemeRegs(t_FmPcdKgScheme *p_Scheme,
37162 + t_FmPcdKgSchemeParams *p_SchemeParams,
37163 + struct fman_kg_scheme_regs *p_SchemeRegs)
37164 +{
37165 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Scheme->h_FmPcd);
37166 + uint32_t grpBits = 0;
37167 + uint8_t grpBase;
37168 + bool direct=TRUE, absolute=FALSE;
37169 + uint16_t profileId=0, numOfProfiles=0, relativeProfileId;
37170 + t_Error err = E_OK;
37171 + int i = 0;
37172 + t_NetEnvParams netEnvParams;
37173 + uint32_t tmpReg, fqbTmp = 0, ppcTmp = 0, selectTmp, maskTmp, knownTmp, genTmp;
37174 + t_FmPcdKgKeyExtractAndHashParams *p_KeyAndHash = NULL;
37175 + uint8_t j, curr, idx;
37176 + uint8_t id, shift=0, code=0, offset=0, size=0;
37177 + t_FmPcdExtractEntry *p_Extract = NULL;
37178 + t_FmPcdKgExtractedOrParams *p_ExtractOr;
37179 + bool generic = FALSE;
37180 + t_KnownFieldsMasks bitMask;
37181 + e_FmPcdKgExtractDfltSelect swDefault = (e_FmPcdKgExtractDfltSelect)0;
37182 + t_FmPcdKgSchemesExtracts *p_LocalExtractsArray;
37183 + uint8_t numOfSwDefaults = 0;
37184 + t_FmPcdKgExtractDflt swDefaults[NUM_OF_SW_DEFAULTS];
37185 + uint8_t currGenId = 0;
37186 +
37187 + memset(swDefaults, 0, NUM_OF_SW_DEFAULTS*sizeof(t_FmPcdKgExtractDflt));
37188 + memset(p_SchemeRegs, 0, sizeof(struct fman_kg_scheme_regs));
37189 +
37190 + if (p_SchemeParams->netEnvParams.numOfDistinctionUnits > FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
37191 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
37192 + ("numOfDistinctionUnits should not exceed %d", FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS));
37193 +
37194 + /* by netEnv parameters, get match vector */
37195 + if (!p_SchemeParams->alwaysDirect)
37196 + {
37197 + p_Scheme->netEnvId = FmPcdGetNetEnvId(p_SchemeParams->netEnvParams.h_NetEnv);
37198 + netEnvParams.netEnvId = p_Scheme->netEnvId;
37199 + netEnvParams.numOfDistinctionUnits = p_SchemeParams->netEnvParams.numOfDistinctionUnits;
37200 + memcpy(netEnvParams.unitIds, p_SchemeParams->netEnvParams.unitIds, (sizeof(uint8_t))*p_SchemeParams->netEnvParams.numOfDistinctionUnits);
37201 + err = PcdGetUnitsVector(p_FmPcd, &netEnvParams);
37202 + if (err)
37203 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
37204 + p_Scheme->matchVector = netEnvParams.vector;
37205 + }
37206 + else
37207 + {
37208 + p_Scheme->matchVector = SCHEME_ALWAYS_DIRECT;
37209 + p_Scheme->netEnvId = ILLEGAL_NETENV;
37210 + }
37211 +
37212 + if (p_SchemeParams->nextEngine == e_FM_PCD_INVALID)
37213 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next Engine of the scheme is not Valid"));
37214 +
37215 + if (p_SchemeParams->bypassFqidGeneration)
37216 + {
37217 +#ifdef FM_KG_NO_BYPASS_FQID_GEN
37218 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
37219 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassFqidGeneration."));
37220 +#endif /* FM_KG_NO_BYPASS_FQID_GEN */
37221 + if (p_SchemeParams->baseFqid)
37222 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid set for a scheme that does not generate an FQID"));
37223 + }
37224 + else
37225 + if (!p_SchemeParams->baseFqid)
37226 + DBG(WARNING, ("baseFqid is 0."));
37227 +
37228 + if (p_SchemeParams->nextEngine == e_FM_PCD_PLCR)
37229 + {
37230 + direct = p_SchemeParams->kgNextEngineParams.plcrProfile.direct;
37231 + p_Scheme->directPlcr = direct;
37232 + absolute = (bool)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? TRUE : FALSE);
37233 + if (!direct && absolute)
37234 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Indirect policing is not available when profile is shared."));
37235 +
37236 + if (direct)
37237 + {
37238 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.directRelativeProfileId;
37239 + numOfProfiles = 1;
37240 + }
37241 + else
37242 + {
37243 + profileId = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
37244 + shift = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
37245 + numOfProfiles = p_SchemeParams->kgNextEngineParams.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
37246 + }
37247 + }
37248 +
37249 + if (p_SchemeParams->nextEngine == e_FM_PCD_CC)
37250 + {
37251 +#ifdef FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
37252 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) && (p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
37253 + {
37254 + if ((p_FmPcd->fmRevInfo.majorRev != 4) && (p_FmPcd->fmRevInfo.majorRev < 6))
37255 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("bypassPlcrProfileGeneration."));
37256 + }
37257 +#endif /* FM_KG_NO_BYPASS_PLCR_PROFILE_GEN */
37258 +
37259 + err = FmPcdCcGetGrpParams(p_SchemeParams->kgNextEngineParams.cc.h_CcTree,
37260 + p_SchemeParams->kgNextEngineParams.cc.grpId,
37261 + &grpBits,
37262 + &grpBase);
37263 + if (err)
37264 + RETURN_ERROR(MAJOR, err, NO_MSG);
37265 + p_Scheme->ccUnits = grpBits;
37266 +
37267 + if ((p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
37268 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration))
37269 + {
37270 + if (p_SchemeParams->kgNextEngineParams.cc.plcrProfile.sharedProfile)
37271 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Shared profile may not be used after Coarse classification."));
37272 + absolute = FALSE;
37273 + direct = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.direct;
37274 + if (direct)
37275 + {
37276 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.directRelativeProfileId;
37277 + numOfProfiles = 1;
37278 + }
37279 + else
37280 + {
37281 + profileId = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
37282 + shift = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.fqidOffsetShift;
37283 + numOfProfiles = p_SchemeParams->kgNextEngineParams.cc.plcrProfile.profileSelect.indirectProfile.numOfProfiles;
37284 + }
37285 + }
37286 + }
37287 +
37288 + /* if policer is used directly after KG, or after CC */
37289 + if ((p_SchemeParams->nextEngine == e_FM_PCD_PLCR) ||
37290 + ((p_SchemeParams->nextEngine == e_FM_PCD_CC) &&
37291 + (p_SchemeParams->kgNextEngineParams.cc.plcrNext) &&
37292 + (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)))
37293 + {
37294 + /* if private policer profile, it may be uninitialized yet, therefore no checks are done at this stage */
37295 + if (absolute)
37296 + {
37297 + /* for absolute direct policy only, */
37298 + relativeProfileId = profileId;
37299 + err = FmPcdPlcrGetAbsoluteIdByProfileParams((t_Handle)p_FmPcd,e_FM_PCD_PLCR_SHARED,NULL, relativeProfileId, &profileId);
37300 + if (err)
37301 + RETURN_ERROR(MAJOR, err, ("Shared profile not valid offset"));
37302 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileId))
37303 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Shared profile not valid."));
37304 + p_Scheme->relativeProfileId = profileId;
37305 + }
37306 + else
37307 + {
37308 + /* save relative profile id's for later check */
37309 + p_Scheme->nextRelativePlcrProfile = TRUE;
37310 + p_Scheme->relativeProfileId = profileId;
37311 + p_Scheme->numOfProfiles = numOfProfiles;
37312 + }
37313 + }
37314 + else
37315 + {
37316 + /* if policer is NOT going to be used after KG at all than if bypassFqidGeneration
37317 + is set, we do not need numOfUsedExtractedOrs and hashDistributionNumOfFqids */
37318 + if (p_SchemeParams->bypassFqidGeneration && p_SchemeParams->numOfUsedExtractedOrs)
37319 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
37320 + ("numOfUsedExtractedOrs is set in a scheme that does not generate FQID or policer profile ID"));
37321 + if (p_SchemeParams->bypassFqidGeneration &&
37322 + p_SchemeParams->useHash &&
37323 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids)
37324 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
37325 + ("hashDistributionNumOfFqids is set in a scheme that does not generate FQID or policer profile ID"));
37326 + }
37327 +
37328 + /* configure all 21 scheme registers */
37329 + tmpReg = KG_SCH_MODE_EN;
37330 + switch (p_SchemeParams->nextEngine)
37331 + {
37332 + case (e_FM_PCD_PLCR):
37333 + /* add to mode register - NIA */
37334 + tmpReg |= KG_SCH_MODE_NIA_PLCR;
37335 + tmpReg |= NIA_ENG_PLCR;
37336 + tmpReg |= (uint32_t)(p_SchemeParams->kgNextEngineParams.plcrProfile.sharedProfile ? NIA_PLCR_ABSOLUTE:0);
37337 + /* initialize policer profile command - */
37338 + /* configure kgse_ppc */
37339 + if (direct)
37340 + /* use profileId as base, other fields are 0 */
37341 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
37342 + else
37343 + {
37344 + if (shift > MAX_PP_SHIFT)
37345 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
37346 +
37347 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
37348 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
37349 +
37350 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
37351 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
37352 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
37353 + ppcTmp |= (uint32_t)profileId;
37354 +
37355 + p_SchemeRegs->kgse_ppc = ppcTmp;
37356 + }
37357 + break;
37358 + case (e_FM_PCD_CC):
37359 + /* mode reg - define NIA */
37360 + tmpReg |= (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
37361 +
37362 + p_SchemeRegs->kgse_ccbs = grpBits;
37363 + tmpReg |= (uint32_t)(grpBase << KG_SCH_MODE_CCOBASE_SHIFT);
37364 +
37365 + if (p_SchemeParams->kgNextEngineParams.cc.plcrNext)
37366 + {
37367 + if (!p_SchemeParams->kgNextEngineParams.cc.bypassPlcrProfileGeneration)
37368 + {
37369 + /* find out if absolute or relative */
37370 + if (absolute)
37371 + 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"));
37372 + if (direct)
37373 + {
37374 + /* mask = 0, base = directProfileId */
37375 + p_SchemeRegs->kgse_ppc = (uint32_t)profileId;
37376 + }
37377 + else
37378 + {
37379 + if (shift > MAX_PP_SHIFT)
37380 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_PP_SHIFT));
37381 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
37382 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
37383 +
37384 + ppcTmp = ((uint32_t)shift << KG_SCH_PP_SHIFT_HIGH_SHIFT) & KG_SCH_PP_SHIFT_HIGH;
37385 + ppcTmp |= ((uint32_t)shift << KG_SCH_PP_SHIFT_LOW_SHIFT) & KG_SCH_PP_SHIFT_LOW;
37386 + ppcTmp |= ((uint32_t)(numOfProfiles-1) << KG_SCH_PP_MASK_SHIFT);
37387 + ppcTmp |= (uint32_t)profileId;
37388 +
37389 + p_SchemeRegs->kgse_ppc = ppcTmp;
37390 + }
37391 + }
37392 + }
37393 + break;
37394 + case (e_FM_PCD_DONE):
37395 + if (p_SchemeParams->kgNextEngineParams.doneAction == e_FM_PCD_DROP_FRAME)
37396 + tmpReg |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
37397 + else
37398 + tmpReg |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
37399 + break;
37400 + default:
37401 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine not supported"));
37402 + }
37403 + p_SchemeRegs->kgse_mode = tmpReg;
37404 +
37405 + p_SchemeRegs->kgse_mv = p_Scheme->matchVector;
37406 +
37407 +#if (DPAA_VERSION >= 11)
37408 + if (p_SchemeParams->overrideStorageProfile)
37409 + {
37410 + p_SchemeRegs->kgse_om |= KG_SCH_OM_VSPE;
37411 +
37412 + if (p_SchemeParams->storageProfile.direct)
37413 + {
37414 + profileId = p_SchemeParams->storageProfile.profileSelect.directRelativeProfileId;
37415 + shift = 0;
37416 + numOfProfiles = 1;
37417 + }
37418 + else
37419 + {
37420 + profileId = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetRelativeProfileIdBase;
37421 + shift = p_SchemeParams->storageProfile.profileSelect.indirectProfile.fqidOffsetShift;
37422 + numOfProfiles = p_SchemeParams->storageProfile.profileSelect.indirectProfile.numOfProfiles;
37423 + }
37424 + if (shift > MAX_SP_SHIFT)
37425 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fqidOffsetShift may not be larger than %d", MAX_SP_SHIFT));
37426 +
37427 + if (!numOfProfiles || !POWER_OF_2(numOfProfiles))
37428 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfProfiles must not be 0 and must be a power of 2"));
37429 +
37430 + tmpReg = (uint32_t)shift << KG_SCH_VSP_SHIFT;
37431 + tmpReg |= ((uint32_t)(numOfProfiles-1) << KG_SCH_VSP_MASK_SHIFT);
37432 + tmpReg |= (uint32_t)profileId;
37433 +
37434 +
37435 + p_SchemeRegs->kgse_vsp = tmpReg;
37436 +
37437 + p_Scheme->vspe = TRUE;
37438 +
37439 + }
37440 + else
37441 + p_SchemeRegs->kgse_vsp = KG_SCH_VSP_NO_KSP_EN;
37442 +#endif /* (DPAA_VERSION >= 11) */
37443 +
37444 + if (p_SchemeParams->useHash)
37445 + {
37446 + p_KeyAndHash = &p_SchemeParams->keyExtractAndHashParams;
37447 +
37448 + if (p_KeyAndHash->numOfUsedExtracts >= FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
37449 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfUsedExtracts out of range"));
37450 +
37451 + /* configure kgse_dv0 */
37452 + p_SchemeRegs->kgse_dv0 = p_KeyAndHash->privateDflt0;
37453 +
37454 + /* configure kgse_dv1 */
37455 + p_SchemeRegs->kgse_dv1 = p_KeyAndHash->privateDflt1;
37456 +
37457 + if (!p_SchemeParams->bypassFqidGeneration)
37458 + {
37459 + if (!p_KeyAndHash->hashDistributionNumOfFqids || !POWER_OF_2(p_KeyAndHash->hashDistributionNumOfFqids))
37460 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionNumOfFqids must not be 0 and must be a power of 2"));
37461 + if ((p_KeyAndHash->hashDistributionNumOfFqids-1) & p_SchemeParams->baseFqid)
37462 + DBG(WARNING, ("baseFqid unaligned. Distribution may result in less than hashDistributionNumOfFqids queues."));
37463 + }
37464 +
37465 + /* configure kgse_ekdv */
37466 + tmpReg = 0;
37467 + for ( i=0 ;i<p_KeyAndHash->numOfUsedDflts ; i++)
37468 + {
37469 + switch (p_KeyAndHash->dflts[i].type)
37470 + {
37471 + case (e_FM_PCD_KG_MAC_ADDR):
37472 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MAC_ADDR_SHIFT);
37473 + break;
37474 + case (e_FM_PCD_KG_TCI):
37475 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCI_SHIFT);
37476 + break;
37477 + case (e_FM_PCD_KG_ENET_TYPE):
37478 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_ENET_TYPE_SHIFT);
37479 + break;
37480 + case (e_FM_PCD_KG_PPP_SESSION_ID):
37481 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_SESSION_ID_SHIFT);
37482 + break;
37483 + case (e_FM_PCD_KG_PPP_PROTOCOL_ID):
37484 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT);
37485 + break;
37486 + case (e_FM_PCD_KG_MPLS_LABEL):
37487 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_MPLS_LABEL_SHIFT);
37488 + break;
37489 + case (e_FM_PCD_KG_IP_ADDR):
37490 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_ADDR_SHIFT);
37491 + break;
37492 + case (e_FM_PCD_KG_PROTOCOL_TYPE):
37493 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_PROTOCOL_TYPE_SHIFT);
37494 + break;
37495 + case (e_FM_PCD_KG_IP_TOS_TC):
37496 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IP_TOS_TC_SHIFT);
37497 + break;
37498 + case (e_FM_PCD_KG_IPV6_FLOW_LABEL):
37499 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
37500 + break;
37501 + case (e_FM_PCD_KG_IPSEC_SPI):
37502 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_IPSEC_SPI_SHIFT);
37503 + break;
37504 + case (e_FM_PCD_KG_L4_PORT):
37505 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_L4_PORT_SHIFT);
37506 + break;
37507 + case (e_FM_PCD_KG_TCP_FLAG):
37508 + tmpReg |= (p_KeyAndHash->dflts[i].dfltSelect << KG_SCH_DEF_TCP_FLAG_SHIFT);
37509 + break;
37510 + case (e_FM_PCD_KG_GENERIC_FROM_DATA):
37511 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA;
37512 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
37513 + numOfSwDefaults ++;
37514 + break;
37515 + case (e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V):
37516 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V;
37517 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
37518 + numOfSwDefaults ++;
37519 + break;
37520 + case (e_FM_PCD_KG_GENERIC_NOT_FROM_DATA):
37521 + swDefaults[numOfSwDefaults].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
37522 + swDefaults[numOfSwDefaults].dfltSelect = p_KeyAndHash->dflts[i].dfltSelect;
37523 + numOfSwDefaults ++;
37524 + break;
37525 + default:
37526 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
37527 + }
37528 + }
37529 + p_SchemeRegs->kgse_ekdv = tmpReg;
37530 +
37531 + p_LocalExtractsArray = (t_FmPcdKgSchemesExtracts *)XX_Malloc(sizeof(t_FmPcdKgSchemesExtracts));
37532 + if (!p_LocalExtractsArray)
37533 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
37534 +
37535 + /* configure kgse_ekfc and kgse_gec */
37536 + knownTmp = 0;
37537 + for ( i=0 ;i<p_KeyAndHash->numOfUsedExtracts ; i++)
37538 + {
37539 + p_Extract = &p_KeyAndHash->extractArray[i];
37540 + switch (p_Extract->type)
37541 + {
37542 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
37543 + knownTmp |= KG_SCH_KN_PORT_ID;
37544 + /* save in driver structure */
37545 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(KG_SCH_KN_PORT_ID);
37546 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
37547 + break;
37548 + case (e_FM_PCD_EXTRACT_BY_HDR):
37549 + switch (p_Extract->extractByHdr.hdr)
37550 + {
37551 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
37552 + case (HEADER_TYPE_UDP_LITE):
37553 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
37554 + break;
37555 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
37556 + case (HEADER_TYPE_UDP_ENCAP_ESP):
37557 + switch (p_Extract->extractByHdr.type)
37558 + {
37559 + case (e_FM_PCD_EXTRACT_FROM_HDR):
37560 + /* case where extraction from ESP only */
37561 + if (p_Extract->extractByHdr.extractByHdrType.fromHdr.offset >= UDP_HEADER_SIZE)
37562 + {
37563 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37564 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset -= UDP_HEADER_SIZE;
37565 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37566 + }
37567 + else
37568 + {
37569 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
37570 + p_Extract->extractByHdr.ignoreProtocolValidation = FALSE;
37571 + }
37572 + break;
37573 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
37574 + switch (p_Extract->extractByHdr.extractByHdrType.fromField.field.udpEncapEsp)
37575 + {
37576 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
37577 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
37578 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
37579 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
37580 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
37581 + break;
37582 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
37583 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
37584 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37585 + /*p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SPI_OFFSET;*/
37586 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37587 + break;
37588 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
37589 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
37590 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37591 + p_Extract->extractByHdr.extractByHdrType.fromField.offset += ESP_SEQ_NUM_OFFSET;
37592 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37593 + break;
37594 + }
37595 + break;
37596 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
37597 + switch (p_Extract->extractByHdr.extractByHdrType.fullField.udpEncapEsp)
37598 + {
37599 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC):
37600 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST):
37601 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN):
37602 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM):
37603 + p_Extract->extractByHdr.hdr = HEADER_TYPE_UDP;
37604 + break;
37605 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI):
37606 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
37607 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37608 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SPI_SIZE;
37609 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SPI_OFFSET;
37610 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37611 + break;
37612 + case (NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM):
37613 + p_Extract->extractByHdr.type = e_FM_PCD_EXTRACT_FROM_HDR;
37614 + p_Extract->extractByHdr.hdr = FmPcdGetAliasHdr(p_FmPcd, p_Scheme->netEnvId, HEADER_TYPE_UDP_ENCAP_ESP);
37615 + p_Extract->extractByHdr.extractByHdrType.fromHdr.size = ESP_SEQ_NUM_SIZE;
37616 + p_Extract->extractByHdr.extractByHdrType.fromHdr.offset = ESP_SEQ_NUM_OFFSET;
37617 + p_Extract->extractByHdr.ignoreProtocolValidation = TRUE;
37618 + break;
37619 + }
37620 + break;
37621 + }
37622 + break;
37623 + default:
37624 + break;
37625 + }
37626 + switch (p_Extract->extractByHdr.type)
37627 + {
37628 + case (e_FM_PCD_EXTRACT_FROM_HDR):
37629 + generic = TRUE;
37630 + /* get the header code for the generic extract */
37631 + code = GetGenHdrCode(p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex, p_Extract->extractByHdr.ignoreProtocolValidation);
37632 + /* set generic register fields */
37633 + offset = p_Extract->extractByHdr.extractByHdrType.fromHdr.offset;
37634 + size = p_Extract->extractByHdr.extractByHdrType.fromHdr.size;
37635 + break;
37636 + case (e_FM_PCD_EXTRACT_FROM_FIELD):
37637 + generic = TRUE;
37638 + /* get the field code for the generic extract */
37639 + code = GetGenFieldCode(p_Extract->extractByHdr.hdr,
37640 + p_Extract->extractByHdr.extractByHdrType.fromField.field, p_Extract->extractByHdr.ignoreProtocolValidation,p_Extract->extractByHdr.hdrIndex);
37641 + offset = p_Extract->extractByHdr.extractByHdrType.fromField.offset;
37642 + size = p_Extract->extractByHdr.extractByHdrType.fromField.size;
37643 + break;
37644 + case (e_FM_PCD_EXTRACT_FULL_FIELD):
37645 + if (!p_Extract->extractByHdr.ignoreProtocolValidation)
37646 + {
37647 + /* if we have a known field for it - use it, otherwise use generic */
37648 + bitMask = GetKnownProtMask(p_FmPcd, p_Extract->extractByHdr.hdr, p_Extract->extractByHdr.hdrIndex,
37649 + p_Extract->extractByHdr.extractByHdrType.fullField);
37650 + if (bitMask)
37651 + {
37652 + knownTmp |= bitMask;
37653 + /* save in driver structure */
37654 + p_LocalExtractsArray->extractsArray[i].id = GetKnownFieldId(bitMask);
37655 + p_LocalExtractsArray->extractsArray[i].known = TRUE;
37656 + }
37657 + else
37658 + generic = TRUE;
37659 + }
37660 + else
37661 + generic = TRUE;
37662 + if (generic)
37663 + {
37664 + /* tmp - till we cover more headers under generic */
37665 + XX_Free(p_LocalExtractsArray);
37666 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Full header selection not supported"));
37667 + }
37668 + break;
37669 + default:
37670 + XX_Free(p_LocalExtractsArray);
37671 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
37672 + }
37673 + break;
37674 + case (e_FM_PCD_EXTRACT_NON_HDR):
37675 + /* use generic */
37676 + generic = TRUE;
37677 + offset = 0;
37678 + /* get the field code for the generic extract */
37679 + code = GetGenCode(p_Extract->extractNonHdr.src, &offset);
37680 + offset += p_Extract->extractNonHdr.offset;
37681 + size = p_Extract->extractNonHdr.size;
37682 + break;
37683 + default:
37684 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
37685 + }
37686 +
37687 + if (generic)
37688 + {
37689 + /* set generic register fields */
37690 + if (currGenId >= FM_KG_NUM_OF_GENERIC_REGS)
37691 + {
37692 + XX_Free(p_LocalExtractsArray);
37693 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
37694 + }
37695 + if (!code)
37696 + {
37697 + XX_Free(p_LocalExtractsArray);
37698 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
37699 + }
37700 +
37701 + genTmp = KG_SCH_GEN_VALID;
37702 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
37703 + genTmp |= offset;
37704 + if ((size > MAX_KG_SCH_SIZE) || (size < 1))
37705 + {
37706 + XX_Free(p_LocalExtractsArray);
37707 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Illegal extraction (size out of range)"));
37708 + }
37709 + genTmp |= (uint32_t)((size - 1) << KG_SCH_GEN_SIZE_SHIFT);
37710 + swDefault = GetGenericSwDefault(swDefaults, numOfSwDefaults, code);
37711 + if (swDefault == e_FM_PCD_KG_DFLT_ILLEGAL)
37712 + DBG(WARNING, ("No sw default configured"));
37713 + else
37714 + genTmp |= swDefault << KG_SCH_GEN_DEF_SHIFT;
37715 +
37716 + genTmp |= KG_SCH_GEN_MASK;
37717 + p_SchemeRegs->kgse_gec[currGenId] = genTmp;
37718 + /* save in driver structure */
37719 + p_LocalExtractsArray->extractsArray[i].id = currGenId++;
37720 + p_LocalExtractsArray->extractsArray[i].known = FALSE;
37721 + generic = FALSE;
37722 + }
37723 + }
37724 + p_SchemeRegs->kgse_ekfc = knownTmp;
37725 +
37726 + selectTmp = 0;
37727 + maskTmp = 0xFFFFFFFF;
37728 + /* configure kgse_bmch, kgse_bmcl and kgse_fqb */
37729 +
37730 + if (p_KeyAndHash->numOfUsedMasks > FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
37731 + {
37732 + XX_Free(p_LocalExtractsArray);
37733 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Only %d masks supported", FM_PCD_KG_NUM_OF_EXTRACT_MASKS));
37734 + }
37735 + for ( i=0 ;i<p_KeyAndHash->numOfUsedMasks ; i++)
37736 + {
37737 + /* Get the relative id of the extract (for known 0-0x1f, for generic 0-7) */
37738 + id = p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].id;
37739 + /* Get the shift of the select field (depending on i) */
37740 + GET_MASK_SEL_SHIFT(shift,i);
37741 + if (p_LocalExtractsArray->extractsArray[p_KeyAndHash->masks[i].extractArrayIndex].known)
37742 + selectTmp |= id << shift;
37743 + else
37744 + selectTmp |= (id + MASK_FOR_GENERIC_BASE_ID) << shift;
37745 +
37746 + /* Get the shift of the offset field (depending on i) - may
37747 + be in kgse_bmch or in kgse_fqb (depending on i) */
37748 + GET_MASK_OFFSET_SHIFT(shift,i);
37749 + if (i<=1)
37750 + selectTmp |= p_KeyAndHash->masks[i].offset << shift;
37751 + else
37752 + fqbTmp |= p_KeyAndHash->masks[i].offset << shift;
37753 +
37754 + /* Get the shift of the mask field (depending on i) */
37755 + GET_MASK_SHIFT(shift,i);
37756 + /* pass all bits */
37757 + maskTmp |= KG_SCH_BITMASK_MASK << shift;
37758 + /* clear bits that need masking */
37759 + maskTmp &= ~(0xFF << shift) ;
37760 + /* set mask bits */
37761 + maskTmp |= (p_KeyAndHash->masks[i].mask << shift) ;
37762 + }
37763 + p_SchemeRegs->kgse_bmch = selectTmp;
37764 + p_SchemeRegs->kgse_bmcl = maskTmp;
37765 + /* kgse_fqb will be written t the end of the routine */
37766 +
37767 + /* configure kgse_hc */
37768 + if (p_KeyAndHash->hashShift > MAX_HASH_SHIFT)
37769 + {
37770 + XX_Free(p_LocalExtractsArray);
37771 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashShift must not be larger than %d", MAX_HASH_SHIFT));
37772 + }
37773 + if (p_KeyAndHash->hashDistributionFqidsShift > MAX_DIST_FQID_SHIFT)
37774 + {
37775 + XX_Free(p_LocalExtractsArray);
37776 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("hashDistributionFqidsShift must not be larger than %d", MAX_DIST_FQID_SHIFT));
37777 + }
37778 +
37779 + tmpReg = 0;
37780 +
37781 + tmpReg |= ((p_KeyAndHash->hashDistributionNumOfFqids - 1) << p_KeyAndHash->hashDistributionFqidsShift);
37782 + tmpReg |= p_KeyAndHash->hashShift << KG_SCH_HASH_CONFIG_SHIFT_SHIFT;
37783 +
37784 + if (p_KeyAndHash->symmetricHash)
37785 + {
37786 + if ((!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_MACDST)) ||
37787 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC1) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST1)) ||
37788 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPSRC2) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_IPDST2)) ||
37789 + (!!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PSRC) != !!(p_SchemeRegs->kgse_ekfc & KG_SCH_KN_L4PDST)))
37790 + {
37791 + XX_Free(p_LocalExtractsArray);
37792 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("symmetricHash set but src/dest extractions missing"));
37793 + }
37794 + tmpReg |= KG_SCH_HASH_CONFIG_SYM;
37795 + }
37796 + p_SchemeRegs->kgse_hc = tmpReg;
37797 +
37798 + /* build the return array describing the order of the extractions */
37799 +
37800 + /* the last currGenId places of the array
37801 + are for generic extracts that are always last.
37802 + We now sort for the calculation of the order of the known
37803 + extractions we sort the known extracts between orderedArray[0] and
37804 + orderedArray[p_KeyAndHash->numOfUsedExtracts - currGenId - 1].
37805 + for the calculation of the order of the generic extractions we use:
37806 + num_of_generic - currGenId
37807 + num_of_known - p_KeyAndHash->numOfUsedExtracts - currGenId
37808 + first_generic_index = num_of_known */
37809 + curr = 0;
37810 + for (i=0;i<p_KeyAndHash->numOfUsedExtracts ; i++)
37811 + {
37812 + if (p_LocalExtractsArray->extractsArray[i].known)
37813 + {
37814 + ASSERT_COND(curr<(p_KeyAndHash->numOfUsedExtracts - currGenId));
37815 + j = curr;
37816 + /* id is the extract id (port id = 0, mac src = 1 etc.). the value in the array is the original
37817 + index in the user's extractions array */
37818 + /* we compare the id of the current extract with the id of the extract in the orderedArray[j-1]
37819 + location */
37820 + while ((j > 0) && (p_LocalExtractsArray->extractsArray[i].id <
37821 + p_LocalExtractsArray->extractsArray[p_Scheme->orderedArray[j-1]].id))
37822 + {
37823 + p_Scheme->orderedArray[j] =
37824 + p_Scheme->orderedArray[j-1];
37825 + j--;
37826 + }
37827 + p_Scheme->orderedArray[j] = (uint8_t)i;
37828 + curr++;
37829 + }
37830 + else
37831 + {
37832 + /* index is first_generic_index + generic index (id) */
37833 + idx = (uint8_t)(p_KeyAndHash->numOfUsedExtracts - currGenId + p_LocalExtractsArray->extractsArray[i].id);
37834 + ASSERT_COND(idx < FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY);
37835 + p_Scheme->orderedArray[idx]= (uint8_t)i;
37836 + }
37837 + }
37838 + XX_Free(p_LocalExtractsArray);
37839 + }
37840 + else
37841 + {
37842 + /* clear all unused registers: */
37843 + p_SchemeRegs->kgse_ekfc = 0;
37844 + p_SchemeRegs->kgse_ekdv = 0;
37845 + p_SchemeRegs->kgse_bmch = 0;
37846 + p_SchemeRegs->kgse_bmcl = 0;
37847 + p_SchemeRegs->kgse_hc = 0;
37848 + p_SchemeRegs->kgse_dv0 = 0;
37849 + p_SchemeRegs->kgse_dv1 = 0;
37850 + }
37851 +
37852 + if (p_SchemeParams->bypassFqidGeneration)
37853 + p_SchemeRegs->kgse_hc |= KG_SCH_HASH_CONFIG_NO_FQID;
37854 +
37855 + /* configure kgse_spc */
37856 + if ( p_SchemeParams->schemeCounter.update)
37857 + p_SchemeRegs->kgse_spc = p_SchemeParams->schemeCounter.value;
37858 +
37859 +
37860 + /* check that are enough generic registers */
37861 + if (p_SchemeParams->numOfUsedExtractedOrs + currGenId > FM_KG_NUM_OF_GENERIC_REGS)
37862 + RETURN_ERROR(MAJOR, E_FULL, ("Generic registers are fully used"));
37863 +
37864 + /* extracted OR mask on Qid */
37865 + for ( i=0 ;i<p_SchemeParams->numOfUsedExtractedOrs ; i++)
37866 + {
37867 +
37868 + p_Scheme->extractedOrs = TRUE;
37869 + /* configure kgse_gec[i] */
37870 + p_ExtractOr = &p_SchemeParams->extractedOrs[i];
37871 + switch (p_ExtractOr->type)
37872 + {
37873 + case (e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO):
37874 + code = KG_SCH_GEN_PARSE_RESULT_N_FQID;
37875 + offset = 0;
37876 + break;
37877 + case (e_FM_PCD_EXTRACT_BY_HDR):
37878 + /* get the header code for the generic extract */
37879 + code = GetGenHdrCode(p_ExtractOr->extractByHdr.hdr, p_ExtractOr->extractByHdr.hdrIndex, p_ExtractOr->extractByHdr.ignoreProtocolValidation);
37880 + /* set generic register fields */
37881 + offset = p_ExtractOr->extractionOffset;
37882 + break;
37883 + case (e_FM_PCD_EXTRACT_NON_HDR):
37884 + /* get the field code for the generic extract */
37885 + offset = 0;
37886 + code = GetGenCode(p_ExtractOr->src, &offset);
37887 + offset += p_ExtractOr->extractionOffset;
37888 + break;
37889 + default:
37890 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
37891 + }
37892 +
37893 + /* set generic register fields */
37894 + if (!code)
37895 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
37896 + genTmp = KG_SCH_GEN_EXTRACT_TYPE | KG_SCH_GEN_VALID;
37897 + genTmp |= (uint32_t)(code << KG_SCH_GEN_HT_SHIFT);
37898 + genTmp |= offset;
37899 + if (!!p_ExtractOr->bitOffsetInFqid == !!p_ExtractOr->bitOffsetInPlcrProfile)
37900 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, (" extracted byte must effect either FQID or Policer profile"));
37901 +
37902 + /************************************************************************************
37903 + bitOffsetInFqid and bitOffsetInPolicerProfile are translated to rotate parameter
37904 + in the following way:
37905 +
37906 + Driver API and implementation:
37907 + ==============================
37908 + FQID: extracted OR byte may be shifted right 1-31 bits to effect parts of the FQID.
37909 + if shifted less than 8 bits, or more than 24 bits a mask is set on the bits that
37910 + are not overlapping FQID.
37911 + ------------------------
37912 + | FQID (24) |
37913 + ------------------------
37914 + --------
37915 + | | extracted OR byte
37916 + --------
37917 +
37918 + Policer Profile: extracted OR byte may be shifted right 1-15 bits to effect parts of the
37919 + PP id. Unless shifted exactly 8 bits to overlap the PP id, a mask is set on the bits that
37920 + are not overlapping PP id.
37921 +
37922 + --------
37923 + | PP (8) |
37924 + --------
37925 + --------
37926 + | | extracted OR byte
37927 + --------
37928 +
37929 + HW implementation
37930 + =================
37931 + FQID and PP construct a 32 bit word in the way describe below. Extracted byte is located
37932 + as the highest byte of that word and may be rotated to effect any part os the FQID or
37933 + the PP.
37934 + ------------------------ --------
37935 + | FQID (24) || PP (8) |
37936 + ------------------------ --------
37937 + --------
37938 + | | extracted OR byte
37939 + --------
37940 +
37941 + ************************************************************************************/
37942 +
37943 + if (p_ExtractOr->bitOffsetInFqid)
37944 + {
37945 + if (p_ExtractOr->bitOffsetInFqid > MAX_KG_SCH_FQID_BIT_OFFSET )
37946 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInFqid out of range)"));
37947 + if (p_ExtractOr->bitOffsetInFqid<8)
37948 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid+24) << KG_SCH_GEN_SIZE_SHIFT);
37949 + else
37950 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInFqid-8) << KG_SCH_GEN_SIZE_SHIFT);
37951 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInFqid, TRUE);
37952 + }
37953 + else /* effect policer profile */
37954 + {
37955 + if (p_ExtractOr->bitOffsetInPlcrProfile > MAX_KG_SCH_PP_BIT_OFFSET )
37956 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal extraction (bitOffsetInPlcrProfile out of range)"));
37957 + p_Scheme->bitOffsetInPlcrProfile = p_ExtractOr->bitOffsetInPlcrProfile;
37958 + genTmp |= (uint32_t)((p_ExtractOr->bitOffsetInPlcrProfile+16) << KG_SCH_GEN_SIZE_SHIFT);
37959 + p_ExtractOr->mask &= GetExtractedOrMask(p_ExtractOr->bitOffsetInPlcrProfile, FALSE);
37960 + }
37961 +
37962 + genTmp |= (uint32_t)(p_ExtractOr->extractionOffset << KG_SCH_GEN_DEF_SHIFT);
37963 + /* clear bits that need masking */
37964 + genTmp &= ~KG_SCH_GEN_MASK ;
37965 + /* set mask bits */
37966 + genTmp |= (uint32_t)(p_ExtractOr->mask << KG_SCH_GEN_MASK_SHIFT);
37967 + p_SchemeRegs->kgse_gec[currGenId++] = genTmp;
37968 +
37969 + }
37970 + /* clear all unused GEC registers */
37971 + for ( i=currGenId ;i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
37972 + p_SchemeRegs->kgse_gec[i] = 0;
37973 +
37974 + /* add base Qid for this scheme */
37975 + /* add configuration for kgse_fqb */
37976 + if (p_SchemeParams->baseFqid & ~0x00FFFFFF)
37977 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("baseFqid must be between 1 and 2^24-1"));
37978 +
37979 + fqbTmp |= p_SchemeParams->baseFqid;
37980 + p_SchemeRegs->kgse_fqb = fqbTmp;
37981 +
37982 + p_Scheme->nextEngine = p_SchemeParams->nextEngine;
37983 + p_Scheme->doneAction = p_SchemeParams->kgNextEngineParams.doneAction;
37984 +
37985 + return E_OK;
37986 +}
37987 +
37988 +
37989 +/*****************************************************************************/
37990 +/* Inter-module API routines */
37991 +/*****************************************************************************/
37992 +
37993 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet)
37994 +{
37995 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
37996 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
37997 + t_FmPcdIpcKgClsPlanParams kgAlloc;
37998 + t_Error err = E_OK;
37999 + uint32_t oredVectors = 0;
38000 + int i, j;
38001 +
38002 + /* this routine is protected by the calling routine ! */
38003 + if (p_Grp->numOfOptions >= FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS))
38004 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Too many classification plan basic options selected."));
38005 +
38006 + /* find a new clsPlan group */
38007 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
38008 + if (!p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used)
38009 + break;
38010 + if (i == FM_MAX_NUM_OF_PORTS)
38011 + RETURN_ERROR(MAJOR, E_FULL,("No classification plan groups available."));
38012 +
38013 + p_FmPcd->p_FmPcdKg->clsPlanGrps[i].used = TRUE;
38014 +
38015 + p_Grp->clsPlanGrpId = (uint8_t)i;
38016 +
38017 + if (p_Grp->numOfOptions == 0)
38018 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = (uint8_t)i;
38019 +
38020 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[i];
38021 + p_ClsPlanGrp->netEnvId = p_Grp->netEnvId;
38022 + p_ClsPlanGrp->owners = 0;
38023 + FmPcdSetClsPlanGrpId(p_FmPcd, p_Grp->netEnvId, p_Grp->clsPlanGrpId);
38024 + if (p_Grp->numOfOptions != 0)
38025 + FmPcdIncNetEnvOwners(p_FmPcd, p_Grp->netEnvId);
38026 +
38027 + p_ClsPlanGrp->sizeOfGrp = (uint16_t)(1 << p_Grp->numOfOptions);
38028 + /* a minimal group of 8 is required */
38029 + if (p_ClsPlanGrp->sizeOfGrp < CLS_PLAN_NUM_PER_GRP)
38030 + p_ClsPlanGrp->sizeOfGrp = CLS_PLAN_NUM_PER_GRP;
38031 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
38032 + {
38033 + err = KgAllocClsPlanEntries(h_FmPcd, p_ClsPlanGrp->sizeOfGrp, p_FmPcd->guestId, &p_ClsPlanGrp->baseEntry);
38034 +
38035 + if (err)
38036 + RETURN_ERROR(MINOR, E_INVALID_STATE, NO_MSG);
38037 + }
38038 + else
38039 + {
38040 + t_FmPcdIpcMsg msg;
38041 + uint32_t replyLength;
38042 + t_FmPcdIpcReply reply;
38043 +
38044 + /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
38045 + memset(&reply, 0, sizeof(reply));
38046 + memset(&msg, 0, sizeof(msg));
38047 + memset(&kgAlloc, 0, sizeof(kgAlloc));
38048 + kgAlloc.guestId = p_FmPcd->guestId;
38049 + kgAlloc.numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
38050 + msg.msgId = FM_PCD_ALLOC_KG_CLSPLAN;
38051 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
38052 + replyLength = (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry));
38053 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
38054 + (uint8_t*)&msg,
38055 + sizeof(msg.msgId) + sizeof(kgAlloc),
38056 + (uint8_t*)&reply,
38057 + &replyLength,
38058 + NULL,
38059 + NULL)) != E_OK)
38060 + RETURN_ERROR(MAJOR, err, NO_MSG);
38061 +
38062 + if (replyLength != (sizeof(uint32_t) + sizeof(p_ClsPlanGrp->baseEntry)))
38063 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
38064 + if ((t_Error)reply.error != E_OK)
38065 + RETURN_ERROR(MINOR, (t_Error)reply.error, NO_MSG);
38066 +
38067 + p_ClsPlanGrp->baseEntry = *(uint8_t*)(reply.replyBody);
38068 + }
38069 +
38070 + /* build classification plan entries parameters */
38071 + p_ClsPlanSet->baseEntry = p_ClsPlanGrp->baseEntry;
38072 + p_ClsPlanSet->numOfClsPlanEntries = p_ClsPlanGrp->sizeOfGrp;
38073 +
38074 + oredVectors = 0;
38075 + for (i = 0; i<p_Grp->numOfOptions; i++)
38076 + {
38077 + oredVectors |= p_Grp->optVectors[i];
38078 + /* save an array of used options - the indexes represent the power of 2 index */
38079 + p_ClsPlanGrp->optArray[i] = p_Grp->options[i];
38080 + }
38081 + /* set the classification plan relevant entries so that all bits
38082 + * relevant to the list of options is cleared
38083 + */
38084 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
38085 + p_ClsPlanSet->vectors[j] = ~oredVectors;
38086 +
38087 + for (i = 0; i<p_Grp->numOfOptions; i++)
38088 + {
38089 + /* option i got the place 2^i in the clsPlan array. all entries that
38090 + * have bit i set, should have the vector bit cleared. So each option
38091 + * has one location that it is exclusive (1,2,4,8...) and represent the
38092 + * presence of that option only, and other locations that represent a
38093 + * combination of options.
38094 + * e.g:
38095 + * If ethernet-BC is option 1 it gets entry 2 in the table. Entry 2
38096 + * now represents a frame with ethernet-BC header - so the bit
38097 + * representing ethernet-BC should be set and all other option bits
38098 + * should be cleared.
38099 + * Entries 2,3,6,7,10... also have ethernet-BC and therefore have bit
38100 + * vector[1] set, but they also have other bits set:
38101 + * 3=1+2, options 0 and 1
38102 + * 6=2+4, options 1 and 2
38103 + * 7=1+2+4, options 0,1,and 2
38104 + * 10=2+8, options 1 and 3
38105 + * etc.
38106 + * */
38107 +
38108 + /* now for each option (i), we set their bits in all entries (j)
38109 + * that contain bit 2^i.
38110 + */
38111 + for (j = 0; j<p_ClsPlanGrp->sizeOfGrp; j++)
38112 + {
38113 + if (j & (1<<i))
38114 + p_ClsPlanSet->vectors[j] |= p_Grp->optVectors[i];
38115 + }
38116 + }
38117 +
38118 + return E_OK;
38119 +}
38120 +
38121 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId)
38122 +{
38123 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38124 + t_FmPcdIpcKgClsPlanParams kgAlloc;
38125 + t_Error err;
38126 + t_FmPcdIpcMsg msg;
38127 + uint32_t replyLength;
38128 + t_FmPcdIpcReply reply;
38129 +
38130 + /* check that no port is bound to this clsPlan */
38131 + if (p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].owners)
38132 + {
38133 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Trying to delete a clsPlan grp that has ports bound to"));
38134 + return;
38135 + }
38136 +
38137 + FmPcdSetClsPlanGrpId(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId, ILLEGAL_CLS_PLAN);
38138 +
38139 + if (grpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
38140 + p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
38141 + else
38142 + FmPcdDecNetEnvOwners(p_FmPcd, p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].netEnvId);
38143 +
38144 + /* free blocks */
38145 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
38146 + KgFreeClsPlanEntries(h_FmPcd,
38147 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp,
38148 + p_FmPcd->guestId,
38149 + p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry);
38150 + else /* in GUEST_PARTITION, we use the IPC, to also set a private driver group if required */
38151 + {
38152 + memset(&reply, 0, sizeof(reply));
38153 + memset(&msg, 0, sizeof(msg));
38154 + kgAlloc.guestId = p_FmPcd->guestId;
38155 + kgAlloc.numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].sizeOfGrp;
38156 + kgAlloc.clsPlanBase = p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId].baseEntry;
38157 + msg.msgId = FM_PCD_FREE_KG_CLSPLAN;
38158 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
38159 + replyLength = sizeof(uint32_t);
38160 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
38161 + (uint8_t*)&msg,
38162 + sizeof(msg.msgId) + sizeof(kgAlloc),
38163 + (uint8_t*)&reply,
38164 + &replyLength,
38165 + NULL,
38166 + NULL);
38167 + if (err != E_OK)
38168 + {
38169 + REPORT_ERROR(MINOR, err, NO_MSG);
38170 + return;
38171 + }
38172 + if (replyLength != sizeof(uint32_t))
38173 + {
38174 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
38175 + return;
38176 + }
38177 + if ((t_Error)reply.error != E_OK)
38178 + {
38179 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Free KG clsPlan failed"));
38180 + return;
38181 + }
38182 + }
38183 +
38184 + /* clear clsPlan driver structure */
38185 + memset(&p_FmPcd->p_FmPcdKg->clsPlanGrps[grpId], 0, sizeof(t_FmPcdKgClsPlanGrp));
38186 +}
38187 +
38188 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_BindPort, uint32_t *p_SpReg, bool add)
38189 +{
38190 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38191 + uint32_t j, schemesPerPortVector = 0;
38192 + t_FmPcdKgScheme *p_Scheme;
38193 + uint8_t i, relativeSchemeId;
38194 + uint32_t tmp, walking1Mask;
38195 + uint8_t swPortIndex = 0;
38196 +
38197 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
38198 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
38199 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
38200 +
38201 + /* for each scheme */
38202 + for (i = 0; i<p_BindPort->numOfSchemes; i++)
38203 + {
38204 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, p_BindPort->schemesIds[i]);
38205 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
38206 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
38207 +
38208 + if (add)
38209 + {
38210 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
38211 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
38212 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
38213 + /* check netEnvId of the port against the scheme netEnvId */
38214 + if ((p_Scheme->netEnvId != p_BindPort->netEnvId) && (p_Scheme->netEnvId != ILLEGAL_NETENV))
38215 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port may not be bound to requested scheme - differ in netEnvId"));
38216 +
38217 + /* if next engine is private port policer profile, we need to check that it is valid */
38218 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, p_BindPort->hardwarePortId);
38219 + if (p_Scheme->nextRelativePlcrProfile)
38220 + {
38221 + for (j = 0;j<p_Scheme->numOfProfiles;j++)
38222 + {
38223 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort);
38224 + if (p_Scheme->relativeProfileId+j >= p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles)
38225 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Relative profile not in range"));
38226 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase + p_Scheme->relativeProfileId + j)))
38227 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Relative profile not valid."));
38228 + }
38229 + }
38230 + if (!p_BindPort->useClsPlan)
38231 + {
38232 + /* This check may be redundant as port is a assigned to the whole NetEnv */
38233 +
38234 + /* if this port does not use clsPlan, it may not be bound to schemes with units that contain
38235 + cls plan options. Schemes that are used only directly, should not be checked.
38236 + it also may not be bound to schemes that go to CC with units that are options - so we OR
38237 + the match vector and the grpBits (= ccUnits) */
38238 + if ((p_Scheme->matchVector != SCHEME_ALWAYS_DIRECT) || p_Scheme->ccUnits)
38239 + {
38240 + uint8_t netEnvId;
38241 + walking1Mask = 0x80000000;
38242 + netEnvId = (p_Scheme->netEnvId == ILLEGAL_NETENV)? p_BindPort->netEnvId:p_Scheme->netEnvId;
38243 + tmp = (p_Scheme->matchVector == SCHEME_ALWAYS_DIRECT)? 0:p_Scheme->matchVector;
38244 + tmp |= p_Scheme->ccUnits;
38245 + while (tmp)
38246 + {
38247 + if (tmp & walking1Mask)
38248 + {
38249 + tmp &= ~walking1Mask;
38250 + if (!PcdNetEnvIsUnitWithoutOpts(p_FmPcd, netEnvId, walking1Mask))
38251 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Port (without clsPlan) may not be bound to requested scheme - uses clsPlan options"));
38252 + }
38253 + walking1Mask >>= 1;
38254 + }
38255 + }
38256 + }
38257 + }
38258 + /* build vector */
38259 + schemesPerPortVector |= 1 << (31 - p_BindPort->schemesIds[i]);
38260 + }
38261 +
38262 + *p_SpReg = schemesPerPortVector;
38263 +
38264 + return E_OK;
38265 +}
38266 +
38267 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
38268 +{
38269 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38270 + uint32_t spReg;
38271 + t_Error err = E_OK;
38272 +
38273 + err = FmPcdKgBuildBindPortToSchemes(h_FmPcd, p_SchemeBind, &spReg, TRUE);
38274 + if (err)
38275 + RETURN_ERROR(MAJOR, err, NO_MSG);
38276 +
38277 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, TRUE);
38278 + if (err)
38279 + RETURN_ERROR(MAJOR, err, NO_MSG);
38280 +
38281 + IncSchemeOwners(p_FmPcd, p_SchemeBind);
38282 +
38283 + return E_OK;
38284 +}
38285 +
38286 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
38287 +{
38288 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38289 + uint32_t spReg;
38290 + t_Error err = E_OK;
38291 +
38292 + err = FmPcdKgBuildBindPortToSchemes(p_FmPcd, p_SchemeBind, &spReg, FALSE);
38293 + if (err)
38294 + RETURN_ERROR(MAJOR, err, NO_MSG);
38295 +
38296 + err = KgWriteSp(p_FmPcd, p_SchemeBind->hardwarePortId, spReg, FALSE);
38297 + if (err)
38298 + RETURN_ERROR(MAJOR, err, NO_MSG);
38299 +
38300 + DecSchemeOwners(p_FmPcd, p_SchemeBind);
38301 +
38302 + return E_OK;
38303 +}
38304 +
38305 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme)
38306 +{
38307 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
38308 +
38309 + return p_Scheme->valid;
38310 +}
38311 +
38312 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId)
38313 +{
38314 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38315 +
38316 + if (p_FmPcd->p_FmPcdKg->schemes[schemeId].matchVector == SCHEME_ALWAYS_DIRECT)
38317 + return TRUE;
38318 + else
38319 + return FALSE;
38320 +}
38321 +
38322 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
38323 +{
38324 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38325 + uint8_t i, j;
38326 +
38327 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
38328 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
38329 +
38330 + /* This routine is issued only on master core of master partition -
38331 + either directly or through IPC, so no need for lock */
38332 +
38333 + for (j = 0, i = 0; i < FM_PCD_KG_NUM_OF_SCHEMES && j < numOfSchemes; i++)
38334 + {
38335 + if (!p_FmPcd->p_FmPcdKg->schemesMng[i].allocated)
38336 + {
38337 + p_FmPcd->p_FmPcdKg->schemesMng[i].allocated = TRUE;
38338 + p_FmPcd->p_FmPcdKg->schemesMng[i].ownerId = guestId;
38339 + p_SchemesIds[j] = i;
38340 + j++;
38341 + }
38342 + }
38343 +
38344 + if (j != numOfSchemes)
38345 + {
38346 + /* roll back */
38347 + for (j--; j; j--)
38348 + {
38349 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].allocated = FALSE;
38350 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[j]].ownerId = 0;
38351 + p_SchemesIds[j] = 0;
38352 + }
38353 +
38354 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("No schemes found"));
38355 + }
38356 +
38357 + return E_OK;
38358 +}
38359 +
38360 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds)
38361 +{
38362 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38363 + uint8_t i;
38364 +
38365 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
38366 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE);
38367 +
38368 + /* This routine is issued only on master core of master partition -
38369 + either directly or through IPC */
38370 +
38371 + for (i = 0; i < numOfSchemes; i++)
38372 + {
38373 + if (!p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated)
38374 + {
38375 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme was not previously allocated"));
38376 + }
38377 + if (p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId != guestId)
38378 + {
38379 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Scheme is not owned by caller. "));
38380 + }
38381 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].allocated = FALSE;
38382 + p_FmPcd->p_FmPcdKg->schemesMng[p_SchemesIds[i]].ownerId = 0;
38383 + }
38384 +
38385 + return E_OK;
38386 +}
38387 +
38388 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First)
38389 +{
38390 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38391 + uint8_t numOfBlocks, blocksFound=0, first=0;
38392 + uint8_t i, j;
38393 +
38394 + /* This routine is issued only on master core of master partition -
38395 + either directly or through IPC, so no need for lock */
38396 +
38397 + if (!numOfClsPlanEntries)
38398 + return E_OK;
38399 +
38400 + if ((numOfClsPlanEntries % CLS_PLAN_NUM_PER_GRP) || (!POWER_OF_2(numOfClsPlanEntries)))
38401 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfClsPlanEntries must be a power of 2 and divisible by 8"));
38402 +
38403 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
38404 +
38405 + /* try to find consequent blocks */
38406 + first = 0;
38407 + for (i = 0; i < FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP;)
38408 + {
38409 + if (!p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated)
38410 + {
38411 + blocksFound++;
38412 + i++;
38413 + if (blocksFound == numOfBlocks)
38414 + break;
38415 + }
38416 + else
38417 + {
38418 + blocksFound = 0;
38419 + /* advance i to the next aligned address */
38420 + first = i = (uint8_t)(first + numOfBlocks);
38421 + }
38422 + }
38423 +
38424 + if (blocksFound == numOfBlocks)
38425 + {
38426 + *p_First = (uint8_t)(first * CLS_PLAN_NUM_PER_GRP);
38427 + for (j = first; j < (first + numOfBlocks); j++)
38428 + {
38429 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].allocated = TRUE;
38430 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[j].ownerId = guestId;
38431 + }
38432 + return E_OK;
38433 + }
38434 + else
38435 + RETURN_ERROR(MINOR, E_FULL, ("No resources for clsPlan"));
38436 +}
38437 +
38438 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base)
38439 +{
38440 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38441 + uint8_t numOfBlocks;
38442 + uint8_t i, baseBlock;
38443 +
38444 +#ifdef DISABLE_ASSERTIONS
38445 +UNUSED(guestId);
38446 +#endif /* DISABLE_ASSERTIONS */
38447 +
38448 + /* This routine is issued only on master core of master partition -
38449 + either directly or through IPC, so no need for lock */
38450 +
38451 + numOfBlocks = (uint8_t)(numOfClsPlanEntries/CLS_PLAN_NUM_PER_GRP);
38452 + ASSERT_COND(!(base%CLS_PLAN_NUM_PER_GRP));
38453 +
38454 + baseBlock = (uint8_t)(base/CLS_PLAN_NUM_PER_GRP);
38455 + for (i=baseBlock;i<baseBlock+numOfBlocks;i++)
38456 + {
38457 + ASSERT_COND(p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated);
38458 + ASSERT_COND(guestId == p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId);
38459 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].allocated = FALSE;
38460 + p_FmPcd->p_FmPcdKg->clsPlanBlocksMng[i].ownerId = 0;
38461 + }
38462 +}
38463 +
38464 +void KgEnable(t_FmPcd *p_FmPcd)
38465 +{
38466 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
38467 +
38468 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
38469 + fman_kg_enable(p_Regs);
38470 +}
38471 +
38472 +void KgDisable(t_FmPcd *p_FmPcd)
38473 +{
38474 + struct fman_kg_regs *p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
38475 +
38476 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
38477 + fman_kg_disable(p_Regs);
38478 +}
38479 +
38480 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set)
38481 +{
38482 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38483 + struct fman_kg_cp_regs *p_FmPcdKgPortRegs;
38484 + uint32_t tmpKgarReg = 0, intFlags;
38485 + uint16_t i, j;
38486 +
38487 + /* This routine is protected by the calling routine ! */
38488 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
38489 + p_FmPcdKgPortRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->clsPlanRegs;
38490 +
38491 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
38492 + for (i=p_Set->baseEntry;i<p_Set->baseEntry+p_Set->numOfClsPlanEntries;i+=8)
38493 + {
38494 + tmpKgarReg = FmPcdKgBuildWriteClsPlanBlockActionReg((uint8_t)(i / CLS_PLAN_NUM_PER_GRP));
38495 +
38496 + for (j = i; j < i+8; j++)
38497 + {
38498 + ASSERT_COND(IN_RANGE(0, (j - p_Set->baseEntry), FM_PCD_MAX_NUM_OF_CLS_PLANS-1));
38499 + WRITE_UINT32(p_FmPcdKgPortRegs->kgcpe[j % CLS_PLAN_NUM_PER_GRP],p_Set->vectors[j - p_Set->baseEntry]);
38500 + }
38501 +
38502 + if (WriteKgarWait(p_FmPcd, tmpKgarReg) != E_OK)
38503 + {
38504 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("WriteKgarWait FAILED"));
38505 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38506 + return;
38507 + }
38508 + }
38509 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
38510 +}
38511 +
38512 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
38513 +{
38514 + t_FmPcdKg *p_FmPcdKg;
38515 +
38516 + UNUSED(p_FmPcd);
38517 +
38518 + if (p_FmPcdParams->numOfSchemes > FM_PCD_KG_NUM_OF_SCHEMES)
38519 + {
38520 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
38521 + ("numOfSchemes should not exceed %d", FM_PCD_KG_NUM_OF_SCHEMES));
38522 + return NULL;
38523 + }
38524 +
38525 + p_FmPcdKg = (t_FmPcdKg *)XX_Malloc(sizeof(t_FmPcdKg));
38526 + if (!p_FmPcdKg)
38527 + {
38528 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Keygen allocation FAILED"));
38529 + return NULL;
38530 + }
38531 + memset(p_FmPcdKg, 0, sizeof(t_FmPcdKg));
38532 +
38533 +
38534 + if (FmIsMaster(p_FmPcd->h_Fm))
38535 + {
38536 + p_FmPcdKg->p_FmPcdKgRegs = (struct fman_kg_regs *)UINT_TO_PTR(FmGetPcdKgBaseAddr(p_FmPcdParams->h_Fm));
38537 + p_FmPcd->exceptions |= DEFAULT_fmPcdKgErrorExceptions;
38538 + p_FmPcdKg->p_IndirectAccessRegs = (u_FmPcdKgIndirectAccessRegs *)&p_FmPcdKg->p_FmPcdKgRegs->fmkg_indirect[0];
38539 + }
38540 +
38541 + p_FmPcdKg->numOfSchemes = p_FmPcdParams->numOfSchemes;
38542 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) && !p_FmPcdKg->numOfSchemes)
38543 + {
38544 + p_FmPcdKg->numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
38545 + DBG(WARNING, ("numOfSchemes was defined 0 by user, re-defined by driver to FM_PCD_KG_NUM_OF_SCHEMES"));
38546 + }
38547 +
38548 + p_FmPcdKg->emptyClsPlanGrpId = ILLEGAL_CLS_PLAN;
38549 +
38550 + return p_FmPcdKg;
38551 +}
38552 +
38553 +t_Error KgInit(t_FmPcd *p_FmPcd)
38554 +{
38555 + t_Error err = E_OK;
38556 +
38557 + p_FmPcd->p_FmPcdKg->h_HwSpinlock = XX_InitSpinlock();
38558 + if (!p_FmPcd->p_FmPcdKg->h_HwSpinlock)
38559 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM KG HW spinlock"));
38560 +
38561 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
38562 + err = KgInitMaster(p_FmPcd);
38563 + else
38564 + err = KgInitGuest(p_FmPcd);
38565 +
38566 + if (err != E_OK)
38567 + {
38568 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
38569 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
38570 + }
38571 +
38572 + return err;
38573 +}
38574 +
38575 +t_Error KgFree(t_FmPcd *p_FmPcd)
38576 +{
38577 + t_FmPcdIpcKgSchemesParams kgAlloc;
38578 + t_Error err = E_OK;
38579 + t_FmPcdIpcMsg msg;
38580 + uint32_t replyLength;
38581 + t_FmPcdIpcReply reply;
38582 +
38583 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_KG, 0, e_FM_INTR_TYPE_ERR);
38584 +
38585 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
38586 + {
38587 + err = FmPcdKgFreeSchemes(p_FmPcd,
38588 + p_FmPcd->p_FmPcdKg->numOfSchemes,
38589 + p_FmPcd->guestId,
38590 + p_FmPcd->p_FmPcdKg->schemesIds);
38591 + if (err)
38592 + RETURN_ERROR(MAJOR, err, NO_MSG);
38593 +
38594 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
38595 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
38596 +
38597 + return E_OK;
38598 + }
38599 +
38600 + /* guest */
38601 + memset(&reply, 0, sizeof(reply));
38602 + memset(&msg, 0, sizeof(msg));
38603 + kgAlloc.numOfSchemes = p_FmPcd->p_FmPcdKg->numOfSchemes;
38604 + kgAlloc.guestId = p_FmPcd->guestId;
38605 + ASSERT_COND(kgAlloc.numOfSchemes < FM_PCD_KG_NUM_OF_SCHEMES);
38606 + memcpy(kgAlloc.schemesIds, p_FmPcd->p_FmPcdKg->schemesIds, (sizeof(uint8_t))*kgAlloc.numOfSchemes);
38607 + msg.msgId = FM_PCD_FREE_KG_SCHEMES;
38608 + memcpy(msg.msgBody, &kgAlloc, sizeof(kgAlloc));
38609 + replyLength = sizeof(uint32_t);
38610 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
38611 + (uint8_t*)&msg,
38612 + sizeof(msg.msgId) + sizeof(kgAlloc),
38613 + (uint8_t*)&reply,
38614 + &replyLength,
38615 + NULL,
38616 + NULL)) != E_OK)
38617 + RETURN_ERROR(MAJOR, err, NO_MSG);
38618 + if (replyLength != sizeof(uint32_t))
38619 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
38620 +
38621 + if (p_FmPcd->p_FmPcdKg->h_HwSpinlock)
38622 + XX_FreeSpinlock(p_FmPcd->p_FmPcdKg->h_HwSpinlock);
38623 +
38624 + return (t_Error)reply.error;
38625 +}
38626 +
38627 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp)
38628 +{
38629 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38630 + t_FmPcdKgInterModuleClsPlanGrpParams grpParams, *p_GrpParams;
38631 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp;
38632 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
38633 + t_Error err;
38634 +
38635 + /* This function is issued only from FM_PORT_SetPcd which locked all PCD modules,
38636 + so no need for lock here */
38637 +
38638 + memset(&grpParams, 0, sizeof(grpParams));
38639 + grpParams.clsPlanGrpId = ILLEGAL_CLS_PLAN;
38640 + p_GrpParams = &grpParams;
38641 +
38642 + p_GrpParams->netEnvId = netEnvId;
38643 +
38644 + /* Get from the NetEnv the information of the clsPlan (can be already created,
38645 + * or needs to build) */
38646 + err = PcdGetClsPlanGrpParams(h_FmPcd, p_GrpParams);
38647 + if (err)
38648 + RETURN_ERROR(MINOR,err,NO_MSG);
38649 +
38650 + if (p_GrpParams->grpExists)
38651 + {
38652 + /* this group was already updated (at least) in SW */
38653 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
38654 + }
38655 + else
38656 + {
38657 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
38658 + if (!p_ClsPlanSet)
38659 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
38660 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
38661 + /* Build (in SW) the clsPlan parameters, including the vectors to be written to HW */
38662 + err = FmPcdKgBuildClsPlanGrp(h_FmPcd, p_GrpParams, p_ClsPlanSet);
38663 + if (err)
38664 + {
38665 + XX_Free(p_ClsPlanSet);
38666 + RETURN_ERROR(MINOR, err, NO_MSG);
38667 + }
38668 + *p_ClsPlanGrpId = p_GrpParams->clsPlanGrpId;
38669 +
38670 + if (p_FmPcd->h_Hc)
38671 + {
38672 + /* write clsPlan entries to memory */
38673 + err = FmHcPcdKgSetClsPlan(p_FmPcd->h_Hc, p_ClsPlanSet);
38674 + if (err)
38675 + {
38676 + XX_Free(p_ClsPlanSet);
38677 + RETURN_ERROR(MAJOR, err, NO_MSG);
38678 + }
38679 + }
38680 + else
38681 + /* write clsPlan entries to memory */
38682 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
38683 +
38684 + XX_Free(p_ClsPlanSet);
38685 + }
38686 +
38687 + /* Set caller parameters */
38688 +
38689 + /* mark if this is an empty classification group */
38690 + if (*p_ClsPlanGrpId == p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId)
38691 + *p_IsEmptyClsPlanGrp = TRUE;
38692 + else
38693 + *p_IsEmptyClsPlanGrp = FALSE;
38694 +
38695 + p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[*p_ClsPlanGrpId];
38696 +
38697 + /* increment owners number */
38698 + p_ClsPlanGrp->owners++;
38699 +
38700 + /* copy options array for port */
38701 + 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));
38702 +
38703 + /* bind port to the new or existing group */
38704 + err = BindPortToClsPlanGrp(p_FmPcd, hardwarePortId, p_GrpParams->clsPlanGrpId);
38705 + if (err)
38706 + RETURN_ERROR(MINOR, err, NO_MSG);
38707 +
38708 + return E_OK;
38709 +}
38710 +
38711 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId)
38712 +{
38713 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
38714 + t_FmPcdKgClsPlanGrp *p_ClsPlanGrp = &p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId];
38715 + t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet;
38716 + t_Error err;
38717 +
38718 + /* This function is issued only from FM_PORT_DeletePcd which locked all PCD modules,
38719 + so no need for lock here */
38720 +
38721 + UnbindPortToClsPlanGrp(p_FmPcd, hardwarePortId);
38722 +
38723 + /* decrement owners number */
38724 + ASSERT_COND(p_ClsPlanGrp->owners);
38725 + p_ClsPlanGrp->owners--;
38726 +
38727 + if (!p_ClsPlanGrp->owners)
38728 + {
38729 + if (p_FmPcd->h_Hc)
38730 + {
38731 + err = FmHcPcdKgDeleteClsPlan(p_FmPcd->h_Hc, clsPlanGrpId);
38732 + return err;
38733 + }
38734 + else
38735 + {
38736 + /* clear clsPlan entries in memory */
38737 + p_ClsPlanSet = (t_FmPcdKgInterModuleClsPlanSet *)XX_Malloc(sizeof(t_FmPcdKgInterModuleClsPlanSet));
38738 + if (!p_ClsPlanSet)
38739 + {
38740 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Classification plan set"));
38741 + }
38742 + memset(p_ClsPlanSet, 0, sizeof(t_FmPcdKgInterModuleClsPlanSet));
38743 +
38744 + p_ClsPlanSet->baseEntry = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].baseEntry;
38745 + p_ClsPlanSet->numOfClsPlanEntries = p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrpId].sizeOfGrp;
38746 + KgSetClsPlan(p_FmPcd, p_ClsPlanSet);
38747 + XX_Free(p_ClsPlanSet);
38748 +
38749 + FmPcdKgDestroyClsPlanGrp(h_FmPcd, clsPlanGrpId);
38750 + }
38751 + }
38752 + return E_OK;
38753 +}
38754 +
38755 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId)
38756 +{
38757 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38758 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38759 +
38760 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredAction;
38761 +}
38762 +
38763 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId)
38764 +{
38765 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38766 +
38767 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38768 +
38769 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].requiredActionFlag;
38770 +}
38771 +
38772 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId)
38773 +{
38774 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38775 +
38776 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38777 +
38778 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].directPlcr;
38779 +}
38780 +
38781 +
38782 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId)
38783 +{
38784 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38785 +
38786 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38787 +
38788 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].relativeProfileId;
38789 +}
38790 +
38791 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId)
38792 +{
38793 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38794 +
38795 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38796 +
38797 + if ((p_FmPcd->p_FmPcdKg->schemes[schemeId].extractedOrs &&
38798 + p_FmPcd->p_FmPcdKg->schemes[schemeId].bitOffsetInPlcrProfile) ||
38799 + p_FmPcd->p_FmPcdKg->schemes[schemeId].nextRelativePlcrProfile)
38800 + return TRUE;
38801 + else
38802 + return FALSE;
38803 +
38804 +}
38805 +
38806 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t relativeSchemeId)
38807 +{
38808 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38809 +
38810 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].valid);
38811 +
38812 + return p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine;
38813 +}
38814 +
38815 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId)
38816 +{
38817 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38818 +
38819 + ASSERT_COND(p_FmPcd->p_FmPcdKg->schemes[schemeId].valid);
38820 +
38821 + return p_FmPcd->p_FmPcdKg->schemes[schemeId].doneAction;
38822 +}
38823 +
38824 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction)
38825 +{
38826 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
38827 +
38828 + /* this routine is protected by calling routine */
38829 +
38830 + ASSERT_COND(p_Scheme->valid);
38831 +
38832 + p_Scheme->requiredAction |= requiredAction;
38833 +}
38834 +
38835 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg)
38836 +{
38837 + return (bool)!!(schemeModeReg & KG_SCH_MODE_EN);
38838 +}
38839 +
38840 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter)
38841 +{
38842 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
38843 + FM_KG_KGAR_GO |
38844 + FM_KG_KGAR_WRITE |
38845 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
38846 + DUMMY_PORT_ID |
38847 + (updateCounter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT:0));
38848 +}
38849 +
38850 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId)
38851 +{
38852 + return (uint32_t)(((uint32_t)schemeId << FM_PCD_KG_KGAR_NUM_SHIFT) |
38853 + FM_KG_KGAR_GO |
38854 + FM_KG_KGAR_READ |
38855 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
38856 + DUMMY_PORT_ID |
38857 + FM_KG_KGAR_SCM_WSEL_UPDATE_CNT);
38858 +
38859 +}
38860 +
38861 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId)
38862 +{
38863 + return (uint32_t)(FM_KG_KGAR_GO |
38864 + FM_KG_KGAR_WRITE |
38865 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
38866 + DUMMY_PORT_ID |
38867 + ((uint32_t)grpId << FM_PCD_KG_KGAR_NUM_SHIFT) |
38868 + FM_PCD_KG_KGAR_WSEL_MASK);
38869 +
38870 + /* if we ever want to write 1 by 1, use:
38871 + sel = (uint8_t)(0x01 << (7- (entryId % CLS_PLAN_NUM_PER_GRP)));
38872 + */
38873 +}
38874 +
38875 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId)
38876 +{
38877 +
38878 + return (uint32_t)(FM_KG_KGAR_GO |
38879 + FM_KG_KGAR_WRITE |
38880 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
38881 + hardwarePortId |
38882 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
38883 +}
38884 +
38885 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId)
38886 +{
38887 +
38888 + return (uint32_t)(FM_KG_KGAR_GO |
38889 + FM_KG_KGAR_READ |
38890 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
38891 + hardwarePortId |
38892 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
38893 +}
38894 +
38895 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId)
38896 +{
38897 +
38898 + return (uint32_t)(FM_KG_KGAR_GO |
38899 + FM_KG_KGAR_WRITE |
38900 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
38901 + hardwarePortId |
38902 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
38903 +}
38904 +
38905 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp)
38906 +{
38907 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38908 +
38909 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].baseEntry;
38910 +}
38911 +
38912 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp)
38913 +{
38914 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38915 +
38916 + return p_FmPcd->p_FmPcdKg->clsPlanGrps[clsPlanGrp].sizeOfGrp;
38917 +}
38918 +
38919 +
38920 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme)
38921 +{
38922 + return ((t_FmPcdKgScheme*)h_Scheme)->schemeId;
38923 +
38924 +}
38925 +
38926 +#if (DPAA_VERSION >= 11)
38927 +bool FmPcdKgGetVspe(t_Handle h_Scheme)
38928 +{
38929 + return ((t_FmPcdKgScheme*)h_Scheme)->vspe;
38930 +
38931 +}
38932 +#endif /* (DPAA_VERSION >= 11) */
38933 +
38934 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId)
38935 +{
38936 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38937 + uint8_t i;
38938 +
38939 + for (i = 0;i<p_FmPcd->p_FmPcdKg->numOfSchemes;i++)
38940 + if (p_FmPcd->p_FmPcdKg->schemesIds[i] == schemeId)
38941 + return i;
38942 +
38943 + if (i == p_FmPcd->p_FmPcdKg->numOfSchemes)
38944 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("Scheme is out of partition range"));
38945 +
38946 + return FM_PCD_KG_NUM_OF_SCHEMES;
38947 +}
38948 +
38949 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId)
38950 +{
38951 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38952 +
38953 + ASSERT_COND(p_FmPcd);
38954 +
38955 + /* check that schemeId is in range */
38956 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
38957 + {
38958 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
38959 + return NULL;
38960 + }
38961 +
38962 + if (!FmPcdKgIsSchemeValidSw(&p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId]))
38963 + return NULL;
38964 +
38965 + return &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
38966 +}
38967 +
38968 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme)
38969 +{
38970 + return (((t_FmPcdKgScheme*)h_Scheme)->owners == 0)?FALSE:TRUE;
38971 +}
38972 +
38973 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value)
38974 +{
38975 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
38976 + uint8_t relativeSchemeId, physicalSchemeId;
38977 + uint32_t tmpKgarReg, tmpReg32 = 0, intFlags;
38978 + t_Error err;
38979 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme*)h_Scheme;
38980 +
38981 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
38982 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, 0);
38983 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
38984 +
38985 + /* Calling function locked all PCD modules, so no need to lock here */
38986 +
38987 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
38988 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
38989 +
38990 + if (p_FmPcd->h_Hc)
38991 + {
38992 + err = FmHcPcdKgCcGetSetParams(p_FmPcd->h_Hc, h_Scheme, requiredAction, value);
38993 +
38994 + UpdateRequiredActionFlag(h_Scheme,TRUE);
38995 + FmPcdKgUpdateRequiredAction(h_Scheme,requiredAction);
38996 + return err;
38997 + }
38998 +
38999 + physicalSchemeId = p_Scheme->schemeId;
39000 +
39001 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
39002 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
39003 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
39004 +
39005 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredActionFlag ||
39006 + !(p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].requiredAction & requiredAction))
39007 + {
39008 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
39009 + {
39010 + switch (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine)
39011 + {
39012 + case (e_FM_PCD_DONE):
39013 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].doneAction == e_FM_PCD_ENQ_FRAME)
39014 + {
39015 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
39016 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
39017 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39018 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
39019 + ASSERT_COND(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME));
39020 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA);
39021 + /* call indirect command for scheme write */
39022 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
39023 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39024 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39025 + }
39026 + break;
39027 + case (e_FM_PCD_PLCR):
39028 + if (!p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].directPlcr ||
39029 + (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].extractedOrs &&
39030 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].bitOffsetInPlcrProfile) ||
39031 + p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextRelativePlcrProfile)
39032 + {
39033 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("In this situation PP can not be with distribution and has to be shared"));
39034 + }
39035 + err = FmPcdPlcrCcGetSetParams(h_FmPcd, p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].relativeProfileId, requiredAction);
39036 + if (err)
39037 + {
39038 + RETURN_ERROR(MAJOR, err, NO_MSG);
39039 + }
39040 + break;
39041 + default:
39042 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("in this situation the next engine after scheme can be or PLCR or ENQ_FRAME"));
39043 + }
39044 + }
39045 + if (requiredAction & UPDATE_KG_NIA_CC_WA)
39046 + {
39047 + if (p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId].nextEngine == e_FM_PCD_CC)
39048 + {
39049 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
39050 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
39051 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39052 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
39053 + ASSERT_COND(tmpReg32 & (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
39054 + tmpReg32 &= ~NIA_FM_CTL_AC_CC;
39055 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32 | NIA_FM_CTL_AC_PRE_CC);
39056 + /* call indirect command for scheme write */
39057 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
39058 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39059 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39060 + }
39061 + }
39062 + if (requiredAction & UPDATE_KG_OPT_MODE)
39063 + {
39064 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
39065 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
39066 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39067 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_om, value);
39068 + /* call indirect command for scheme write */
39069 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
39070 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39071 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39072 + }
39073 + if (requiredAction & UPDATE_KG_NIA)
39074 + {
39075 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
39076 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
39077 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39078 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode);
39079 + tmpReg32 &= ~(NIA_ENG_MASK | NIA_AC_MASK);
39080 + tmpReg32 |= value;
39081 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, tmpReg32);
39082 + /* call indirect command for scheme write */
39083 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
39084 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39085 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39086 + }
39087 + }
39088 +
39089 + UpdateRequiredActionFlag(h_Scheme, TRUE);
39090 + FmPcdKgUpdateRequiredAction(h_Scheme, requiredAction);
39091 +
39092 + return E_OK;
39093 +}
39094 +/*********************** End of inter-module routines ************************/
39095 +
39096 +
39097 +/****************************************/
39098 +/* API routines */
39099 +/****************************************/
39100 +
39101 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd, t_FmPcdKgSchemeParams *p_SchemeParams)
39102 +{
39103 + t_FmPcd *p_FmPcd;
39104 + struct fman_kg_scheme_regs schemeRegs;
39105 + struct fman_kg_scheme_regs *p_MemRegs;
39106 + uint8_t i;
39107 + t_Error err = E_OK;
39108 + uint32_t tmpKgarReg;
39109 + uint32_t intFlags;
39110 + uint8_t physicalSchemeId, relativeSchemeId = 0;
39111 + t_FmPcdKgScheme *p_Scheme;
39112 +
39113 + if (p_SchemeParams->modify)
39114 + {
39115 + p_Scheme = (t_FmPcdKgScheme *)p_SchemeParams->id.h_Scheme;
39116 + p_FmPcd = p_Scheme->h_FmPcd;
39117 +
39118 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
39119 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
39120 +
39121 + if (!FmPcdKgIsSchemeValidSw(p_Scheme))
39122 + {
39123 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
39124 + ("Scheme is invalid"));
39125 + return NULL;
39126 + }
39127 +
39128 + if (!KgSchemeFlagTryLock(p_Scheme))
39129 + {
39130 + DBG(TRACE, ("Scheme Try Lock - BUSY"));
39131 + /* Signal to caller BUSY condition */
39132 + p_SchemeParams->id.h_Scheme = NULL;
39133 + return NULL;
39134 + }
39135 + }
39136 + else
39137 + {
39138 + p_FmPcd = (t_FmPcd*)h_FmPcd;
39139 +
39140 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, NULL);
39141 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdKg, E_INVALID_HANDLE, NULL);
39142 +
39143 + relativeSchemeId = p_SchemeParams->id.relativeSchemeId;
39144 + /* check that schemeId is in range */
39145 + if (relativeSchemeId >= p_FmPcd->p_FmPcdKg->numOfSchemes)
39146 + {
39147 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, ("relative-scheme-id %d!", relativeSchemeId));
39148 + return NULL;
39149 + }
39150 +
39151 + p_Scheme = &p_FmPcd->p_FmPcdKg->schemes[relativeSchemeId];
39152 + if (FmPcdKgIsSchemeValidSw(p_Scheme))
39153 + {
39154 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS,
39155 + ("Scheme id (%d)!", relativeSchemeId));
39156 + return NULL;
39157 + }
39158 + /* Clear all fields, scheme may have beed previously used */
39159 + memset(p_Scheme, 0, sizeof(t_FmPcdKgScheme));
39160 +
39161 + p_Scheme->schemeId = p_FmPcd->p_FmPcdKg->schemesIds[relativeSchemeId];
39162 + p_Scheme->h_FmPcd = p_FmPcd;
39163 +
39164 + p_Scheme->p_Lock = FmPcdAcquireLock(p_FmPcd);
39165 + if (!p_Scheme->p_Lock)
39166 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM KG Scheme lock obj!"));
39167 + }
39168 +
39169 + err = BuildSchemeRegs((t_Handle)p_Scheme, p_SchemeParams, &schemeRegs);
39170 + if (err)
39171 + {
39172 + REPORT_ERROR(MAJOR, err, NO_MSG);
39173 + if (p_SchemeParams->modify)
39174 + KgSchemeFlagUnlock(p_Scheme);
39175 + if (!p_SchemeParams->modify &&
39176 + p_Scheme->p_Lock)
39177 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
39178 + return NULL;
39179 + }
39180 +
39181 + if (p_FmPcd->h_Hc)
39182 + {
39183 + err = FmHcPcdKgSetScheme(p_FmPcd->h_Hc,
39184 + (t_Handle)p_Scheme,
39185 + &schemeRegs,
39186 + p_SchemeParams->schemeCounter.update);
39187 + if (p_SchemeParams->modify)
39188 + KgSchemeFlagUnlock(p_Scheme);
39189 + if (err)
39190 + {
39191 + if (!p_SchemeParams->modify &&
39192 + p_Scheme->p_Lock)
39193 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
39194 + return NULL;
39195 + }
39196 + if (!p_SchemeParams->modify)
39197 + ValidateSchemeSw(p_Scheme);
39198 + return (t_Handle)p_Scheme;
39199 + }
39200 +
39201 + physicalSchemeId = p_Scheme->schemeId;
39202 +
39203 + /* configure all 21 scheme registers */
39204 + p_MemRegs = &p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs;
39205 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
39206 + WRITE_UINT32(p_MemRegs->kgse_ppc, schemeRegs.kgse_ppc);
39207 + WRITE_UINT32(p_MemRegs->kgse_ccbs, schemeRegs.kgse_ccbs);
39208 + WRITE_UINT32(p_MemRegs->kgse_mode, schemeRegs.kgse_mode);
39209 + WRITE_UINT32(p_MemRegs->kgse_mv, schemeRegs.kgse_mv);
39210 + WRITE_UINT32(p_MemRegs->kgse_dv0, schemeRegs.kgse_dv0);
39211 + WRITE_UINT32(p_MemRegs->kgse_dv1, schemeRegs.kgse_dv1);
39212 + WRITE_UINT32(p_MemRegs->kgse_ekdv, schemeRegs.kgse_ekdv);
39213 + WRITE_UINT32(p_MemRegs->kgse_ekfc, schemeRegs.kgse_ekfc);
39214 + WRITE_UINT32(p_MemRegs->kgse_bmch, schemeRegs.kgse_bmch);
39215 + WRITE_UINT32(p_MemRegs->kgse_bmcl, schemeRegs.kgse_bmcl);
39216 + WRITE_UINT32(p_MemRegs->kgse_hc, schemeRegs.kgse_hc);
39217 + WRITE_UINT32(p_MemRegs->kgse_spc, schemeRegs.kgse_spc);
39218 + WRITE_UINT32(p_MemRegs->kgse_fqb, schemeRegs.kgse_fqb);
39219 + WRITE_UINT32(p_MemRegs->kgse_om, schemeRegs.kgse_om);
39220 + WRITE_UINT32(p_MemRegs->kgse_vsp, schemeRegs.kgse_vsp);
39221 + for (i=0 ; i<FM_KG_NUM_OF_GENERIC_REGS ; i++)
39222 + WRITE_UINT32(p_MemRegs->kgse_gec[i], schemeRegs.kgse_gec[i]);
39223 +
39224 + /* call indirect command for scheme write */
39225 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, p_SchemeParams->schemeCounter.update);
39226 +
39227 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39228 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39229 +
39230 + if (!p_SchemeParams->modify)
39231 + ValidateSchemeSw(p_Scheme);
39232 + else
39233 + KgSchemeFlagUnlock(p_Scheme);
39234 +
39235 + return (t_Handle)p_Scheme;
39236 +}
39237 +
39238 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme)
39239 +{
39240 + t_FmPcd *p_FmPcd;
39241 + uint8_t physicalSchemeId;
39242 + uint32_t tmpKgarReg, intFlags;
39243 + t_Error err = E_OK;
39244 + t_FmPcdKgScheme *p_Scheme = (t_FmPcdKgScheme *)h_Scheme;
39245 +
39246 + SANITY_CHECK_RETURN_ERROR(h_Scheme, E_INVALID_HANDLE);
39247 +
39248 + p_FmPcd = (t_FmPcd*)(p_Scheme->h_FmPcd);
39249 +
39250 + UpdateRequiredActionFlag(h_Scheme, FALSE);
39251 +
39252 + /* check that no port is bound to this scheme */
39253 + err = InvalidateSchemeSw(h_Scheme);
39254 + if (err)
39255 + RETURN_ERROR(MINOR, err, NO_MSG);
39256 +
39257 + if (p_FmPcd->h_Hc)
39258 + {
39259 + err = FmHcPcdKgDeleteScheme(p_FmPcd->h_Hc, h_Scheme);
39260 + if (p_Scheme->p_Lock)
39261 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
39262 + return err;
39263 + }
39264 +
39265 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
39266 +
39267 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
39268 + /* clear mode register, including enable bit */
39269 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode, 0);
39270 +
39271 + /* call indirect command for scheme write */
39272 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, FALSE);
39273 +
39274 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39275 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39276 +
39277 + if (p_Scheme->p_Lock)
39278 + FmPcdReleaseLock(p_FmPcd, p_Scheme->p_Lock);
39279 +
39280 + return E_OK;
39281 +}
39282 +
39283 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme)
39284 +{
39285 + t_FmPcd *p_FmPcd;
39286 + uint32_t tmpKgarReg, spc, intFlags;
39287 + uint8_t physicalSchemeId;
39288 +
39289 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
39290 +
39291 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
39292 + if (p_FmPcd->h_Hc)
39293 + return FmHcPcdKgGetSchemeCounter(p_FmPcd->h_Hc, h_Scheme);
39294 +
39295 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
39296 +
39297 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
39298 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
39299 +
39300 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
39301 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
39302 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39303 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
39304 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
39305 + spc = GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc);
39306 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39307 +
39308 + return spc;
39309 +}
39310 +
39311 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value)
39312 +{
39313 + t_FmPcd *p_FmPcd;
39314 + uint32_t tmpKgarReg, intFlags;
39315 + uint8_t physicalSchemeId;
39316 +
39317 + SANITY_CHECK_RETURN_VALUE(h_Scheme, E_INVALID_HANDLE, 0);
39318 +
39319 + p_FmPcd = (t_FmPcd*)(((t_FmPcdKgScheme *)h_Scheme)->h_FmPcd);
39320 +
39321 + if (!FmPcdKgIsSchemeValidSw(h_Scheme))
39322 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Requested scheme is invalid."));
39323 +
39324 + if (p_FmPcd->h_Hc)
39325 + return FmHcPcdKgSetSchemeCounter(p_FmPcd->h_Hc, h_Scheme, value);
39326 +
39327 + physicalSchemeId = ((t_FmPcdKgScheme *)h_Scheme)->schemeId;
39328 + /* check that schemeId is in range */
39329 + if (FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId) == FM_PCD_KG_NUM_OF_SCHEMES)
39330 + REPORT_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
39331 +
39332 + /* read specified scheme into scheme registers */
39333 + tmpKgarReg = FmPcdKgBuildReadSchemeActionReg(physicalSchemeId);
39334 + intFlags = KgHwLock(p_FmPcd->p_FmPcdKg);
39335 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39336 + if (!(GET_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_mode) & KG_SCH_MODE_EN))
39337 + {
39338 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39339 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, ("Scheme is Invalid"));
39340 + }
39341 +
39342 + /* change counter value */
39343 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_IndirectAccessRegs->schemeRegs.kgse_spc, value);
39344 +
39345 + /* call indirect command for scheme write */
39346 + tmpKgarReg = FmPcdKgBuildWriteSchemeActionReg(physicalSchemeId, TRUE);
39347 +
39348 + WriteKgarWait(p_FmPcd, tmpKgarReg);
39349 + KgHwUnlock(p_FmPcd->p_FmPcdKg, intFlags);
39350 +
39351 + return E_OK;
39352 +}
39353 +
39354 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset)
39355 +{
39356 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39357 + struct fman_kg_regs *p_Regs;
39358 +
39359 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
39360 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
39361 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
39362 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
39363 +
39364 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
39365 + if (!FmIsMaster(p_FmPcd->h_Fm))
39366 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetAdditionalDataAfterParsing - guest mode!"));
39367 +
39368 + WRITE_UINT32(p_Regs->fmkg_fdor,payloadOffset);
39369 +
39370 + return E_OK;
39371 +}
39372 +
39373 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value)
39374 +{
39375 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
39376 + struct fman_kg_regs *p_Regs;
39377 +
39378 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
39379 + SANITY_CHECK_RETURN_ERROR(((valueId == 0) || (valueId == 1)), E_INVALID_VALUE);
39380 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_NULL_POINTER);
39381 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg, E_NULL_POINTER);
39382 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs, E_NULL_POINTER);
39383 +
39384 + p_Regs = p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs;
39385 +
39386 + if (!FmIsMaster(p_FmPcd->h_Fm))
39387 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_KgSetDfltValue - guest mode!"));
39388 +
39389 + if (valueId == 0)
39390 + WRITE_UINT32(p_Regs->fmkg_gdv0r,value);
39391 + else
39392 + WRITE_UINT32(p_Regs->fmkg_gdv1r,value);
39393 + return E_OK;
39394 +}
39395 --- /dev/null
39396 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_kg.h
39397 @@ -0,0 +1,206 @@
39398 +/*
39399 + * Copyright 2008-2012 Freescale Semiconductor Inc.
39400 + *
39401 + * Redistribution and use in source and binary forms, with or without
39402 + * modification, are permitted provided that the following conditions are met:
39403 + * * Redistributions of source code must retain the above copyright
39404 + * notice, this list of conditions and the following disclaimer.
39405 + * * Redistributions in binary form must reproduce the above copyright
39406 + * notice, this list of conditions and the following disclaimer in the
39407 + * documentation and/or other materials provided with the distribution.
39408 + * * Neither the name of Freescale Semiconductor nor the
39409 + * names of its contributors may be used to endorse or promote products
39410 + * derived from this software without specific prior written permission.
39411 + *
39412 + *
39413 + * ALTERNATIVELY, this software may be distributed under the terms of the
39414 + * GNU General Public License ("GPL") as published by the Free Software
39415 + * Foundation, either version 2 of that License or (at your option) any
39416 + * later version.
39417 + *
39418 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
39419 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39420 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39421 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
39422 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39423 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39424 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39425 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39426 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39427 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39428 + */
39429 +
39430 +
39431 +/******************************************************************************
39432 + @File fm_kg.h
39433 +
39434 + @Description FM KG private header
39435 +*//***************************************************************************/
39436 +#ifndef __FM_KG_H
39437 +#define __FM_KG_H
39438 +
39439 +#include "std_ext.h"
39440 +
39441 +/***********************************************************************/
39442 +/* Keygen defines */
39443 +/***********************************************************************/
39444 +/* maskes */
39445 +#if (DPAA_VERSION >= 11)
39446 +#define KG_SCH_VSP_SHIFT_MASK 0x0003f000
39447 +#define KG_SCH_OM_VSPE 0x00000001
39448 +#define KG_SCH_VSP_NO_KSP_EN 0x80000000
39449 +
39450 +#define MAX_SP_SHIFT 23
39451 +#define KG_SCH_VSP_MASK_SHIFT 12
39452 +#define KG_SCH_VSP_SHIFT 24
39453 +#endif /* (DPAA_VERSION >= 11) */
39454 +
39455 +typedef uint32_t t_KnownFieldsMasks;
39456 +#define KG_SCH_KN_PORT_ID 0x80000000
39457 +#define KG_SCH_KN_MACDST 0x40000000
39458 +#define KG_SCH_KN_MACSRC 0x20000000
39459 +#define KG_SCH_KN_TCI1 0x10000000
39460 +#define KG_SCH_KN_TCI2 0x08000000
39461 +#define KG_SCH_KN_ETYPE 0x04000000
39462 +#define KG_SCH_KN_PPPSID 0x02000000
39463 +#define KG_SCH_KN_PPPID 0x01000000
39464 +#define KG_SCH_KN_MPLS1 0x00800000
39465 +#define KG_SCH_KN_MPLS2 0x00400000
39466 +#define KG_SCH_KN_MPLS_LAST 0x00200000
39467 +#define KG_SCH_KN_IPSRC1 0x00100000
39468 +#define KG_SCH_KN_IPDST1 0x00080000
39469 +#define KG_SCH_KN_PTYPE1 0x00040000
39470 +#define KG_SCH_KN_IPTOS_TC1 0x00020000
39471 +#define KG_SCH_KN_IPV6FL1 0x00010000
39472 +#define KG_SCH_KN_IPSRC2 0x00008000
39473 +#define KG_SCH_KN_IPDST2 0x00004000
39474 +#define KG_SCH_KN_PTYPE2 0x00002000
39475 +#define KG_SCH_KN_IPTOS_TC2 0x00001000
39476 +#define KG_SCH_KN_IPV6FL2 0x00000800
39477 +#define KG_SCH_KN_GREPTYPE 0x00000400
39478 +#define KG_SCH_KN_IPSEC_SPI 0x00000200
39479 +#define KG_SCH_KN_IPSEC_NH 0x00000100
39480 +#define KG_SCH_KN_IPPID 0x00000080
39481 +#define KG_SCH_KN_L4PSRC 0x00000004
39482 +#define KG_SCH_KN_L4PDST 0x00000002
39483 +#define KG_SCH_KN_TFLG 0x00000001
39484 +
39485 +typedef uint8_t t_GenericCodes;
39486 +#define KG_SCH_GEN_SHIM1 0x70
39487 +#define KG_SCH_GEN_DEFAULT 0x10
39488 +#define KG_SCH_GEN_PARSE_RESULT_N_FQID 0x20
39489 +#define KG_SCH_GEN_START_OF_FRM 0x40
39490 +#define KG_SCH_GEN_SHIM2 0x71
39491 +#define KG_SCH_GEN_IP_PID_NO_V 0x72
39492 +#define KG_SCH_GEN_ETH 0x03
39493 +#define KG_SCH_GEN_ETH_NO_V 0x73
39494 +#define KG_SCH_GEN_SNAP 0x04
39495 +#define KG_SCH_GEN_SNAP_NO_V 0x74
39496 +#define KG_SCH_GEN_VLAN1 0x05
39497 +#define KG_SCH_GEN_VLAN1_NO_V 0x75
39498 +#define KG_SCH_GEN_VLAN2 0x06
39499 +#define KG_SCH_GEN_VLAN2_NO_V 0x76
39500 +#define KG_SCH_GEN_ETH_TYPE 0x07
39501 +#define KG_SCH_GEN_ETH_TYPE_NO_V 0x77
39502 +#define KG_SCH_GEN_PPP 0x08
39503 +#define KG_SCH_GEN_PPP_NO_V 0x78
39504 +#define KG_SCH_GEN_MPLS1 0x09
39505 +#define KG_SCH_GEN_MPLS2 0x19
39506 +#define KG_SCH_GEN_MPLS3 0x29
39507 +#define KG_SCH_GEN_MPLS1_NO_V 0x79
39508 +#define KG_SCH_GEN_MPLS_LAST 0x0a
39509 +#define KG_SCH_GEN_MPLS_LAST_NO_V 0x7a
39510 +#define KG_SCH_GEN_IPV4 0x0b
39511 +#define KG_SCH_GEN_IPV6 0x1b
39512 +#define KG_SCH_GEN_L3_NO_V 0x7b
39513 +#define KG_SCH_GEN_IPV4_TUNNELED 0x0c
39514 +#define KG_SCH_GEN_IPV6_TUNNELED 0x1c
39515 +#define KG_SCH_GEN_MIN_ENCAP 0x2c
39516 +#define KG_SCH_GEN_IP2_NO_V 0x7c
39517 +#define KG_SCH_GEN_GRE 0x0d
39518 +#define KG_SCH_GEN_GRE_NO_V 0x7d
39519 +#define KG_SCH_GEN_TCP 0x0e
39520 +#define KG_SCH_GEN_UDP 0x1e
39521 +#define KG_SCH_GEN_IPSEC_AH 0x2e
39522 +#define KG_SCH_GEN_SCTP 0x3e
39523 +#define KG_SCH_GEN_DCCP 0x4e
39524 +#define KG_SCH_GEN_IPSEC_ESP 0x6e
39525 +#define KG_SCH_GEN_L4_NO_V 0x7e
39526 +#define KG_SCH_GEN_NEXTHDR 0x7f
39527 +/* shifts */
39528 +#define KG_SCH_PP_SHIFT_HIGH_SHIFT 27
39529 +#define KG_SCH_PP_SHIFT_LOW_SHIFT 12
39530 +#define KG_SCH_PP_MASK_SHIFT 16
39531 +#define KG_SCH_MODE_CCOBASE_SHIFT 24
39532 +#define KG_SCH_DEF_MAC_ADDR_SHIFT 30
39533 +#define KG_SCH_DEF_TCI_SHIFT 28
39534 +#define KG_SCH_DEF_ENET_TYPE_SHIFT 26
39535 +#define KG_SCH_DEF_PPP_SESSION_ID_SHIFT 24
39536 +#define KG_SCH_DEF_PPP_PROTOCOL_ID_SHIFT 22
39537 +#define KG_SCH_DEF_MPLS_LABEL_SHIFT 20
39538 +#define KG_SCH_DEF_IP_ADDR_SHIFT 18
39539 +#define KG_SCH_DEF_PROTOCOL_TYPE_SHIFT 16
39540 +#define KG_SCH_DEF_IP_TOS_TC_SHIFT 14
39541 +#define KG_SCH_DEF_IPV6_FLOW_LABEL_SHIFT 12
39542 +#define KG_SCH_DEF_IPSEC_SPI_SHIFT 10
39543 +#define KG_SCH_DEF_L4_PORT_SHIFT 8
39544 +#define KG_SCH_DEF_TCP_FLAG_SHIFT 6
39545 +#define KG_SCH_HASH_CONFIG_SHIFT_SHIFT 24
39546 +#define KG_SCH_GEN_MASK_SHIFT 16
39547 +#define KG_SCH_GEN_HT_SHIFT 8
39548 +#define KG_SCH_GEN_SIZE_SHIFT 24
39549 +#define KG_SCH_GEN_DEF_SHIFT 29
39550 +#define FM_PCD_KG_KGAR_NUM_SHIFT 16
39551 +
39552 +/* others */
39553 +#define NUM_OF_SW_DEFAULTS 3
39554 +#define MAX_PP_SHIFT 23
39555 +#define MAX_KG_SCH_SIZE 16
39556 +#define MASK_FOR_GENERIC_BASE_ID 0x20
39557 +#define MAX_HASH_SHIFT 40
39558 +#define MAX_KG_SCH_FQID_BIT_OFFSET 31
39559 +#define MAX_KG_SCH_PP_BIT_OFFSET 15
39560 +#define MAX_DIST_FQID_SHIFT 23
39561 +
39562 +#define GET_MASK_SEL_SHIFT(shift,i) \
39563 +switch (i) { \
39564 + case (0):shift = 26;break; \
39565 + case (1):shift = 20;break; \
39566 + case (2):shift = 10;break; \
39567 + case (3):shift = 4;break; \
39568 + default: \
39569 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
39570 +}
39571 +
39572 +#define GET_MASK_OFFSET_SHIFT(shift,i) \
39573 +switch (i) { \
39574 + case (0):shift = 16;break; \
39575 + case (1):shift = 0;break; \
39576 + case (2):shift = 28;break; \
39577 + case (3):shift = 24;break; \
39578 + default: \
39579 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
39580 +}
39581 +
39582 +#define GET_MASK_SHIFT(shift,i) \
39583 +switch (i) { \
39584 + case (0):shift = 24;break; \
39585 + case (1):shift = 16;break; \
39586 + case (2):shift = 8;break; \
39587 + case (3):shift = 0;break; \
39588 + default: \
39589 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG); \
39590 +}
39591 +
39592 +/***********************************************************************/
39593 +/* Keygen defines */
39594 +/***********************************************************************/
39595 +
39596 +#define KG_DOUBLE_MEANING_REGS_OFFSET 0x100
39597 +#define NO_VALIDATION 0x70
39598 +#define KG_ACTION_REG_TO 1024
39599 +#define KG_MAX_PROFILE 255
39600 +#define SCHEME_ALWAYS_DIRECT 0xFFFFFFFF
39601 +
39602 +
39603 +#endif /* __FM_KG_H */
39604 --- /dev/null
39605 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.c
39606 @@ -0,0 +1,5571 @@
39607 +/*
39608 + * Copyright 2008-2012 Freescale Semiconductor Inc.
39609 + *
39610 + * Redistribution and use in source and binary forms, with or without
39611 + * modification, are permitted provided that the following conditions are met:
39612 + * * Redistributions of source code must retain the above copyright
39613 + * notice, this list of conditions and the following disclaimer.
39614 + * * Redistributions in binary form must reproduce the above copyright
39615 + * notice, this list of conditions and the following disclaimer in the
39616 + * documentation and/or other materials provided with the distribution.
39617 + * * Neither the name of Freescale Semiconductor nor the
39618 + * names of its contributors may be used to endorse or promote products
39619 + * derived from this software without specific prior written permission.
39620 + *
39621 + *
39622 + * ALTERNATIVELY, this software may be distributed under the terms of the
39623 + * GNU General Public License ("GPL") as published by the Free Software
39624 + * Foundation, either version 2 of that License or (at your option) any
39625 + * later version.
39626 + *
39627 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
39628 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
39629 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39630 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
39631 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39632 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39633 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39634 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39635 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39636 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39637 + */
39638 +
39639 +
39640 +/******************************************************************************
39641 + @File fm_manip.c
39642 +
39643 + @Description FM PCD manip ...
39644 + *//***************************************************************************/
39645 +#include "std_ext.h"
39646 +#include "error_ext.h"
39647 +#include "string_ext.h"
39648 +#include "debug_ext.h"
39649 +#include "fm_pcd_ext.h"
39650 +#include "fm_port_ext.h"
39651 +#include "fm_muram_ext.h"
39652 +#include "memcpy_ext.h"
39653 +
39654 +#include "fm_common.h"
39655 +#include "fm_hc.h"
39656 +#include "fm_manip.h"
39657 +
39658 +/****************************************/
39659 +/* static functions */
39660 +/****************************************/
39661 +static t_Handle GetManipInfo(t_FmPcdManip *p_Manip, e_ManipInfo manipInfo)
39662 +{
39663 + t_FmPcdManip *p_CurManip = p_Manip;
39664 +
39665 + if (!MANIP_IS_UNIFIED(p_Manip))
39666 + p_CurManip = p_Manip;
39667 + else
39668 + {
39669 + /* go to first unified */
39670 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
39671 + p_CurManip = p_CurManip->h_PrevManip;
39672 + }
39673 +
39674 + switch (manipInfo)
39675 + {
39676 + case (e_MANIP_HMCT):
39677 + return p_CurManip->p_Hmct;
39678 + case (e_MANIP_HMTD):
39679 + return p_CurManip->h_Ad;
39680 + case (e_MANIP_HANDLER_TABLE_OWNER):
39681 + return (t_Handle)p_CurManip;
39682 + default:
39683 + return NULL;
39684 + }
39685 +}
39686 +
39687 +static uint16_t GetHmctSize(t_FmPcdManip *p_Manip)
39688 +{
39689 + uint16_t size = 0;
39690 + t_FmPcdManip *p_CurManip = p_Manip;
39691 +
39692 + if (!MANIP_IS_UNIFIED(p_Manip))
39693 + return p_Manip->tableSize;
39694 +
39695 + /* accumulate sizes, starting with the first node */
39696 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
39697 + p_CurManip = p_CurManip->h_PrevManip;
39698 +
39699 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39700 + {
39701 + size += p_CurManip->tableSize;
39702 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
39703 + }
39704 + size += p_CurManip->tableSize; /* add last size */
39705 +
39706 + return (size);
39707 +}
39708 +
39709 +static uint16_t GetDataSize(t_FmPcdManip *p_Manip)
39710 +{
39711 + uint16_t size = 0;
39712 + t_FmPcdManip *p_CurManip = p_Manip;
39713 +
39714 + if (!MANIP_IS_UNIFIED(p_Manip))
39715 + return p_Manip->dataSize;
39716 +
39717 + /* accumulate sizes, starting with the first node */
39718 + while (MANIP_IS_UNIFIED_NON_FIRST(p_CurManip))
39719 + p_CurManip = p_CurManip->h_PrevManip;
39720 +
39721 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
39722 + {
39723 + size += p_CurManip->dataSize;
39724 + p_CurManip = (t_FmPcdManip *)p_CurManip->h_NextManip;
39725 + }
39726 + size += p_CurManip->dataSize; /* add last size */
39727 +
39728 + return (size);
39729 +}
39730 +
39731 +static t_Error CalculateTableSize(t_FmPcdManipParams *p_FmPcdManipParams,
39732 + uint16_t *p_TableSize, uint8_t *p_DataSize)
39733 +{
39734 + uint8_t localDataSize, remain, tableSize = 0, dataSize = 0;
39735 +
39736 + if (p_FmPcdManipParams->u.hdr.rmv)
39737 + {
39738 + switch (p_FmPcdManipParams->u.hdr.rmvParams.type)
39739 + {
39740 + case (e_FM_PCD_MANIP_RMV_GENERIC):
39741 + tableSize += HMCD_BASIC_SIZE;
39742 + break;
39743 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
39744 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
39745 + {
39746 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
39747 +#if (DPAA_VERSION >= 11)
39748 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
39749 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
39750 +#endif /* (DPAA_VERSION >= 11) */
39751 + tableSize += HMCD_BASIC_SIZE;
39752 + break;
39753 + default:
39754 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39755 + ("Unknown byHdr.type"));
39756 + }
39757 + break;
39758 + default:
39759 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39760 + ("Unknown rmvParams.type"));
39761 + }
39762 + }
39763 +
39764 + if (p_FmPcdManipParams->u.hdr.insrt)
39765 + {
39766 + switch (p_FmPcdManipParams->u.hdr.insrtParams.type)
39767 + {
39768 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
39769 + remain =
39770 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
39771 + % 4);
39772 + if (remain)
39773 + localDataSize =
39774 + (uint8_t)(p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
39775 + + 4 - remain);
39776 + else
39777 + localDataSize =
39778 + p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
39779 + tableSize += (uint8_t)(HMCD_BASIC_SIZE + localDataSize);
39780 + break;
39781 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
39782 + {
39783 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
39784 + {
39785 +
39786 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
39787 + tableSize += HMCD_BASIC_SIZE + HMCD_PTR_SIZE;
39788 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
39789 + {
39790 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
39791 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
39792 + dataSize +=
39793 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
39794 + break;
39795 + default:
39796 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
39797 + }
39798 + break;
39799 +#if (DPAA_VERSION >= 11)
39800 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
39801 + tableSize +=
39802 + (HMCD_BASIC_SIZE + HMCD_PTR_SIZE
39803 + + HMCD_PARAM_SIZE
39804 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
39805 + dataSize += 2;
39806 + break;
39807 +
39808 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
39809 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
39810 + tableSize += (HMCD_BASIC_SIZE + HMCD_L4_HDR_SIZE);
39811 +
39812 + break;
39813 +
39814 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
39815 + tableSize +=
39816 + (HMCD_BASIC_SIZE
39817 + + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
39818 + break;
39819 +#endif /* (DPAA_VERSION >= 11) */
39820 + default:
39821 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39822 + ("Unknown byHdr.type"));
39823 + }
39824 + }
39825 + break;
39826 + default:
39827 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39828 + ("Unknown insrtParams.type"));
39829 + }
39830 + }
39831 +
39832 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
39833 + {
39834 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
39835 + {
39836 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
39837 + tableSize += HMCD_BASIC_SIZE;
39838 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
39839 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
39840 + {
39841 + tableSize += HMCD_PTR_SIZE;
39842 + dataSize += DSCP_TO_VLAN_TABLE_SIZE;
39843 + }
39844 + break;
39845 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
39846 + tableSize += HMCD_BASIC_SIZE;
39847 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39848 + & HDR_MANIP_IPV4_ID)
39849 + {
39850 + tableSize += HMCD_PARAM_SIZE;
39851 + dataSize += 2;
39852 + }
39853 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39854 + & HDR_MANIP_IPV4_SRC)
39855 + tableSize += HMCD_IPV4_ADDR_SIZE;
39856 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39857 + & HDR_MANIP_IPV4_DST)
39858 + tableSize += HMCD_IPV4_ADDR_SIZE;
39859 + break;
39860 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
39861 + tableSize += HMCD_BASIC_SIZE;
39862 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39863 + & HDR_MANIP_IPV6_SRC)
39864 + tableSize += HMCD_IPV6_ADDR_SIZE;
39865 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
39866 + & HDR_MANIP_IPV6_DST)
39867 + tableSize += HMCD_IPV6_ADDR_SIZE;
39868 + break;
39869 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
39870 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
39871 + == HDR_MANIP_TCP_UDP_CHECKSUM)
39872 + /* we implement this case with the update-checksum descriptor */
39873 + tableSize += HMCD_BASIC_SIZE;
39874 + else
39875 + /* we implement this case with the TCP/UDP-update descriptor */
39876 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
39877 + break;
39878 + default:
39879 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39880 + ("Unknown fieldUpdateParams.type"));
39881 + }
39882 + }
39883 +
39884 + if (p_FmPcdManipParams->u.hdr.custom)
39885 + {
39886 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
39887 + {
39888 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
39889 + {
39890 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE + HMCD_PARAM_SIZE;
39891 + dataSize +=
39892 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
39893 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
39894 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
39895 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
39896 + dataSize += 2;
39897 + }
39898 + break;
39899 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
39900 + tableSize += HMCD_BASIC_SIZE + HMCD_PARAM_SIZE;
39901 + break;
39902 + default:
39903 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
39904 + ("Unknown customParams.type"));
39905 + }
39906 + }
39907 +
39908 + *p_TableSize = tableSize;
39909 + *p_DataSize = dataSize;
39910 +
39911 + return E_OK;
39912 +}
39913 +
39914 +static t_Error GetPrOffsetByHeaderOrField(t_FmManipHdrInfo *p_HdrInfo,
39915 + uint8_t *parseArrayOffset)
39916 +{
39917 + e_NetHeaderType hdr = p_HdrInfo->hdr;
39918 + e_FmPcdHdrIndex hdrIndex = p_HdrInfo->hdrIndex;
39919 + bool byField = p_HdrInfo->byField;
39920 + t_FmPcdFields field;
39921 +
39922 + if (byField)
39923 + field = p_HdrInfo->fullField;
39924 +
39925 + if (byField)
39926 + {
39927 + switch (hdr)
39928 + {
39929 + case (HEADER_TYPE_ETH):
39930 + switch (field.eth)
39931 + {
39932 + case (NET_HEADER_FIELD_ETH_TYPE):
39933 + *parseArrayOffset = CC_PC_PR_ETYPE_LAST_OFFSET;
39934 + break;
39935 + default:
39936 + RETURN_ERROR(
39937 + MAJOR,
39938 + E_NOT_SUPPORTED,
39939 + ("Header manipulation of the type Ethernet with this field not supported"));
39940 + }
39941 + break;
39942 + case (HEADER_TYPE_VLAN):
39943 + switch (field.vlan)
39944 + {
39945 + case (NET_HEADER_FIELD_VLAN_TCI):
39946 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
39947 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
39948 + *parseArrayOffset = CC_PC_PR_VLAN1_OFFSET;
39949 + else
39950 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
39951 + *parseArrayOffset = CC_PC_PR_VLAN2_OFFSET;
39952 + break;
39953 + default:
39954 + RETURN_ERROR(
39955 + MAJOR,
39956 + E_NOT_SUPPORTED,
39957 + ("Header manipulation of the type VLAN with this field not supported"));
39958 + }
39959 + break;
39960 + default:
39961 + RETURN_ERROR(
39962 + MAJOR,
39963 + E_NOT_SUPPORTED,
39964 + ("Header manipulation of this header by field not supported"));
39965 + }
39966 + }
39967 + else
39968 + {
39969 + switch (hdr)
39970 + {
39971 + case (HEADER_TYPE_ETH):
39972 + *parseArrayOffset = (uint8_t)CC_PC_PR_ETH_OFFSET;
39973 + break;
39974 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
39975 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM1_OFFSET;
39976 + break;
39977 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
39978 + *parseArrayOffset = (uint8_t)CC_PC_PR_USER_DEFINED_SHIM2_OFFSET;
39979 + break;
39980 + case (HEADER_TYPE_LLC_SNAP):
39981 + *parseArrayOffset = CC_PC_PR_USER_LLC_SNAP_OFFSET;
39982 + break;
39983 + case (HEADER_TYPE_PPPoE):
39984 + *parseArrayOffset = CC_PC_PR_PPPOE_OFFSET;
39985 + break;
39986 + case (HEADER_TYPE_MPLS):
39987 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
39988 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
39989 + *parseArrayOffset = CC_PC_PR_MPLS1_OFFSET;
39990 + else
39991 + if (hdrIndex == e_FM_PCD_HDR_INDEX_LAST)
39992 + *parseArrayOffset = CC_PC_PR_MPLS_LAST_OFFSET;
39993 + break;
39994 + case (HEADER_TYPE_IPv4):
39995 + case (HEADER_TYPE_IPv6):
39996 + if ((hdrIndex == e_FM_PCD_HDR_INDEX_NONE)
39997 + || (hdrIndex == e_FM_PCD_HDR_INDEX_1))
39998 + *parseArrayOffset = CC_PC_PR_IP1_OFFSET;
39999 + else
40000 + if (hdrIndex == e_FM_PCD_HDR_INDEX_2)
40001 + *parseArrayOffset = CC_PC_PR_IP_LAST_OFFSET;
40002 + break;
40003 + case (HEADER_TYPE_MINENCAP):
40004 + *parseArrayOffset = CC_PC_PR_MINENC_OFFSET;
40005 + break;
40006 + case (HEADER_TYPE_GRE):
40007 + *parseArrayOffset = CC_PC_PR_GRE_OFFSET;
40008 + break;
40009 + case (HEADER_TYPE_TCP):
40010 + case (HEADER_TYPE_UDP):
40011 + case (HEADER_TYPE_IPSEC_AH):
40012 + case (HEADER_TYPE_IPSEC_ESP):
40013 + case (HEADER_TYPE_DCCP):
40014 + case (HEADER_TYPE_SCTP):
40015 + *parseArrayOffset = CC_PC_PR_L4_OFFSET;
40016 + break;
40017 + case (HEADER_TYPE_CAPWAP):
40018 + case (HEADER_TYPE_CAPWAP_DTLS):
40019 + *parseArrayOffset = CC_PC_PR_NEXT_HEADER_OFFSET;
40020 + break;
40021 + default:
40022 + RETURN_ERROR(
40023 + MAJOR,
40024 + E_NOT_SUPPORTED,
40025 + ("Header manipulation of this header is not supported"));
40026 + }
40027 + }
40028 + return E_OK;
40029 +}
40030 +
40031 +static t_Error BuildHmct(t_FmPcdManip *p_Manip,
40032 + t_FmPcdManipParams *p_FmPcdManipParams,
40033 + uint8_t *p_DestHmct, uint8_t *p_DestData, bool new)
40034 +{
40035 + uint32_t *p_TmpHmct = (uint32_t*)p_DestHmct, *p_LocalData;
40036 + uint32_t tmpReg = 0, *p_Last = NULL, tmp_ipv6_addr;
40037 + uint8_t remain, i, size = 0, origSize, *p_UsrData = NULL, *p_TmpData =
40038 + p_DestData;
40039 + t_Handle h_FmPcd = p_Manip->h_FmPcd;
40040 + uint8_t j = 0;
40041 +
40042 + if (p_FmPcdManipParams->u.hdr.rmv)
40043 + {
40044 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
40045 + == e_FM_PCD_MANIP_RMV_GENERIC)
40046 + {
40047 + /* initialize HMCD */
40048 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_RMV) << HMCD_OC_SHIFT;
40049 + /* tmp, should be conditional */
40050 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.offset
40051 + << HMCD_RMV_OFFSET_SHIFT;
40052 + tmpReg |= p_FmPcdManipParams->u.hdr.rmvParams.u.generic.size
40053 + << HMCD_RMV_SIZE_SHIFT;
40054 + }
40055 + else
40056 + if (p_FmPcdManipParams->u.hdr.rmvParams.type
40057 + == e_FM_PCD_MANIP_RMV_BY_HDR)
40058 + {
40059 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.type)
40060 + {
40061 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
40062 + {
40063 + uint8_t hmcdOpt;
40064 +
40065 + /* initialize HMCD */
40066 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_RMV) << HMCD_OC_SHIFT;
40067 +
40068 + switch (p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.specificL2)
40069 + {
40070 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET):
40071 + hmcdOpt = HMCD_RMV_L2_ETHERNET;
40072 + break;
40073 + case (e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS):
40074 + hmcdOpt = HMCD_RMV_L2_STACKED_QTAGS;
40075 + break;
40076 + case (e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS):
40077 + hmcdOpt = HMCD_RMV_L2_ETHERNET_AND_MPLS;
40078 + break;
40079 + case (e_FM_PCD_MANIP_HDR_RMV_MPLS):
40080 + hmcdOpt = HMCD_RMV_L2_MPLS;
40081 + break;
40082 + case (e_FM_PCD_MANIP_HDR_RMV_PPPOE):
40083 + hmcdOpt = HMCD_RMV_L2_PPPOE;
40084 + break;
40085 + default:
40086 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
40087 + }
40088 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
40089 + break;
40090 + }
40091 +#if (DPAA_VERSION >= 11)
40092 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
40093 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_RMV)
40094 + << HMCD_OC_SHIFT;
40095 + break;
40096 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
40097 + {
40098 + uint8_t prsArrayOffset;
40099 + t_Error err = E_OK;
40100 +
40101 + tmpReg = (uint32_t)(HMCD_OPCODE_RMV_TILL)
40102 + << HMCD_OC_SHIFT;
40103 +
40104 + err =
40105 + GetPrOffsetByHeaderOrField(
40106 + &p_FmPcdManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
40107 + &prsArrayOffset);
40108 + ASSERT_COND(!err);
40109 + /* was previously checked */
40110 +
40111 + tmpReg |= ((uint32_t)prsArrayOffset << 16);
40112 + }
40113 + break;
40114 +#endif /* (DPAA_VERSION >= 11) */
40115 + default:
40116 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
40117 + ("manip header remove by hdr type!"));
40118 + }
40119 + }
40120 +
40121 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40122 + /* save a pointer to the "last" indication word */
40123 + p_Last = p_TmpHmct;
40124 + /* advance to next command */
40125 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40126 + }
40127 +
40128 + if (p_FmPcdManipParams->u.hdr.insrt)
40129 + {
40130 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
40131 + == e_FM_PCD_MANIP_INSRT_GENERIC)
40132 + {
40133 + /* initialize HMCD */
40134 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.generic.replace)
40135 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_REPLACE)
40136 + << HMCD_OC_SHIFT;
40137 + else
40138 + tmpReg = (uint32_t)(HMCD_OPCODE_GENERIC_INSRT) << HMCD_OC_SHIFT;
40139 +
40140 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.offset
40141 + << HMCD_INSRT_OFFSET_SHIFT;
40142 + tmpReg |= p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size
40143 + << HMCD_INSRT_SIZE_SHIFT;
40144 +
40145 + size = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.size;
40146 + p_UsrData = p_FmPcdManipParams->u.hdr.insrtParams.u.generic.p_Data;
40147 +
40148 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40149 + /* save a pointer to the "last" indication word */
40150 + p_Last = p_TmpHmct;
40151 +
40152 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40153 +
40154 + /* initialize data to be inserted */
40155 + /* if size is not a multiple of 4, padd with 0's */
40156 + origSize = size;
40157 + remain = (uint8_t)(size % 4);
40158 + if (remain)
40159 + {
40160 + size += (uint8_t)(4 - remain);
40161 + p_LocalData = (uint32_t *)XX_Malloc(size);
40162 + memset((uint8_t *)p_LocalData, 0, size);
40163 + memcpy((uint8_t *)p_LocalData, p_UsrData, origSize);
40164 + }
40165 + else
40166 + p_LocalData = (uint32_t*)p_UsrData;
40167 +
40168 + /* initialize data and advance pointer to next command */
40169 + MemCpy8(p_TmpHmct, p_LocalData, size);
40170 + p_TmpHmct += size / sizeof(uint32_t);
40171 +
40172 + if (remain)
40173 + XX_Free(p_LocalData);
40174 + }
40175 +
40176 + else
40177 + if (p_FmPcdManipParams->u.hdr.insrtParams.type
40178 + == e_FM_PCD_MANIP_INSRT_BY_HDR)
40179 + {
40180 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.type)
40181 + {
40182 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
40183 + {
40184 + uint8_t hmcdOpt;
40185 +
40186 + /* initialize HMCD */
40187 + tmpReg = (uint32_t)(HMCD_OPCODE_L2_INSRT)
40188 + << HMCD_OC_SHIFT;
40189 +
40190 + switch (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.specificL2)
40191 + {
40192 + case (e_FM_PCD_MANIP_HDR_INSRT_MPLS):
40193 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.update)
40194 + hmcdOpt = HMCD_INSRT_N_UPDATE_L2_MPLS;
40195 + else
40196 + hmcdOpt = HMCD_INSRT_L2_MPLS;
40197 + break;
40198 + case (e_FM_PCD_MANIP_HDR_INSRT_PPPOE):
40199 + hmcdOpt = HMCD_INSRT_L2_PPPOE;
40200 + break;
40201 + default:
40202 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, NO_MSG);
40203 + }
40204 + tmpReg |= hmcdOpt << HMCD_L2_MODE_SHIFT;
40205 +
40206 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40207 + /* save a pointer to the "last" indication word */
40208 + p_Last = p_TmpHmct;
40209 +
40210 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40211 +
40212 + /* set size and pointer of user's data */
40213 + size =
40214 + (uint8_t)p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.size;
40215 +
40216 + ASSERT_COND(p_TmpData);
40217 + MemCpy8(
40218 + p_TmpData,
40219 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.specificL2Params.p_Data,
40220 + size);
40221 + tmpReg =
40222 + (size << HMCD_INSRT_L2_SIZE_SHIFT)
40223 + | (uint32_t)(XX_VirtToPhys(p_TmpData)
40224 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
40225 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40226 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40227 + p_TmpData += size;
40228 + }
40229 + break;
40230 +#if (DPAA_VERSION >= 11)
40231 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
40232 + tmpReg = (uint32_t)(HMCD_OPCODE_IP_INSRT)
40233 + << HMCD_OC_SHIFT;
40234 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.calcL4Checksum)
40235 + tmpReg |= HMCD_IP_L4_CS_CALC;
40236 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.mappingMode
40237 + == e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS)
40238 + tmpReg |= HMCD_IP_OR_QOS;
40239 + tmpReg |=
40240 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastPidOffset
40241 + & HMCD_IP_LAST_PID_MASK;
40242 + tmpReg |=
40243 + ((p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
40244 + << HMCD_IP_SIZE_SHIFT)
40245 + & HMCD_IP_SIZE_MASK);
40246 + if (p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.dontFragOverwrite)
40247 + tmpReg |= HMCD_IP_DF_MODE;
40248 +
40249 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40250 +
40251 + /* save a pointer to the "last" indication word */
40252 + p_Last = p_TmpHmct;
40253 +
40254 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40255 +
40256 + /* set IP id */
40257 + ASSERT_COND(p_TmpData);
40258 + WRITE_UINT16(
40259 + *(uint16_t*)p_TmpData,
40260 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.id);
40261 + WRITE_UINT32(
40262 + *p_TmpHmct,
40263 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
40264 + p_TmpData += 2;
40265 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40266 +
40267 + WRITE_UINT8(*p_TmpHmct, p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.lastDstOffset);
40268 + p_TmpHmct += HMCD_PARAM_SIZE / 4;
40269 +
40270 + MemCpy8(
40271 + p_TmpHmct,
40272 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.p_Data,
40273 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size);
40274 + p_TmpHmct +=
40275 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
40276 + / 4;
40277 + break;
40278 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
40279 + tmpReg = HMCD_INSRT_UDP_LITE;
40280 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
40281 + tmpReg |= (uint32_t)(HMCD_OPCODE_UDP_INSRT)
40282 + << HMCD_OC_SHIFT;
40283 +
40284 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40285 +
40286 + /* save a pointer to the "last" indication word */
40287 + p_Last = p_TmpHmct;
40288 +
40289 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40290 +
40291 + MemCpy8(
40292 + p_TmpHmct,
40293 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
40294 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
40295 + p_TmpHmct +=
40296 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40297 + / 4;
40298 + break;
40299 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
40300 + tmpReg = (uint32_t)(HMCD_OPCODE_CAPWAP_INSRT)
40301 + << HMCD_OC_SHIFT;
40302 + tmpReg |= HMCD_CAPWAP_INSRT;
40303 +
40304 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40305 +
40306 + /* save a pointer to the "last" indication word */
40307 + p_Last = p_TmpHmct;
40308 +
40309 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40310 +
40311 + MemCpy8(
40312 + p_TmpHmct,
40313 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.p_Data,
40314 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size);
40315 + p_TmpHmct +=
40316 + p_FmPcdManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
40317 + / 4;
40318 + break;
40319 +#endif /* (DPAA_VERSION >= 11) */
40320 + default:
40321 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
40322 + ("manip header insert by header type!"));
40323 +
40324 + }
40325 + }
40326 + }
40327 +
40328 + if (p_FmPcdManipParams->u.hdr.fieldUpdate)
40329 + {
40330 + switch (p_FmPcdManipParams->u.hdr.fieldUpdateParams.type)
40331 + {
40332 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN):
40333 + /* set opcode */
40334 + tmpReg = (uint32_t)(HMCD_OPCODE_VLAN_PRI_UPDATE)
40335 + << HMCD_OC_SHIFT;
40336 +
40337 + /* set mode & table pointer */
40338 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40339 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
40340 + {
40341 + /* set Mode */
40342 + tmpReg |= (uint32_t)(HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI)
40343 + << HMCD_VLAN_PRI_REP_MODE_SHIFT;
40344 + /* set VPRI default */
40345 + tmpReg |=
40346 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal;
40347 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40348 + /* save a pointer to the "last" indication word */
40349 + p_Last = p_TmpHmct;
40350 + /* write the table pointer into the Manip descriptor */
40351 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40352 +
40353 + tmpReg = 0;
40354 + ASSERT_COND(p_TmpData);
40355 + for (i = 0; i < HMCD_DSCP_VALUES; i++)
40356 + {
40357 + /* first we build from each 8 values a 32bit register */
40358 + tmpReg |=
40359 + (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i])
40360 + << (32 - 4 * (j + 1));
40361 + j++;
40362 + /* Than we write this register to the next table word
40363 + * (i=7-->word 0, i=15-->word 1,... i=63-->word 7) */
40364 + if ((i % 8) == 7)
40365 + {
40366 + WRITE_UINT32(*((uint32_t*)p_TmpData + (i+1)/8-1),
40367 + tmpReg);
40368 + tmpReg = 0;
40369 + j = 0;
40370 + }
40371 + }
40372 +
40373 + WRITE_UINT32(
40374 + *p_TmpHmct,
40375 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
40376 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40377 +
40378 + p_TmpData += DSCP_TO_VLAN_TABLE_SIZE;
40379 + }
40380 + else
40381 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
40382 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
40383 + {
40384 + /* set Mode */
40385 + /* line commented out as it has no-side-effect ('0' value). */
40386 + /*tmpReg |= HMCD_VLAN_PRI_UPDATE << HMCD_VLAN_PRI_REP_MODE_SHIFT*/;
40387 + /* set VPRI parameter */
40388 + tmpReg |=
40389 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri;
40390 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40391 + /* save a pointer to the "last" indication word */
40392 + p_Last = p_TmpHmct;
40393 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40394 + }
40395 + break;
40396 +
40397 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4):
40398 + /* set opcode */
40399 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV4_UPDATE) << HMCD_OC_SHIFT;
40400 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40401 + & HDR_MANIP_IPV4_TTL)
40402 + tmpReg |= HMCD_IPV4_UPDATE_TTL;
40403 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40404 + & HDR_MANIP_IPV4_TOS)
40405 + {
40406 + tmpReg |= HMCD_IPV4_UPDATE_TOS;
40407 + tmpReg |=
40408 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.tos
40409 + << HMCD_IPV4_UPDATE_TOS_SHIFT;
40410 + }
40411 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40412 + & HDR_MANIP_IPV4_ID)
40413 + tmpReg |= HMCD_IPV4_UPDATE_ID;
40414 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40415 + & HDR_MANIP_IPV4_SRC)
40416 + tmpReg |= HMCD_IPV4_UPDATE_SRC;
40417 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40418 + & HDR_MANIP_IPV4_DST)
40419 + tmpReg |= HMCD_IPV4_UPDATE_DST;
40420 + /* write the first 4 bytes of the descriptor */
40421 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40422 + /* save a pointer to the "last" indication word */
40423 + p_Last = p_TmpHmct;
40424 +
40425 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40426 +
40427 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40428 + & HDR_MANIP_IPV4_ID)
40429 + {
40430 + ASSERT_COND(p_TmpData);
40431 + WRITE_UINT16(
40432 + *(uint16_t*)p_TmpData,
40433 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.id);
40434 + WRITE_UINT32(
40435 + *p_TmpHmct,
40436 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
40437 + p_TmpData += 2;
40438 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40439 + }
40440 +
40441 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40442 + & HDR_MANIP_IPV4_SRC)
40443 + {
40444 + WRITE_UINT32(
40445 + *p_TmpHmct,
40446 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.src);
40447 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
40448 + }
40449 +
40450 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.validUpdates
40451 + & HDR_MANIP_IPV4_DST)
40452 + {
40453 + WRITE_UINT32(
40454 + *p_TmpHmct,
40455 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv4.dst);
40456 + p_TmpHmct += HMCD_IPV4_ADDR_SIZE / 4;
40457 + }
40458 + break;
40459 +
40460 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6):
40461 + /* set opcode */
40462 + tmpReg = (uint32_t)(HMCD_OPCODE_IPV6_UPDATE) << HMCD_OC_SHIFT;
40463 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40464 + & HDR_MANIP_IPV6_HL)
40465 + tmpReg |= HMCD_IPV6_UPDATE_HL;
40466 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40467 + & HDR_MANIP_IPV6_TC)
40468 + {
40469 + tmpReg |= HMCD_IPV6_UPDATE_TC;
40470 + tmpReg |=
40471 + p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.trafficClass
40472 + << HMCD_IPV6_UPDATE_TC_SHIFT;
40473 + }
40474 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40475 + & HDR_MANIP_IPV6_SRC)
40476 + tmpReg |= HMCD_IPV6_UPDATE_SRC;
40477 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40478 + & HDR_MANIP_IPV6_DST)
40479 + tmpReg |= HMCD_IPV6_UPDATE_DST;
40480 + /* write the first 4 bytes of the descriptor */
40481 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40482 + /* save a pointer to the "last" indication word */
40483 + p_Last = p_TmpHmct;
40484 +
40485 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40486 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40487 + & HDR_MANIP_IPV6_SRC)
40488 + {
40489 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
40490 + {
40491 + memcpy(&tmp_ipv6_addr,
40492 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.src[i],
40493 + sizeof(uint32_t));
40494 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
40495 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40496 + }
40497 + }
40498 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.validUpdates
40499 + & HDR_MANIP_IPV6_DST)
40500 + {
40501 + for (i = 0; i < NET_HEADER_FIELD_IPv6_ADDR_SIZE; i += 4)
40502 + {
40503 + memcpy(&tmp_ipv6_addr,
40504 + &p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.ipv6.dst[i],
40505 + sizeof(uint32_t));
40506 + WRITE_UINT32(*p_TmpHmct, tmp_ipv6_addr);
40507 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40508 + }
40509 + }
40510 + break;
40511 +
40512 + case (e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP):
40513 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40514 + == HDR_MANIP_TCP_UDP_CHECKSUM)
40515 + {
40516 + /* we implement this case with the update-checksum descriptor */
40517 + /* set opcode */
40518 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_CHECKSUM)
40519 + << HMCD_OC_SHIFT;
40520 + /* write the first 4 bytes of the descriptor */
40521 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40522 + /* save a pointer to the "last" indication word */
40523 + p_Last = p_TmpHmct;
40524 +
40525 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40526 + }
40527 + else
40528 + {
40529 + /* we implement this case with the TCP/UDP update descriptor */
40530 + /* set opcode */
40531 + tmpReg = (uint32_t)(HMCD_OPCODE_TCP_UDP_UPDATE)
40532 + << HMCD_OC_SHIFT;
40533 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40534 + & HDR_MANIP_TCP_UDP_DST)
40535 + tmpReg |= HMCD_TCP_UDP_UPDATE_DST;
40536 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40537 + & HDR_MANIP_TCP_UDP_SRC)
40538 + tmpReg |= HMCD_TCP_UDP_UPDATE_SRC;
40539 + /* write the first 4 bytes of the descriptor */
40540 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40541 + /* save a pointer to the "last" indication word */
40542 + p_Last = p_TmpHmct;
40543 +
40544 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40545 +
40546 + tmpReg = 0;
40547 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40548 + & HDR_MANIP_TCP_UDP_SRC)
40549 + tmpReg |=
40550 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.src)
40551 + << HMCD_TCP_UDP_UPDATE_SRC_SHIFT;
40552 + if (p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.validUpdates
40553 + & HDR_MANIP_TCP_UDP_DST)
40554 + tmpReg |=
40555 + ((uint32_t)p_FmPcdManipParams->u.hdr.fieldUpdateParams.u.tcpUdp.dst);
40556 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40557 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40558 + }
40559 + break;
40560 +
40561 + default:
40562 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
40563 + ("Unknown fieldUpdateParams.type"));
40564 + }
40565 + }
40566 +
40567 + if (p_FmPcdManipParams->u.hdr.custom)
40568 + {
40569 + switch (p_FmPcdManipParams->u.hdr.customParams.type)
40570 + {
40571 + case (e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE):
40572 + /* set opcode */
40573 + tmpReg = (uint32_t)(HMCD_OPCODE_REPLACE_IP) << HMCD_OC_SHIFT;
40574 +
40575 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.decTtlHl)
40576 + tmpReg |= HMCD_IP_REPLACE_TTL_HL;
40577 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
40578 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6)
40579 + /* line commented out as it has no-side-effect ('0' value). */
40580 + /*tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV4*/;
40581 + else
40582 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
40583 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
40584 + {
40585 + tmpReg |= HMCD_IP_REPLACE_REPLACE_IPV6;
40586 + if (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id)
40587 + tmpReg |= HMCD_IP_REPLACE_ID;
40588 + }
40589 + else
40590 + RETURN_ERROR(
40591 + MINOR,
40592 + E_NOT_SUPPORTED,
40593 + ("One flag out of HDR_MANIP_IP_REPLACE_IPV4, HDR_MANIP_IP_REPLACE_IPV6 - must be set."));
40594 +
40595 + /* write the first 4 bytes of the descriptor */
40596 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40597 + /* save a pointer to the "last" indication word */
40598 + p_Last = p_TmpHmct;
40599 +
40600 + p_TmpHmct += HMCD_BASIC_SIZE / 4;
40601 +
40602 + size =
40603 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdrSize;
40604 + ASSERT_COND(p_TmpData);
40605 + MemCpy8(
40606 + p_TmpData,
40607 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.hdr,
40608 + size);
40609 + tmpReg = (uint32_t)(size << HMCD_IP_REPLACE_L3HDRSIZE_SHIFT);
40610 + tmpReg |= (uint32_t)(XX_VirtToPhys(p_TmpData)
40611 + - (((t_FmPcd*)h_FmPcd)->physicalMuramBase));
40612 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40613 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40614 + p_TmpData += size;
40615 +
40616 + if ((p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.replaceType
40617 + == e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4)
40618 + && (p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.updateIpv4Id))
40619 + {
40620 + WRITE_UINT16(
40621 + *(uint16_t*)p_TmpData,
40622 + p_FmPcdManipParams->u.hdr.customParams.u.ipHdrReplace.id);
40623 + WRITE_UINT32(
40624 + *p_TmpHmct,
40625 + (uint32_t)(XX_VirtToPhys(p_TmpData) - (((t_FmPcd*)h_FmPcd)->physicalMuramBase)));
40626 + p_TmpData += 2;
40627 + }
40628 + p_TmpHmct += HMCD_PTR_SIZE / 4;
40629 + break;
40630 + case (e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE):
40631 + /* set opcode */
40632 + tmpReg = (uint32_t)(HMCD_OPCODE_GEN_FIELD_REPLACE) << HMCD_OC_SHIFT;
40633 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.size << HMCD_GEN_FIELD_SIZE_SHIFT;
40634 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset << HMCD_GEN_FIELD_SRC_OFF_SHIFT;
40635 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset << HMCD_GEN_FIELD_DST_OFF_SHIFT;
40636 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
40637 + tmpReg |= HMCD_GEN_FIELD_MASK_EN;
40638 +
40639 + /* write the first 4 bytes of the descriptor */
40640 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40641 + /* save a pointer to the "last" indication word */
40642 + p_Last = p_TmpHmct;
40643 +
40644 + p_TmpHmct += HMCD_BASIC_SIZE/4;
40645 +
40646 + if (p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask)
40647 + {
40648 + tmpReg = p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.mask << HMCD_GEN_FIELD_MASK_SHIFT;
40649 + tmpReg |= p_FmPcdManipParams->u.hdr.customParams.u.genFieldReplace.maskOffset << HMCD_GEN_FIELD_MASK_OFF_SHIFT;
40650 + /* write the next 4 bytes of the descriptor */
40651 + WRITE_UINT32(*p_TmpHmct, tmpReg);
40652 + }
40653 + p_TmpHmct += HMCD_PARAM_SIZE/4;
40654 + break;
40655 + default:
40656 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
40657 + ("Unknown customParams.type"));
40658 + }
40659 + }
40660 +
40661 + /* If this node has a nextManip, and no parsing is required, the old table must be copied to the new table
40662 + the old table and should be freed */
40663 + if (p_FmPcdManipParams->h_NextManip
40664 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
40665 + && (MANIP_DONT_REPARSE(p_Manip)))
40666 + {
40667 + if (new)
40668 + {
40669 + /* If this is the first time this manip is created we need to free unused memory. If it
40670 + * is a dynamic changes case, the memory used is either the CC shadow or the existing
40671 + * table - no allocation, no free */
40672 + MANIP_UPDATE_UNIFIED_POSITION(p_FmPcdManipParams->h_NextManip);
40673 +
40674 + p_Manip->unifiedPosition = e_MANIP_UNIFIED_FIRST;
40675 + }
40676 + }
40677 + else
40678 + {
40679 + ASSERT_COND(p_Last);
40680 + /* set the "last" indication on the last command of the current table */
40681 + WRITE_UINT32(*p_Last, GET_UINT32(*p_Last) | HMCD_LAST);
40682 + }
40683 +
40684 + return E_OK;
40685 +}
40686 +
40687 +static t_Error CreateManipActionNew(t_FmPcdManip *p_Manip,
40688 + t_FmPcdManipParams *p_FmPcdManipParams)
40689 +{
40690 + t_FmPcdManip *p_CurManip;
40691 + t_Error err;
40692 + uint32_t nextSize = 0, totalSize;
40693 + uint16_t tmpReg;
40694 + uint8_t *p_OldHmct, *p_TmpHmctPtr, *p_TmpDataPtr;
40695 +
40696 + /* set Manip structure */
40697 +
40698 + p_Manip->dontParseAfterManip =
40699 + p_FmPcdManipParams->u.hdr.dontParseAfterManip;
40700 +
40701 + if (p_FmPcdManipParams->h_NextManip)
40702 + { /* Next Header manipulation exists */
40703 + p_Manip->nextManipType = MANIP_GET_TYPE(p_FmPcdManipParams->h_NextManip);
40704 +
40705 + if ((p_Manip->nextManipType == e_FM_PCD_MANIP_HDR) && p_Manip->dontParseAfterManip)
40706 + nextSize = (uint32_t)(GetHmctSize(p_FmPcdManipParams->h_NextManip)
40707 + + GetDataSize(p_FmPcdManipParams->h_NextManip));
40708 + else /* either parsing is required or next manip is Frag; no table merging. */
40709 + p_Manip->cascaded = TRUE;
40710 + /* pass up the "cascaded" attribute. The whole chain is cascaded
40711 + * if something is cascaded along the way. */
40712 + if (MANIP_IS_CASCADED(p_FmPcdManipParams->h_NextManip))
40713 + p_Manip->cascaded = TRUE;
40714 + }
40715 +
40716 + /* Allocate new table */
40717 + /* calculate table size according to manip parameters */
40718 + err = CalculateTableSize(p_FmPcdManipParams, &p_Manip->tableSize,
40719 + &p_Manip->dataSize);
40720 + if (err)
40721 + RETURN_ERROR(MINOR, err, NO_MSG);
40722 +
40723 + totalSize = (uint16_t)(p_Manip->tableSize + p_Manip->dataSize + nextSize);
40724 +
40725 + p_Manip->p_Hmct = (uint8_t*)FM_MURAM_AllocMem(
40726 + ((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram, totalSize, 4);
40727 + if (!p_Manip->p_Hmct)
40728 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc failed"));
40729 +
40730 + if (p_Manip->dataSize)
40731 + p_Manip->p_Data =
40732 + (uint8_t*)PTR_MOVE(p_Manip->p_Hmct, (p_Manip->tableSize + nextSize));
40733 +
40734 + /* update shadow size to allow runtime replacement of Header manipulation */
40735 + /* The allocated shadow is divided as follows:
40736 + 0 . . . 16 . . .
40737 + --------------------------------
40738 + | Shadow | Shadow HMTD |
40739 + | HMTD | Match Table |
40740 + | (16 bytes) | (maximal size) |
40741 + --------------------------------
40742 + */
40743 +
40744 + err = FmPcdUpdateCcShadow(p_Manip->h_FmPcd, (uint32_t)(totalSize + 16),
40745 + (uint16_t)FM_PCD_CC_AD_TABLE_ALIGN);
40746 + if (err != E_OK)
40747 + {
40748 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
40749 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
40750 + ("MURAM allocation for HdrManip node shadow"));
40751 + }
40752 +
40753 + if (p_FmPcdManipParams->h_NextManip
40754 + && (p_Manip->nextManipType == e_FM_PCD_MANIP_HDR)
40755 + && (MANIP_DONT_REPARSE(p_Manip)))
40756 + {
40757 + p_OldHmct = (uint8_t *)GetManipInfo(p_FmPcdManipParams->h_NextManip,
40758 + e_MANIP_HMCT);
40759 + p_CurManip = p_FmPcdManipParams->h_NextManip;
40760 + /* Run till the last Manip (which is the first to configure) */
40761 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
40762 + p_CurManip = p_CurManip->h_NextManip;
40763 +
40764 + while (p_CurManip)
40765 + {
40766 + /* If this is a unified table, point to the part of the table
40767 + * which is the relative offset in HMCT.
40768 + */
40769 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
40770 + (p_Manip->tableSize +
40771 + (PTR_TO_UINT(p_CurManip->p_Hmct) -
40772 + PTR_TO_UINT(p_OldHmct))));
40773 + if (p_CurManip->p_Data)
40774 + p_TmpDataPtr = (uint8_t*)PTR_MOVE(p_Manip->p_Hmct,
40775 + (p_Manip->tableSize +
40776 + (PTR_TO_UINT(p_CurManip->p_Data) -
40777 + PTR_TO_UINT(p_OldHmct))));
40778 + else
40779 + p_TmpDataPtr = NULL;
40780 +
40781 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
40782 + p_TmpDataPtr, FALSE);
40783 + /* update old manip table pointer */
40784 + MANIP_SET_HMCT_PTR(p_CurManip, p_TmpHmctPtr);
40785 + MANIP_SET_DATA_PTR(p_CurManip, p_TmpDataPtr);
40786 +
40787 + p_CurManip = p_CurManip->h_PrevManip;
40788 + }
40789 + /* We copied the HMCT to create a new large HMCT so we can free the old one */
40790 + FM_MURAM_FreeMem(MANIP_GET_MURAM(p_FmPcdManipParams->h_NextManip),
40791 + p_OldHmct);
40792 + }
40793 +
40794 + /* Fill table */
40795 + err = BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct,
40796 + p_Manip->p_Data, TRUE);
40797 + if (err)
40798 + {
40799 + FM_MURAM_FreeMem(p_Manip->h_FmPcd, p_Manip->p_Hmct);
40800 + RETURN_ERROR(MINOR, err, NO_MSG);
40801 + }
40802 +
40803 + /* Build HMTD (table descriptor) */
40804 + tmpReg = HMTD_CFG_TYPE; /* NADEN = 0 */
40805 +
40806 + /* add parseAfterManip */
40807 + if (!p_Manip->dontParseAfterManip)
40808 + tmpReg |= HMTD_CFG_PRS_AFTER_HM;
40809 +
40810 + /* create cascade */
40811 + /*if (p_FmPcdManipParams->h_NextManip
40812 + && (!MANIP_DONT_REPARSE(p_Manip) || (p_Manip->nextManipType != e_FM_PCD_MANIP_HDR)))*/
40813 + if (p_Manip->cascaded)
40814 + {
40815 + uint16_t nextAd;
40816 + /* indicate that there's another HM table descriptor */
40817 + tmpReg |= HMTD_CFG_NEXT_AD_EN;
40818 + /* get address of next HMTD (table descriptor; h_Ad).
40819 + * If the next HMTD was removed due to table unifing, get the address
40820 + * of the "next next" as written in the h_Ad of the next h_Manip node.
40821 + */
40822 + if (p_Manip->unifiedPosition != e_MANIP_UNIFIED_FIRST)
40823 + nextAd = (uint16_t)((uint32_t)(XX_VirtToPhys(MANIP_GET_HMTD_PTR(p_FmPcdManipParams->h_NextManip)) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
40824 + else
40825 + nextAd = ((t_Hmtd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad)->nextAdIdx;
40826 +
40827 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->nextAdIdx, nextAd);
40828 + }
40829 +
40830 + WRITE_UINT16(((t_Hmtd *)p_Manip->h_Ad)->cfg, tmpReg);
40831 + WRITE_UINT32(
40832 + ((t_Hmtd *)p_Manip->h_Ad)->hmcdBasePtr,
40833 + (uint32_t)(XX_VirtToPhys(p_Manip->p_Hmct) - (((t_FmPcd*)p_Manip->h_FmPcd)->physicalMuramBase)));
40834 +
40835 + WRITE_UINT8(((t_Hmtd *)p_Manip->h_Ad)->opCode, HMAN_OC);
40836 +
40837 + if (p_Manip->unifiedPosition == e_MANIP_UNIFIED_FIRST)
40838 + {
40839 + /* The HMTD of the next Manip is never going to be used */
40840 + if (((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->muramAllocate)
40841 + FM_MURAM_FreeMem(
40842 + ((t_FmPcd *)((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_FmPcd)->h_FmMuram,
40843 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
40844 + else
40845 + XX_Free(((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad);
40846 + ((t_FmPcdManip *)p_FmPcdManipParams->h_NextManip)->h_Ad = NULL;
40847 + }
40848 +
40849 + return E_OK;
40850 +}
40851 +
40852 +static t_Error CreateManipActionShadow(t_FmPcdManip *p_Manip,
40853 + t_FmPcdManipParams *p_FmPcdManipParams)
40854 +{
40855 + uint8_t *p_WholeHmct, *p_TmpHmctPtr, newDataSize, *p_TmpDataPtr = NULL;
40856 + uint16_t newSize;
40857 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
40858 + t_Error err;
40859 + t_FmPcdManip *p_CurManip = p_Manip;
40860 +
40861 + err = CalculateTableSize(p_FmPcdManipParams, &newSize, &newDataSize);
40862 + if (err)
40863 + RETURN_ERROR(MINOR, err, NO_MSG);
40864 +
40865 + /* check coherency of new table parameters */
40866 + if (newSize > p_Manip->tableSize)
40867 + RETURN_ERROR(
40868 + MINOR,
40869 + E_INVALID_VALUE,
40870 + ("New Hdr Manip configuration requires larger size than current one (command table)."));
40871 + if (newDataSize > p_Manip->dataSize)
40872 + RETURN_ERROR(
40873 + MINOR,
40874 + E_INVALID_VALUE,
40875 + ("New Hdr Manip configuration requires larger size than current one (data)."));
40876 + if (p_FmPcdManipParams->h_NextManip)
40877 + RETURN_ERROR(
40878 + MINOR, E_INVALID_VALUE,
40879 + ("New Hdr Manip configuration can not contain h_NextManip."));
40880 + if (MANIP_IS_UNIFIED(p_Manip) && (newSize != p_Manip->tableSize))
40881 + RETURN_ERROR(
40882 + MINOR,
40883 + E_INVALID_VALUE,
40884 + ("New Hdr Manip configuration in a chained manipulation requires different size than current one."));
40885 + if (p_Manip->dontParseAfterManip
40886 + != p_FmPcdManipParams->u.hdr.dontParseAfterManip)
40887 + RETURN_ERROR(
40888 + MINOR,
40889 + E_INVALID_VALUE,
40890 + ("New Hdr Manip configuration differs in dontParseAfterManip value."));
40891 +
40892 + p_Manip->tableSize = newSize;
40893 + p_Manip->dataSize = newDataSize;
40894 +
40895 + /* Build the new table in the shadow */
40896 + if (!MANIP_IS_UNIFIED(p_Manip))
40897 + {
40898 + p_TmpHmctPtr = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
40899 + if (p_Manip->p_Data)
40900 + p_TmpDataPtr =
40901 + (uint8_t*)PTR_MOVE(p_TmpHmctPtr,
40902 + (PTR_TO_UINT(p_Manip->p_Data) - PTR_TO_UINT(p_Manip->p_Hmct)));
40903 +
40904 + BuildHmct(p_Manip, p_FmPcdManipParams, p_TmpHmctPtr, p_Manip->p_Data,
40905 + FALSE);
40906 + }
40907 + else
40908 + {
40909 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
40910 + ASSERT_COND(p_WholeHmct);
40911 +
40912 + /* Run till the last Manip (which is the first to configure) */
40913 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
40914 + p_CurManip = p_CurManip->h_NextManip;
40915 +
40916 + while (p_CurManip)
40917 + {
40918 + /* If this is a non-head node in a unified table, point to the part of the shadow
40919 + * which is the relative offset in HMCT.
40920 + * else, point to the beginning of the
40921 + * shadow table (we save 16 for the HMTD.
40922 + */
40923 + p_TmpHmctPtr =
40924 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
40925 + (16 + PTR_TO_UINT(p_CurManip->p_Hmct) - PTR_TO_UINT(p_WholeHmct)));
40926 + if (p_CurManip->p_Data)
40927 + p_TmpDataPtr =
40928 + (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow,
40929 + (16 + PTR_TO_UINT(p_CurManip->p_Data) - PTR_TO_UINT(p_WholeHmct)));
40930 +
40931 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
40932 + p_TmpDataPtr, FALSE);
40933 + p_CurManip = p_CurManip->h_PrevManip;
40934 + }
40935 + }
40936 +
40937 + return E_OK;
40938 +}
40939 +
40940 +static t_Error CreateManipActionBackToOrig(
40941 + t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_FmPcdManipParams)
40942 +{
40943 + uint8_t *p_WholeHmct = NULL, *p_TmpHmctPtr, *p_TmpDataPtr;
40944 + t_FmPcdManip *p_CurManip = p_Manip;
40945 +
40946 + /* Build the new table in the shadow */
40947 + if (!MANIP_IS_UNIFIED(p_Manip))
40948 + BuildHmct(p_Manip, p_FmPcdManipParams, p_Manip->p_Hmct, p_Manip->p_Data,
40949 + FALSE);
40950 + else
40951 + {
40952 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
40953 + ASSERT_COND(p_WholeHmct);
40954 +
40955 + /* Run till the last Manip (which is the first to configure) */
40956 + while (MANIP_IS_UNIFIED_NON_LAST(p_CurManip))
40957 + p_CurManip = p_CurManip->h_NextManip;
40958 +
40959 + while (p_CurManip)
40960 + {
40961 + /* If this is a unified table, point to the part of the table
40962 + * which is the relative offset in HMCT.
40963 + */
40964 + p_TmpHmctPtr = p_CurManip->p_Hmct; /*- (uint32_t)p_WholeHmct*/
40965 + p_TmpDataPtr = p_CurManip->p_Data; /*- (uint32_t)p_WholeHmct*/
40966 +
40967 + BuildHmct(p_CurManip, &p_CurManip->manipParams, p_TmpHmctPtr,
40968 + p_TmpDataPtr, FALSE);
40969 +
40970 + p_CurManip = p_CurManip->h_PrevManip;
40971 + }
40972 + }
40973 +
40974 + return E_OK;
40975 +}
40976 +
40977 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
40978 +static t_Error UpdateManipIc(t_Handle h_Manip, uint8_t icOffset)
40979 +{
40980 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
40981 + t_Handle p_Ad;
40982 + uint32_t tmpReg32 = 0;
40983 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
40984 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
40985 +
40986 + switch (p_Manip->opcode)
40987 + {
40988 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
40989 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
40990 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
40991 + {
40992 + tmpReg32 =
40993 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets;
40994 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
40995 + *(uint32_t *)&((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets =
40996 + tmpReg32;
40997 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
40998 + p_Manip->icOffset = icOffset;
40999 + }
41000 + else
41001 + {
41002 + if (p_Manip->icOffset != icOffset)
41003 + RETURN_ERROR(
41004 + MAJOR,
41005 + E_INVALID_VALUE,
41006 + ("this manipulation was updated previously by different value"););
41007 + }
41008 + break;
41009 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
41010 + if (p_Manip->h_Frag)
41011 + {
41012 + if (p_Manip->updateParams & INTERNAL_CONTEXT_OFFSET)
41013 + {
41014 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
41015 + tmpReg32 |= GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets);
41016 + tmpReg32 |= (uint32_t)((uint32_t)icOffset << 16);
41017 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets, tmpReg32);
41018 + p_Manip->updateParams &= ~INTERNAL_CONTEXT_OFFSET;
41019 + p_Manip->icOffset = icOffset;
41020 + }
41021 + else
41022 + {
41023 + if (p_Manip->icOffset != icOffset)
41024 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("this manipulation was updated previousely by different value"););
41025 + }
41026 + }
41027 + break;
41028 + }
41029 +
41030 + return E_OK;
41031 +}
41032 +
41033 +static t_Error UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(
41034 + t_Handle h_FmPort, t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate)
41035 +{
41036 +
41037 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
41038 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41039 + t_Error err;
41040 + uint32_t tmpReg32;
41041 +
41042 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
41043 +
41044 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41045 + SANITY_CHECK_RETURN_ERROR(
41046 + (p_Manip->opcode & HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX),
41047 + E_INVALID_STATE);
41048 + SANITY_CHECK_RETURN_ERROR(!p_Manip->muramAllocate, E_INVALID_STATE);
41049 +
41050 + if (p_Manip->updateParams)
41051 + {
41052 + if ((!(p_Manip->updateParams & OFFSET_OF_PR))
41053 + || (p_Manip->shadowUpdateParams & OFFSET_OF_PR))
41054 + RETURN_ERROR(
41055 + MAJOR, E_INVALID_STATE,
41056 + ("in this stage parameters from Port has not be updated"));
41057 +
41058 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
41059 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
41060 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
41061 +
41062 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
41063 + if (err)
41064 + RETURN_ERROR(MAJOR, err, NO_MSG);
41065 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
41066 + RETURN_ERROR(
41067 + MAJOR, E_INVALID_STATE,
41068 + ("Parser result offset wasn't configured previousely"));
41069 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
41070 + ASSERT_COND(!(fmPortGetSetCcParams.getCcParams.prOffset % 16));
41071 +#endif
41072 + }
41073 + else
41074 + if (validate)
41075 + {
41076 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
41077 + || (p_Manip->updateParams & OFFSET_OF_PR))
41078 + RETURN_ERROR(
41079 + MAJOR, E_INVALID_STATE,
41080 + ("in this stage parameters from Port has be updated"));
41081 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
41082 + fmPortGetSetCcParams.setCcParams.type = UPDATE_PSO;
41083 + fmPortGetSetCcParams.setCcParams.psoSize = 16;
41084 +
41085 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
41086 + if (err)
41087 + RETURN_ERROR(MAJOR, err, NO_MSG);
41088 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR)
41089 + RETURN_ERROR(
41090 + MAJOR, E_INVALID_STATE,
41091 + ("Parser result offset wasn't configured previousely"));
41092 +
41093 + }
41094 +
41095 + ASSERT_COND(p_Ad);
41096 +
41097 + if (p_Manip->updateParams & OFFSET_OF_PR)
41098 + {
41099 + tmpReg32 = 0;
41100 + tmpReg32 |= fmPortGetSetCcParams.getCcParams.prOffset;
41101 + WRITE_UINT32(p_Ad->matchTblPtr,
41102 + (GET_UINT32(p_Ad->matchTblPtr) | tmpReg32));
41103 + p_Manip->updateParams &= ~OFFSET_OF_PR;
41104 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
41105 + }
41106 + else
41107 + if (validate)
41108 + {
41109 + tmpReg32 = GET_UINT32(p_Ad->matchTblPtr);
41110 + if ((uint8_t)tmpReg32 != fmPortGetSetCcParams.getCcParams.prOffset)
41111 + RETURN_ERROR(
41112 + MAJOR,
41113 + E_INVALID_STATE,
41114 + ("this manipulation was updated previousely by different value"););
41115 + }
41116 +
41117 + return E_OK;
41118 +}
41119 +
41120 +static t_Error UpdateModifyCapwapFragmenation(t_FmPcdManip *p_Manip, t_Handle h_Ad, bool validate,t_Handle h_FmTree)
41121 +{
41122 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)h_Ad;
41123 + t_FmPcdCcSavedManipParams *p_SavedManipParams = NULL;
41124 + uint32_t tmpReg32 = 0;
41125 +
41126 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
41127 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
41128 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
41129 + 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);
41130 +
41131 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
41132 +
41133 + if (p_Manip->updateParams)
41134 + {
41135 +
41136 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
41137 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
41138 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
41139 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
41140 + if (!p_SavedManipParams)
41141 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
41142 + p_Manip->capwapFragParams.dataOffset = p_SavedManipParams->capwapParams.dataOffset;
41143 +
41144 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
41145 + tmpReg32 |= ((uint32_t)p_Manip->capwapFragParams.dataOffset<< 16);
41146 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
41147 +
41148 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
41149 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
41150 + }
41151 + else if (validate)
41152 + {
41153 +
41154 + p_SavedManipParams = FmPcdCcTreeGetSavedManipParams(h_FmTree);
41155 + if (!p_SavedManipParams)
41156 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("for this manipulation tree has to be configured previosely with this type"));
41157 + if (p_Manip->capwapFragParams.dataOffset != p_SavedManipParams->capwapParams.dataOffset)
41158 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
41159 + }
41160 +
41161 + return E_OK;
41162 +}
41163 +
41164 +static t_Error UpdateInitCapwapFragmentation(t_Handle h_FmPort,
41165 + t_FmPcdManip *p_Manip,
41166 + t_Handle h_Ad,
41167 + bool validate,
41168 + t_Handle h_FmTree)
41169 +{
41170 + t_AdOfTypeContLookup *p_Ad;
41171 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41172 + t_Error err;
41173 + uint32_t tmpReg32 = 0;
41174 + t_FmPcdCcSavedManipParams *p_SavedManipParams;
41175 +
41176 + UNUSED(h_Ad);
41177 +
41178 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
41179 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
41180 + SANITY_CHECK_RETURN_ERROR(p_Manip->frag,E_INVALID_HANDLE);
41181 + SANITY_CHECK_RETURN_ERROR(((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION) ||
41182 + (p_Manip->opcode == HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER)), E_INVALID_STATE);
41183 +
41184 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
41185 +
41186 + if (p_Manip->updateParams)
41187 + {
41188 + if ((!(p_Manip->updateParams & OFFSET_OF_DATA)) ||
41189 + ((p_Manip->shadowUpdateParams & OFFSET_OF_DATA)))
41190 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
41191 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
41192 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
41193 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
41194 + /* For CAPWAP Rassembly used FMAN_CTRL2 hardcoded - so for fragmentation its better to use FMAN_CTRL1 */
41195 + fmPortGetSetCcParams.setCcParams.orFmanCtrl = FPM_PORT_FM_CTL1;
41196 +
41197 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
41198 + if (err)
41199 + RETURN_ERROR(MAJOR, err, NO_MSG);
41200 +
41201 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
41202 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
41203 +
41204 + p_SavedManipParams = (t_FmPcdCcSavedManipParams *)XX_Malloc(sizeof(t_FmPcdCcSavedManipParams));
41205 + p_SavedManipParams->capwapParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
41206 +
41207 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
41208 + ASSERT_COND(!(p_SavedManipParams->capwapParams.dataOffset % 16));
41209 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
41210 +
41211 + FmPcdCcTreeSetSavedManipParams(h_FmTree, (t_Handle)p_SavedManipParams);
41212 + }
41213 + else if (validate)
41214 + {
41215 + if ((!(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)) ||
41216 + ((p_Manip->updateParams & OFFSET_OF_DATA)))
41217 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
41218 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
41219 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN | UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
41220 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
41221 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
41222 + if (err)
41223 + RETURN_ERROR(MAJOR, err, NO_MSG);
41224 +
41225 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
41226 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Data offset wasn't configured previousely"));
41227 + }
41228 +
41229 + if (p_Manip->updateParams)
41230 + {
41231 + tmpReg32 = GET_UINT32(p_Ad->pcAndOffsets);
41232 + tmpReg32 |= ((uint32_t)fmPortGetSetCcParams.getCcParams.dataOffset<< 16);
41233 + WRITE_UINT32(p_Ad->pcAndOffsets,tmpReg32);
41234 +
41235 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
41236 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
41237 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
41238 + }
41239 + else if (validate)
41240 + {
41241 + if (p_Manip->capwapFragParams.dataOffset != fmPortGetSetCcParams.getCcParams.dataOffset)
41242 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("this manipulation was updated previousely by different value"));
41243 + }
41244 +
41245 + return E_OK;
41246 +}
41247 +
41248 +static t_Error UpdateInitCapwapReasm(t_Handle h_FmPcd,
41249 + t_Handle h_FmPort,
41250 + t_FmPcdManip *p_Manip,
41251 + t_Handle h_Ad,
41252 + bool validate)
41253 +{
41254 + t_CapwapReasmPram *p_ReassmTbl;
41255 + t_Error err;
41256 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41257 + uint8_t i = 0;
41258 + uint16_t size;
41259 + uint32_t tmpReg32;
41260 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
41261 + t_FmPcdCcCapwapReassmTimeoutParams ccCapwapReassmTimeoutParams;
41262 +
41263 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
41264 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Frag,E_INVALID_HANDLE);
41265 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag,E_INVALID_HANDLE);
41266 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST), E_INVALID_STATE);
41267 + SANITY_CHECK_RETURN_ERROR(h_FmPcd,E_INVALID_HANDLE);
41268 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc,E_INVALID_HANDLE);
41269 +
41270 + if (p_Manip->h_FmPcd != h_FmPcd)
41271 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
41272 + ("handler of PCD previously was initiated by different value"));
41273 +
41274 + UNUSED(h_Ad);
41275 +
41276 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
41277 + p_ReassmTbl = (t_CapwapReasmPram *)p_Manip->h_Frag;
41278 +
41279 + if (p_Manip->updateParams)
41280 + {
41281 + if ((!(p_Manip->updateParams & NUM_OF_TASKS) &&
41282 + !(p_Manip->updateParams & OFFSET_OF_DATA) &&
41283 + !(p_Manip->updateParams & OFFSET_OF_PR) &&
41284 + !(p_Manip->updateParams & HW_PORT_ID)) ||
41285 + ((p_Manip->shadowUpdateParams & NUM_OF_TASKS) ||
41286 + (p_Manip->shadowUpdateParams & OFFSET_OF_DATA) || (p_Manip->shadowUpdateParams & OFFSET_OF_PR) ||
41287 + (p_Manip->shadowUpdateParams & HW_PORT_ID)))
41288 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has not be updated"));
41289 +
41290 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams;
41291 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
41292 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
41293 +
41294 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
41295 + if (err)
41296 + RETURN_ERROR(MAJOR, err, NO_MSG);
41297 +
41298 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
41299 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Num of tasks wasn't configured previousely"));
41300 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
41301 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previousely"));
41302 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
41303 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
41304 +#ifdef FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
41305 + ASSERT_COND((fmPortGetSetCcParams.getCcParams.dataOffset % 16) == 0);
41306 +#endif /* FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004 */
41307 + }
41308 + else if (validate)
41309 + {
41310 + if ((!(p_Manip->shadowUpdateParams & NUM_OF_TASKS) &&
41311 + !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA) &&
41312 + !(p_Manip->shadowUpdateParams & OFFSET_OF_PR) &&
41313 + !(p_Manip->shadowUpdateParams & HW_PORT_ID)) &&
41314 + ((p_Manip->updateParams & NUM_OF_TASKS) ||
41315 + (p_Manip->updateParams & OFFSET_OF_DATA) || (p_Manip->updateParams & OFFSET_OF_PR) ||
41316 + (p_Manip->updateParams & HW_PORT_ID)))
41317 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("in this stage parameters from Port has be updated"));
41318 +
41319 + fmPortGetSetCcParams.getCcParams.type = p_Manip->shadowUpdateParams;
41320 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
41321 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
41322 +
41323 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
41324 + if (err)
41325 + RETURN_ERROR(MAJOR, err, NO_MSG);
41326 +
41327 + if (fmPortGetSetCcParams.getCcParams.type & NUM_OF_TASKS)
41328 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("NumOfTasks wasn't configured previously"));
41329 + if (fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_DATA)
41330 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("offset of the data wasn't configured previously"));
41331 + if (fmPortGetSetCcParams.getCcParams.type & HW_PORT_ID)
41332 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("hwPortId wasn't updated"));
41333 + }
41334 +
41335 + if (p_Manip->updateParams)
41336 + {
41337 + if (p_Manip->updateParams & NUM_OF_TASKS)
41338 + {
41339 + /*recommendation of Microcode team - (maxNumFramesInProcess * 2) */
41340 + size = (uint16_t)(p_Manip->capwapFragParams.maxNumFramesInProcess*2 + fmPortGetSetCcParams.getCcParams.numOfTasks);
41341 + if (size > 255)
41342 + RETURN_ERROR(MAJOR,E_INVALID_VALUE, ("numOfOpenReassmEntries + numOfTasks per port can not be greater than 256"));
41343 +
41344 + p_Manip->capwapFragParams.numOfTasks = fmPortGetSetCcParams.getCcParams.numOfTasks;
41345 +
41346 + /*p_ReassmFrmDescrIndxPoolTbl*/
41347 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl =
41348 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41349 + (uint32_t)(size + 1),
41350 + 4);
41351 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
41352 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer index pool table"));
41353 +
41354 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, 0, (uint32_t)(size + 1));
41355 +
41356 + for ( i = 0; i < size; i++)
41357 + WRITE_UINT8(*(uint8_t *)PTR_MOVE(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl, i), (uint8_t)(i+1));
41358 +
41359 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl) - p_FmPcd->physicalMuramBase);
41360 +
41361 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescIndexPoolTblPtr, tmpReg32);
41362 +
41363 + /*p_ReassmFrmDescrPoolTbl*/
41364 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl =
41365 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41366 + (uint32_t)((size + 1) * FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE),
41367 + 4);
41368 +
41369 + if (!p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
41370 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly frame buffer pool table"));
41371 +
41372 + MemSet8(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl, 0, (uint32_t)((size +1)* FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE));
41373 +
41374 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl) - p_FmPcd->physicalMuramBase);
41375 +
41376 + WRITE_UINT32(p_ReassmTbl->reasmFrmDescPoolTblPtr, tmpReg32);
41377 +
41378 + /*p_TimeOutTbl*/
41379 +
41380 + p_Manip->capwapFragParams.p_TimeOutTbl =
41381 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41382 + (uint32_t)((size + 1)* FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE),
41383 + 4);
41384 +
41385 + if (!p_Manip->capwapFragParams.p_TimeOutTbl)
41386 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP Reassembly timeout table"));
41387 +
41388 + MemSet8(p_Manip->capwapFragParams.p_TimeOutTbl, 0, (uint16_t)((size + 1)*FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE));
41389 +
41390 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_TimeOutTbl) - p_FmPcd->physicalMuramBase);
41391 + WRITE_UINT32(p_ReassmTbl->timeOutTblPtr, tmpReg32);
41392 +
41393 + p_Manip->updateParams &= ~NUM_OF_TASKS;
41394 + p_Manip->shadowUpdateParams |= NUM_OF_TASKS;
41395 + }
41396 +
41397 + if (p_Manip->updateParams & OFFSET_OF_DATA)
41398 + {
41399 + p_Manip->capwapFragParams.dataOffset = fmPortGetSetCcParams.getCcParams.dataOffset;
41400 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
41401 + tmpReg32|= p_Manip->capwapFragParams.dataOffset;
41402 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
41403 + p_Manip->updateParams &= ~OFFSET_OF_DATA;
41404 + p_Manip->shadowUpdateParams |= OFFSET_OF_DATA;
41405 + }
41406 +
41407 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
41408 + {
41409 + p_Manip->capwapFragParams.prOffset = fmPortGetSetCcParams.getCcParams.prOffset;
41410 +
41411 + tmpReg32 = GET_UINT32(p_ReassmTbl->mode);
41412 + tmpReg32|= FM_PCD_MANIP_CAPWAP_REASM_PR_COPY;
41413 + WRITE_UINT32(p_ReassmTbl->mode, tmpReg32);
41414 +
41415 + tmpReg32 = GET_UINT32(p_ReassmTbl->intStatsTblPtr);
41416 + tmpReg32 |= (uint32_t)p_Manip->capwapFragParams.prOffset << 24;
41417 + WRITE_UINT32(p_ReassmTbl->intStatsTblPtr, tmpReg32);
41418 + p_Manip->updateParams &= ~OFFSET_OF_PR;
41419 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
41420 + }
41421 + else
41422 + {
41423 + p_Manip->capwapFragParams.prOffset = 0xff;
41424 + p_Manip->updateParams &= ~OFFSET_OF_PR;
41425 + p_Manip->shadowUpdateParams |= OFFSET_OF_PR;
41426 + }
41427 +
41428 + p_Manip->capwapFragParams.hwPortId = fmPortGetSetCcParams.getCcParams.hardwarePortId;
41429 + p_Manip->updateParams &= ~HW_PORT_ID;
41430 + p_Manip->shadowUpdateParams |= HW_PORT_ID;
41431 +
41432 + /*timeout hc */
41433 + ccCapwapReassmTimeoutParams.fqidForTimeOutFrames = p_Manip->capwapFragParams.fqidForTimeOutFrames;
41434 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl = (uint32_t)p_Manip->capwapFragParams.hwPortId << 24;
41435 + ccCapwapReassmTimeoutParams.portIdAndCapwapReassmTbl |= (uint32_t)((XX_VirtToPhys(p_ReassmTbl) - p_FmPcd->physicalMuramBase));
41436 + ccCapwapReassmTimeoutParams.timeoutRequestTime = (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_Manip->capwapFragParams.timeoutRoutineRequestTime)/2;
41437 + return FmHcPcdCcCapwapTimeoutReassm(p_FmPcd->h_Hc,&ccCapwapReassmTimeoutParams);
41438 + }
41439 +
41440 + else if (validate)
41441 + {
41442 + if (fmPortGetSetCcParams.getCcParams.hardwarePortId != p_Manip->capwapFragParams.hwPortId)
41443 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Reassembly manipulation previously was assigned to another port"));
41444 + if (fmPortGetSetCcParams.getCcParams.numOfTasks != p_Manip->capwapFragParams.numOfTasks)
41445 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfTasks for this manipulation previously was defined by another value "));
41446 +
41447 + if (!(fmPortGetSetCcParams.getCcParams.type & OFFSET_OF_PR))
41448 + {
41449 + if (p_Manip->capwapFragParams.prOffset != fmPortGetSetCcParams.getCcParams.prOffset)
41450 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
41451 + }
41452 + else
41453 + {
41454 + if (p_Manip->capwapFragParams.prOffset != 0xff)
41455 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Parse result offset previously was defined by another value "));
41456 + }
41457 + if (fmPortGetSetCcParams.getCcParams.dataOffset != p_Manip->capwapFragParams.dataOffset)
41458 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Data offset previously was defined by another value "));
41459 + }
41460 +
41461 + return E_OK;
41462 +}
41463 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
41464 +
41465 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
41466 +{
41467 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
41468 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = { 0 };
41469 + t_Error err = E_OK;
41470 + uint8_t result;
41471 + uint32_t bitFor1Micro, tsbs, log2num;
41472 +
41473 + ASSERT_COND(p_FmPcd);
41474 + ASSERT_COND(h_ReasmCommonPramTbl);
41475 +
41476 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
41477 + if (bitFor1Micro == 0)
41478 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
41479 +
41480 + bitFor1Micro = 32 - bitFor1Micro;
41481 + LOG2(FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH, log2num);
41482 + tsbs = bitFor1Micro - log2num;
41483 +
41484 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(
41485 + h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
41486 + ccReassmTimeoutParams.tsbs = (uint8_t)tsbs;
41487 + ccReassmTimeoutParams.activate = TRUE;
41488 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams,
41489 + &result)) != E_OK)
41490 + RETURN_ERROR(MAJOR, err, NO_MSG);
41491 +
41492 + switch (result)
41493 + {
41494 + case (0):
41495 + return E_OK;
41496 + case (1):
41497 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("failed to allocate TNUM"));
41498 + case (2):
41499 + RETURN_ERROR(
41500 + MAJOR, E_NO_MEMORY,
41501 + ("failed to allocate internal buffer from the HC-Port"));
41502 + case (3):
41503 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
41504 + ("'Disable Timeout Task' with invalid IPRCPT"));
41505 + case (4):
41506 + RETURN_ERROR(MAJOR, E_FULL, ("too many timeout tasks"));
41507 + case (5):
41508 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("invalid sub command"));
41509 + default:
41510 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
41511 + }
41512 + return E_OK;
41513 +}
41514 +
41515 +static t_Error CreateReassCommonTable(t_FmPcdManip *p_Manip)
41516 +{
41517 + uint32_t tmpReg32 = 0, i, bitFor1Micro;
41518 + uint64_t tmpReg64, size;
41519 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
41520 + t_Error err = E_OK;
41521 +
41522 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
41523 + if (bitFor1Micro == 0)
41524 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
41525 +
41526 + /* Allocation of the Reassembly Common Parameters table. This table is located in the
41527 + MURAM. Its size is 64 bytes and its base address should be 8-byte aligned. */
41528 + p_Manip->reassmParams.p_ReassCommonTbl =
41529 + (t_ReassCommonTbl *)FM_MURAM_AllocMem(
41530 + p_FmPcd->h_FmMuram,
41531 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE,
41532 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN);
41533 +
41534 + if (!p_Manip->reassmParams.p_ReassCommonTbl)
41535 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41536 + ("MURAM alloc for Reassembly common parameters table"));
41537 +
41538 + MemSet8(p_Manip->reassmParams.p_ReassCommonTbl, 0,
41539 + FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE);
41540 +
41541 + /* Setting the TimeOut Mode.*/
41542 + tmpReg32 = 0;
41543 + if (p_Manip->reassmParams.timeOutMode
41544 + == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
41545 + tmpReg32 |= FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES;
41546 +
41547 + /* Setting TimeOut FQID - Frames that time out are enqueued to this FQID.
41548 + In order to cause TimeOut frames to be discarded, this queue should be configured accordingly*/
41549 + tmpReg32 |= p_Manip->reassmParams.fqidForTimeOutFrames;
41550 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeoutModeAndFqid,
41551 + tmpReg32);
41552 +
41553 + /* Calculation the size of IP Reassembly Frame Descriptor - number of frames that are allowed to be reassembled simultaneously + 129.*/
41554 + size = p_Manip->reassmParams.maxNumFramesInProcess + 129;
41555 +
41556 + /*Allocation of IP Reassembly Frame Descriptor Indexes Pool - This pool resides in the MURAM */
41557 + p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr =
41558 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41559 + (uint32_t)(size * 2),
41560 + 256));
41561 + if (!p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
41562 + RETURN_ERROR(
41563 + MAJOR, E_NO_MEMORY,
41564 + ("MURAM alloc for Reassembly frame descriptor indexes pool"));
41565 +
41566 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr),
41567 + 0, (uint32_t)(size * 2));
41568 +
41569 + /* The entries in IP Reassembly Frame Descriptor Indexes Pool contains indexes starting with 1 up to
41570 + the maximum number of frames that are allowed to be reassembled simultaneously + 128.
41571 + The last entry in this pool must contain the index zero*/
41572 + for (i = 0; i < (size - 1); i++)
41573 + WRITE_UINT16(
41574 + *(uint16_t *)PTR_MOVE(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr), (i<<1)),
41575 + (uint16_t)(i+1));
41576 +
41577 + /* Sets the IP Reassembly Frame Descriptor Indexes Pool offset from MURAM */
41578 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
41579 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr))
41580 + - p_FmPcd->physicalMuramBase);
41581 + WRITE_UINT32(
41582 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescIndexPoolTblPtr,
41583 + tmpReg32);
41584 +
41585 + /* Allocation of the Reassembly Frame Descriptors Pool - This pool resides in external memory.
41586 + The number of entries in this pool should be equal to the number of entries in IP Reassembly Frame Descriptor Indexes Pool.*/
41587 + p_Manip->reassmParams.reassFrmDescrPoolTblAddr =
41588 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(size * 64), p_Manip->reassmParams.dataMemId, 64));
41589 +
41590 + if (!p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
41591 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
41592 +
41593 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr), 0,
41594 + (uint32_t)(size * 64));
41595 +
41596 + /* Sets the Reassembly Frame Descriptors Pool and liodn offset*/
41597 + tmpReg64 = (uint64_t)(XX_VirtToPhys(
41598 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr)));
41599 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41600 + & FM_PCD_MANIP_REASM_LIODN_MASK)
41601 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
41602 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41603 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
41604 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
41605 + WRITE_UINT32(
41606 + p_Manip->reassmParams.p_ReassCommonTbl->liodnAndReassFrmDescPoolPtrHi,
41607 + (uint32_t)(tmpReg64 >> 32));
41608 + WRITE_UINT32(
41609 + p_Manip->reassmParams.p_ReassCommonTbl->reassFrmDescPoolPtrLow,
41610 + (uint32_t)tmpReg64);
41611 +
41612 + /*Allocation of the TimeOut table - This table resides in the MURAM.
41613 + The number of entries in this table is identical to the number of entries in the Reassembly Frame Descriptors Pool*/
41614 + p_Manip->reassmParams.timeOutTblAddr =
41615 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, (uint32_t)(size * 8),8));
41616 +
41617 + if (!p_Manip->reassmParams.timeOutTblAddr)
41618 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
41619 + ("MURAM alloc for Reassembly timeout table"));
41620 +
41621 + MemSet8(UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr), 0,
41622 + (uint16_t)(size * 8));
41623 +
41624 + /* Sets the TimeOut table offset from MURAM */
41625 + tmpReg32 = (uint32_t)(XX_VirtToPhys(
41626 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr))
41627 + - p_FmPcd->physicalMuramBase);
41628 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->timeOutTblPtr,
41629 + tmpReg32);
41630 +
41631 + /* Sets the Expiration Delay */
41632 + tmpReg32 = 0;
41633 + tmpReg32 |= (((uint32_t)(1 << bitFor1Micro))
41634 + * p_Manip->reassmParams.timeoutThresholdForReassmProcess);
41635 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->expirationDelay,
41636 + tmpReg32);
41637 +
41638 + err = FmPcdRegisterReassmPort(p_FmPcd,
41639 + p_Manip->reassmParams.p_ReassCommonTbl);
41640 + if (err != E_OK)
41641 + {
41642 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
41643 + p_Manip->reassmParams.p_ReassCommonTbl);
41644 + RETURN_ERROR(MAJOR, err, ("port registration"));
41645 + }
41646 +
41647 + return err;
41648 +}
41649 +
41650 +static t_Error CreateReassTable(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
41651 +{
41652 + t_FmPcd *p_FmPcd = p_Manip->h_FmPcd;
41653 + uint32_t tmpReg32, autoLearnHashTblSize;
41654 + uint32_t numOfWays, setSize, setSizeCode, keySize;
41655 + uint32_t waySize, numOfSets, numOfEntries;
41656 + uint64_t tmpReg64;
41657 + uint16_t minFragSize;
41658 + uint16_t maxReassemSize;
41659 + uintptr_t *p_AutoLearnHashTblAddr, *p_AutoLearnSetLockTblAddr;
41660 + t_ReassTbl **p_ReassTbl;
41661 +
41662 + switch (hdr)
41663 + {
41664 + case HEADER_TYPE_IPv4:
41665 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv4ReassTbl;
41666 + p_AutoLearnHashTblAddr =
41667 + &p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr;
41668 + p_AutoLearnSetLockTblAddr =
41669 + &p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr;
41670 + minFragSize = p_Manip->reassmParams.ip.minFragSize[0];
41671 + maxReassemSize = 0;
41672 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0];
41673 + keySize = 4 + 4 + 1 + 2; /* 3-tuple + IP-Id */
41674 + break;
41675 + case HEADER_TYPE_IPv6:
41676 + p_ReassTbl = &p_Manip->reassmParams.ip.p_Ipv6ReassTbl;
41677 + p_AutoLearnHashTblAddr =
41678 + &p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr;
41679 + p_AutoLearnSetLockTblAddr =
41680 + &p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr;
41681 + minFragSize = p_Manip->reassmParams.ip.minFragSize[1];
41682 + maxReassemSize = 0;
41683 + numOfWays = p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1];
41684 + keySize = 16 + 16 + 4; /* 2-tuple + IP-Id */
41685 + if (numOfWays > e_FM_PCD_MANIP_SIX_WAYS_HASH)
41686 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("num of ways"));
41687 + break;
41688 + case HEADER_TYPE_CAPWAP:
41689 + p_ReassTbl = &p_Manip->reassmParams.capwap.p_ReassTbl;
41690 + p_AutoLearnHashTblAddr =
41691 + &p_Manip->reassmParams.capwap.autoLearnHashTblAddr;
41692 + p_AutoLearnSetLockTblAddr =
41693 + &p_Manip->reassmParams.capwap.autoLearnSetLockTblAddr;
41694 + minFragSize = 0;
41695 + maxReassemSize = p_Manip->reassmParams.capwap.maxRessembledsSize;
41696 + numOfWays = p_Manip->reassmParams.capwap.numOfFramesPerHashEntry;
41697 + keySize = 4;
41698 + break;
41699 + default:
41700 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
41701 + }
41702 + keySize += 2; /* 2 bytes reserved for RFDIndex */
41703 +#if (DPAA_VERSION >= 11)
41704 + keySize += 2; /* 2 bytes reserved */
41705 +#endif /* (DPAA_VERSION >= 11) */
41706 + waySize = ROUND_UP(keySize, 8);
41707 +
41708 + /* Allocates the Reassembly Parameters Table - This table is located in the MURAM.*/
41709 + *p_ReassTbl = (t_ReassTbl *)FM_MURAM_AllocMem(
41710 + p_FmPcd->h_FmMuram, FM_PCD_MANIP_REASM_TABLE_SIZE,
41711 + FM_PCD_MANIP_REASM_TABLE_ALIGN);
41712 + if (!*p_ReassTbl)
41713 + RETURN_ERROR( MAJOR, E_NO_MEMORY,
41714 + ("MURAM alloc for Reassembly specific parameters table"));
41715 + memset(*p_ReassTbl, 0, sizeof(t_ReassTbl));
41716 +
41717 + /* Sets the Reassembly common Parameters table offset from MURAM in the Reassembly Table descriptor*/
41718 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->reassmParams.p_ReassCommonTbl)
41719 + - p_FmPcd->physicalMuramBase);
41720 + WRITE_UINT32((*p_ReassTbl)->reassCommonPrmTblPtr, tmpReg32);
41721 +
41722 + /* Calculate set size (set size is rounded-up to next power of 2) */
41723 + NEXT_POWER_OF_2(numOfWays * waySize, setSize);
41724 +
41725 + /* Get set size code */
41726 + LOG2(setSize, setSizeCode);
41727 +
41728 + /* Sets ways number and set size code */
41729 + WRITE_UINT16((*p_ReassTbl)->waysNumAndSetSize,
41730 + (uint16_t)((numOfWays << 8) | setSizeCode));
41731 +
41732 + /* It is recommended that the total number of entries in this table
41733 + (number of sets * number of ways) will be twice the number of frames that
41734 + are expected to be reassembled simultaneously.*/
41735 + numOfEntries = (uint32_t)(p_Manip->reassmParams.maxNumFramesInProcess * 2);
41736 +
41737 + /* sets number calculation - number of entries = number of sets * number of ways */
41738 + numOfSets = numOfEntries / numOfWays;
41739 +
41740 + /* Sets AutoLearnHashKeyMask*/
41741 + NEXT_POWER_OF_2(numOfSets, numOfSets);
41742 +
41743 + WRITE_UINT16((*p_ReassTbl)->autoLearnHashKeyMask,
41744 + (uint16_t)(numOfSets - 1));
41745 +
41746 + /* Allocation of Reassembly Automatic Learning Hash Table - This table resides in external memory.
41747 + The size of this table is determined by the number of sets and the set size.
41748 + Table size = set size * number of sets
41749 + This table base address should be aligned to SetSize.*/
41750 + autoLearnHashTblSize = numOfSets * setSize;
41751 +
41752 + *p_AutoLearnHashTblAddr =
41753 + PTR_TO_UINT(XX_MallocSmart(autoLearnHashTblSize, p_Manip->reassmParams.dataMemId, setSize));
41754 + if (!*p_AutoLearnHashTblAddr)
41755 + {
41756 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
41757 + *p_ReassTbl = NULL;
41758 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
41759 + }
41760 + MemSet8(UINT_TO_PTR(*p_AutoLearnHashTblAddr), 0, autoLearnHashTblSize);
41761 +
41762 + /* Sets the Reassembly Automatic Learning Hash Table and liodn offset */
41763 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41764 + & FM_PCD_MANIP_REASM_LIODN_MASK)
41765 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
41766 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41767 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
41768 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
41769 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
41770 + WRITE_UINT32( (*p_ReassTbl)->liodnAlAndAutoLearnHashTblPtrHi,
41771 + (uint32_t)(tmpReg64 >> 32));
41772 + WRITE_UINT32((*p_ReassTbl)->autoLearnHashTblPtrLow, (uint32_t)tmpReg64);
41773 +
41774 + /* Allocation of the Set Lock table - This table resides in external memory
41775 + The size of this table is (number of sets in the Reassembly Automatic Learning Hash table)*4 bytes.
41776 + This table resides in external memory and its base address should be 4-byte aligned */
41777 + *p_AutoLearnSetLockTblAddr =
41778 + PTR_TO_UINT(XX_MallocSmart((uint32_t)(numOfSets * 4), p_Manip->reassmParams.dataMemId, 4));
41779 + if (!*p_AutoLearnSetLockTblAddr)
41780 + {
41781 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, *p_ReassTbl);
41782 + *p_ReassTbl = NULL;
41783 + XX_FreeSmart(UINT_TO_PTR(*p_AutoLearnHashTblAddr));
41784 + *p_AutoLearnHashTblAddr = 0;
41785 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation FAILED"));
41786 + }
41787 + MemSet8(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr), 0, (numOfSets * 4));
41788 +
41789 + /* sets Set Lock table pointer and liodn offset*/
41790 + tmpReg64 = ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41791 + & FM_PCD_MANIP_REASM_LIODN_MASK)
41792 + << (uint64_t)FM_PCD_MANIP_REASM_LIODN_SHIFT);
41793 + tmpReg64 |= ((uint64_t)(p_Manip->reassmParams.dataLiodnOffset
41794 + & FM_PCD_MANIP_REASM_ELIODN_MASK)
41795 + << (uint64_t)FM_PCD_MANIP_REASM_ELIODN_SHIFT);
41796 + tmpReg64 |= XX_VirtToPhys(UINT_TO_PTR(*p_AutoLearnSetLockTblAddr));
41797 + WRITE_UINT32( (*p_ReassTbl)->liodnSlAndAutoLearnSetLockTblPtrHi,
41798 + (uint32_t)(tmpReg64 >> 32));
41799 + WRITE_UINT32((*p_ReassTbl)->autoLearnSetLockTblPtrLow, (uint32_t)tmpReg64);
41800 +
41801 + /* Sets user's requested minimum fragment size (in Bytes) for First/Middle fragment */
41802 + WRITE_UINT16((*p_ReassTbl)->minFragSize, minFragSize);
41803 +
41804 + WRITE_UINT16((*p_ReassTbl)->maxReassemblySize, maxReassemSize);
41805 +
41806 + return E_OK;
41807 +}
41808 +
41809 +static t_Error UpdateInitReasm(t_Handle h_FmPcd, t_Handle h_PcdParams,
41810 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
41811 + t_Handle h_Ad, bool validate)
41812 +{
41813 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
41814 + uint32_t tmpReg32;
41815 + t_Error err;
41816 + t_FmPortPcdParams *p_PcdParams = (t_FmPortPcdParams *)h_PcdParams;
41817 +#if (DPAA_VERSION >= 11)
41818 + t_FmPcdCtrlParamsPage *p_ParamsPage;
41819 +#endif /* (DPAA_VERSION >= 11) */
41820 +
41821 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
41822 + SANITY_CHECK_RETURN_ERROR(!p_Manip->frag, E_INVALID_HANDLE);
41823 + SANITY_CHECK_RETURN_ERROR(
41824 + (p_Manip->opcode == HMAN_OC_IP_REASSEMBLY) || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY),
41825 + E_INVALID_STATE);
41826 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
41827 + SANITY_CHECK_RETURN_ERROR(!p_Manip->updateParams || h_PcdParams,
41828 + E_INVALID_HANDLE);
41829 +
41830 + UNUSED(h_Ad);
41831 +
41832 + if (!p_Manip->updateParams)
41833 + return E_OK;
41834 +
41835 + if (p_Manip->h_FmPcd != h_FmPcd)
41836 + RETURN_ERROR(
41837 + MAJOR, E_INVALID_STATE,
41838 + ("handler of PCD previously was initiated by different value"));
41839 +
41840 + if (p_Manip->updateParams)
41841 + {
41842 + if ((!(p_Manip->updateParams
41843 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK)))
41844 + || ((p_Manip->shadowUpdateParams
41845 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))))
41846 + RETURN_ERROR(
41847 + MAJOR, E_INVALID_STATE,
41848 + ("in this stage parameters from Port has not be updated"));
41849 +
41850 + fmPortGetSetCcParams.setCcParams.type = 0;
41851 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
41852 + {
41853 + fmPortGetSetCcParams.setCcParams.type |= UPDATE_OFP_DPTE;
41854 + fmPortGetSetCcParams.setCcParams.ofpDpde = 0xF;
41855 + }
41856 + fmPortGetSetCcParams.getCcParams.type = p_Manip->updateParams | FM_REV;
41857 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
41858 + != E_OK)
41859 + RETURN_ERROR(MAJOR, err, NO_MSG);
41860 + if (fmPortGetSetCcParams.getCcParams.type
41861 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK | FM_REV))
41862 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
41863 + ("offset of the data wasn't configured previously"));
41864 + if (p_Manip->updateParams
41865 + & (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK))
41866 + {
41867 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
41868 + uint8_t *p_Ptr, i, totalNumOfTnums;
41869 +
41870 + totalNumOfTnums =
41871 + (uint8_t)(fmPortGetSetCcParams.getCcParams.numOfTasks
41872 + + fmPortGetSetCcParams.getCcParams.numOfExtraTasks);
41873 +
41874 + p_Manip->reassmParams.internalBufferPoolAddr =
41875 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41876 + (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS),
41877 + BMI_FIFO_UNITS));
41878 + if (!p_Manip->reassmParams.internalBufferPoolAddr)
41879 + RETURN_ERROR(
41880 + MAJOR, E_NO_MEMORY,
41881 + ("MURAM alloc for Reassembly internal buffers pool"));
41882 + MemSet8(
41883 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr),
41884 + 0, (uint32_t)(totalNumOfTnums * BMI_FIFO_UNITS));
41885 +
41886 + p_Manip->reassmParams.internalBufferPoolManagementIndexAddr =
41887 + PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
41888 + (uint32_t)(5 + totalNumOfTnums),
41889 + 4));
41890 + if (!p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
41891 + RETURN_ERROR(
41892 + MAJOR,
41893 + E_NO_MEMORY,
41894 + ("MURAM alloc for Reassembly internal buffers management"));
41895 +
41896 + p_Ptr =
41897 + (uint8_t*)UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr);
41898 + WRITE_UINT32(
41899 + *(uint32_t*)p_Ptr,
41900 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr)) - p_FmPcd->physicalMuramBase));
41901 + for (i = 0, p_Ptr += 4; i < totalNumOfTnums; i++, p_Ptr++)
41902 + WRITE_UINT8(*p_Ptr, i);
41903 + WRITE_UINT8(*p_Ptr, 0xFF);
41904 +
41905 + tmpReg32 =
41906 + (4 << FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT)
41907 + | ((uint32_t)(XX_VirtToPhys(
41908 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr))
41909 + - p_FmPcd->physicalMuramBase));
41910 + WRITE_UINT32(
41911 + p_Manip->reassmParams.p_ReassCommonTbl->internalBufferManagement,
41912 + tmpReg32);
41913 +
41914 + p_Manip->updateParams &= ~(NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
41915 + | DISCARD_MASK);
41916 + p_Manip->shadowUpdateParams |= (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS
41917 + | DISCARD_MASK);
41918 + }
41919 + }
41920 +
41921 + if (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
41922 + {
41923 + if (p_Manip->reassmParams.capwap.h_Scheme)
41924 + {
41925 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
41926 + p_Manip->reassmParams.capwap.h_Scheme;
41927 + p_PcdParams->p_KgParams->numOfSchemes++;
41928 + }
41929 +
41930 + }
41931 + else
41932 + {
41933 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
41934 + {
41935 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
41936 + p_Manip->reassmParams.ip.h_Ipv4Scheme;
41937 + p_PcdParams->p_KgParams->numOfSchemes++;
41938 + }
41939 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
41940 + {
41941 + p_PcdParams->p_KgParams->h_Schemes[p_PcdParams->p_KgParams->numOfSchemes] =
41942 + p_Manip->reassmParams.ip.h_Ipv6Scheme;
41943 + p_PcdParams->p_KgParams->numOfSchemes++;
41944 + }
41945 +#if (DPAA_VERSION >= 11)
41946 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev >= 6)
41947 + {
41948 + if ((err = FmPortSetGprFunc(h_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
41949 + (void**)&p_ParamsPage)) != E_OK)
41950 + RETURN_ERROR(MAJOR, err, NO_MSG);
41951 +
41952 + tmpReg32 = NIA_ENG_KG;
41953 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
41954 + {
41955 + tmpReg32 |= NIA_KG_DIRECT;
41956 + tmpReg32 |= NIA_KG_CC_EN;
41957 + tmpReg32 |= FmPcdKgGetSchemeId(
41958 + p_Manip->reassmParams.ip.h_Ipv4Scheme);
41959 + WRITE_UINT32(p_ParamsPage->iprIpv4Nia, tmpReg32);
41960 + }
41961 + if (p_Manip->reassmParams.ip.h_Ipv6Scheme)
41962 + {
41963 + tmpReg32 &= ~NIA_AC_MASK;
41964 + tmpReg32 |= NIA_KG_DIRECT;
41965 + tmpReg32 |= NIA_KG_CC_EN;
41966 + tmpReg32 |= FmPcdKgGetSchemeId(
41967 + p_Manip->reassmParams.ip.h_Ipv6Scheme);
41968 + WRITE_UINT32(p_ParamsPage->iprIpv6Nia, tmpReg32);
41969 + }
41970 + }
41971 +#else
41972 + if (fmPortGetSetCcParams.getCcParams.revInfo.majorRev < 6)
41973 + {
41974 + WRITE_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->discardMask,
41975 + fmPortGetSetCcParams.getCcParams.discardMask);
41976 + }
41977 +#endif /* (DPAA_VERSION >= 11) */
41978 + }
41979 + return E_OK;
41980 +}
41981 +
41982 +#if (DPAA_VERSION == 10)
41983 +static t_Error FmPcdFragHcScratchPoolFill(t_Handle h_FmPcd, uint8_t scratchBpid)
41984 +{
41985 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
41986 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
41987 + t_Error err;
41988 +
41989 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
41990 +
41991 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
41992 +
41993 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers = NUM_OF_SCRATCH_POOL_BUFFERS;
41994 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
41995 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, TRUE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
41996 + RETURN_ERROR(MAJOR, err, NO_MSG);
41997 +
41998 + if (fmPcdCcFragScratchPoolCmdParams.numOfBuffers != 0)
41999 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Fill scratch pool failed,"
42000 + "Failed to release %d buffers to the BM (missing FBPRs)",
42001 + fmPcdCcFragScratchPoolCmdParams.numOfBuffers));
42002 +
42003 + return E_OK;
42004 +}
42005 +
42006 +static t_Error FmPcdFragHcScratchPoolEmpty(t_Handle h_FmPcd, uint8_t scratchBpid)
42007 +{
42008 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
42009 + t_FmPcdCcFragScratchPoolCmdParams fmPcdCcFragScratchPoolCmdParams;
42010 + t_Error err;
42011 +
42012 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
42013 +
42014 + memset(&fmPcdCcFragScratchPoolCmdParams, 0, sizeof(t_FmPcdCcFragScratchPoolCmdParams));
42015 +
42016 + fmPcdCcFragScratchPoolCmdParams.bufferPoolId = scratchBpid;
42017 + if ((err = FmHcPcdCcIpFragScratchPollCmd(p_FmPcd->h_Hc, FALSE, &fmPcdCcFragScratchPoolCmdParams)) != E_OK)
42018 + RETURN_ERROR(MAJOR, err, NO_MSG);
42019 +
42020 + return E_OK;
42021 +}
42022 +#endif /* (DPAA_VERSION == 10) */
42023 +
42024 +static void ReleaseManipHandler(t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
42025 +{
42026 + if (p_Manip->h_Ad)
42027 + {
42028 + if (p_Manip->muramAllocate)
42029 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Ad);
42030 + else
42031 + XX_Free(p_Manip->h_Ad);
42032 + p_Manip->h_Ad = NULL;
42033 + }
42034 + if (p_Manip->p_Template)
42035 + {
42036 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_Template);
42037 + p_Manip->p_Template = NULL;
42038 + }
42039 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42040 + if (p_Manip->h_Frag)
42041 + {
42042 + if (p_Manip->capwapFragParams.p_AutoLearnHashTbl)
42043 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
42044 + p_Manip->capwapFragParams.p_AutoLearnHashTbl);
42045 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl)
42046 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
42047 + p_Manip->capwapFragParams.p_ReassmFrmDescrPoolTbl);
42048 + if (p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl)
42049 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
42050 + p_Manip->capwapFragParams.p_ReassmFrmDescrIndxPoolTbl);
42051 + if (p_Manip->capwapFragParams.p_TimeOutTbl)
42052 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
42053 + p_Manip->capwapFragParams.p_TimeOutTbl);
42054 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->h_Frag);
42055 +
42056 + }
42057 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42058 + if (p_Manip->frag)
42059 + {
42060 + if (p_Manip->fragParams.p_Frag)
42061 + {
42062 +#if (DPAA_VERSION == 10)
42063 + FmPcdFragHcScratchPoolEmpty((t_Handle)p_FmPcd, p_Manip->fragParams.scratchBpid);
42064 +#endif /* (DPAA_VERSION == 10) */
42065 +
42066 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
42067 + }
42068 + }
42069 + else
42070 + if (p_Manip->reassm)
42071 + {
42072 + FmPcdUnregisterReassmPort(p_FmPcd,
42073 + p_Manip->reassmParams.p_ReassCommonTbl);
42074 +
42075 + if (p_Manip->reassmParams.timeOutTblAddr)
42076 + FM_MURAM_FreeMem(
42077 + p_FmPcd->h_FmMuram,
42078 + UINT_TO_PTR(p_Manip->reassmParams.timeOutTblAddr));
42079 + if (p_Manip->reassmParams.reassFrmDescrPoolTblAddr)
42080 + XX_FreeSmart(
42081 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrPoolTblAddr));
42082 + if (p_Manip->reassmParams.p_ReassCommonTbl)
42083 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
42084 + p_Manip->reassmParams.p_ReassCommonTbl);
42085 + if (p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr)
42086 + FM_MURAM_FreeMem(
42087 + p_FmPcd->h_FmMuram,
42088 + UINT_TO_PTR(p_Manip->reassmParams.reassFrmDescrIndxPoolTblAddr));
42089 + if (p_Manip->reassmParams.internalBufferPoolManagementIndexAddr)
42090 + FM_MURAM_FreeMem(
42091 + p_FmPcd->h_FmMuram,
42092 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolManagementIndexAddr));
42093 + if (p_Manip->reassmParams.internalBufferPoolAddr)
42094 + FM_MURAM_FreeMem(
42095 + p_FmPcd->h_FmMuram,
42096 + UINT_TO_PTR(p_Manip->reassmParams.internalBufferPoolAddr));
42097 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_CAPWAP)
42098 + {
42099 +
42100 + }
42101 + else
42102 + {
42103 + if (p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr)
42104 + XX_FreeSmart(
42105 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnHashTblAddr));
42106 + if (p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr)
42107 + XX_FreeSmart(
42108 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnHashTblAddr));
42109 + if (p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr)
42110 + XX_FreeSmart(
42111 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv4AutoLearnSetLockTblAddr));
42112 + if (p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr)
42113 + XX_FreeSmart(
42114 + UINT_TO_PTR(p_Manip->reassmParams.ip.ipv6AutoLearnSetLockTblAddr));
42115 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
42116 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
42117 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl);
42118 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
42119 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram,
42120 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl);
42121 + if (p_Manip->reassmParams.ip.h_Ipv6Ad)
42122 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv6Ad);
42123 + if (p_Manip->reassmParams.ip.h_Ipv4Ad)
42124 + XX_FreeSmart(p_Manip->reassmParams.ip.h_Ipv4Ad);
42125 + }
42126 + }
42127 +
42128 + if (p_Manip->p_StatsTbl)
42129 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->p_StatsTbl);
42130 +}
42131 +
42132 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42133 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdManipParams *p_ManipParams)
42134 +{
42135 + if (p_ManipParams->u.hdr.rmv)
42136 + {
42137 + switch (p_ManipParams->u.hdr.rmvParams.type)
42138 + {
42139 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
42140 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
42141 + {
42142 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START) :
42143 + if (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.include)
42144 + {
42145 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
42146 + {
42147 + case (HEADER_TYPE_CAPWAP_DTLS) :
42148 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
42149 + p_Manip->muramAllocate = TRUE;
42150 + if (p_ManipParams->u.hdr.insrt)
42151 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for CAPWAP_DTLS_HDR remove can not be insrt manipualtion after"));
42152 + if (p_ManipParams->fragOrReasm)
42153 + {
42154 + if (!p_ManipParams->fragOrReasmParams.frag)
42155 + {
42156 + switch (p_ManipParams->fragOrReasmParams.hdr)
42157 + {
42158 + case (HEADER_TYPE_CAPWAP):
42159 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
42160 + break;
42161 + default:
42162 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("unsupported header for Reassembly"));
42163 + }
42164 + }
42165 + else
42166 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for this type of manipulation frag can not be TRUE"));
42167 + }
42168 + break;
42169 + default:
42170 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("non valid net header of remove location"));
42171 + }
42172 + }
42173 + else
42174 + {
42175 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.u.fromStartByHdr.hdrInfo.hdr)
42176 + {
42177 + case (HEADER_TYPE_CAPWAP_DTLS) :
42178 + case (HEADER_TYPE_CAPWAP) :
42179 + if (p_ManipParams->fragOrReasm || p_ManipParams->u.hdr.insrt)
42180 + 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"));
42181 + p_Manip->opcode = HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
42182 + p_Manip->muramAllocate = TRUE;
42183 + p_ManipParams->u.hdr.insrt = TRUE; //internal frame header
42184 + break;
42185 + default :
42186 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
42187 + }
42188 + }
42189 + break;
42190 + default :
42191 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
42192 + }
42193 + break;
42194 + default:
42195 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid type of remove manipulation"));
42196 + }
42197 + }
42198 + else if (p_ManipParams->u.hdr.insrt)
42199 + {
42200 + switch (p_ManipParams->u.hdr.insrtParams.type)
42201 + {
42202 + case (e_FM_PCD_MANIP_INSRT_BY_TEMPLATE) :
42203 +
42204 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
42205 + p_Manip->muramAllocate = FALSE;
42206 + if (p_ManipParams->fragOrReasm)
42207 + {
42208 + if (p_ManipParams->fragOrReasmParams.frag)
42209 + {
42210 + switch (p_ManipParams->fragOrReasmParams.hdr)
42211 + {
42212 + case (HEADER_TYPE_CAPWAP):
42213 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
42214 + break;
42215 + default:
42216 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header for fragmentation"));
42217 + }
42218 + }
42219 + else
42220 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("can not reach this point"));
42221 + }
42222 + break;
42223 +
42224 + default:
42225 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("for only isert manipulation unsupported type"));
42226 + }
42227 + }
42228 + else if (p_ManipParams->fragOrReasm)
42229 + {
42230 + if (p_ManipParams->fragOrReasmParams.frag)
42231 + {
42232 + switch (p_ManipParams->fragOrReasmParams.hdr)
42233 + {
42234 + case (HEADER_TYPE_CAPWAP):
42235 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
42236 + p_Manip->muramAllocate = FALSE;
42237 + break;
42238 + default:
42239 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for fragmentation"));
42240 + }
42241 + }
42242 + else
42243 + {
42244 + switch (p_ManipParams->fragOrReasmParams.hdr)
42245 + {
42246 + case (HEADER_TYPE_CAPWAP):
42247 + 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"));
42248 + default:
42249 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported header for reassembly"));
42250 + }
42251 + }
42252 +
42253 + }
42254 + else
42255 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("User didn't ask for any manipulation"));
42256 +
42257 + p_Manip->insrt = p_ManipParams->u.hdr.insrt;
42258 + p_Manip->rmv = p_ManipParams->u.hdr.rmv;
42259 +
42260 + return E_OK;
42261 +}
42262 +
42263 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42264 +static t_Error CheckManipParamsAndSetType(t_FmPcdManip *p_Manip,
42265 + t_FmPcdManipParams *p_ManipParams)
42266 +{
42267 + switch (p_ManipParams->type)
42268 + {
42269 + case e_FM_PCD_MANIP_HDR:
42270 + /* Check that next-manip is not already used */
42271 + if (p_ManipParams->h_NextManip)
42272 + {
42273 + if (!MANIP_IS_FIRST(p_ManipParams->h_NextManip))
42274 + RETURN_ERROR(
42275 + MAJOR, E_INVALID_STATE,
42276 + ("h_NextManip is already a part of another chain"));
42277 + if ((MANIP_GET_TYPE(p_ManipParams->h_NextManip)
42278 + != e_FM_PCD_MANIP_HDR) &&
42279 + (MANIP_GET_TYPE(p_ManipParams->h_NextManip)
42280 + != e_FM_PCD_MANIP_FRAG))
42281 + RETURN_ERROR(
42282 + MAJOR,
42283 + E_NOT_SUPPORTED,
42284 + ("For a Header Manipulation node - no support of h_NextManip of type other than Header Manipulation or Fragmentation."));
42285 + }
42286 +
42287 + if (p_ManipParams->u.hdr.rmv)
42288 + {
42289 + switch (p_ManipParams->u.hdr.rmvParams.type)
42290 + {
42291 + case (e_FM_PCD_MANIP_RMV_BY_HDR):
42292 + switch (p_ManipParams->u.hdr.rmvParams.u.byHdr.type)
42293 + {
42294 + case (e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2):
42295 + break;
42296 +#if (DPAA_VERSION >= 11)
42297 + case (e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP):
42298 + break;
42299 + case (e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START):
42300 + {
42301 + t_Error err;
42302 + uint8_t prsArrayOffset;
42303 +
42304 + err =
42305 + GetPrOffsetByHeaderOrField(
42306 + &p_ManipParams->u.hdr.rmvParams.u.byHdr.u.hdrInfo,
42307 + &prsArrayOffset);
42308 + if (err)
42309 + RETURN_ERROR(MAJOR, err, NO_MSG);
42310 + break;
42311 + }
42312 +#endif /* (DPAA_VERSION >= 11) */
42313 + default:
42314 + RETURN_ERROR(
42315 + MAJOR,
42316 + E_INVALID_STATE,
42317 + ("invalid type of remove manipulation"));
42318 + }
42319 + break;
42320 + case (e_FM_PCD_MANIP_RMV_GENERIC):
42321 + break;
42322 + default:
42323 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
42324 + ("invalid type of remove manipulation"));
42325 + }
42326 + p_Manip->opcode = HMAN_OC;
42327 + p_Manip->muramAllocate = TRUE;
42328 + p_Manip->rmv = TRUE;
42329 + }
42330 + else
42331 + if (p_ManipParams->u.hdr.insrt)
42332 + {
42333 + switch (p_ManipParams->u.hdr.insrtParams.type)
42334 + {
42335 + case (e_FM_PCD_MANIP_INSRT_BY_HDR):
42336 + {
42337 + switch (p_ManipParams->u.hdr.insrtParams.u.byHdr.type)
42338 + {
42339 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2):
42340 + /* nothing to check */
42341 + break;
42342 +#if (DPAA_VERSION >= 11)
42343 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_IP):
42344 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.ipParams.insrt.size
42345 + % 4)
42346 + RETURN_ERROR(
42347 + MAJOR,
42348 + E_INVALID_VALUE,
42349 + ("IP inserted header must be of size which is a multiple of four bytes"));
42350 + break;
42351 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP):
42352 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
42353 + % 4)
42354 + RETURN_ERROR(
42355 + MAJOR,
42356 + E_INVALID_VALUE,
42357 + ("CAPWAP inserted header must be of size which is a multiple of four bytes"));
42358 + break;
42359 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP):
42360 + case (e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE):
42361 + if (p_ManipParams->u.hdr.insrtParams.u.byHdr.u.insrt.size
42362 + != 8)
42363 + RETURN_ERROR(
42364 + MAJOR,
42365 + E_INVALID_VALUE,
42366 + ("Inserted header must be of size 8"));
42367 + break;
42368 +#endif /* (DPAA_VERSION >= 11) */
42369 + default:
42370 + RETURN_ERROR(
42371 + MAJOR,
42372 + E_INVALID_STATE,
42373 + ("unsupported insert by header type"));
42374 + }
42375 + }
42376 + case (e_FM_PCD_MANIP_INSRT_GENERIC):
42377 + break;
42378 + default:
42379 + RETURN_ERROR(
42380 + MAJOR,
42381 + E_INVALID_STATE,
42382 + ("for only insert manipulation unsupported type"));
42383 + }
42384 + p_Manip->opcode = HMAN_OC;
42385 + p_Manip->muramAllocate = TRUE;
42386 + p_Manip->insrt = TRUE;
42387 + }
42388 + else
42389 + if (p_ManipParams->u.hdr.fieldUpdate)
42390 + {
42391 + /* Check parameters */
42392 + if (p_ManipParams->u.hdr.fieldUpdateParams.type
42393 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN)
42394 + {
42395 + if ((p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
42396 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI)
42397 + && (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.vpri
42398 + > 7))
42399 + RETURN_ERROR(
42400 + MAJOR, E_INVALID_VALUE,
42401 + ("vpri should get values of 0-7 "));
42402 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.updateType
42403 + == e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN)
42404 + {
42405 + int i;
42406 +
42407 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.vpriDefVal
42408 + > 7)
42409 + RETURN_ERROR(
42410 + MAJOR,
42411 + E_INVALID_VALUE,
42412 + ("vpriDefVal should get values of 0-7 "));
42413 + for (i = 0; i < FM_PCD_MANIP_DSCP_TO_VLAN_TRANS;
42414 + i++)
42415 + if (p_ManipParams->u.hdr.fieldUpdateParams.u.vlan.u.dscpToVpri.dscpToVpriTable[i]
42416 + & 0xf0)
42417 + RETURN_ERROR(
42418 + MAJOR,
42419 + E_INVALID_VALUE,
42420 + ("dscpToVpriTabl value out of range (0-15)"));
42421 + }
42422 +
42423 + }
42424 +
42425 + p_Manip->opcode = HMAN_OC;
42426 + p_Manip->muramAllocate = TRUE;
42427 + p_Manip->fieldUpdate = TRUE;
42428 + }
42429 + else
42430 + if (p_ManipParams->u.hdr.custom)
42431 + {
42432 + if (p_ManipParams->u.hdr.customParams.type == e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE)
42433 + {
42434 +
42435 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.size == 0) ||
42436 + (p_ManipParams->u.hdr.customParams.u.genFieldReplace.size > 8))
42437 + RETURN_ERROR(
42438 + MAJOR, E_INVALID_VALUE,
42439 + ("size should get values of 1-8 "));
42440 +
42441 + if (p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset > 7)
42442 + RETURN_ERROR(
42443 + MAJOR, E_INVALID_VALUE,
42444 + ("srcOffset should be <= 7"));
42445 +
42446 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.srcOffset +
42447 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 8)
42448 + RETURN_ERROR(
42449 + MAJOR, E_INVALID_VALUE,
42450 + ("(srcOffset + size) should be <= 8"));
42451 +
42452 + if ((p_ManipParams->u.hdr.customParams.u.genFieldReplace.dstOffset +
42453 + p_ManipParams->u.hdr.customParams.u.genFieldReplace.size) > 256)
42454 + RETURN_ERROR(
42455 + MAJOR, E_INVALID_VALUE,
42456 + ("(dstOffset + size) should be <= 256"));
42457 +
42458 + }
42459 +
42460 + p_Manip->opcode = HMAN_OC;
42461 + p_Manip->muramAllocate = TRUE;
42462 + p_Manip->custom = TRUE;
42463 + }
42464 + break;
42465 + case e_FM_PCD_MANIP_REASSEM:
42466 + if (p_ManipParams->h_NextManip)
42467 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42468 + ("next manip with reassembly"));
42469 + switch (p_ManipParams->u.reassem.hdr)
42470 + {
42471 + case (HEADER_TYPE_IPv4):
42472 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv4;
42473 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
42474 + break;
42475 + case (HEADER_TYPE_IPv6):
42476 + p_Manip->reassmParams.hdr = HEADER_TYPE_IPv6;
42477 + p_Manip->opcode = HMAN_OC_IP_REASSEMBLY;
42478 + break;
42479 +#if (DPAA_VERSION >= 11)
42480 + case (HEADER_TYPE_CAPWAP):
42481 + p_Manip->reassmParams.hdr = HEADER_TYPE_CAPWAP;
42482 + p_Manip->opcode = HMAN_OC_CAPWAP_REASSEMBLY;
42483 + break;
42484 +#endif /* (DPAA_VERSION >= 11) */
42485 + default:
42486 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42487 + ("header for reassembly"));
42488 + }
42489 + break;
42490 + case e_FM_PCD_MANIP_FRAG:
42491 + if (p_ManipParams->h_NextManip)
42492 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42493 + ("next manip with fragmentation"));
42494 + switch (p_ManipParams->u.frag.hdr)
42495 + {
42496 + case (HEADER_TYPE_IPv4):
42497 + case (HEADER_TYPE_IPv6):
42498 + p_Manip->opcode = HMAN_OC_IP_FRAGMENTATION;
42499 + break;
42500 +#if (DPAA_VERSION >= 11)
42501 + case (HEADER_TYPE_CAPWAP):
42502 + p_Manip->opcode = HMAN_OC_CAPWAP_FRAGMENTATION;
42503 + break;
42504 +#endif /* (DPAA_VERSION >= 11) */
42505 + default:
42506 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42507 + ("header for fragmentation"));
42508 + }
42509 + p_Manip->muramAllocate = TRUE;
42510 + break;
42511 + case e_FM_PCD_MANIP_SPECIAL_OFFLOAD:
42512 + switch (p_ManipParams->u.specialOffload.type)
42513 + {
42514 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC):
42515 + p_Manip->opcode = HMAN_OC_IPSEC_MANIP;
42516 + p_Manip->muramAllocate = TRUE;
42517 + break;
42518 +#if (DPAA_VERSION >= 11)
42519 + case (e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP):
42520 + p_Manip->opcode = HMAN_OC_CAPWAP_MANIP;
42521 + p_Manip->muramAllocate = TRUE;
42522 + break;
42523 +#endif /* (DPAA_VERSION >= 11) */
42524 + default:
42525 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
42526 + ("special offload type"));
42527 + }
42528 + break;
42529 + default:
42530 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("manip type"));
42531 + }
42532 +
42533 + return E_OK;
42534 +}
42535 +#endif /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
42536 +
42537 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
42538 +
42539 +static t_Error UpdateIndxStats(t_Handle h_FmPcd,
42540 + t_Handle h_FmPort,
42541 + t_FmPcdManip *p_Manip)
42542 +{
42543 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
42544 + uint32_t tmpReg32 = 0;
42545 + t_AdOfTypeContLookup *p_Ad;
42546 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
42547 + t_Error err;
42548 +
42549 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_INVALID_HANDLE);
42550 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42551 +
42552 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42553 + if (p_Manip->h_FmPcd != h_FmPcd)
42554 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
42555 + ("handler of PCD previously was initiated by different value"));
42556 +
42557 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
42558 +
42559 + if (!p_Manip->p_StatsTbl)
42560 + {
42561 +
42562 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
42563 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
42564 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
42565 + if (err)
42566 + RETURN_ERROR(MAJOR, err, NO_MSG);
42567 +
42568 + tmpReg32 = GET_UINT32(p_Ad->ccAdBase);
42569 +
42570 + p_Manip->p_StatsTbl =
42571 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42572 + (uint32_t)p_Manip->owner * FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE,
42573 + 4);
42574 + if (!p_Manip->p_StatsTbl)
42575 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation indexed statistics table"));
42576 +
42577 + MemSet8(p_Manip->p_StatsTbl, 0, (uint32_t)(p_Manip->owner * 4));
42578 +
42579 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->p_StatsTbl) - p_FmPcd->physicalMuramBase);
42580 +
42581 + if (p_Manip->cnia)
42582 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_CNIA;
42583 +
42584 + tmpReg32 |= FM_PCD_MANIP_INDEXED_STATS_DPD;
42585 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42586 + }
42587 + else
42588 + {
42589 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
42590 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_CC;
42591 + err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams);
42592 + if (err)
42593 + RETURN_ERROR(MAJOR, err, NO_MSG);
42594 + }
42595 +
42596 + return E_OK;
42597 +}
42598 +
42599 +static t_Error RmvHdrTillSpecLocNOrInsrtIntFrmHdr(t_FmPcdManipHdrRmvParams *p_ManipParams, t_FmPcdManip *p_Manip)
42600 +{
42601 + t_AdOfTypeContLookup *p_Ad;
42602 + uint32_t tmpReg32 = 0;
42603 + uint8_t prsArrayOffset = 0;
42604 + t_Error err;
42605 +
42606 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
42607 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
42608 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42609 +
42610 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42611 + if (p_Manip->rmv)
42612 + {
42613 + err = GetPrOffsetByHeaderOrField(&p_ManipParams->u.byHdr.u.fromStartByHdr.hdrInfo, &prsArrayOffset);
42614 + if (err)
42615 + RETURN_ERROR(MAJOR, err, NO_MSG);
42616 +
42617 + tmpReg32 |= (uint32_t)prsArrayOffset << 24;
42618 + tmpReg32 |= HMAN_RMV_HDR;
42619 + }
42620 +
42621 + if (p_Manip->insrt)
42622 + tmpReg32 |= HMAN_INSRT_INT_FRM_HDR;
42623 +
42624 + tmpReg32 |= (uint32_t)HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR;
42625 +
42626 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42627 +
42628 + tmpReg32 = 0;
42629 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42630 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42631 +
42632 + return E_OK;
42633 +}
42634 +
42635 +static t_Error MvIntFrameHeaderFromFrameToBufferPrefix(t_FmPcdManip *p_Manip,
42636 + bool caamUsed)
42637 +{
42638 + t_AdOfTypeContLookup *p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42639 + uint32_t tmpReg32 = 0;
42640 +
42641 + SANITY_CHECK_RETURN_ERROR(p_Ad, E_INVALID_HANDLE);
42642 +
42643 + p_Manip->updateParams |= OFFSET_OF_PR | INTERNAL_CONTEXT_OFFSET;
42644 +
42645 + tmpReg32 = 0;
42646 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42647 + *(uint32_t *)&p_Ad->ccAdBase = tmpReg32;
42648 +
42649 + tmpReg32 = 0;
42650 + tmpReg32 |= HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
42651 + tmpReg32 |= (uint32_t)0x16 << 16;
42652 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
42653 +
42654 + if (caamUsed)
42655 + *(uint32_t *)&p_Ad->gmask = 0xf0000000;
42656 +
42657 + return E_OK;
42658 +}
42659 +
42660 +static t_Error CapwapRmvDtlsHdr(t_FmPcd *p_FmPcd, t_FmPcdManip *p_Manip)
42661 +{
42662 + t_AdOfTypeContLookup *p_Ad;
42663 + uint32_t tmpReg32 = 0;
42664 + t_Error err = E_OK;
42665 +
42666 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42667 +
42668 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42669 +
42670 + tmpReg32 = 0;
42671 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
42672 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42673 +
42674 + tmpReg32 = 0;
42675 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42676 +
42677 +
42678 + if (p_Manip->h_Frag)
42679 + {
42680 + p_Manip->updateParams |= INTERNAL_CONTEXT_OFFSET;
42681 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
42682 + }
42683 +
42684 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42685 +
42686 + return err;
42687 +}
42688 +
42689 +static t_Error CapwapReassembly(t_CapwapReassemblyParams *p_ManipParams,
42690 + t_FmPcdManip *p_Manip,
42691 + t_FmPcd *p_FmPcd,
42692 + uint8_t poolId)
42693 +{
42694 + t_Handle p_Table;
42695 + uint32_t tmpReg32 = 0;
42696 + int i = 0;
42697 + uint8_t log2Num;
42698 + uint8_t numOfSets;
42699 + uint32_t j = 0;
42700 + uint32_t bitFor1Micro;
42701 +
42702 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
42703 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
42704 +
42705 + if (!p_FmPcd->h_Hc)
42706 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("hc port has to be initialized in this mode"));
42707 + if (!POWER_OF_2(p_ManipParams->timeoutRoutineRequestTime))
42708 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("timeoutRoutineRequestTime has to be power of 2"));
42709 + if (!POWER_OF_2(p_ManipParams->maxNumFramesInProcess))
42710 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("maxNumFramesInProcess has to be power of 2"));
42711 + if (!p_ManipParams->timeoutRoutineRequestTime && p_ManipParams->timeoutThresholdForReassmProcess)
42712 + DBG(WARNING, ("if timeoutRoutineRequestTime 0, timeoutThresholdForReassmProcess is uselessly"));
42713 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH)
42714 + {
42715 + if ((p_ManipParams->maxNumFramesInProcess < 4) ||
42716 + (p_ManipParams->maxNumFramesInProcess > 512))
42717 + 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"));
42718 + }
42719 + else
42720 + {
42721 + if ((p_ManipParams->maxNumFramesInProcess < 8) ||
42722 + (p_ManipParams->maxNumFramesInProcess > 2048))
42723 + 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"));
42724 + }
42725 +
42726 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
42727 + if (bitFor1Micro == 0)
42728 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
42729 +
42730 + p_Manip->updateParams |= (NUM_OF_TASKS | OFFSET_OF_PR | OFFSET_OF_DATA | HW_PORT_ID);
42731 +
42732 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42733 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE,
42734 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
42735 + if (!p_Manip->h_Frag)
42736 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc CAPWAP reassembly parameters table"));
42737 +
42738 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE);
42739 +
42740 + p_Table = (t_CapwapReasmPram *)p_Manip->h_Frag;
42741 +
42742 + p_Manip->capwapFragParams.p_AutoLearnHashTbl =
42743 + (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42744 + (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE),
42745 + FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN);
42746 +
42747 + if (!p_Manip->capwapFragParams.p_AutoLearnHashTbl)
42748 + RETURN_ERROR(MAJOR, E_NO_MEMORY,("MURAM alloc for CAPWAP automatic learning hash table"));
42749 +
42750 + MemSet8(p_Manip->capwapFragParams.p_AutoLearnHashTbl, 0, (uint32_t)(p_ManipParams->maxNumFramesInProcess * 2 * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE));
42751 +
42752 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->capwapFragParams.p_AutoLearnHashTbl) - p_FmPcd->physicalMuramBase);
42753 +
42754 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->autoLearnHashTblPtr, tmpReg32);
42755 +
42756 + tmpReg32 = 0;
42757 + if (p_ManipParams->timeOutMode == e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES)
42758 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES;
42759 + if (p_ManipParams->haltOnDuplicationFrag)
42760 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG;
42761 + if (p_ManipParams->numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH)
42762 + {
42763 + i = 8;
42764 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS;
42765 + }
42766 + else
42767 + i = 4;
42768 +
42769 + numOfSets = (uint8_t)((p_ManipParams->maxNumFramesInProcess * 2) / i);
42770 + LOG2(numOfSets, log2Num);
42771 + tmpReg32 |= (uint32_t)(log2Num - 1) << 24;
42772 +
42773 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->mode, tmpReg32);
42774 +
42775 + for (j=0; j<p_ManipParams->maxNumFramesInProcess*2; j++)
42776 + if (((j / i) % 2)== 0)
42777 + WRITE_UINT32(*(uint32_t *)PTR_MOVE(p_Manip->capwapFragParams.p_AutoLearnHashTbl, j * FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE), 0x80000000);
42778 +
42779 + tmpReg32 = 0x00008000;
42780 + tmpReg32 |= (uint32_t)poolId << 16;
42781 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->bufferPoolIdAndRisc1SetIndexes, tmpReg32);
42782 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc23SetIndexes, 0x80008000);
42783 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->risc4SetIndexesAndExtendedStatsTblPtr, 0x80000000);
42784 +
42785 + p_Manip->capwapFragParams.maxNumFramesInProcess = p_ManipParams->maxNumFramesInProcess;
42786 +
42787 + p_Manip->capwapFragParams.sgBpid = poolId;
42788 +
42789 + p_Manip->capwapFragParams.fqidForTimeOutFrames = p_ManipParams->fqidForTimeOutFrames;
42790 + p_Manip->capwapFragParams.timeoutRoutineRequestTime = p_ManipParams->timeoutRoutineRequestTime;
42791 + p_Manip->capwapFragParams.bitFor1Micro = bitFor1Micro;
42792 +
42793 + tmpReg32 = 0;
42794 + tmpReg32 |= (((uint32_t)1<<p_Manip->capwapFragParams.bitFor1Micro) * p_ManipParams->timeoutThresholdForReassmProcess);
42795 + WRITE_UINT32(((t_CapwapReasmPram *)p_Table)->expirationDelay, tmpReg32);
42796 +
42797 + return E_OK;
42798 +}
42799 +
42800 +static t_Error CapwapFragmentation(t_CapwapFragmentationParams *p_ManipParams,
42801 + t_FmPcdManip *p_Manip,
42802 + t_FmPcd *p_FmPcd,
42803 + uint8_t poolId)
42804 +{
42805 + t_AdOfTypeContLookup *p_Ad;
42806 + uint32_t tmpReg32 = 0;
42807 +
42808 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42809 +
42810 + p_Manip->updateParams |= OFFSET_OF_DATA;
42811 +
42812 + p_Manip->frag = TRUE;
42813 +
42814 + p_Manip->h_Frag = (t_Handle)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42815 + FM_PCD_CC_AD_ENTRY_SIZE,
42816 + FM_PCD_CC_AD_TABLE_ALIGN);
42817 + if (!p_Manip->h_Frag)
42818 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for CAPWAP fragmentation table descriptor"));
42819 +
42820 + MemSet8(p_Manip->h_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
42821 +
42822 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Frag;
42823 +
42824 + tmpReg32 = 0;
42825 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
42826 +
42827 + if (p_ManipParams->headerOptionsCompr)
42828 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN;
42829 + tmpReg32 |= ((uint32_t)poolId << 8);
42830 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42831 +
42832 + tmpReg32 = 0;
42833 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42834 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42835 +
42836 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
42837 + p_Manip->capwapFragParams.sgBpid = poolId;
42838 +
42839 + return E_OK;
42840 +}
42841 +
42842 +static t_Error IndxStats(t_FmPcdStatsParams *p_StatsParams,t_FmPcdManip *p_Manip,t_FmPcd *p_FmPcd)
42843 +{
42844 + t_AdOfTypeContLookup *p_Ad;
42845 + uint32_t tmpReg32 = 0;
42846 +
42847 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42848 +
42849 + UNUSED(p_FmPcd);
42850 +
42851 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42852 +
42853 + tmpReg32 = 0;
42854 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_INDEXED_STATS;
42855 + if (p_StatsParams->type == e_FM_PCD_STATS_PER_FLOWID)
42856 + tmpReg32 |= (uint32_t)0x16 << 16;
42857 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
42858 +
42859 + tmpReg32 = 0;
42860 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
42861 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
42862 +
42863 + return E_OK;
42864 +}
42865 +
42866 +static t_Error InsrtHdrByTempl(t_FmPcdManipHdrInsrtParams *p_ManipParams, t_FmPcdManip *p_Manip, t_FmPcd *p_FmPcd)
42867 +{
42868 + t_FmPcdManipHdrInsrtByTemplateParams *p_InsrtByTemplate = &p_ManipParams->u.byTemplate;
42869 + uint8_t tmpReg8 = 0xff;
42870 + t_AdOfTypeContLookup *p_Ad;
42871 + bool ipModify = FALSE;
42872 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
42873 + uint16_t tmpReg16 = 0;
42874 + t_Error err = E_OK;
42875 + uint8_t extraAddedBytes = 0, blockSize = 0, extraAddedBytesAlignedToBlockSize = 0, log2Num = 0;
42876 + uint8_t *p_Template = NULL;
42877 +
42878 + SANITY_CHECK_RETURN_ERROR(p_ManipParams,E_NULL_POINTER);
42879 + SANITY_CHECK_RETURN_ERROR(p_Manip,E_NULL_POINTER);
42880 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad,E_INVALID_HANDLE);
42881 + SANITY_CHECK_RETURN_ERROR(p_FmPcd,E_NULL_POINTER);
42882 +
42883 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
42884 + if (p_Manip->insrt)
42885 + {
42886 + if ((!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp) ||
42887 + (!p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterVlan))
42888 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : asking for header template modifications with no template for insertion (template size)"));
42889 +
42890 + if (p_InsrtByTemplate->size && p_InsrtByTemplate->modifyOuterIp && (p_InsrtByTemplate->size <= p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset))
42891 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : size of template < ipOuterOffset"));
42892 +
42893 + if (p_InsrtByTemplate->size > 128)
42894 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size of header template for insertion can not be more than 128"));
42895 +
42896 + if (p_InsrtByTemplate->size)
42897 + {
42898 + p_Manip->p_Template = (uint8_t *)FM_MURAM_AllocMem(p_FmPcd->h_FmMuram,
42899 + p_InsrtByTemplate->size,
42900 + FM_PCD_CC_AD_TABLE_ALIGN);
42901 + if(!p_Manip->p_Template)
42902 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Memory allocation in MURAM FAILED"));
42903 +
42904 + tmpReg32 = (uint32_t)(XX_VirtToPhys(p_Manip->p_Template) - (p_FmPcd->physicalMuramBase));
42905 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->size << 24;
42906 + *(uint32_t *)&p_Ad->matchTblPtr = tmpReg32;
42907 + }
42908 +
42909 + tmpReg32 = 0;
42910 +
42911 + p_Template = (uint8_t *)XX_Malloc(p_InsrtByTemplate->size * sizeof(uint8_t));
42912 +
42913 + if (!p_Template)
42914 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("XX_Malloc allocation FAILED"));
42915 +
42916 + memcpy(p_Template, p_InsrtByTemplate->hdrTemplate, p_InsrtByTemplate->size * sizeof(uint8_t));
42917 +
42918 + if (p_InsrtByTemplate->modifyOuterIp)
42919 + {
42920 + ipModify = TRUE;
42921 +
42922 + tmpReg8 = (uint8_t)p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset];
42923 +
42924 + if((tmpReg8 & 0xf0) == 0x40)
42925 + tmpReg8 = 4;
42926 + else if((tmpReg8 & 0xf0) == 0x60)
42927 + tmpReg8 = 6;
42928 + else
42929 + tmpReg8 = 0xff;
42930 +
42931 + if (tmpReg8 != 0xff)
42932 + {
42933 + if(p_InsrtByTemplate->modifyOuterIpParams.dscpEcn & 0xff00)
42934 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : IPV4 present in header template, dscpEcn has to be only 1 byte"));
42935 + if(p_InsrtByTemplate->modifyOuterIpParams.recalculateLength)
42936 + {
42937 +
42938 + if((p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize) > 255)
42939 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("extra Byte added can not be more than 256 bytes"));
42940 + extraAddedBytes = (uint8_t) (p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize + p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedNotAlignedToBlockSize);
42941 + blockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.blockSize;
42942 + extraAddedBytesAlignedToBlockSize = p_InsrtByTemplate->modifyOuterIpParams.recalculateLengthParams.extraBytesAddedAlignedToBlockSize;
42943 + /*IP header template - IP totalLength -
42944 + (1 byte) extraByteForIp = headerTemplateSize - ipOffset + insertedBytesAfterThisStage ,
42945 + in the case of SEC insertedBytesAfterThisStage - SEC trailer (21/31) + header(13)
42946 + second byte - extraByteForIp = headerTemplate - ipOffset + insertedBytesAfterThisStage*/
42947 + }
42948 + if (blockSize)
42949 + {
42950 + if (!POWER_OF_2(blockSize))
42951 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("inputFrmPaddingUpToBlockSize has to be power of 2"));
42952 + }
42953 +
42954 + }
42955 + if (tmpReg8 == 4)
42956 + {
42957 + if ((IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset) > p_InsrtByTemplate->size)
42958 + 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"));
42959 +
42960 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_DSCECN_FIELD_OFFSET_FROM_IP] = (uint8_t)p_InsrtByTemplate->modifyOuterIpParams.dscpEcn;
42961 +
42962 + if (blockSize)
42963 + blockSize -= 1;
42964 +
42965 + if ((p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes) > 255)
42966 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes has to be less than 255"));
42967 +
42968 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP + 1] = blockSize; // IPV6 - in AD instead of SEQ IND
42969 + 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
42970 +
42971 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP] = 0x00;
42972 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_ID_FIELD_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
42973 +
42974 + /*IP header template - relevant only for ipv4 CheckSum = 0*/
42975 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP] = 0x00;
42976 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP + 1] = 0x00;
42977 +
42978 + /*UDP checksum has to be 0*/
42979 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
42980 + {
42981 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
42982 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
42983 +
42984 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP ] = 0x00;
42985 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
42986 +
42987 + }
42988 +
42989 + if (p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId > 7)
42990 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("ipIdentGenId has to be one out of 8 sequence number generators (0 - 7) for IP identification field"));
42991 +
42992 + tmpRegNia |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipIdentGenId<<24;
42993 + }
42994 + else if (tmpReg8 == 6)
42995 + {
42996 + /*TODO - add check for maximum value of blockSize;*/
42997 + if (blockSize)
42998 + LOG2(blockSize, log2Num);
42999 + tmpRegNia |= (uint32_t)log2Num << 24;
43000 +
43001 + // for IPV6 decrement additional 40 bytes of IPV6 heade size - because IPV6 header size is not included in payloadLength
43002 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP] = (uint8_t)(p_InsrtByTemplate->size - p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + extraAddedBytes - 40);
43003 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP + 1] = extraAddedBytesAlignedToBlockSize;
43004 + if (p_InsrtByTemplate->modifyOuterIpParams.udpPresent)
43005 + {
43006 + if ((p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + UDP_CHECKSUM_FIELD_SIZE) > p_InsrtByTemplate->size)
43007 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inconsistent parameters : UDP present according to user but (UDP offset + UDP header size) < size of header template"));
43008 + if (p_Template[p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset + IPv6_NEXT_HEADER_OFFSET_FROM_IP] != 0x88)
43009 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("OUr suppport is only IPv6/UDPLite"));
43010 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP] = 0x00;
43011 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_LENGTH_FIELD_OFFSET_FROM_UDP + 1] = 0x08;
43012 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP] = 0x00;
43013 + p_Template[p_InsrtByTemplate->modifyOuterIpParams.udpOffset + UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP + 1] = 0x00;
43014 + }
43015 + }
43016 + else
43017 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("IP version supported only IPV4"));
43018 + }
43019 +
43020 + tmpReg32 = tmpReg16 = tmpReg8 = 0;
43021 + /*TODO - check it*/
43022 + if (p_InsrtByTemplate->modifyOuterVlan)
43023 + {
43024 + if (p_InsrtByTemplate->modifyOuterVlanParams.vpri & ~0x07)
43025 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but VPRI more than 3 bits"));
43026 +
43027 + memcpy(&tmpReg16, &p_Template[VLAN_TAG_FIELD_OFFSET_FROM_ETH], 2*(sizeof(uint8_t)));
43028 + if ((tmpReg16 != 0x9100) && (tmpReg16!= 0x9200) && (tmpReg16 != 0x8100))
43029 + RETURN_ERROR(MAJOR, E_INVALID_STATE,("Inconsistent parameters : user asked for VLAN modifications but Tag Protocol identifier is not VLAN "));
43030 +
43031 + memcpy(&tmpReg8, &p_Template[14],1*(sizeof(uint8_t)));
43032 + tmpReg8 &= 0x1f;
43033 + tmpReg8 |= (uint8_t)(p_InsrtByTemplate->modifyOuterVlanParams.vpri << 5);
43034 +
43035 + p_Template[14] = tmpReg8;
43036 + }
43037 +
43038 + MemCpy8(p_Manip->p_Template, p_Template, p_InsrtByTemplate->size);
43039 +
43040 + XX_Free(p_Template);
43041 + }
43042 +
43043 + tmpReg32 = 0;
43044 + if (p_Manip->h_Frag)
43045 + {
43046 + tmpRegNia |= (uint32_t)(XX_VirtToPhys(p_Manip->h_Frag) - (p_FmPcd->physicalMuramBase));
43047 + tmpReg32 |= (uint32_t)p_Manip->sizeForFragmentation << 16;
43048 + }
43049 + else
43050 + tmpReg32 = 0xffff0000;
43051 +
43052 + if (ipModify)
43053 + tmpReg32 |= (uint32_t)p_InsrtByTemplate->modifyOuterIpParams.ipOuterOffset << 8;
43054 + else
43055 + tmpReg32 |= (uint32_t)0x0000ff00;
43056 +
43057 + tmpReg32 |= (uint32_t)HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
43058 + *(uint32_t *)&p_Ad->pcAndOffsets = tmpReg32;
43059 +
43060 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43061 + *(uint32_t *)&p_Ad->ccAdBase = tmpRegNia;
43062 +
43063 + return err;
43064 +}
43065 +
43066 +static t_Error CheckStatsParamsAndSetType(t_FmPcdManip *p_Manip, t_FmPcdStatsParams *p_StatsParams)
43067 +{
43068 +
43069 + switch (p_StatsParams->type)
43070 + {
43071 + case (e_FM_PCD_STATS_PER_FLOWID):
43072 + p_Manip->opcode = HMAN_OC_CAPWAP_INDEXED_STATS;
43073 + p_Manip->muramAllocate = TRUE;
43074 + break;
43075 + default:
43076 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported statistics type"));
43077 + }
43078 +
43079 + return E_OK;
43080 +}
43081 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
43082 +
43083 +static t_Error FillReassmManipParams(t_FmPcdManip *p_Manip, e_NetHeaderType hdr)
43084 +{
43085 + t_AdOfTypeContLookup *p_Ad;
43086 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
43087 + uint32_t tmpReg32;
43088 + t_Error err = E_OK;
43089 +
43090 + /* Creates the Reassembly Parameters table. It contains parameters that are specific to either the IPv4 reassembly
43091 + function or to the IPv6 reassembly function. If both IPv4 reassembly and IPv6 reassembly are required, then
43092 + two separate IP Reassembly Parameter tables are required.*/
43093 + if ((err = CreateReassTable(p_Manip, hdr)) != E_OK)
43094 + RETURN_ERROR(MAJOR, err, NO_MSG);
43095 +
43096 + /* Sets the first Ad register (ccAdBase) - Action Descriptor Type and Pointer to the Reassembly Parameters Table offset from MURAM*/
43097 + tmpReg32 = 0;
43098 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43099 +
43100 + /* Gets the required Action descriptor table pointer */
43101 + switch (hdr)
43102 + {
43103 + case HEADER_TYPE_IPv4:
43104 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv4Ad;
43105 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
43106 + p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
43107 + - (p_FmPcd->physicalMuramBase));
43108 + break;
43109 + case HEADER_TYPE_IPv6:
43110 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.ip.h_Ipv6Ad;
43111 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
43112 + p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
43113 + - (p_FmPcd->physicalMuramBase));
43114 + break;
43115 + case HEADER_TYPE_CAPWAP:
43116 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->reassmParams.capwap.h_Ad;
43117 + tmpReg32 |= (uint32_t)(XX_VirtToPhys(
43118 + p_Manip->reassmParams.capwap.p_ReassTbl)
43119 + - (p_FmPcd->physicalMuramBase));
43120 + break;
43121 + default:
43122 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("header type"));
43123 + }
43124 +
43125 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
43126 +
43127 + /* Sets the second Ad register (matchTblPtr) - Buffer pool ID (BPID for V2) and Scatter/Gather table offset*/
43128 + /* mark the Scatter/Gather table offset to be set later on when the port will be known */
43129 + p_Manip->updateParams = (NUM_OF_TASKS | NUM_OF_EXTRA_TASKS | DISCARD_MASK);
43130 +
43131 + if ((hdr == HEADER_TYPE_IPv6) || (hdr == HEADER_TYPE_IPv4))
43132 + {
43133 +#if (DPAA_VERSION == 10)
43134 + tmpReg32 = (uint32_t)(p_Manip->reassmParams.sgBpid << 8);
43135 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
43136 +#endif /* (DPAA_VERSION == 10) */
43137 +#if (DPAA_VERSION >= 11)
43138 + if (p_Manip->reassmParams.ip.nonConsistentSpFqid != 0)
43139 + {
43140 + tmpReg32 = FM_PCD_AD_NCSPFQIDM_MASK
43141 + | (uint32_t)(p_Manip->reassmParams.ip.nonConsistentSpFqid);
43142 + WRITE_UINT32(p_Ad->gmask, tmpReg32);
43143 + }
43144 +#endif /* (DPAA_VERSION >= 11) */
43145 + /* Sets the third Ad register (pcAndOffsets)- IP Reassemble Operation Code*/
43146 + tmpReg32 = 0;
43147 + tmpReg32 |= (uint32_t)HMAN_OC_IP_REASSEMBLY;
43148 + }
43149 +#if (DPAA_VERSION >= 11)
43150 + else
43151 + if (hdr == HEADER_TYPE_CAPWAP)
43152 + {
43153 + tmpReg32 = 0;
43154 + tmpReg32 |= (uint32_t)HMAN_OC_CAPWAP_REASSEMBLY;
43155 + }
43156 +#endif /* (DPAA_VERSION >= 11) */
43157 +
43158 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
43159 +
43160 + p_Manip->reassm = TRUE;
43161 +
43162 + return E_OK;
43163 +}
43164 +
43165 +static t_Error SetIpv4ReassmManip(t_FmPcdManip *p_Manip)
43166 +{
43167 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
43168 +
43169 + /* Allocation if IPv4 Action descriptor */
43170 + p_Manip->reassmParams.ip.h_Ipv4Ad = (t_Handle)XX_MallocSmart(
43171 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
43172 + FM_PCD_CC_AD_TABLE_ALIGN);
43173 + if (!p_Manip->reassmParams.ip.h_Ipv4Ad)
43174 + {
43175 + ReleaseManipHandler(p_Manip, p_FmPcd);
43176 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43177 + ("Allocation of IPv4 table descriptor"));
43178 + }
43179 +
43180 + memset(p_Manip->reassmParams.ip.h_Ipv4Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43181 +
43182 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
43183 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv4);
43184 +}
43185 +
43186 +static t_Error SetIpv6ReassmManip(t_FmPcdManip *p_Manip)
43187 +{
43188 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
43189 +
43190 + /* Allocation if IPv6 Action descriptor */
43191 + p_Manip->reassmParams.ip.h_Ipv6Ad = (t_Handle)XX_MallocSmart(
43192 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
43193 + FM_PCD_CC_AD_TABLE_ALIGN);
43194 + if (!p_Manip->reassmParams.ip.h_Ipv6Ad)
43195 + {
43196 + ReleaseManipHandler(p_Manip, p_FmPcd);
43197 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43198 + ("Allocation of IPv6 table descriptor"));
43199 + }
43200 +
43201 + memset(p_Manip->reassmParams.ip.h_Ipv6Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43202 +
43203 + /* Fill reassembly manipulation parameter in the IP Reassembly Action Descriptor */
43204 + return FillReassmManipParams(p_Manip, HEADER_TYPE_IPv6);
43205 +}
43206 +
43207 +static t_Error IpReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
43208 + t_FmPcdManip *p_Manip)
43209 +{
43210 + uint32_t maxSetNumber = 10000;
43211 + t_FmPcdManipReassemIpParams reassmManipParams =
43212 + p_ManipReassmParams->u.ipReassem;
43213 + t_Error res;
43214 +
43215 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
43216 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
43217 + E_INVALID_HANDLE);
43218 +
43219 + /* Check validation of user's parameter.*/
43220 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
43221 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
43222 + RETURN_ERROR(
43223 + MAJOR, E_INVALID_VALUE,
43224 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
43225 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
43226 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
43227 + if (reassmManipParams.maxNumFramesInProcess
43228 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
43229 + RETURN_ERROR(
43230 + MAJOR,
43231 + E_INVALID_VALUE,
43232 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
43233 +
43234 + if ((p_ManipReassmParams->hdr == HEADER_TYPE_IPv6)
43235 + && (reassmManipParams.minFragSize[1] < 256))
43236 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("minFragSize[1] must be >= 256"));
43237 +
43238 + /* Saves user's reassembly manipulation parameters */
43239 + p_Manip->reassmParams.ip.relativeSchemeId[0] =
43240 + reassmManipParams.relativeSchemeId[0];
43241 + p_Manip->reassmParams.ip.relativeSchemeId[1] =
43242 + reassmManipParams.relativeSchemeId[1];
43243 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[0] =
43244 + reassmManipParams.numOfFramesPerHashEntry[0];
43245 + p_Manip->reassmParams.ip.numOfFramesPerHashEntry[1] =
43246 + reassmManipParams.numOfFramesPerHashEntry[1];
43247 + p_Manip->reassmParams.ip.minFragSize[0] = reassmManipParams.minFragSize[0];
43248 + p_Manip->reassmParams.ip.minFragSize[1] = reassmManipParams.minFragSize[1];
43249 + p_Manip->reassmParams.maxNumFramesInProcess =
43250 + reassmManipParams.maxNumFramesInProcess;
43251 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
43252 + p_Manip->reassmParams.fqidForTimeOutFrames =
43253 + reassmManipParams.fqidForTimeOutFrames;
43254 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
43255 + reassmManipParams.timeoutThresholdForReassmProcess;
43256 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
43257 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
43258 +#if (DPAA_VERSION == 10)
43259 + p_Manip->reassmParams.sgBpid = reassmManipParams.sgBpid;
43260 +#endif /* (DPAA_VERSION == 10) */
43261 +#if (DPAA_VERSION >= 11)
43262 + if (reassmManipParams.nonConsistentSpFqid != 0)
43263 + {
43264 + p_Manip->reassmParams.ip.nonConsistentSpFqid =
43265 + reassmManipParams.nonConsistentSpFqid;
43266 + }
43267 +#endif /* (DPAA_VERSION >= 11) */
43268 +
43269 + /* Creates and initializes the IP Reassembly common parameter table */
43270 + CreateReassCommonTable(p_Manip);
43271 +
43272 + /* Creation of IPv4 reassembly manipulation */
43273 + if ((p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
43274 + || (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv4))
43275 + {
43276 + res = SetIpv4ReassmManip(p_Manip);
43277 + if (res != E_OK)
43278 + return res;
43279 + }
43280 +
43281 + /* Creation of IPv6 reassembly manipulation */
43282 + if (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6)
43283 + {
43284 + res = SetIpv6ReassmManip(p_Manip);
43285 + if (res != E_OK)
43286 + return res;
43287 + }
43288 +
43289 + return E_OK;
43290 +}
43291 +
43292 +static void setIpReassmSchemeParams(t_FmPcd* p_FmPcd,
43293 + t_FmPcdKgSchemeParams *p_Scheme,
43294 + t_Handle h_CcTree, bool ipv4,
43295 + uint8_t groupId)
43296 +{
43297 + uint32_t j;
43298 + uint8_t res;
43299 +
43300 + /* Configures scheme's network environment parameters */
43301 + p_Scheme->netEnvParams.numOfDistinctionUnits = 2;
43302 + if (ipv4)
43303 + res = FmPcdNetEnvGetUnitId(
43304 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
43305 + HEADER_TYPE_IPv4, FALSE, 0);
43306 + else
43307 + res = FmPcdNetEnvGetUnitId(
43308 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
43309 + HEADER_TYPE_IPv6, FALSE, 0);
43310 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
43311 + p_Scheme->netEnvParams.unitIds[0] = res;
43312 +
43313 + res = FmPcdNetEnvGetUnitId(
43314 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
43315 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
43316 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
43317 + p_Scheme->netEnvParams.unitIds[1] = res;
43318 +
43319 + /* Configures scheme's next engine parameters*/
43320 + p_Scheme->nextEngine = e_FM_PCD_CC;
43321 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
43322 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
43323 + p_Scheme->useHash = TRUE;
43324 +
43325 + /* Configures scheme's key*/
43326 + if (ipv4 == TRUE)
43327 + {
43328 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 4;
43329 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
43330 + e_FM_PCD_EXTRACT_BY_HDR;
43331 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
43332 + e_FM_PCD_EXTRACT_FULL_FIELD;
43333 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
43334 + HEADER_TYPE_IPv4;
43335 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv4 =
43336 + NET_HEADER_FIELD_IPv4_DST_IP;
43337 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
43338 + e_FM_PCD_EXTRACT_BY_HDR;
43339 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
43340 + e_FM_PCD_EXTRACT_FULL_FIELD;
43341 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
43342 + HEADER_TYPE_IPv4;
43343 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv4 =
43344 + NET_HEADER_FIELD_IPv4_SRC_IP;
43345 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
43346 + e_FM_PCD_EXTRACT_BY_HDR;
43347 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
43348 + e_FM_PCD_EXTRACT_FULL_FIELD;
43349 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
43350 + HEADER_TYPE_IPv4;
43351 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fullField.ipv4 =
43352 + NET_HEADER_FIELD_IPv4_PROTO;
43353 + p_Scheme->keyExtractAndHashParams.extractArray[3].type =
43354 + e_FM_PCD_EXTRACT_BY_HDR;
43355 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.hdr =
43356 + HEADER_TYPE_IPv4;
43357 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.type =
43358 + e_FM_PCD_EXTRACT_FROM_HDR;
43359 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.ignoreProtocolValidation =
43360 + FALSE;
43361 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.size =
43362 + 2;
43363 + p_Scheme->keyExtractAndHashParams.extractArray[3].extractByHdr.extractByHdrType.fromHdr.offset =
43364 + 4;
43365 + }
43366 + else /* IPv6 */
43367 + {
43368 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 3;
43369 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
43370 + e_FM_PCD_EXTRACT_BY_HDR;
43371 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.type =
43372 + e_FM_PCD_EXTRACT_FULL_FIELD;
43373 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.hdr =
43374 + HEADER_TYPE_IPv6;
43375 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractByHdr.extractByHdrType.fullField.ipv6 =
43376 + NET_HEADER_FIELD_IPv6_DST_IP;
43377 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
43378 + e_FM_PCD_EXTRACT_BY_HDR;
43379 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.type =
43380 + e_FM_PCD_EXTRACT_FULL_FIELD;
43381 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.hdr =
43382 + HEADER_TYPE_IPv6;
43383 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractByHdr.extractByHdrType.fullField.ipv6 =
43384 + NET_HEADER_FIELD_IPv6_SRC_IP;
43385 + p_Scheme->keyExtractAndHashParams.extractArray[2].type =
43386 + e_FM_PCD_EXTRACT_BY_HDR;
43387 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.hdr =
43388 + HEADER_TYPE_USER_DEFINED_SHIM2;
43389 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.type =
43390 + e_FM_PCD_EXTRACT_FROM_HDR;
43391 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.size =
43392 + 4;
43393 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.extractByHdrType.fromHdr.offset =
43394 + 4;
43395 + p_Scheme->keyExtractAndHashParams.extractArray[2].extractByHdr.ignoreProtocolValidation =
43396 + TRUE;
43397 + }
43398 +
43399 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x01020304;
43400 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x11121314;
43401 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts =
43402 + FM_PCD_KG_NUM_OF_DEFAULT_GROUPS;
43403 + for (j = 0; j < FM_PCD_KG_NUM_OF_DEFAULT_GROUPS; j++)
43404 + {
43405 + p_Scheme->keyExtractAndHashParams.dflts[j].type =
43406 + (e_FmPcdKgKnownFieldsDfltTypes)j; /* all types */
43407 + p_Scheme->keyExtractAndHashParams.dflts[j].dfltSelect =
43408 + e_FM_PCD_KG_DFLT_GBL_0;
43409 + }
43410 +}
43411 +
43412 +static t_Error IpReassemblyStats(t_FmPcdManip *p_Manip,
43413 + t_FmPcdManipReassemIpStats *p_Stats)
43414 +{
43415 + ASSERT_COND(p_Manip);
43416 + ASSERT_COND(p_Stats);
43417 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
43418 +
43419 + p_Stats->timeout =
43420 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
43421 + p_Stats->rfdPoolBusy =
43422 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
43423 + p_Stats->internalBufferBusy =
43424 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
43425 + p_Stats->externalBufferBusy =
43426 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
43427 + p_Stats->sgFragments =
43428 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
43429 + p_Stats->dmaSemaphoreDepletion =
43430 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
43431 +#if (DPAA_VERSION >= 11)
43432 + p_Stats->nonConsistentSp =
43433 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
43434 +#endif /* (DPAA_VERSION >= 11) */
43435 +
43436 + if (p_Manip->reassmParams.ip.p_Ipv4ReassTbl)
43437 + {
43438 + p_Stats->specificHdrStatistics[0].successfullyReassembled =
43439 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSuccessfullyReasmFramesCounter);
43440 + p_Stats->specificHdrStatistics[0].validFragments =
43441 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalValidFragmentCounter);
43442 + p_Stats->specificHdrStatistics[0].processedFragments =
43443 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalProcessedFragCounter);
43444 + p_Stats->specificHdrStatistics[0].malformedFragments =
43445 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMalformdFragCounter);
43446 + p_Stats->specificHdrStatistics[0].autoLearnBusy =
43447 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalSetBusyCounter);
43448 + p_Stats->specificHdrStatistics[0].discardedFragments =
43449 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalDiscardedFragsCounter);
43450 + p_Stats->specificHdrStatistics[0].moreThan16Fragments =
43451 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv4ReassTbl->totalMoreThan16FramesCounter);
43452 + }
43453 + if (p_Manip->reassmParams.ip.p_Ipv6ReassTbl)
43454 + {
43455 + p_Stats->specificHdrStatistics[1].successfullyReassembled =
43456 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSuccessfullyReasmFramesCounter);
43457 + p_Stats->specificHdrStatistics[1].validFragments =
43458 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalValidFragmentCounter);
43459 + p_Stats->specificHdrStatistics[1].processedFragments =
43460 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalProcessedFragCounter);
43461 + p_Stats->specificHdrStatistics[1].malformedFragments =
43462 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMalformdFragCounter);
43463 + p_Stats->specificHdrStatistics[1].autoLearnBusy =
43464 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalSetBusyCounter);
43465 + p_Stats->specificHdrStatistics[1].discardedFragments =
43466 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalDiscardedFragsCounter);
43467 + p_Stats->specificHdrStatistics[1].moreThan16Fragments =
43468 + GET_UINT32(p_Manip->reassmParams.ip.p_Ipv6ReassTbl->totalMoreThan16FramesCounter);
43469 + }
43470 + return E_OK;
43471 +}
43472 +
43473 +static t_Error IpFragmentationStats(t_FmPcdManip *p_Manip,
43474 + t_FmPcdManipFragIpStats *p_Stats)
43475 +{
43476 + t_AdOfTypeContLookup *p_Ad;
43477 +
43478 + ASSERT_COND(p_Manip);
43479 + ASSERT_COND(p_Stats);
43480 + ASSERT_COND(p_Manip->h_Ad);
43481 + ASSERT_COND(p_Manip->fragParams.p_Frag);
43482 +
43483 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43484 +
43485 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
43486 + p_Stats->fragmentedFrames = GET_UINT32(p_Manip->fragParams.p_Frag->ccAdBase)
43487 + & 0x00ffffff;
43488 + p_Stats->generatedFragments =
43489 + GET_UINT32(p_Manip->fragParams.p_Frag->matchTblPtr);
43490 +
43491 + return E_OK;
43492 +}
43493 +
43494 +static t_Error IpFragmentation(t_FmPcdManipFragIpParams *p_ManipParams,
43495 + t_FmPcdManip *p_Manip)
43496 +{
43497 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
43498 + t_FmPcd *p_FmPcd;
43499 +#if (DPAA_VERSION == 10)
43500 + t_Error err = E_OK;
43501 +#endif /* (DPAA_VERSION == 10) */
43502 +
43503 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
43504 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
43505 + E_INVALID_VALUE);
43506 +
43507 + p_FmPcd = p_Manip->h_FmPcd;
43508 + /* Allocation of fragmentation Action Descriptor */
43509 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
43510 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
43511 + FM_PCD_CC_AD_TABLE_ALIGN);
43512 + if (!p_Manip->fragParams.p_Frag)
43513 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43514 + ("MURAM alloc for Fragmentation table descriptor"));
43515 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43516 +
43517 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
43518 + pcAndOffsetsReg = (uint32_t)HMAN_OC_IP_FRAGMENTATION;
43519 +
43520 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
43521 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
43522 + ccAdBaseReg |= (p_ManipParams->dontFragAction
43523 + << FM_PCD_MANIP_IP_FRAG_DF_SHIFT);
43524 +
43525 +
43526 + /* Set Scatter/Gather BPid */
43527 + if (p_ManipParams->sgBpidEn)
43528 + {
43529 + ccAdBaseReg |= FM_PCD_MANIP_IP_FRAG_SG_BDID_EN;
43530 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
43531 + << FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT)
43532 + & FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK);
43533 + }
43534 +
43535 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
43536 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr))
43537 + - p_FmPcd->physicalMuramBase);
43538 +#if (DPAA_VERSION == 10)
43539 + gmaskReg |= p_ManipParams->scratchBpid << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
43540 +#else
43541 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
43542 +#endif /* (DPAA_VERSION == 10) */
43543 +
43544 + /* Set all Ad registers */
43545 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
43546 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
43547 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
43548 +
43549 + /* Saves user's fragmentation manipulation parameters */
43550 + p_Manip->frag = TRUE;
43551 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
43552 +
43553 +#if (DPAA_VERSION == 10)
43554 + p_Manip->fragParams.scratchBpid = p_ManipParams->scratchBpid;
43555 +
43556 + /* scratch buffer pool initialization */
43557 + if ((err = FmPcdFragHcScratchPoolFill((t_Handle)p_FmPcd, p_ManipParams->scratchBpid)) != E_OK)
43558 + {
43559 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, p_Manip->fragParams.p_Frag);
43560 + p_Manip->fragParams.p_Frag = NULL;
43561 + RETURN_ERROR(MAJOR, err, NO_MSG);
43562 + }
43563 +#endif /* (DPAA_VERSION == 10) */
43564 +
43565 + return E_OK;
43566 +}
43567 +
43568 +static t_Error IPManip(t_FmPcdManip *p_Manip)
43569 +{
43570 + t_Error err = E_OK;
43571 + t_FmPcd *p_FmPcd;
43572 + t_AdOfTypeContLookup *p_Ad;
43573 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
43574 +
43575 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43576 + p_FmPcd = p_Manip->h_FmPcd;
43577 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
43578 +
43579 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43580 +
43581 + tmpReg32 = FM_PCD_MANIP_IP_NO_FRAGMENTATION;
43582 + if (p_Manip->frag == TRUE)
43583 + {
43584 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
43585 + - (p_FmPcd->physicalMuramBase));
43586 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
43587 + << FM_PCD_MANIP_IP_MTU_SHIFT;
43588 + }
43589 +
43590 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43591 + tmpReg32 |= HMAN_OC_IP_MANIP;
43592 +
43593 +#if (DPAA_VERSION >= 11)
43594 + tmpRegNia |= FM_PCD_MANIP_IP_CNIA;
43595 +#endif /* (DPAA_VERSION >= 11) */
43596 +
43597 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
43598 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
43599 + WRITE_UINT32(p_Ad->gmask, 0);
43600 + /* Total frame counter - MUST be initialized to zero.*/
43601 +
43602 + return err;
43603 +}
43604 +
43605 +static t_Error UpdateInitIpFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
43606 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
43607 + t_Handle h_Ad, bool validate)
43608 +{
43609 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
43610 + t_Error err;
43611 +
43612 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43613 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION),
43614 + E_INVALID_STATE);
43615 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
43616 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
43617 +
43618 + UNUSED(h_FmPcd);
43619 + UNUSED(h_Ad);
43620 + UNUSED(h_PcdParams);
43621 + UNUSED(validate);
43622 + UNUSED(p_Manip);
43623 +
43624 + fmPortGetSetCcParams.setCcParams.type = 0;
43625 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
43626 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
43627 + RETURN_ERROR(MAJOR, err, NO_MSG);
43628 +
43629 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
43630 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
43631 +
43632 + return E_OK;
43633 +}
43634 +
43635 +static t_Error IPSecManip(t_FmPcdManipParams *p_ManipParams,
43636 + t_FmPcdManip *p_Manip)
43637 +{
43638 + t_AdOfTypeContLookup *p_Ad;
43639 + t_FmPcdManipSpecialOffloadIPSecParams *p_IPSecParams;
43640 + t_Error err = E_OK;
43641 + uint32_t tmpReg32 = 0;
43642 + uint32_t power;
43643 +
43644 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43645 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43646 +
43647 + p_IPSecParams = &p_ManipParams->u.specialOffload.u.ipsec;
43648 +
43649 + SANITY_CHECK_RETURN_ERROR(
43650 + !p_IPSecParams->variableIpHdrLen || p_IPSecParams->decryption,
43651 + E_INVALID_VALUE);
43652 + SANITY_CHECK_RETURN_ERROR(
43653 + !p_IPSecParams->variableIpVersion || !p_IPSecParams->decryption,
43654 + E_INVALID_VALUE);
43655 + SANITY_CHECK_RETURN_ERROR(
43656 + !p_IPSecParams->variableIpVersion || p_IPSecParams->outerIPHdrLen,
43657 + E_INVALID_VALUE);
43658 + SANITY_CHECK_RETURN_ERROR(
43659 + !p_IPSecParams->arwSize || p_IPSecParams->arwAddr,
43660 + E_INVALID_VALUE);
43661 + SANITY_CHECK_RETURN_ERROR(
43662 + !p_IPSecParams->arwSize || p_IPSecParams->decryption,
43663 + E_INVALID_VALUE);
43664 + SANITY_CHECK_RETURN_ERROR((p_IPSecParams->arwSize % 16) == 0, E_INVALID_VALUE);
43665 +
43666 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43667 +
43668 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43669 + tmpReg32 |= (p_IPSecParams->decryption) ? FM_PCD_MANIP_IPSEC_DEC : 0;
43670 + tmpReg32 |= (p_IPSecParams->ecnCopy) ? FM_PCD_MANIP_IPSEC_ECN_EN : 0;
43671 + tmpReg32 |= (p_IPSecParams->dscpCopy) ? FM_PCD_MANIP_IPSEC_DSCP_EN : 0;
43672 + tmpReg32 |=
43673 + (p_IPSecParams->variableIpHdrLen) ? FM_PCD_MANIP_IPSEC_VIPL_EN : 0;
43674 + tmpReg32 |=
43675 + (p_IPSecParams->variableIpVersion) ? FM_PCD_MANIP_IPSEC_VIPV_EN : 0;
43676 + if (p_IPSecParams->arwSize)
43677 + tmpReg32 |= (uint32_t)((XX_VirtToPhys(UINT_TO_PTR(p_IPSecParams->arwAddr))-FM_MM_MURAM)
43678 + & (FM_MURAM_SIZE-1));
43679 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
43680 +
43681 + tmpReg32 = 0;
43682 + if (p_IPSecParams->arwSize) {
43683 + NEXT_POWER_OF_2((p_IPSecParams->arwSize + 32), power);
43684 + LOG2(power, power);
43685 + tmpReg32 = (p_IPSecParams->arwSize | (power - 5)) << FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT;
43686 + }
43687 +
43688 + if (p_ManipParams->h_NextManip)
43689 + tmpReg32 |=
43690 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)-
43691 + (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4;
43692 + WRITE_UINT32(p_Ad->matchTblPtr, tmpReg32);
43693 +
43694 + tmpReg32 = HMAN_OC_IPSEC_MANIP;
43695 + tmpReg32 |= p_IPSecParams->outerIPHdrLen
43696 + << FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT;
43697 + if (p_ManipParams->h_NextManip)
43698 + tmpReg32 |= FM_PCD_MANIP_IPSEC_NADEN;
43699 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
43700 +
43701 + return err;
43702 +}
43703 +
43704 +static t_Error SetCapwapReassmManip(t_FmPcdManip *p_Manip)
43705 +{
43706 + t_FmPcd *p_FmPcd = (t_FmPcd *)p_Manip->h_FmPcd;
43707 +
43708 + /* Allocation if CAPWAP Action descriptor */
43709 + p_Manip->reassmParams.capwap.h_Ad = (t_Handle)XX_MallocSmart(
43710 + FM_PCD_CC_AD_ENTRY_SIZE, p_Manip->reassmParams.dataMemId,
43711 + FM_PCD_CC_AD_TABLE_ALIGN);
43712 + if (!p_Manip->reassmParams.capwap.h_Ad)
43713 + {
43714 + ReleaseManipHandler(p_Manip, p_FmPcd);
43715 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43716 + ("Allocation of CAPWAP table descriptor"));
43717 + }
43718 +
43719 + memset(p_Manip->reassmParams.capwap.h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43720 +
43721 + /* Fill reassembly manipulation parameter in the Reassembly Action Descriptor */
43722 + return FillReassmManipParams(p_Manip, HEADER_TYPE_CAPWAP);
43723 +}
43724 +
43725 +static void setCapwapReassmSchemeParams(t_FmPcd* p_FmPcd,
43726 + t_FmPcdKgSchemeParams *p_Scheme,
43727 + t_Handle h_CcTree, uint8_t groupId)
43728 +{
43729 + uint8_t res;
43730 +
43731 + /* Configures scheme's network environment parameters */
43732 + p_Scheme->netEnvParams.numOfDistinctionUnits = 1;
43733 + res = FmPcdNetEnvGetUnitId(
43734 + p_FmPcd, FmPcdGetNetEnvId(p_Scheme->netEnvParams.h_NetEnv),
43735 + HEADER_TYPE_USER_DEFINED_SHIM2, FALSE, 0);
43736 + ASSERT_COND(res != FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
43737 + p_Scheme->netEnvParams.unitIds[0] = res;
43738 +
43739 + /* Configures scheme's next engine parameters*/
43740 + p_Scheme->nextEngine = e_FM_PCD_CC;
43741 + p_Scheme->kgNextEngineParams.cc.h_CcTree = h_CcTree;
43742 + p_Scheme->kgNextEngineParams.cc.grpId = groupId;
43743 + p_Scheme->useHash = TRUE;
43744 +
43745 + /* Configures scheme's key*/
43746 + p_Scheme->keyExtractAndHashParams.numOfUsedExtracts = 2;
43747 + p_Scheme->keyExtractAndHashParams.extractArray[0].type =
43748 + e_FM_PCD_EXTRACT_NON_HDR;
43749 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.src =
43750 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT;
43751 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.action =
43752 + e_FM_PCD_ACTION_NONE;
43753 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.offset = 20;
43754 + p_Scheme->keyExtractAndHashParams.extractArray[0].extractNonHdr.size = 4;
43755 + p_Scheme->keyExtractAndHashParams.extractArray[1].type =
43756 + e_FM_PCD_EXTRACT_NON_HDR;
43757 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.src =
43758 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE;
43759 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.action =
43760 + e_FM_PCD_ACTION_NONE;
43761 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.offset = 0;
43762 + p_Scheme->keyExtractAndHashParams.extractArray[1].extractNonHdr.size = 1;
43763 +
43764 + p_Scheme->keyExtractAndHashParams.privateDflt0 = 0x0;
43765 + p_Scheme->keyExtractAndHashParams.privateDflt1 = 0x0;
43766 + p_Scheme->keyExtractAndHashParams.numOfUsedDflts = 1;
43767 + p_Scheme->keyExtractAndHashParams.dflts[0].type = e_FM_PCD_KG_GENERIC_NOT_FROM_DATA;
43768 + p_Scheme->keyExtractAndHashParams.dflts[0].dfltSelect = e_FM_PCD_KG_DFLT_PRIVATE_0;
43769 +}
43770 +
43771 +#if (DPAA_VERSION >= 11)
43772 +static t_Error CapwapReassemblyStats(t_FmPcdManip *p_Manip,
43773 + t_FmPcdManipReassemCapwapStats *p_Stats)
43774 +{
43775 + ASSERT_COND(p_Manip);
43776 + ASSERT_COND(p_Stats);
43777 + ASSERT_COND(p_Manip->reassmParams.p_ReassCommonTbl);
43778 +
43779 + p_Stats->timeout =
43780 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalTimeOutCounter);
43781 + p_Stats->rfdPoolBusy =
43782 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalRfdPoolBusyCounter);
43783 + p_Stats->internalBufferBusy =
43784 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalInternalBufferBusy);
43785 + p_Stats->externalBufferBusy =
43786 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalExternalBufferBusy);
43787 + p_Stats->sgFragments =
43788 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalSgFragmentCounter);
43789 + p_Stats->dmaSemaphoreDepletion =
43790 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalDmaSemaphoreDepletionCounter);
43791 + p_Stats->exceedMaxReassemblyFrameLen =
43792 + GET_UINT32(p_Manip->reassmParams.p_ReassCommonTbl->totalNCSPCounter);
43793 +
43794 + p_Stats->successfullyReassembled =
43795 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSuccessfullyReasmFramesCounter);
43796 + p_Stats->validFragments =
43797 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalValidFragmentCounter);
43798 + p_Stats->processedFragments =
43799 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalProcessedFragCounter);
43800 + p_Stats->malformedFragments =
43801 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMalformdFragCounter);
43802 + p_Stats->autoLearnBusy =
43803 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalSetBusyCounter);
43804 + p_Stats->discardedFragments =
43805 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalDiscardedFragsCounter);
43806 + p_Stats->moreThan16Fragments =
43807 + GET_UINT32(p_Manip->reassmParams.capwap.p_ReassTbl->totalMoreThan16FramesCounter);
43808 +
43809 + return E_OK;
43810 +}
43811 +
43812 +static t_Error CapwapFragmentationStats(t_FmPcdManip *p_Manip,
43813 + t_FmPcdManipFragCapwapStats *p_Stats)
43814 +{
43815 + t_AdOfTypeContLookup *p_Ad;
43816 +
43817 + ASSERT_COND(p_Manip);
43818 + ASSERT_COND(p_Stats);
43819 + ASSERT_COND(p_Manip->h_Ad);
43820 + ASSERT_COND(p_Manip->fragParams.p_Frag);
43821 +
43822 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43823 +
43824 + p_Stats->totalFrames = GET_UINT32(p_Ad->gmask);
43825 +
43826 + return E_OK;
43827 +}
43828 +
43829 +static t_Error CapwapReassembly(t_FmPcdManipReassemParams *p_ManipReassmParams,
43830 + t_FmPcdManip *p_Manip)
43831 +{
43832 + uint32_t maxSetNumber = 10000;
43833 + t_FmPcdManipReassemCapwapParams reassmManipParams =
43834 + p_ManipReassmParams->u.capwapReassem;
43835 + t_Error res;
43836 +
43837 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_FmPcd, E_INVALID_HANDLE);
43838 + SANITY_CHECK_RETURN_ERROR(((t_FmPcd *)p_Manip->h_FmPcd)->h_Hc,
43839 + E_INVALID_HANDLE);
43840 +
43841 + /* Check validation of user's parameter.*/
43842 + if ((reassmManipParams.timeoutThresholdForReassmProcess < 1000)
43843 + || (reassmManipParams.timeoutThresholdForReassmProcess > 8000000))
43844 + RETURN_ERROR(
43845 + MAJOR, E_INVALID_VALUE,
43846 + ("timeoutThresholdForReassmProcess should be 1msec - 8sec"));
43847 + /* It is recommended that the total number of entries in this table (number of sets * number of ways)
43848 + will be twice the number of frames that are expected to be reassembled simultaneously.*/
43849 + if (reassmManipParams.maxNumFramesInProcess
43850 + > (reassmManipParams.maxNumFramesInProcess * maxSetNumber / 2))
43851 + RETURN_ERROR(
43852 + MAJOR,
43853 + E_INVALID_VALUE,
43854 + ("maxNumFramesInProcess has to be less than (maximun set number * number of ways / 2)"));
43855 +
43856 + /* Saves user's reassembly manipulation parameters */
43857 + p_Manip->reassmParams.capwap.relativeSchemeId =
43858 + reassmManipParams.relativeSchemeId;
43859 + p_Manip->reassmParams.capwap.numOfFramesPerHashEntry =
43860 + reassmManipParams.numOfFramesPerHashEntry;
43861 + p_Manip->reassmParams.capwap.maxRessembledsSize =
43862 + reassmManipParams.maxReassembledFrameLength;
43863 + p_Manip->reassmParams.maxNumFramesInProcess =
43864 + reassmManipParams.maxNumFramesInProcess;
43865 + p_Manip->reassmParams.timeOutMode = reassmManipParams.timeOutMode;
43866 + p_Manip->reassmParams.fqidForTimeOutFrames =
43867 + reassmManipParams.fqidForTimeOutFrames;
43868 + p_Manip->reassmParams.timeoutThresholdForReassmProcess =
43869 + reassmManipParams.timeoutThresholdForReassmProcess;
43870 + p_Manip->reassmParams.dataMemId = reassmManipParams.dataMemId;
43871 + p_Manip->reassmParams.dataLiodnOffset = reassmManipParams.dataLiodnOffset;
43872 +
43873 + /* Creates and initializes the Reassembly common parameter table */
43874 + CreateReassCommonTable(p_Manip);
43875 +
43876 + res = SetCapwapReassmManip(p_Manip);
43877 + if (res != E_OK)
43878 + return res;
43879 +
43880 + return E_OK;
43881 +}
43882 +
43883 +static t_Error CapwapFragmentation(t_FmPcdManipFragCapwapParams *p_ManipParams,
43884 + t_FmPcdManip *p_Manip)
43885 +{
43886 + t_FmPcd *p_FmPcd;
43887 + t_AdOfTypeContLookup *p_Ad;
43888 + uint32_t pcAndOffsetsReg = 0, ccAdBaseReg = 0, gmaskReg = 0;
43889 + uint32_t tmpReg32 = 0, tmpRegNia = 0;
43890 +
43891 + SANITY_CHECK_RETURN_ERROR(p_Manip->h_Ad, E_INVALID_HANDLE);
43892 + SANITY_CHECK_RETURN_ERROR(p_ManipParams->sizeForFragmentation != 0xFFFF,
43893 + E_INVALID_VALUE);
43894 + p_FmPcd = p_Manip->h_FmPcd;
43895 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
43896 +
43897 + /* Allocation of fragmentation Action Descriptor */
43898 + p_Manip->fragParams.p_Frag = (t_AdOfTypeContLookup *)FM_MURAM_AllocMem(
43899 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
43900 + FM_PCD_CC_AD_TABLE_ALIGN);
43901 + if (!p_Manip->fragParams.p_Frag)
43902 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
43903 + ("MURAM alloc for Fragmentation table descriptor"));
43904 + MemSet8(p_Manip->fragParams.p_Frag, 0, FM_PCD_CC_AD_ENTRY_SIZE);
43905 +
43906 + /* Prepare the third Ad register (pcAndOffsets)- OperationCode */
43907 + pcAndOffsetsReg = (uint32_t)HMAN_OC_CAPWAP_FRAGMENTATION;
43908 +
43909 + /* Prepare the first Ad register (ccAdBase) - Don't frag action and Action descriptor type*/
43910 + ccAdBaseReg = FM_PCD_AD_CONT_LOOKUP_TYPE;
43911 + ccAdBaseReg |=
43912 + (p_ManipParams->compressModeEn) ? FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN :
43913 + 0;
43914 +
43915 + /* Set Scatter/Gather BPid */
43916 + if (p_ManipParams->sgBpidEn)
43917 + {
43918 + ccAdBaseReg |= FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN;
43919 + pcAndOffsetsReg |= ((p_ManipParams->sgBpid
43920 + << FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT)
43921 + & FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK);
43922 + }
43923 +
43924 + /* Prepare the first Ad register (gmask) - scratch buffer pool id and Pointer to fragment ID */
43925 + gmaskReg = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr))
43926 + - p_FmPcd->physicalMuramBase);
43927 + gmaskReg |= (0xFF) << FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID;
43928 +
43929 + /* Set all Ad registers */
43930 + WRITE_UINT32(p_Manip->fragParams.p_Frag->pcAndOffsets, pcAndOffsetsReg);
43931 + WRITE_UINT32(p_Manip->fragParams.p_Frag->ccAdBase, ccAdBaseReg);
43932 + WRITE_UINT32(p_Manip->fragParams.p_Frag->gmask, gmaskReg);
43933 +
43934 + /* Saves user's fragmentation manipulation parameters */
43935 + p_Manip->frag = TRUE;
43936 + p_Manip->sizeForFragmentation = p_ManipParams->sizeForFragmentation;
43937 +
43938 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
43939 +
43940 + tmpRegNia = (uint32_t)(XX_VirtToPhys(p_Manip->fragParams.p_Frag)
43941 + - (p_FmPcd->physicalMuramBase));
43942 + tmpReg32 = (uint32_t)p_Manip->sizeForFragmentation
43943 + << FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT;
43944 +
43945 + tmpRegNia |= FM_PCD_AD_CONT_LOOKUP_TYPE;
43946 + tmpReg32 |= HMAN_OC_CAPWAP_FRAG_CHECK;
43947 +
43948 + tmpRegNia |= FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA;
43949 +
43950 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
43951 + WRITE_UINT32(p_Ad->ccAdBase, tmpRegNia);
43952 + WRITE_UINT32(p_Ad->gmask, 0);
43953 + /* Total frame counter - MUST be initialized to zero.*/
43954 +
43955 + return E_OK;
43956 +}
43957 +
43958 +static t_Error UpdateInitCapwapFrag(t_Handle h_FmPcd, t_Handle h_PcdParams,
43959 + t_Handle h_FmPort, t_FmPcdManip *p_Manip,
43960 + t_Handle h_Ad, bool validate)
43961 +{
43962 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
43963 + t_Error err;
43964 +
43965 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43966 + SANITY_CHECK_RETURN_ERROR((p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION),
43967 + E_INVALID_STATE);
43968 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
43969 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
43970 +
43971 + UNUSED(h_FmPcd);
43972 + UNUSED(h_Ad);
43973 + UNUSED(h_PcdParams);
43974 + UNUSED(validate);
43975 + UNUSED(p_Manip);
43976 +
43977 + fmPortGetSetCcParams.setCcParams.type = 0;
43978 + fmPortGetSetCcParams.getCcParams.type = MANIP_EXTRA_SPACE;
43979 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams)) != E_OK)
43980 + RETURN_ERROR(MAJOR, err, NO_MSG);
43981 +
43982 + if (!fmPortGetSetCcParams.getCcParams.internalBufferOffset)
43983 + DBG(WARNING, ("manipExtraSpace must be larger than '0'"));
43984 +
43985 + return E_OK;
43986 +}
43987 +
43988 +static t_Error CapwapManip(t_FmPcdManipParams *p_ManipParams,
43989 + t_FmPcdManip *p_Manip)
43990 +{
43991 + t_AdOfTypeContLookup *p_Ad;
43992 + t_FmPcdManipSpecialOffloadCapwapParams *p_Params;
43993 + t_Error err = E_OK;
43994 + uint32_t tmpReg32 = 0;
43995 +
43996 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
43997 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
43998 +
43999 + p_Params = &p_ManipParams->u.specialOffload.u.capwap;
44000 +
44001 + p_Ad = (t_AdOfTypeContLookup *)p_Manip->h_Ad;
44002 + tmpReg32 |= FM_PCD_AD_CONT_LOOKUP_TYPE;
44003 + tmpReg32 |= (p_Params->dtls) ? FM_PCD_MANIP_CAPWAP_DTLS : 0;
44004 + /* TODO - add 'qosSrc' */
44005 + WRITE_UINT32(p_Ad->ccAdBase, tmpReg32);
44006 +
44007 + tmpReg32 = HMAN_OC_CAPWAP_MANIP;
44008 + if (p_ManipParams->h_NextManip)
44009 + {
44010 + WRITE_UINT32(
44011 + p_Ad->matchTblPtr,
44012 + (uint32_t)(XX_VirtToPhys(((t_FmPcdManip *)p_ManipParams->h_NextManip)->h_Ad)- (((t_FmPcd *)p_Manip->h_FmPcd)->physicalMuramBase)) >> 4);
44013 +
44014 + tmpReg32 |= FM_PCD_MANIP_CAPWAP_NADEN;
44015 + }
44016 +
44017 + WRITE_UINT32(p_Ad->pcAndOffsets, tmpReg32);
44018 +
44019 + return err;
44020 +}
44021 +#endif /* (DPAA_VERSION >= 11) */
44022 +
44023 +static t_Handle ManipOrStatsSetNode(t_Handle h_FmPcd, t_Handle *p_Params,
44024 + bool stats)
44025 +{
44026 + t_FmPcdManip *p_Manip;
44027 + t_Error err;
44028 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
44029 +
44030 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
44031 + if (!p_Manip)
44032 + {
44033 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
44034 + return NULL;
44035 + }
44036 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
44037 +
44038 + p_Manip->type = ((t_FmPcdManipParams *)p_Params)->type;
44039 + memcpy((uint8_t*)&p_Manip->manipParams, p_Params,
44040 + sizeof(p_Manip->manipParams));
44041 +
44042 + if (!stats)
44043 + err = CheckManipParamsAndSetType(p_Manip,
44044 + (t_FmPcdManipParams *)p_Params);
44045 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44046 + else
44047 + err = CheckStatsParamsAndSetType(p_Manip, (t_FmPcdStatsParams *)p_Params);
44048 +#else /* not (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44049 + else
44050 + {
44051 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Statistics node!"));
44052 + XX_Free(p_Manip);
44053 + return NULL;
44054 + }
44055 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44056 + if (err)
44057 + {
44058 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Invalid header manipulation type"));
44059 + XX_Free(p_Manip);
44060 + return NULL;
44061 + }
44062 +
44063 + if ((p_Manip->opcode != HMAN_OC_IP_REASSEMBLY) && (p_Manip->opcode != HMAN_OC_CAPWAP_REASSEMBLY))
44064 + {
44065 + /* In Case of reassembly manipulation the reassembly action descriptor will
44066 + be defines later on */
44067 + if (p_Manip->muramAllocate)
44068 + {
44069 + p_Manip->h_Ad = (t_Handle)FM_MURAM_AllocMem(
44070 + p_FmPcd->h_FmMuram, FM_PCD_CC_AD_ENTRY_SIZE,
44071 + FM_PCD_CC_AD_TABLE_ALIGN);
44072 + if (!p_Manip->h_Ad)
44073 + {
44074 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for Manipulation action descriptor"));
44075 + ReleaseManipHandler(p_Manip, p_FmPcd);
44076 + XX_Free(p_Manip);
44077 + return NULL;
44078 + }
44079 +
44080 + MemSet8(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
44081 + }
44082 + else
44083 + {
44084 + p_Manip->h_Ad = (t_Handle)XX_Malloc(
44085 + FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
44086 + if (!p_Manip->h_Ad)
44087 + {
44088 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
44089 + ReleaseManipHandler(p_Manip, p_FmPcd);
44090 + XX_Free(p_Manip);
44091 + return NULL;
44092 + }
44093 +
44094 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
44095 + }
44096 + }
44097 +
44098 + p_Manip->h_FmPcd = h_FmPcd;
44099 +
44100 + return p_Manip;
44101 +}
44102 +
44103 +static void UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
44104 + t_FmPcdManip *p_CrntMdfManip, t_List *h_NodesLst)
44105 +{
44106 + t_CcNodeInformation *p_CcNodeInformation;
44107 + t_FmPcdCcNode *p_NodePtrOnCurrentMdfManip = NULL;
44108 + t_List *p_Pos;
44109 + int i = 0;
44110 + t_Handle p_AdTablePtOnCrntCurrentMdfNode/*, p_AdTableNewModified*/;
44111 + t_CcNodeInformation ccNodeInfo;
44112 +
44113 + LIST_FOR_EACH(p_Pos, &p_CrntMdfManip->nodesLst)
44114 + {
44115 + p_CcNodeInformation = CC_NODE_F_OBJECT(p_Pos);
44116 + p_NodePtrOnCurrentMdfManip =
44117 + (t_FmPcdCcNode *)p_CcNodeInformation->h_CcNode;
44118 +
44119 + ASSERT_COND(p_NodePtrOnCurrentMdfManip);
44120 +
44121 + /* Search in the previous node which exact index points on this current modified node for getting AD */
44122 + for (i = 0; i < p_NodePtrOnCurrentMdfManip->numOfKeys + 1; i++)
44123 + {
44124 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.nextEngine
44125 + == e_FM_PCD_CC)
44126 + {
44127 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].nextEngineParams.h_Manip
44128 + == (t_Handle)p_CrntMdfManip)
44129 + {
44130 + if (p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj)
44131 + p_AdTablePtOnCrntCurrentMdfNode =
44132 + p_NodePtrOnCurrentMdfManip->keyAndNextEngineParams[i].p_StatsObj->h_StatsAd;
44133 + else
44134 + p_AdTablePtOnCrntCurrentMdfNode =
44135 + PTR_MOVE(p_NodePtrOnCurrentMdfManip->h_AdTable, i*FM_PCD_CC_AD_ENTRY_SIZE);
44136 +
44137 + memset(&ccNodeInfo, 0, sizeof(t_CcNodeInformation));
44138 + ccNodeInfo.h_CcNode = p_AdTablePtOnCrntCurrentMdfNode;
44139 + EnqueueNodeInfoToRelevantLst(h_NodesLst, &ccNodeInfo, NULL);
44140 + }
44141 + }
44142 + }
44143 +
44144 + ASSERT_COND(i != p_NodePtrOnCurrentMdfManip->numOfKeys);
44145 + }
44146 +}
44147 +
44148 +static void BuildHmtd(uint8_t *p_Dest, uint8_t *p_Src, uint8_t *p_Hmcd,
44149 + t_FmPcd *p_FmPcd)
44150 +{
44151 + t_Error err;
44152 +
44153 + /* Copy the HMTD */
44154 + MemCpy8(p_Dest, (uint8_t*)p_Src, 16);
44155 + /* Replace the HMCT table pointer */
44156 + WRITE_UINT32(
44157 + ((t_Hmtd *)p_Dest)->hmcdBasePtr,
44158 + (uint32_t)(XX_VirtToPhys(p_Hmcd) - ((t_FmPcd*)p_FmPcd)->physicalMuramBase));
44159 + /* Call Host Command to replace HMTD by a new HMTD */
44160 + err = FmHcPcdCcDoDynamicChange(
44161 + p_FmPcd->h_Hc,
44162 + (uint32_t)(XX_VirtToPhys(p_Src) - p_FmPcd->physicalMuramBase),
44163 + (uint32_t)(XX_VirtToPhys(p_Dest) - p_FmPcd->physicalMuramBase));
44164 + if (err)
44165 + REPORT_ERROR(MINOR, err, ("Failed in dynamic manip change, continued to the rest of the owners."));
44166 +}
44167 +
44168 +static t_Error FmPcdManipInitUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
44169 + t_Handle h_FmPort, t_Handle h_Manip,
44170 + t_Handle h_Ad, bool validate, int level,
44171 + t_Handle h_FmTree)
44172 +{
44173 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44174 + t_Error err = E_OK;
44175 +
44176 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
44177 +
44178 + UNUSED(level);
44179 + UNUSED(h_FmTree);
44180 +
44181 + switch (p_Manip->opcode)
44182 + {
44183 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44184 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
44185 + err = UpdateInitMvIntFrameHeaderFromFrameToBufferPrefix(h_FmPort,
44186 + p_Manip,
44187 + h_Ad,
44188 + validate);
44189 + break;
44190 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
44191 + if (!p_Manip->h_Frag)
44192 + break;
44193 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44194 + err = UpdateInitCapwapFragmentation(h_FmPort, p_Manip, h_Ad, validate, h_FmTree);
44195 + break;
44196 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44197 + if (p_Manip->h_Frag)
44198 + err = UpdateInitCapwapReasm(h_FmPcd, h_FmPort, p_Manip, h_Ad, validate);
44199 + break;
44200 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
44201 + err = UpdateIndxStats(h_FmPcd, h_FmPort, p_Manip);
44202 + break;
44203 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44204 + case (HMAN_OC_IP_REASSEMBLY):
44205 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
44206 + validate);
44207 + break;
44208 + case (HMAN_OC_IP_FRAGMENTATION):
44209 + err = UpdateInitIpFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
44210 + h_Ad, validate);
44211 + break;
44212 +#if (DPAA_VERSION >= 11)
44213 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44214 + err = UpdateInitCapwapFrag(h_FmPcd, h_PcdParams, h_FmPort, p_Manip,
44215 + h_Ad, validate);
44216 + break;
44217 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44218 + err = UpdateInitReasm(h_FmPcd, h_PcdParams, h_FmPort, p_Manip, h_Ad,
44219 + validate);
44220 + break;
44221 +#endif /* (DPAA_VERSION >= 11) */
44222 + default:
44223 + return E_OK;
44224 + }
44225 +
44226 + return err;
44227 +}
44228 +
44229 +static t_Error FmPcdManipModifyUpdate(t_Handle h_Manip, t_Handle h_Ad,
44230 + bool validate, int level,
44231 + t_Handle h_FmTree)
44232 +{
44233 +
44234 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44235 + t_Error err = E_OK;
44236 +
44237 + UNUSED(level);
44238 +
44239 + switch (p_Manip->opcode)
44240 + {
44241 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44242 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
44243 + RETURN_ERROR(
44244 + MAJOR,
44245 + E_INVALID_STATE,
44246 + ("modify node with this type of manipulation is not suppported"));
44247 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44248 +
44249 + if (p_Manip->h_Frag)
44250 + {
44251 + if (!(p_Manip->shadowUpdateParams & NUM_OF_TASKS)
44252 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_DATA)
44253 + && !(p_Manip->shadowUpdateParams & OFFSET_OF_PR))
44254 + RETURN_ERROR(
44255 + MAJOR,
44256 + E_INVALID_STATE,
44257 + ("modify node with this type of manipulation requires manipulation be updated previously in SetPcd function"));
44258 + }
44259 + break;
44260 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
44261 + if (p_Manip->h_Frag)
44262 + err = UpdateModifyCapwapFragmenation(p_Manip, h_Ad, validate, h_FmTree);
44263 + break;
44264 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44265 + default:
44266 + return E_OK;
44267 + }
44268 +
44269 + return err;
44270 +}
44271 +
44272 +/*****************************************************************************/
44273 +/* Inter-module API routines */
44274 +/*****************************************************************************/
44275 +
44276 +t_Error FmPcdManipUpdate(t_Handle h_FmPcd, t_Handle h_PcdParams,
44277 + t_Handle h_FmPort, t_Handle h_Manip, t_Handle h_Ad,
44278 + bool validate, int level, t_Handle h_FmTree,
44279 + bool modify)
44280 +{
44281 + t_Error err;
44282 +
44283 + if (!modify)
44284 + err = FmPcdManipInitUpdate(h_FmPcd, h_PcdParams, h_FmPort, h_Manip,
44285 + h_Ad, validate, level, h_FmTree);
44286 + else
44287 + err = FmPcdManipModifyUpdate(h_Manip, h_Ad, validate, level, h_FmTree);
44288 +
44289 + return err;
44290 +}
44291 +
44292 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add)
44293 +{
44294 +
44295 + uint32_t intFlags;
44296 +
44297 + intFlags = XX_LockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock);
44298 + if (add)
44299 + ((t_FmPcdManip *)h_Manip)->owner++;
44300 + else
44301 + {
44302 + ASSERT_COND(((t_FmPcdManip *)h_Manip)->owner);
44303 + ((t_FmPcdManip *)h_Manip)->owner--;
44304 + }
44305 + XX_UnlockIntrSpinlock(((t_FmPcdManip *)h_Manip)->h_Spinlock, intFlags);
44306 +}
44307 +
44308 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip)
44309 +{
44310 + ASSERT_COND(h_Manip);
44311 + return &((t_FmPcdManip *)h_Manip)->nodesLst;
44312 +}
44313 +
44314 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip)
44315 +{
44316 + ASSERT_COND(h_Manip);
44317 + return ((t_FmPcdManip *)h_Manip)->h_Spinlock;
44318 +}
44319 +
44320 +t_Error FmPcdManipCheckParamsForCcNextEngine(
44321 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
44322 + uint32_t *requiredAction)
44323 +{
44324 + t_FmPcdManip *p_Manip;
44325 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44326 + t_Error err = E_OK;
44327 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))*/
44328 + bool pointFromCc = TRUE;
44329 +
44330 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams, E_NULL_POINTER);
44331 + SANITY_CHECK_RETURN_ERROR(p_FmPcdCcNextEngineParams->h_Manip,
44332 + E_NULL_POINTER);
44333 +
44334 + p_Manip = (t_FmPcdManip *)(p_FmPcdCcNextEngineParams->h_Manip);
44335 + *requiredAction = 0;
44336 +
44337 + while (p_Manip)
44338 + {
44339 + switch (p_Manip->opcode)
44340 + {
44341 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44342 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
44343 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
44344 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
44345 + if (p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
44346 + p_Manip->cnia = TRUE;
44347 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44348 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
44349 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
44350 + p_Manip->ownerTmp++;
44351 + break;
44352 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
44353 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
44354 + && !p_FmPcdCcNextEngineParams->params.enqueueParams.overrideFqid)
44355 + RETURN_ERROR(
44356 + MAJOR,
44357 + E_INVALID_STATE,
44358 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE with fqidForCtrlFlow FALSE"));
44359 + p_Manip->ownerTmp++;
44360 + break;
44361 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
44362 + if ((p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_CC)
44363 + && (FmPcdCcGetParseCode(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode)
44364 + != CC_PC_GENERIC_IC_HASH_INDEXED))
44365 + 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"));
44366 + err = UpdateManipIc(p_FmPcdCcNextEngineParams->h_Manip,
44367 + FmPcdCcGetOffset(p_FmPcdCcNextEngineParams->params.ccParams.h_CcNode));
44368 + if (err)
44369 + RETURN_ERROR(MAJOR, err, NO_MSG);
44370 + *requiredAction = UPDATE_NIA_ENQ_WITHOUT_DMA;
44371 + break;
44372 + #endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44373 + case (HMAN_OC_IP_FRAGMENTATION):
44374 + case (HMAN_OC_IP_REASSEMBLY):
44375 +#if (DPAA_VERSION >= 11)
44376 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44377 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44378 +#endif /* (DPAA_VERSION >= 11) */
44379 + if (p_FmPcdCcNextEngineParams->nextEngine != e_FM_PCD_DONE)
44380 + RETURN_ERROR(
44381 + MAJOR,
44382 + E_INVALID_STATE,
44383 + ("For this type of header manipulation has to be nextEngine e_FM_PCD_DONE"));
44384 + p_Manip->ownerTmp++;
44385 + break;
44386 + case (HMAN_OC_IPSEC_MANIP):
44387 +#if (DPAA_VERSION >= 11)
44388 + case (HMAN_OC_CAPWAP_MANIP):
44389 +#endif /* (DPAA_VERSION >= 11) */
44390 + p_Manip->ownerTmp++;
44391 + break;
44392 + case (HMAN_OC):
44393 + if ((p_FmPcdCcNextEngineParams->nextEngine == e_FM_PCD_CC)
44394 + && MANIP_IS_CASCADED(p_Manip))
44395 + RETURN_ERROR(
44396 + MINOR,
44397 + E_INVALID_STATE,
44398 + ("Can't have a cascaded manipulation when and Next Engine is CC"));
44399 + if (!MANIP_IS_FIRST(p_Manip) && pointFromCc)
44400 + RETURN_ERROR(
44401 + MAJOR,
44402 + E_INVALID_STATE,
44403 + ("h_Manip is already used and may not be shared (no sharing of non-head manip nodes)"));
44404 + break;
44405 + default:
44406 + RETURN_ERROR(
44407 + MAJOR, E_INVALID_STATE,
44408 + ("invalid type of header manipulation for this state"));
44409 + }
44410 + p_Manip = p_Manip->h_NextManip;
44411 + pointFromCc = FALSE;
44412 + }
44413 + return E_OK;
44414 +}
44415 +
44416 +
44417 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip,
44418 + t_Handle h_FmPcdCcNode)
44419 +{
44420 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44421 + t_Error err = E_OK;
44422 +
44423 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
44424 + SANITY_CHECK_RETURN_ERROR(h_FmPcdCcNode, E_INVALID_HANDLE);
44425 +
44426 + switch (p_Manip->opcode)
44427 + {
44428 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44429 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
44430 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
44431 + RETURN_ERROR(
44432 + MAJOR,
44433 + E_INVALID_VALUE,
44434 + ("The manipulation of the type statistics flowId if exist has to be pointed by all numOfKeys"));
44435 + break;
44436 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44437 + if (p_Manip->h_Frag)
44438 + {
44439 + if (p_Manip->ownerTmp != FmPcdCcGetNumOfKeys(h_FmPcdCcNode))
44440 + RETURN_ERROR(
44441 + MAJOR,
44442 + E_INVALID_VALUE,
44443 + ("The manipulation of the type remove DTLS if exist has to be pointed by all numOfKeys"));
44444 + err = UpdateManipIc(h_Manip, FmPcdCcGetOffset(h_FmPcdCcNode));
44445 + if (err)
44446 + RETURN_ERROR(MAJOR, err, NO_MSG);
44447 + }
44448 + break;
44449 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44450 + default:
44451 + break;
44452 + }
44453 +
44454 + return err;
44455 +}
44456 +
44457 +void FmPcdManipUpdateAdResultForCc(
44458 + t_Handle h_Manip, t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
44459 + t_Handle p_Ad, t_Handle *p_AdNewPtr)
44460 +{
44461 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44462 +
44463 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
44464 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
44465 +
44466 + ASSERT_COND(p_Manip);
44467 + ASSERT_COND(p_CcNextEngineParams);
44468 + ASSERT_COND(p_Ad);
44469 + ASSERT_COND(p_AdNewPtr);
44470 +
44471 + FmPcdManipUpdateOwner(h_Manip, TRUE);
44472 +
44473 + /* According to "type", either build & initialize a new AD (p_AdNew) or initialize
44474 + * p_Ad ( the AD in the match table) and set p_AdNew = NULL. */
44475 + switch (p_Manip->opcode)
44476 + {
44477 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44478 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
44479 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44480 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
44481 + *p_AdNewPtr = p_Manip->h_Ad;
44482 + break;
44483 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
44484 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44485 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->fqid,
44486 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->fqid);
44487 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->plcrProfile,
44488 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->plcrProfile);
44489 + WRITE_UINT32(((t_AdOfTypeResult *)p_Ad)->nia,
44490 + ((t_AdOfTypeResult *)(p_Manip->h_Ad))->nia);
44491 + *p_AdNewPtr = NULL;
44492 + break;
44493 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44494 + case (HMAN_OC_IPSEC_MANIP):
44495 +#if (DPAA_VERSION >= 11)
44496 + case (HMAN_OC_CAPWAP_MANIP):
44497 +#endif /* (DPAA_VERSION >= 11) */
44498 + *p_AdNewPtr = p_Manip->h_Ad;
44499 + break;
44500 + case (HMAN_OC_IP_FRAGMENTATION):
44501 +#if (DPAA_VERSION >= 11)
44502 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44503 +#endif /* (DPAA_VERSION >= 11) */
44504 + if ((p_CcNextEngineParams->nextEngine == e_FM_PCD_DONE)
44505 + && (!p_CcNextEngineParams->params.enqueueParams.overrideFqid))
44506 + {
44507 + memcpy((uint8_t *)p_Ad, (uint8_t *)p_Manip->h_Ad,
44508 + sizeof(t_AdOfTypeContLookup));
44509 +#if (DPAA_VERSION >= 11)
44510 + WRITE_UINT32(
44511 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
44512 + GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) & ~FM_PCD_MANIP_IP_CNIA);
44513 +#endif /* (DPAA_VERSION >= 11) */
44514 + *p_AdNewPtr = NULL;
44515 + }
44516 + else
44517 + *p_AdNewPtr = p_Manip->h_Ad;
44518 + break;
44519 + case (HMAN_OC_IP_REASSEMBLY):
44520 + if (FmPcdManipIpReassmIsIpv6Hdr(p_Manip))
44521 + {
44522 + if (!p_Manip->reassmParams.ip.ipv6Assigned)
44523 + {
44524 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv6Ad;
44525 + p_Manip->reassmParams.ip.ipv6Assigned = TRUE;
44526 + FmPcdManipUpdateOwner(h_Manip, FALSE);
44527 + }
44528 + else
44529 + {
44530 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
44531 + p_Manip->reassmParams.ip.ipv6Assigned = FALSE;
44532 + }
44533 + }
44534 + else
44535 + *p_AdNewPtr = p_Manip->reassmParams.ip.h_Ipv4Ad;
44536 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
44537 + sizeof(t_AdOfTypeContLookup));
44538 + *p_AdNewPtr = NULL;
44539 + break;
44540 +#if (DPAA_VERSION >= 11)
44541 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44542 + *p_AdNewPtr = p_Manip->reassmParams.capwap.h_Ad;
44543 + memcpy((uint8_t *)p_Ad, (uint8_t *)*p_AdNewPtr,
44544 + sizeof(t_AdOfTypeContLookup));
44545 + *p_AdNewPtr = NULL;
44546 + break;
44547 +#endif /* (DPAA_VERSION >= 11) */
44548 + case (HMAN_OC):
44549 + /* Allocate and initialize HMTD */
44550 + *p_AdNewPtr = p_Manip->h_Ad;
44551 + break;
44552 + default:
44553 + break;
44554 + }
44555 +}
44556 +
44557 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad,
44558 + t_Handle *p_AdNewPtr,
44559 + uint32_t adTableOffset)
44560 +{
44561 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44562 +
44563 + /* This routine creates a Manip AD and can return in "p_AdNewPtr"
44564 + * either the new descriptor or NULL if it writes the Manip AD into p_AD (into the match table) */
44565 + ASSERT_COND(p_Manip);
44566 +
44567 + FmPcdManipUpdateOwner(h_Manip, TRUE);
44568 +
44569 + switch (p_Manip->opcode)
44570 + {
44571 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44572 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
44573 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
44574 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->ccAdBase);
44575 + WRITE_UINT32(
44576 + ((t_AdOfTypeContLookup *)p_Ad)->matchTblPtr,
44577 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->matchTblPtr);
44578 + WRITE_UINT32(
44579 + ((t_AdOfTypeContLookup *)p_Ad)->pcAndOffsets,
44580 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->pcAndOffsets);
44581 + WRITE_UINT32(((t_AdOfTypeContLookup *)p_Ad)->gmask,
44582 + ((t_AdOfTypeContLookup *)(p_Manip->h_Ad))->gmask);
44583 + WRITE_UINT32(
44584 + ((t_AdOfTypeContLookup *)p_Ad)->ccAdBase,
44585 + (GET_UINT32(((t_AdOfTypeContLookup *)p_Ad)->ccAdBase) | adTableOffset));
44586 + *p_AdNewPtr = NULL;
44587 + break;
44588 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44589 + case (HMAN_OC):
44590 + /* Initialize HMTD within the match table*/
44591 + MemSet8(p_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE);
44592 + /* copy the existing HMTD *//* ask Alla - memcpy??? */
44593 + memcpy((uint8_t*)p_Ad, p_Manip->h_Ad, sizeof(t_Hmtd));
44594 + /* update NADEN to be "1"*/
44595 + WRITE_UINT16(
44596 + ((t_Hmtd *)p_Ad)->cfg,
44597 + (uint16_t)(GET_UINT16(((t_Hmtd *)p_Ad)->cfg) | HMTD_CFG_NEXT_AD_EN));
44598 + /* update next action descriptor */
44599 + WRITE_UINT16(((t_Hmtd *)p_Ad)->nextAdIdx,
44600 + (uint16_t)(adTableOffset >> 4));
44601 + /* mark that Manip's HMTD is not used */
44602 + *p_AdNewPtr = NULL;
44603 + break;
44604 +
44605 + default:
44606 + break;
44607 + }
44608 +}
44609 +
44610 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
44611 + t_Handle h_CcTree, t_Handle h_Manip,
44612 + bool isIpv4, uint8_t groupId)
44613 +{
44614 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44615 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
44616 + t_Handle h_Scheme;
44617 +
44618 + ASSERT_COND(p_FmPcd);
44619 + ASSERT_COND(h_NetEnv);
44620 + ASSERT_COND(p_Manip);
44621 +
44622 + /* scheme was already build, no need to check for IPv6 */
44623 + if (p_Manip->reassmParams.ip.h_Ipv4Scheme)
44624 + return E_OK;
44625 +
44626 + if (isIpv4) {
44627 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[0]);
44628 + if (h_Scheme) {
44629 + /* scheme was found */
44630 + p_Manip->reassmParams.ip.h_Ipv4Scheme = h_Scheme;
44631 + return E_OK;
44632 + }
44633 + } else {
44634 + h_Scheme = FmPcdKgGetSchemeHandle(p_FmPcd, p_Manip->reassmParams.ip.relativeSchemeId[1]);
44635 + if (h_Scheme) {
44636 + /* scheme was found */
44637 + p_Manip->reassmParams.ip.h_Ipv6Scheme = h_Scheme;
44638 + return E_OK;
44639 + }
44640 + }
44641 +
44642 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
44643 + if (!p_SchemeParams)
44644 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
44645 + ("Memory allocation failed for scheme"));
44646 +
44647 + /* Configures the IPv4 or IPv6 scheme*/
44648 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
44649 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
44650 + p_SchemeParams->id.relativeSchemeId = (uint8_t)(
44651 + (isIpv4 == TRUE) ? p_Manip->reassmParams.ip.relativeSchemeId[0] :
44652 + p_Manip->reassmParams.ip.relativeSchemeId[1]);
44653 + p_SchemeParams->schemeCounter.update = TRUE;
44654 +#if (DPAA_VERSION >= 11)
44655 + p_SchemeParams->alwaysDirect = TRUE;
44656 + p_SchemeParams->bypassFqidGeneration = TRUE;
44657 +#else
44658 + p_SchemeParams->keyExtractAndHashParams.hashDistributionNumOfFqids = 1;
44659 + p_SchemeParams->baseFqid = 0xFFFFFF; /*TODO- baseFqid*/
44660 +#endif /* (DPAA_VERSION >= 11) */
44661 +
44662 + setIpReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, isIpv4, groupId);
44663 +
44664 + /* Sets the new scheme */
44665 + if (isIpv4)
44666 + p_Manip->reassmParams.ip.h_Ipv4Scheme = FM_PCD_KgSchemeSet(
44667 + p_FmPcd, p_SchemeParams);
44668 + else
44669 + p_Manip->reassmParams.ip.h_Ipv6Scheme = FM_PCD_KgSchemeSet(
44670 + p_FmPcd, p_SchemeParams);
44671 +
44672 + XX_Free(p_SchemeParams);
44673 +
44674 + return E_OK;
44675 +}
44676 +
44677 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip)
44678 +{
44679 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44680 +
44681 + ASSERT_COND(p_Manip);
44682 +
44683 + if ((p_Manip->reassmParams.ip.h_Ipv4Scheme) &&
44684 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv4Scheme))
44685 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv4Scheme);
44686 +
44687 + if ((p_Manip->reassmParams.ip.h_Ipv6Scheme) &&
44688 + !FmPcdKgIsSchemeHasOwners(p_Manip->reassmParams.ip.h_Ipv6Scheme))
44689 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.ip.h_Ipv6Scheme);
44690 +
44691 + return E_OK;
44692 +}
44693 +
44694 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip)
44695 +{
44696 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44697 +
44698 + ASSERT_COND(p_Manip);
44699 +
44700 + return (p_Manip->reassmParams.hdr == HEADER_TYPE_IPv6);
44701 +}
44702 +
44703 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv,
44704 + t_Handle h_CcTree, t_Handle h_Manip,
44705 + uint8_t groupId)
44706 +{
44707 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44708 + t_FmPcdKgSchemeParams *p_SchemeParams = NULL;
44709 +
44710 + ASSERT_COND(p_FmPcd);
44711 + ASSERT_COND(h_NetEnv);
44712 + ASSERT_COND(p_Manip);
44713 +
44714 + /* scheme was already build, no need to check for IPv6 */
44715 + if (p_Manip->reassmParams.capwap.h_Scheme)
44716 + return E_OK;
44717 +
44718 + p_SchemeParams = XX_Malloc(sizeof(t_FmPcdKgSchemeParams));
44719 + if (!p_SchemeParams)
44720 + RETURN_ERROR(MAJOR, E_NO_MEMORY,
44721 + ("Memory allocation failed for scheme"));
44722 +
44723 + memset(p_SchemeParams, 0, sizeof(t_FmPcdKgSchemeParams));
44724 + p_SchemeParams->netEnvParams.h_NetEnv = h_NetEnv;
44725 + p_SchemeParams->id.relativeSchemeId =
44726 + (uint8_t)p_Manip->reassmParams.capwap.relativeSchemeId;
44727 + p_SchemeParams->schemeCounter.update = TRUE;
44728 + p_SchemeParams->bypassFqidGeneration = TRUE;
44729 +
44730 + setCapwapReassmSchemeParams(p_FmPcd, p_SchemeParams, h_CcTree, groupId);
44731 +
44732 + p_Manip->reassmParams.capwap.h_Scheme = FM_PCD_KgSchemeSet(p_FmPcd,
44733 + p_SchemeParams);
44734 +
44735 + XX_Free(p_SchemeParams);
44736 +
44737 + return E_OK;
44738 +}
44739 +
44740 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip)
44741 +{
44742 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44743 +
44744 + ASSERT_COND(p_Manip);
44745 +
44746 + if (p_Manip->reassmParams.capwap.h_Scheme)
44747 + FM_PCD_KgSchemeDelete(p_Manip->reassmParams.capwap.h_Scheme);
44748 +
44749 + return E_OK;
44750 +}
44751 +
44752 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44753 +t_Handle FmPcdManipApplSpecificBuild(void)
44754 +{
44755 + t_FmPcdManip *p_Manip;
44756 +
44757 + p_Manip = (t_FmPcdManip*)XX_Malloc(sizeof(t_FmPcdManip));
44758 + if (!p_Manip)
44759 + {
44760 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
44761 + return NULL;
44762 + }
44763 + memset(p_Manip, 0, sizeof(t_FmPcdManip));
44764 +
44765 + p_Manip->opcode = HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX;
44766 + p_Manip->muramAllocate = FALSE;
44767 +
44768 + p_Manip->h_Ad = (t_Handle)XX_Malloc(FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
44769 + if (!p_Manip->h_Ad)
44770 + {
44771 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Allocation of Manipulation action descriptor"));
44772 + XX_Free(p_Manip);
44773 + return NULL;
44774 + }
44775 +
44776 + memset(p_Manip->h_Ad, 0, FM_PCD_CC_AD_ENTRY_SIZE * sizeof(uint8_t));
44777 +
44778 + /*treatFdStatusFieldsAsErrors = TRUE hardcoded - assumption its always come after CAAM*/
44779 + /*Application specific = type of flowId index, move internal frame header from data to IC,
44780 + SEC errors check*/
44781 + if (MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE)!= E_OK)
44782 + {
44783 + XX_Free(p_Manip->h_Ad);
44784 + XX_Free(p_Manip);
44785 + return NULL;
44786 + }
44787 + return p_Manip;
44788 +}
44789 +
44790 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip)
44791 +{
44792 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip;
44793 + ASSERT_COND(h_Manip);
44794 +
44795 + return (bool)((p_Manip->opcode == HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST) ? TRUE : FALSE);
44796 +}
44797 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44798 +/*********************** End of inter-module routines ************************/
44799 +
44800 +/****************************************/
44801 +/* API Init unit functions */
44802 +/****************************************/
44803 +
44804 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd,
44805 + t_FmPcdManipParams *p_ManipParams)
44806 +{
44807 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
44808 + t_FmPcdManip *p_Manip;
44809 + t_Error err;
44810 +
44811 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
44812 + SANITY_CHECK_RETURN_VALUE(p_ManipParams, E_INVALID_HANDLE, NULL);
44813 +
44814 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_ManipParams, FALSE);
44815 + if (!p_Manip)
44816 + return NULL;
44817 +
44818 + if (((p_Manip->opcode == HMAN_OC_IP_REASSEMBLY)
44819 + || (p_Manip->opcode == HMAN_OC_IP_FRAGMENTATION)
44820 + || (p_Manip->opcode == HMAN_OC)
44821 + || (p_Manip->opcode == HMAN_OC_IPSEC_MANIP)
44822 +#if (DPAA_VERSION >= 11)
44823 + || (p_Manip->opcode == HMAN_OC_CAPWAP_MANIP)
44824 + || (p_Manip->opcode == HMAN_OC_CAPWAP_FRAGMENTATION)
44825 + || (p_Manip->opcode == HMAN_OC_CAPWAP_REASSEMBLY)
44826 +#endif /* (DPAA_VERSION >= 11) */
44827 + ) && (!FmPcdIsAdvancedOffloadSupported(p_FmPcd)))
44828 + {
44829 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
44830 + XX_Free(p_Manip);
44831 + return NULL;
44832 + }
44833 + p_Manip->h_Spinlock = XX_InitSpinlock();
44834 + if (!p_Manip->h_Spinlock)
44835 + {
44836 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
44837 + ReleaseManipHandler(p_Manip, p_FmPcd);
44838 + XX_Free(p_Manip);
44839 + return NULL;
44840 + }INIT_LIST(&p_Manip->nodesLst);
44841 +
44842 + switch (p_Manip->opcode)
44843 + {
44844 + case (HMAN_OC_IP_REASSEMBLY):
44845 + /* IpReassembly */
44846 + err = IpReassembly(&p_ManipParams->u.reassem, p_Manip);
44847 + break;
44848 + case (HMAN_OC_IP_FRAGMENTATION):
44849 + /* IpFragmentation */
44850 + err = IpFragmentation(&p_ManipParams->u.frag.u.ipFrag, p_Manip);
44851 + if (err)
44852 + break;
44853 + err = IPManip(p_Manip);
44854 + break;
44855 + case (HMAN_OC_IPSEC_MANIP):
44856 + err = IPSecManip(p_ManipParams, p_Manip);
44857 + break;
44858 +#if (DPAA_VERSION >= 11)
44859 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44860 + /* CapwapReassembly */
44861 + err = CapwapReassembly(&p_ManipParams->u.reassem, p_Manip);
44862 + break;
44863 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44864 + /* CapwapFragmentation */
44865 + err = CapwapFragmentation(&p_ManipParams->u.frag.u.capwapFrag,
44866 + p_Manip);
44867 + break;
44868 + case (HMAN_OC_CAPWAP_MANIP):
44869 + err = CapwapManip(p_ManipParams, p_Manip);
44870 + break;
44871 +#endif /* (DPAA_VERSION >= 11) */
44872 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
44873 + case (HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR):
44874 + /* HmanType1 */
44875 + err = RmvHdrTillSpecLocNOrInsrtIntFrmHdr(&p_ManipParams->u.hdr.rmvParams, p_Manip);
44876 + break;
44877 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
44878 + err = CapwapFragmentation(&p_ManipParams->fragOrReasmParams.u.capwapFragParams,
44879 + p_Manip,
44880 + p_FmPcd,
44881 + p_ManipParams->fragOrReasmParams.sgBpid);
44882 + if (err)
44883 + {
44884 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
44885 + ReleaseManipHandler(p_Manip, p_FmPcd);
44886 + XX_Free(p_Manip);
44887 + return NULL;
44888 + }
44889 + if (p_Manip->insrt)
44890 + p_Manip->opcode = HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER;
44891 + case (HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER):
44892 + /* HmanType2 + if user asked only for fragmentation still need to allocate HmanType2 */
44893 + err = InsrtHdrByTempl(&p_ManipParams->u.hdr.insrtParams, p_Manip, p_FmPcd);
44894 + break;
44895 + case (HMAN_OC_CAPWAP_REASSEMBLY):
44896 + err = CapwapReassembly(&p_ManipParams->fragOrReasmParams.u.capwapReasmParams,
44897 + p_Manip,
44898 + p_FmPcd,
44899 + p_ManipParams->fragOrReasmParams.sgBpid);
44900 + if (err)
44901 + {
44902 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
44903 + ReleaseManipHandler(p_Manip, p_FmPcd);
44904 + XX_Free(p_Manip);
44905 + return NULL;
44906 + }
44907 + if (p_Manip->rmv)
44908 + p_Manip->opcode = HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST;
44909 + case (HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST):
44910 + /*CAPWAP decapsulation + if user asked only for reassembly still need to allocate CAPWAP decapsulation*/
44911 + err = CapwapRmvDtlsHdr(p_FmPcd, p_Manip);
44912 + break;
44913 + case (HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX):
44914 + /*Application Specific type 1*/
44915 + err = MvIntFrameHeaderFromFrameToBufferPrefix(p_Manip, TRUE);
44916 + break;
44917 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
44918 + case (HMAN_OC):
44919 + /* New Manip */
44920 + err = CreateManipActionNew(p_Manip, p_ManipParams);
44921 + break;
44922 + default:
44923 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED HEADER MANIPULATION TYPE"));
44924 + ReleaseManipHandler(p_Manip, p_FmPcd);
44925 + XX_Free(p_Manip);
44926 + return NULL;
44927 + }
44928 +
44929 + if (err)
44930 + {
44931 + REPORT_ERROR(MAJOR, err, NO_MSG);
44932 + ReleaseManipHandler(p_Manip, p_FmPcd);
44933 + XX_Free(p_Manip);
44934 + return NULL;
44935 + }
44936 +
44937 + if (p_ManipParams->h_NextManip)
44938 + {
44939 + /* in the check routine we've verified that h_NextManip has no owners
44940 + * and that only supported types are allowed. */
44941 + p_Manip->h_NextManip = p_ManipParams->h_NextManip;
44942 + /* save a "prev" pointer in h_NextManip */
44943 + MANIP_SET_PREV(p_Manip->h_NextManip, p_Manip);
44944 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, TRUE);
44945 + }
44946 +
44947 + return p_Manip;
44948 +}
44949 +
44950 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_Manip,
44951 + t_FmPcdManipParams *p_ManipParams)
44952 +{
44953 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_Manip, *p_FirstManip;
44954 + t_FmPcd *p_FmPcd = (t_FmPcd *)(p_Manip->h_FmPcd);
44955 + t_Error err;
44956 + uint8_t *p_WholeHmct = NULL, *p_ShadowHmct = NULL, *p_Hmtd = NULL;
44957 + t_List lstOfNodeshichPointsOnCrntMdfManip, *p_Pos;
44958 + t_CcNodeInformation *p_CcNodeInfo;
44959 + SANITY_CHECK_RETURN_ERROR(h_Manip, E_INVALID_HANDLE);
44960 + SANITY_CHECK_RETURN_ERROR(p_ManipParams, E_INVALID_HANDLE);
44961 +
44962 + INIT_LIST(&lstOfNodeshichPointsOnCrntMdfManip);
44963 +
44964 + if ((p_ManipParams->type != e_FM_PCD_MANIP_HDR)
44965 + || (p_Manip->type != e_FM_PCD_MANIP_HDR))
44966 + RETURN_ERROR(
44967 + MINOR,
44968 + E_NOT_SUPPORTED,
44969 + ("FM_PCD_ManipNodeReplace Functionality supported only for Header Manipulation."));
44970 +
44971 + ASSERT_COND(p_Manip->opcode == HMAN_OC);
44972 + ASSERT_COND(p_Manip->manipParams.h_NextManip == p_Manip->h_NextManip);
44973 + memcpy((uint8_t*)&p_Manip->manipParams, p_ManipParams,
44974 + sizeof(p_Manip->manipParams));
44975 + p_Manip->manipParams.h_NextManip = p_Manip->h_NextManip;
44976 +
44977 + /* The replacement of the HdrManip depends on the node type.*/
44978 + /*
44979 + * (1) If this is an independent node, all its owners should be updated.
44980 + *
44981 + * (2) If it is the head of a cascaded chain (it does not have a "prev" but
44982 + * it has a "next" and it has a "cascaded" indication), the next
44983 + * node remains unchanged, and the behavior is as in (1).
44984 + *
44985 + * (3) If it is not the head, but a part of a cascaded chain, in can be
44986 + * also replaced as a regular node with just one owner.
44987 + *
44988 + * (4) If it is a part of a chain implemented as a unified table, the
44989 + * whole table is replaced and the owners of the head node must be updated.
44990 + *
44991 + */
44992 + /* lock shadow */
44993 + if (!p_FmPcd->p_CcShadow)
44994 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("CC Shadow not allocated"));
44995 +
44996 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
44997 + return ERROR_CODE(E_BUSY);
44998 +
44999 + /* this routine creates a new manip action in the CC Shadow. */
45000 + err = CreateManipActionShadow(p_Manip, p_ManipParams);
45001 + if (err)
45002 + RETURN_ERROR(MINOR, err, NO_MSG);
45003 +
45004 + /* If the owners list is empty (these are NOT the "owners" counter, but pointers from CC)
45005 + * replace only HMTD and no lcok is required. Otherwise
45006 + * lock the whole PCD
45007 + * In case 4 MANIP_IS_UNIFIED_NON_FIRST(p_Manip) - Use the head node instead. */
45008 + if (!FmPcdLockTryLockAll(p_FmPcd))
45009 + {
45010 + DBG(TRACE, ("FmPcdLockTryLockAll failed"));
45011 + return ERROR_CODE(E_BUSY);
45012 + }
45013 +
45014 + p_ShadowHmct = (uint8_t*)PTR_MOVE(p_FmPcd->p_CcShadow, 16);
45015 +
45016 + p_FirstManip = (t_FmPcdManip*)GetManipInfo(p_Manip,
45017 + e_MANIP_HANDLER_TABLE_OWNER);
45018 + ASSERT_COND(p_FirstManip);
45019 +
45020 + if (!LIST_IsEmpty(&p_FirstManip->nodesLst))
45021 + UpdateAdPtrOfNodesWhichPointsOnCrntMdfManip(
45022 + p_FirstManip, &lstOfNodeshichPointsOnCrntMdfManip);
45023 +
45024 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
45025 + ASSERT_COND(p_Hmtd);
45026 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_ShadowHmct,
45027 + ((t_FmPcd*)(p_Manip->h_FmPcd)));
45028 +
45029 + LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
45030 + {
45031 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
45032 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
45033 + p_ShadowHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
45034 + }
45035 +
45036 + p_WholeHmct = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMCT);
45037 + ASSERT_COND(p_WholeHmct);
45038 +
45039 + /* re-build the HMCT n the original location */
45040 + err = CreateManipActionBackToOrig(p_Manip, p_ManipParams);
45041 + if (err)
45042 + {
45043 + RELEASE_LOCK(p_FmPcd->shadowLock);
45044 + RETURN_ERROR(MINOR, err, NO_MSG);
45045 + }
45046 +
45047 + p_Hmtd = (uint8_t *)GetManipInfo(p_Manip, e_MANIP_HMTD);
45048 + ASSERT_COND(p_Hmtd);
45049 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_Hmtd, p_WholeHmct,
45050 + ((t_FmPcd*)p_Manip->h_FmPcd));
45051 +
45052 + /* If LIST > 0, create a list of p_Ad's that point to the HMCT. Join also t_HMTD to this list.
45053 + * For each p_Hmct (from list+fixed):
45054 + * call Host Command to replace HMTD by a new one */LIST_FOR_EACH(p_Pos, &lstOfNodeshichPointsOnCrntMdfManip)
45055 + {
45056 + p_CcNodeInfo = CC_NODE_F_OBJECT(p_Pos);
45057 + BuildHmtd(p_FmPcd->p_CcShadow, (uint8_t *)p_CcNodeInfo->h_CcNode,
45058 + p_WholeHmct, ((t_FmPcd*)(p_Manip->h_FmPcd)));
45059 + }
45060 +
45061 +
45062 + ReleaseLst(&lstOfNodeshichPointsOnCrntMdfManip);
45063 +
45064 + FmPcdLockUnlockAll(p_FmPcd);
45065 +
45066 + /* unlock shadow */
45067 + RELEASE_LOCK(p_FmPcd->shadowLock);
45068 +
45069 + return E_OK;
45070 +}
45071 +
45072 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode)
45073 +{
45074 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
45075 +
45076 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
45077 +
45078 + if (p_Manip->owner)
45079 + RETURN_ERROR(
45080 + MAJOR,
45081 + E_INVALID_STATE,
45082 + ("This manipulation node not be removed because this node is occupied, first - unbind this node "));
45083 +
45084 + if (p_Manip->h_NextManip)
45085 + {
45086 + MANIP_SET_PREV(p_Manip->h_NextManip, NULL);
45087 + FmPcdManipUpdateOwner(p_Manip->h_NextManip, FALSE);
45088 + }
45089 +
45090 + if (p_Manip->p_Hmct
45091 + && (MANIP_IS_UNIFIED_FIRST(p_Manip) || !MANIP_IS_UNIFIED(p_Manip)))
45092 + FM_MURAM_FreeMem(((t_FmPcd *)p_Manip->h_FmPcd)->h_FmMuram,
45093 + p_Manip->p_Hmct);
45094 +
45095 + if (p_Manip->h_Spinlock)
45096 + {
45097 + XX_FreeSpinlock(p_Manip->h_Spinlock);
45098 + p_Manip->h_Spinlock = NULL;
45099 + }
45100 +
45101 + ReleaseManipHandler(p_Manip, p_Manip->h_FmPcd);
45102 +
45103 + XX_Free(h_ManipNode);
45104 +
45105 + return E_OK;
45106 +}
45107 +
45108 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode,
45109 + t_FmPcdManipStats *p_FmPcdManipStats)
45110 +{
45111 + t_FmPcdManip *p_Manip = (t_FmPcdManip *)h_ManipNode;
45112 +
45113 + SANITY_CHECK_RETURN_ERROR(p_Manip, E_INVALID_HANDLE);
45114 + SANITY_CHECK_RETURN_ERROR(p_FmPcdManipStats, E_NULL_POINTER);
45115 +
45116 + switch (p_Manip->opcode)
45117 + {
45118 + case (HMAN_OC_IP_REASSEMBLY):
45119 + return IpReassemblyStats(p_Manip,
45120 + &p_FmPcdManipStats->u.reassem.u.ipReassem);
45121 + case (HMAN_OC_IP_FRAGMENTATION):
45122 + return IpFragmentationStats(p_Manip,
45123 + &p_FmPcdManipStats->u.frag.u.ipFrag);
45124 +#if (DPAA_VERSION >= 11)
45125 + case (HMAN_OC_CAPWAP_REASSEMBLY):
45126 + return CapwapReassemblyStats(
45127 + p_Manip, &p_FmPcdManipStats->u.reassem.u.capwapReassem);
45128 + case (HMAN_OC_CAPWAP_FRAGMENTATION):
45129 + return CapwapFragmentationStats(
45130 + p_Manip, &p_FmPcdManipStats->u.frag.u.capwapFrag);
45131 +#endif /* (DPAA_VERSION >= 11) */
45132 + default:
45133 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
45134 + ("no statistics to this type of manip"));
45135 + }
45136 +
45137 + return E_OK;
45138 +}
45139 +
45140 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45141 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_StatsParams)
45142 +{
45143 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
45144 + t_FmPcdManip *p_Manip;
45145 + t_Error err;
45146 +
45147 + SANITY_CHECK_RETURN_VALUE(h_FmPcd,E_INVALID_HANDLE,NULL);
45148 + SANITY_CHECK_RETURN_VALUE(p_StatsParams,E_INVALID_HANDLE,NULL);
45149 +
45150 + p_Manip = ManipOrStatsSetNode(h_FmPcd, (t_Handle)p_StatsParams, TRUE);
45151 + if (!p_Manip)
45152 + return NULL;
45153 +
45154 + switch (p_Manip->opcode)
45155 + {
45156 + case (HMAN_OC_CAPWAP_INDEXED_STATS):
45157 + /* Indexed statistics */
45158 + err = IndxStats(p_StatsParams, p_Manip, p_FmPcd);
45159 + break;
45160 + default:
45161 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("UNSUPPORTED Statistics type"));
45162 + ReleaseManipHandler(p_Manip, p_FmPcd);
45163 + XX_Free(p_Manip);
45164 + return NULL;
45165 + }
45166 +
45167 + if (err)
45168 + {
45169 + REPORT_ERROR(MAJOR, err, NO_MSG);
45170 + ReleaseManipHandler(p_Manip, p_FmPcd);
45171 + XX_Free(p_Manip);
45172 + return NULL;
45173 + }
45174 +
45175 + return p_Manip;
45176 +}
45177 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45178 --- /dev/null
45179 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_manip.h
45180 @@ -0,0 +1,555 @@
45181 +/*
45182 + * Copyright 2008-2012 Freescale Semiconductor Inc.
45183 + *
45184 + * Redistribution and use in source and binary forms, with or without
45185 + * modification, are permitted provided that the following conditions are met:
45186 + * * Redistributions of source code must retain the above copyright
45187 + * notice, this list of conditions and the following disclaimer.
45188 + * * Redistributions in binary form must reproduce the above copyright
45189 + * notice, this list of conditions and the following disclaimer in the
45190 + * documentation and/or other materials provided with the distribution.
45191 + * * Neither the name of Freescale Semiconductor nor the
45192 + * names of its contributors may be used to endorse or promote products
45193 + * derived from this software without specific prior written permission.
45194 + *
45195 + *
45196 + * ALTERNATIVELY, this software may be distributed under the terms of the
45197 + * GNU General Public License ("GPL") as published by the Free Software
45198 + * Foundation, either version 2 of that License or (at your option) any
45199 + * later version.
45200 + *
45201 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
45202 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45203 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45204 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
45205 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45206 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45207 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45208 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45209 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45210 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45211 + */
45212 +
45213 +
45214 +/******************************************************************************
45215 + @File fm_manip.h
45216 +
45217 + @Description FM PCD manip...
45218 +*//***************************************************************************/
45219 +#ifndef __FM_MANIP_H
45220 +#define __FM_MANIP_H
45221 +
45222 +#include "std_ext.h"
45223 +#include "error_ext.h"
45224 +#include "list_ext.h"
45225 +
45226 +#include "fm_cc.h"
45227 +
45228 +
45229 +/***********************************************************************/
45230 +/* Header manipulations defines */
45231 +/***********************************************************************/
45232 +
45233 +#define NUM_OF_SCRATCH_POOL_BUFFERS 1000 /*TODO - Change it!!*/
45234 +
45235 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45236 +#define HMAN_OC_RMV_N_OR_INSRT_INT_FRM_HDR 0x2e
45237 +#define HMAN_OC_INSRT_HDR_BY_TEMPL_N_OR_FRAG_AFTER 0x31
45238 +#define HMAN_OC_MV_INT_FRAME_HDR_FROM_FRM_TO_BUFFER_PREFFIX 0x2f
45239 +#define HMAN_OC_CAPWAP_RMV_DTLS_IF_EXIST 0x30
45240 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x11 /* dummy */
45241 +#define HMAN_OC_CAPWAP_INDEXED_STATS 0x32 /* dummy */
45242 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
45243 +#else
45244 +#define HMAN_OC_CAPWAP_MANIP 0x2F
45245 +#define HMAN_OC_CAPWAP_FRAG_CHECK 0x2E
45246 +#define HMAN_OC_CAPWAP_FRAGMENTATION 0x33
45247 +#define HMAN_OC_CAPWAP_REASSEMBLY 0x30
45248 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45249 +#define HMAN_OC_IP_MANIP 0x34
45250 +#define HMAN_OC_IP_FRAGMENTATION 0x74
45251 +#define HMAN_OC_IP_REASSEMBLY 0xB4
45252 +#define HMAN_OC_IPSEC_MANIP 0xF4
45253 +#define HMAN_OC 0x35
45254 +
45255 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45256 +#define HMAN_RMV_HDR 0x80000000
45257 +#define HMAN_INSRT_INT_FRM_HDR 0x40000000
45258 +
45259 +#define UDP_CHECKSUM_FIELD_OFFSET_FROM_UDP 6
45260 +#define UDP_CHECKSUM_FIELD_SIZE 2
45261 +#define UDP_LENGTH_FIELD_OFFSET_FROM_UDP 4
45262 +
45263 +#define IPv4_DSCECN_FIELD_OFFSET_FROM_IP 1
45264 +#define IPv4_TOTALLENGTH_FIELD_OFFSET_FROM_IP 2
45265 +#define IPv4_HDRCHECKSUM_FIELD_OFFSET_FROM_IP 10
45266 +#define VLAN_TAG_FIELD_OFFSET_FROM_ETH 12
45267 +#define IPv4_ID_FIELD_OFFSET_FROM_IP 4
45268 +
45269 +#define IPv6_PAYLOAD_LENGTH_OFFSET_FROM_IP 4
45270 +#define IPv6_NEXT_HEADER_OFFSET_FROM_IP 6
45271 +
45272 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_SIZE 0x80
45273 +#define FM_PCD_MANIP_CAPWAP_REASM_TABLE_ALIGN 8
45274 +#define FM_PCD_MANIP_CAPWAP_REASM_RFD_SIZE 32
45275 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTO_LEARNING_HASH_ENTRY_SIZE 4
45276 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_ENTRY_SIZE 8
45277 +
45278 +
45279 +#define FM_PCD_MANIP_CAPWAP_REASM_TIME_OUT_BETWEEN_FRAMES 0x40000000
45280 +#define FM_PCD_MANIP_CAPWAP_REASM_HALT_ON_DUPLICATE_FRAG 0x10000000
45281 +#define FM_PCD_MANIP_CAPWAP_REASM_AUTOMATIC_LEARNIN_HASH_8_WAYS 0x08000000
45282 +#define FM_PCD_MANIP_CAPWAP_REASM_PR_COPY 0x00800000
45283 +
45284 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPR_OPTION_FIELD_EN 0x80000000
45285 +
45286 +#define FM_PCD_MANIP_INDEXED_STATS_ENTRY_SIZE 4
45287 +#define FM_PCD_MANIP_INDEXED_STATS_CNIA 0x20000000
45288 +#define FM_PCD_MANIP_INDEXED_STATS_DPD 0x10000000
45289 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45290 +
45291 +#if (DPAA_VERSION >= 11)
45292 +#define FM_PCD_MANIP_CAPWAP_DTLS 0x00040000
45293 +#define FM_PCD_MANIP_CAPWAP_NADEN 0x20000000
45294 +
45295 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_MTU_SHIFT 16
45296 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_NO_FRAGMENTATION 0xFFFF0000
45297 +#define FM_PCD_MANIP_CAPWAP_FRAG_CHECK_CNIA 0x20000000
45298 +
45299 +#define FM_PCD_MANIP_CAPWAP_FRAG_COMPRESS_EN 0x04000000
45300 +#define FM_PCD_MANIP_CAPWAP_FRAG_SCRATCH_BPID 24
45301 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_EN 0x08000000
45302 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_MASK 0xFF000000
45303 +#define FM_PCD_MANIP_CAPWAP_FRAG_SG_BDID_SHIFT 24
45304 +#endif /* (DPAA_VERSION >= 11) */
45305 +
45306 +#define FM_PCD_MANIP_REASM_TABLE_SIZE 0x40
45307 +#define FM_PCD_MANIP_REASM_TABLE_ALIGN 8
45308 +
45309 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_SIZE 64
45310 +#define FM_PCD_MANIP_REASM_COMMON_PARAM_TABLE_ALIGN 8
45311 +#define FM_PCD_MANIP_REASM_TIME_OUT_BETWEEN_FRAMES 0x80000000
45312 +#define FM_PCD_MANIP_REASM_COUPLING_ENABLE 0x40000000
45313 +#define FM_PCD_MANIP_REASM_COUPLING_MASK 0xFF000000
45314 +#define FM_PCD_MANIP_REASM_COUPLING_SHIFT 24
45315 +#define FM_PCD_MANIP_REASM_LIODN_MASK 0x0000003F
45316 +#define FM_PCD_MANIP_REASM_LIODN_SHIFT 56
45317 +#define FM_PCD_MANIP_REASM_ELIODN_MASK 0x000003c0
45318 +#define FM_PCD_MANIP_REASM_ELIODN_SHIFT 38
45319 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_MASK 0x000000FF
45320 +#define FM_PCD_MANIP_REASM_COMMON_INT_BUFFER_IDX_SHIFT 24
45321 +#define FM_PCD_MANIP_REASM_TIMEOUT_THREAD_THRESH 1024
45322 +
45323 +#define FM_PCD_MANIP_IP_MTU_SHIFT 16
45324 +#define FM_PCD_MANIP_IP_NO_FRAGMENTATION 0xFFFF0000
45325 +#define FM_PCD_MANIP_IP_CNIA 0x20000000
45326 +
45327 +#define FM_PCD_MANIP_IP_FRAG_DF_SHIFT 28
45328 +#define FM_PCD_MANIP_IP_FRAG_SCRATCH_BPID 24
45329 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_EN 0x08000000
45330 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_MASK 0xFF000000
45331 +#define FM_PCD_MANIP_IP_FRAG_SG_BDID_SHIFT 24
45332 +
45333 +#define FM_PCD_MANIP_IPSEC_DEC 0x10000000
45334 +#define FM_PCD_MANIP_IPSEC_VIPV_EN 0x08000000
45335 +#define FM_PCD_MANIP_IPSEC_ECN_EN 0x04000000
45336 +#define FM_PCD_MANIP_IPSEC_DSCP_EN 0x02000000
45337 +#define FM_PCD_MANIP_IPSEC_VIPL_EN 0x01000000
45338 +#define FM_PCD_MANIP_IPSEC_NADEN 0x20000000
45339 +
45340 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_MASK 0x00FF0000
45341 +#define FM_PCD_MANIP_IPSEC_IP_HDR_LEN_SHIFT 16
45342 +
45343 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_MASK 0xFFFF0000
45344 +#define FM_PCD_MANIP_IPSEC_ARW_SIZE_SHIFT 16
45345 +
45346 +#define e_FM_MANIP_IP_INDX 1
45347 +
45348 +#define HMCD_OPCODE_GENERIC_RMV 0x01
45349 +#define HMCD_OPCODE_GENERIC_INSRT 0x02
45350 +#define HMCD_OPCODE_GENERIC_REPLACE 0x05
45351 +#define HMCD_OPCODE_L2_RMV 0x08
45352 +#define HMCD_OPCODE_L2_INSRT 0x09
45353 +#define HMCD_OPCODE_VLAN_PRI_UPDATE 0x0B
45354 +#define HMCD_OPCODE_IPV4_UPDATE 0x0C
45355 +#define HMCD_OPCODE_IPV6_UPDATE 0x10
45356 +#define HMCD_OPCODE_TCP_UDP_UPDATE 0x0E
45357 +#define HMCD_OPCODE_TCP_UDP_CHECKSUM 0x14
45358 +#define HMCD_OPCODE_REPLACE_IP 0x12
45359 +#define HMCD_OPCODE_RMV_TILL 0x15
45360 +#define HMCD_OPCODE_UDP_INSRT 0x16
45361 +#define HMCD_OPCODE_IP_INSRT 0x17
45362 +#define HMCD_OPCODE_CAPWAP_RMV 0x18
45363 +#define HMCD_OPCODE_CAPWAP_INSRT 0x18
45364 +#define HMCD_OPCODE_GEN_FIELD_REPLACE 0x19
45365 +
45366 +#define HMCD_LAST 0x00800000
45367 +
45368 +#define HMCD_DSCP_VALUES 64
45369 +
45370 +#define HMCD_BASIC_SIZE 4
45371 +#define HMCD_PTR_SIZE 4
45372 +#define HMCD_PARAM_SIZE 4
45373 +#define HMCD_IPV4_ADDR_SIZE 4
45374 +#define HMCD_IPV6_ADDR_SIZE 0x10
45375 +#define HMCD_L4_HDR_SIZE 8
45376 +
45377 +#define HMCD_CAPWAP_INSRT 0x00010000
45378 +#define HMCD_INSRT_UDP_LITE 0x00010000
45379 +#define HMCD_IP_ID_MASK 0x0000FFFF
45380 +#define HMCD_IP_SIZE_MASK 0x0000FF00
45381 +#define HMCD_IP_SIZE_SHIFT 8
45382 +#define HMCD_IP_LAST_PID_MASK 0x000000FF
45383 +#define HMCD_IP_OR_QOS 0x00010000
45384 +#define HMCD_IP_L4_CS_CALC 0x00040000
45385 +#define HMCD_IP_DF_MODE 0x00400000
45386 +
45387 +
45388 +#define HMCD_OC_SHIFT 24
45389 +
45390 +#define HMCD_RMV_OFFSET_SHIFT 0
45391 +#define HMCD_RMV_SIZE_SHIFT 8
45392 +
45393 +#define HMCD_INSRT_OFFSET_SHIFT 0
45394 +#define HMCD_INSRT_SIZE_SHIFT 8
45395 +
45396 +#define HMTD_CFG_TYPE 0x4000
45397 +#define HMTD_CFG_EXT_HMCT 0x0080
45398 +#define HMTD_CFG_PRS_AFTER_HM 0x0040
45399 +#define HMTD_CFG_NEXT_AD_EN 0x0020
45400 +
45401 +#define HMCD_RMV_L2_ETHERNET 0
45402 +#define HMCD_RMV_L2_STACKED_QTAGS 1
45403 +#define HMCD_RMV_L2_ETHERNET_AND_MPLS 2
45404 +#define HMCD_RMV_L2_MPLS 3
45405 +#define HMCD_RMV_L2_PPPOE 4
45406 +
45407 +#define HMCD_INSRT_L2_MPLS 0
45408 +#define HMCD_INSRT_N_UPDATE_L2_MPLS 1
45409 +#define HMCD_INSRT_L2_PPPOE 2
45410 +#define HMCD_INSRT_L2_SIZE_SHIFT 24
45411 +
45412 +#define HMCD_L2_MODE_SHIFT 16
45413 +
45414 +#define HMCD_VLAN_PRI_REP_MODE_SHIFT 16
45415 +#define HMCD_VLAN_PRI_UPDATE 0
45416 +#define HMCD_VLAN_PRI_UPDATE_DSCP_TO_VPRI 1
45417 +
45418 +#define HMCD_IPV4_UPDATE_TTL 0x00000001
45419 +#define HMCD_IPV4_UPDATE_TOS 0x00000002
45420 +#define HMCD_IPV4_UPDATE_DST 0x00000020
45421 +#define HMCD_IPV4_UPDATE_SRC 0x00000040
45422 +#define HMCD_IPV4_UPDATE_ID 0x00000080
45423 +#define HMCD_IPV4_UPDATE_TOS_SHIFT 8
45424 +
45425 +#define HMCD_IPV6_UPDATE_HL 0x00000001
45426 +#define HMCD_IPV6_UPDATE_TC 0x00000002
45427 +#define HMCD_IPV6_UPDATE_DST 0x00000040
45428 +#define HMCD_IPV6_UPDATE_SRC 0x00000080
45429 +#define HMCD_IPV6_UPDATE_TC_SHIFT 8
45430 +
45431 +#define HMCD_TCP_UDP_UPDATE_DST 0x00004000
45432 +#define HMCD_TCP_UDP_UPDATE_SRC 0x00008000
45433 +#define HMCD_TCP_UDP_UPDATE_SRC_SHIFT 16
45434 +
45435 +#define HMCD_IP_REPLACE_REPLACE_IPV4 0x00000000
45436 +#define HMCD_IP_REPLACE_REPLACE_IPV6 0x00010000
45437 +#define HMCD_IP_REPLACE_TTL_HL 0x00200000
45438 +#define HMCD_IP_REPLACE_ID 0x00400000
45439 +
45440 +#define HMCD_IP_REPLACE_L3HDRSIZE_SHIFT 24
45441 +
45442 +#define HMCD_GEN_FIELD_SIZE_SHIFT 16
45443 +#define HMCD_GEN_FIELD_SRC_OFF_SHIFT 8
45444 +#define HMCD_GEN_FIELD_DST_OFF_SHIFT 0
45445 +#define HMCD_GEN_FIELD_MASK_EN 0x00400000
45446 +
45447 +#define HMCD_GEN_FIELD_MASK_OFF_SHIFT 16
45448 +#define HMCD_GEN_FIELD_MASK_SHIFT 24
45449 +
45450 +#define DSCP_TO_VLAN_TABLE_SIZE 32
45451 +
45452 +#define MANIP_GET_HMCT_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->tableSize)
45453 +#define MANIP_GET_DATA_SIZE(h_Manip) (((t_FmPcdManip *)h_Manip)->dataSize)
45454 +
45455 +#define MANIP_GET_HMCT_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Hmct)
45456 +#define MANIP_GET_DATA_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->p_Data)
45457 +
45458 +#define MANIP_SET_HMCT_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Hmct = h_NewPtr)
45459 +#define MANIP_SET_DATA_PTR(h_Manip, h_NewPtr) (((t_FmPcdManip *)h_Manip)->p_Data = h_NewPtr)
45460 +
45461 +#define MANIP_GET_HMTD_PTR(h_Manip) (((t_FmPcdManip *)h_Manip)->h_Ad)
45462 +#define MANIP_DONT_REPARSE(h_Manip) (((t_FmPcdManip *)h_Manip)->dontParseAfterManip)
45463 +#define MANIP_SET_PREV(h_Manip, h_Prev) (((t_FmPcdManip *)h_Manip)->h_PrevManip = h_Prev)
45464 +#define MANIP_GET_OWNERS(h_Manip) (((t_FmPcdManip *)h_Manip)->owner)
45465 +#define MANIP_GET_TYPE(h_Manip) (((t_FmPcdManip *)h_Manip)->type)
45466 +#define MANIP_SET_UNIFIED_TBL_PTR_INDICATION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedTablePtr = TRUE)
45467 +#define MANIP_GET_MURAM(h_Manip) (((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram)
45468 +#define MANIP_FREE_HMTD(h_Manip) \
45469 + {if (((t_FmPcdManip *)h_Manip)->muramAllocate) \
45470 + FM_MURAM_FreeMem(((t_FmPcd *)((t_FmPcdManip *)h_Manip)->h_FmPcd)->h_FmMuram, ((t_FmPcdManip *)h_Manip)->h_Ad);\
45471 + else \
45472 + XX_Free(((t_FmPcdManip *)h_Manip)->h_Ad); \
45473 + ((t_FmPcdManip *)h_Manip)->h_Ad = NULL; \
45474 + }
45475 +/* position regarding Manip SW structure */
45476 +#define MANIP_IS_FIRST(h_Manip) (!(((t_FmPcdManip *)h_Manip)->h_PrevManip))
45477 +#define MANIP_IS_CASCADED(h_Manip) (((t_FmPcdManip *)h_Manip)->cascaded)
45478 +#define MANIP_IS_UNIFIED(h_Manip) (!(((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE))
45479 +#define MANIP_IS_UNIFIED_NON_FIRST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID) || \
45480 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST))
45481 +#define MANIP_IS_UNIFIED_NON_LAST(h_Manip) ((((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST) ||\
45482 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_MID))
45483 +#define MANIP_IS_UNIFIED_FIRST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_FIRST)
45484 +#define MANIP_IS_UNIFIED_LAST(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_LAST)
45485 +
45486 +#define MANIP_UPDATE_UNIFIED_POSITION(h_Manip) (((t_FmPcdManip *)h_Manip)->unifiedPosition = \
45487 + (((t_FmPcdManip *)h_Manip)->unifiedPosition == e_MANIP_UNIFIED_NONE)? \
45488 + e_MANIP_UNIFIED_LAST : e_MANIP_UNIFIED_MID)
45489 +
45490 +typedef enum e_ManipUnifiedPosition {
45491 + e_MANIP_UNIFIED_NONE = 0,
45492 + e_MANIP_UNIFIED_FIRST,
45493 + e_MANIP_UNIFIED_MID,
45494 + e_MANIP_UNIFIED_LAST
45495 +} e_ManipUnifiedPosition;
45496 +
45497 +typedef enum e_ManipInfo {
45498 + e_MANIP_HMTD,
45499 + e_MANIP_HMCT,
45500 + e_MANIP_HANDLER_TABLE_OWNER
45501 +}e_ManipInfo;
45502 +/***********************************************************************/
45503 +/* Memory map */
45504 +/***********************************************************************/
45505 +#if defined(__MWERKS__) && !defined(__GNUC__)
45506 +#pragma pack(push,1)
45507 +#endif /* defined(__MWERKS__) && ... */
45508 +
45509 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45510 +typedef struct t_CapwapReasmPram {
45511 + volatile uint32_t mode;
45512 + volatile uint32_t autoLearnHashTblPtr;
45513 + volatile uint32_t intStatsTblPtr;
45514 + volatile uint32_t reasmFrmDescPoolTblPtr;
45515 + volatile uint32_t reasmFrmDescIndexPoolTblPtr;
45516 + volatile uint32_t timeOutTblPtr;
45517 + volatile uint32_t bufferPoolIdAndRisc1SetIndexes;
45518 + volatile uint32_t risc23SetIndexes;
45519 + volatile uint32_t risc4SetIndexesAndExtendedStatsTblPtr;
45520 + volatile uint32_t extendedStatsTblPtr;
45521 + volatile uint32_t expirationDelay;
45522 + volatile uint32_t totalProcessedFragCounter;
45523 + volatile uint32_t totalUnsuccessfulReasmFramesCounter;
45524 + volatile uint32_t totalDuplicatedFragCounter;
45525 + volatile uint32_t totalMalformdFragCounter;
45526 + volatile uint32_t totalTimeOutCounter;
45527 + volatile uint32_t totalSetBusyCounter;
45528 + volatile uint32_t totalRfdPoolBusyCounter;
45529 + volatile uint32_t totalDiscardedFragsCounter;
45530 + volatile uint32_t totalMoreThan16FramesCounter;
45531 + volatile uint32_t internalBufferBusy;
45532 + volatile uint32_t externalBufferBusy;
45533 + volatile uint32_t reserved1[4];
45534 +} t_CapwapReasmPram;
45535 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45536 +
45537 +typedef _Packed struct t_ReassTbl {
45538 + volatile uint16_t waysNumAndSetSize;
45539 + volatile uint16_t autoLearnHashKeyMask;
45540 + volatile uint32_t reassCommonPrmTblPtr;
45541 + volatile uint32_t liodnAlAndAutoLearnHashTblPtrHi;
45542 + volatile uint32_t autoLearnHashTblPtrLow;
45543 + volatile uint32_t liodnSlAndAutoLearnSetLockTblPtrHi;
45544 + volatile uint32_t autoLearnSetLockTblPtrLow;
45545 + volatile uint16_t minFragSize; /* Not relevant for CAPWAP*/
45546 + volatile uint16_t maxReassemblySize; /* Only relevant for CAPWAP*/
45547 + volatile uint32_t totalSuccessfullyReasmFramesCounter;
45548 + volatile uint32_t totalValidFragmentCounter;
45549 + volatile uint32_t totalProcessedFragCounter;
45550 + volatile uint32_t totalMalformdFragCounter;
45551 + volatile uint32_t totalSetBusyCounter;
45552 + volatile uint32_t totalDiscardedFragsCounter;
45553 + volatile uint32_t totalMoreThan16FramesCounter;
45554 + volatile uint32_t reserved2[2];
45555 +} _PackedType t_ReassTbl;
45556 +
45557 +typedef struct t_ReassCommonTbl {
45558 + volatile uint32_t timeoutModeAndFqid;
45559 + volatile uint32_t reassFrmDescIndexPoolTblPtr;
45560 + volatile uint32_t liodnAndReassFrmDescPoolPtrHi;
45561 + volatile uint32_t reassFrmDescPoolPtrLow;
45562 + volatile uint32_t timeOutTblPtr;
45563 + volatile uint32_t expirationDelay;
45564 + volatile uint32_t internalBufferManagement;
45565 + volatile uint32_t reserved2;
45566 + volatile uint32_t totalTimeOutCounter;
45567 + volatile uint32_t totalRfdPoolBusyCounter;
45568 + volatile uint32_t totalInternalBufferBusy;
45569 + volatile uint32_t totalExternalBufferBusy;
45570 + volatile uint32_t totalSgFragmentCounter;
45571 + volatile uint32_t totalDmaSemaphoreDepletionCounter;
45572 + volatile uint32_t totalNCSPCounter;
45573 + volatile uint32_t discardMask;
45574 +} t_ReassCommonTbl;
45575 +
45576 +typedef _Packed struct t_Hmtd {
45577 + volatile uint16_t cfg;
45578 + volatile uint8_t eliodnOffset;
45579 + volatile uint8_t extHmcdBasePtrHi;
45580 + volatile uint32_t hmcdBasePtr;
45581 + volatile uint16_t nextAdIdx;
45582 + volatile uint8_t res1;
45583 + volatile uint8_t opCode;
45584 + volatile uint32_t res2;
45585 +} _PackedType t_Hmtd;
45586 +
45587 +#if defined(__MWERKS__) && !defined(__GNUC__)
45588 +#pragma pack(pop)
45589 +#endif /* defined(__MWERKS__) && ... */
45590 +
45591 +
45592 +/***********************************************************************/
45593 +/* Driver's internal structures */
45594 +/***********************************************************************/
45595 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45596 +typedef struct
45597 +{
45598 + t_Handle p_AutoLearnHashTbl;
45599 + t_Handle p_ReassmFrmDescrPoolTbl;
45600 + t_Handle p_ReassmFrmDescrIndxPoolTbl;
45601 + t_Handle p_TimeOutTbl;
45602 + uint16_t maxNumFramesInProcess;
45603 + uint8_t numOfTasks;
45604 + //uint8_t poolId;
45605 + uint8_t prOffset;
45606 + uint16_t dataOffset;
45607 + uint8_t sgBpid;
45608 + uint8_t hwPortId;
45609 + uint32_t fqidForTimeOutFrames;
45610 + uint32_t timeoutRoutineRequestTime;
45611 + uint32_t bitFor1Micro;
45612 +} t_CapwapFragParams;
45613 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45614 +
45615 +typedef struct
45616 +{
45617 + t_AdOfTypeContLookup *p_Frag;
45618 +#if (DPAA_VERSION == 10)
45619 + uint8_t scratchBpid;
45620 +#endif /* (DPAA_VERSION == 10) */
45621 +} t_FragParams;
45622 +
45623 +typedef struct t_ReassmParams
45624 +{
45625 + e_NetHeaderType hdr; /* Header selection */
45626 + t_ReassCommonTbl *p_ReassCommonTbl;
45627 + uintptr_t reassFrmDescrIndxPoolTblAddr;
45628 + uintptr_t reassFrmDescrPoolTblAddr;
45629 + uintptr_t timeOutTblAddr;
45630 + uintptr_t internalBufferPoolManagementIndexAddr;
45631 + uintptr_t internalBufferPoolAddr;
45632 + uint32_t maxNumFramesInProcess;
45633 + uint8_t sgBpid;
45634 + uint8_t dataMemId;
45635 + uint16_t dataLiodnOffset;
45636 + uint32_t fqidForTimeOutFrames;
45637 + e_FmPcdManipReassemTimeOutMode timeOutMode;
45638 + uint32_t timeoutThresholdForReassmProcess;
45639 + union {
45640 + struct {
45641 + t_Handle h_Ipv4Ad;
45642 + t_Handle h_Ipv6Ad;
45643 + bool ipv6Assigned;
45644 + t_ReassTbl *p_Ipv4ReassTbl;
45645 + t_ReassTbl *p_Ipv6ReassTbl;
45646 + uintptr_t ipv4AutoLearnHashTblAddr;
45647 + uintptr_t ipv6AutoLearnHashTblAddr;
45648 + uintptr_t ipv4AutoLearnSetLockTblAddr;
45649 + uintptr_t ipv6AutoLearnSetLockTblAddr;
45650 + uint16_t minFragSize[2];
45651 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
45652 + uint8_t relativeSchemeId[2];
45653 + t_Handle h_Ipv4Scheme;
45654 + t_Handle h_Ipv6Scheme;
45655 + uint32_t nonConsistentSpFqid;
45656 + } ip;
45657 + struct {
45658 + t_Handle h_Ad;
45659 + t_ReassTbl *p_ReassTbl;
45660 + uintptr_t autoLearnHashTblAddr;
45661 + uintptr_t autoLearnSetLockTblAddr;
45662 + uint16_t maxRessembledsSize;
45663 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
45664 + uint8_t relativeSchemeId;
45665 + t_Handle h_Scheme;
45666 + } capwap;
45667 + };
45668 +} t_ReassmParams;
45669 +
45670 +typedef struct{
45671 + e_FmPcdManipType type;
45672 + t_FmPcdManipParams manipParams;
45673 + bool muramAllocate;
45674 + t_Handle h_Ad;
45675 + uint32_t opcode;
45676 + bool rmv;
45677 + bool insrt;
45678 + t_Handle h_NextManip;
45679 + t_Handle h_PrevManip;
45680 + e_FmPcdManipType nextManipType;
45681 + /* HdrManip parameters*/
45682 + uint8_t *p_Hmct;
45683 + uint8_t *p_Data;
45684 + bool dontParseAfterManip;
45685 + bool fieldUpdate;
45686 + bool custom;
45687 + uint16_t tableSize;
45688 + uint8_t dataSize;
45689 + bool cascaded;
45690 + e_ManipUnifiedPosition unifiedPosition;
45691 + /* end HdrManip */
45692 + uint8_t *p_Template;
45693 + uint16_t owner;
45694 + uint32_t updateParams;
45695 + uint32_t shadowUpdateParams;
45696 + bool frag;
45697 + bool reassm;
45698 + uint16_t sizeForFragmentation;
45699 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
45700 + t_Handle h_Frag;
45701 + t_CapwapFragParams capwapFragParams;
45702 +#endif /* (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10)) */
45703 + union {
45704 + t_ReassmParams reassmParams;
45705 + t_FragParams fragParams;
45706 + };
45707 + uint8_t icOffset;
45708 + uint16_t ownerTmp;
45709 + bool cnia;
45710 + t_Handle p_StatsTbl;
45711 + t_Handle h_FmPcd;
45712 + t_List nodesLst;
45713 + t_Handle h_Spinlock;
45714 +} t_FmPcdManip;
45715 +
45716 +typedef struct t_FmPcdCcSavedManipParams
45717 +{
45718 + union
45719 + {
45720 + struct
45721 + {
45722 + uint16_t dataOffset;
45723 + //uint8_t poolId;
45724 + }capwapParams;
45725 + struct
45726 + {
45727 + uint16_t dataOffset;
45728 + uint8_t poolId;
45729 + }ipParams;
45730 + };
45731 +
45732 +} t_FmPcdCcSavedManipParams;
45733 +
45734 +
45735 +#endif /* __FM_MANIP_H */
45736 --- /dev/null
45737 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.c
45738 @@ -0,0 +1,2095 @@
45739 +/*
45740 + * Copyright 2008-2012 Freescale Semiconductor Inc.
45741 + *
45742 + * Redistribution and use in source and binary forms, with or without
45743 + * modification, are permitted provided that the following conditions are met:
45744 + * * Redistributions of source code must retain the above copyright
45745 + * notice, this list of conditions and the following disclaimer.
45746 + * * Redistributions in binary form must reproduce the above copyright
45747 + * notice, this list of conditions and the following disclaimer in the
45748 + * documentation and/or other materials provided with the distribution.
45749 + * * Neither the name of Freescale Semiconductor nor the
45750 + * names of its contributors may be used to endorse or promote products
45751 + * derived from this software without specific prior written permission.
45752 + *
45753 + *
45754 + * ALTERNATIVELY, this software may be distributed under the terms of the
45755 + * GNU General Public License ("GPL") as published by the Free Software
45756 + * Foundation, either version 2 of that License or (at your option) any
45757 + * later version.
45758 + *
45759 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
45760 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45761 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45762 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
45763 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45764 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45765 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45766 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45767 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45768 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
45769 + */
45770 +
45771 +
45772 +/******************************************************************************
45773 + @File fm_pcd.c
45774 +
45775 + @Description FM PCD ...
45776 +*//***************************************************************************/
45777 +#include "std_ext.h"
45778 +#include "error_ext.h"
45779 +#include "string_ext.h"
45780 +#include "xx_ext.h"
45781 +#include "sprint_ext.h"
45782 +#include "debug_ext.h"
45783 +#include "net_ext.h"
45784 +#include "fm_ext.h"
45785 +#include "fm_pcd_ext.h"
45786 +
45787 +#include "fm_common.h"
45788 +#include "fm_pcd.h"
45789 +#include "fm_pcd_ipc.h"
45790 +#include "fm_hc.h"
45791 +#include "fm_muram_ext.h"
45792 +
45793 +
45794 +/****************************************/
45795 +/* static functions */
45796 +/****************************************/
45797 +
45798 +static t_Error CheckFmPcdParameters(t_FmPcd *p_FmPcd)
45799 +{
45800 + if (!p_FmPcd->h_Fm)
45801 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("h_Fm has to be initialized"));
45802 +
45803 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
45804 + {
45805 + if (p_FmPcd->p_FmPcdKg && !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs)
45806 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
45807 +
45808 + if (p_FmPcd->p_FmPcdPlcr && !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs)
45809 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Something WRONG"));
45810 +
45811 + if (!p_FmPcd->f_Exception)
45812 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdExceptions has to be initialized"));
45813 +
45814 + if ((!p_FmPcd->f_FmPcdIndexedException) && (p_FmPcd->p_FmPcdPlcr || p_FmPcd->p_FmPcdKg))
45815 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("f_FmPcdIndexedException has to be initialized"));
45816 +
45817 + if (p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit > PRS_MAX_CYCLE_LIMIT)
45818 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("prsMaxParseCycleLimit has to be less than 8191"));
45819 + }
45820 +
45821 + return E_OK;
45822 +}
45823 +
45824 +static volatile bool blockingFlag = FALSE;
45825 +static void IpcMsgCompletionCB(t_Handle h_FmPcd,
45826 + uint8_t *p_Msg,
45827 + uint8_t *p_Reply,
45828 + uint32_t replyLength,
45829 + t_Error status)
45830 +{
45831 + UNUSED(h_FmPcd);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
45832 + blockingFlag = FALSE;
45833 +}
45834 +
45835 +static t_Error IpcMsgHandlerCB(t_Handle h_FmPcd,
45836 + uint8_t *p_Msg,
45837 + uint32_t msgLength,
45838 + uint8_t *p_Reply,
45839 + uint32_t *p_ReplyLength)
45840 +{
45841 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
45842 + t_Error err = E_OK;
45843 + t_FmPcdIpcMsg *p_IpcMsg = (t_FmPcdIpcMsg*)p_Msg;
45844 + t_FmPcdIpcReply *p_IpcReply = (t_FmPcdIpcReply*)p_Reply;
45845 +
45846 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
45847 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
45848 +
45849 +#ifdef DISABLE_SANITY_CHECKS
45850 + UNUSED(msgLength);
45851 +#endif /* DISABLE_SANITY_CHECKS */
45852 +
45853 + ASSERT_COND(p_Msg);
45854 +
45855 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_PCD_MAX_REPLY_SIZE));
45856 + *p_ReplyLength = 0;
45857 +
45858 + switch (p_IpcMsg->msgId)
45859 + {
45860 + case (FM_PCD_MASTER_IS_ALIVE):
45861 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
45862 + p_IpcReply->error = E_OK;
45863 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
45864 + break;
45865 + case (FM_PCD_MASTER_IS_ENABLED):
45866 + /* count partitions registrations */
45867 + if (p_FmPcd->enabled)
45868 + p_FmPcd->numOfEnabledGuestPartitionsPcds++;
45869 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)p_FmPcd->enabled;
45870 + p_IpcReply->error = E_OK;
45871 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
45872 + break;
45873 + case (FM_PCD_GUEST_DISABLE):
45874 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds)
45875 + {
45876 + p_FmPcd->numOfEnabledGuestPartitionsPcds--;
45877 + p_IpcReply->error = E_OK;
45878 + }
45879 + else
45880 + {
45881 + REPORT_ERROR(MINOR, E_INVALID_STATE,("Trying to disable an unregistered partition"));
45882 + p_IpcReply->error = E_INVALID_STATE;
45883 + }
45884 + *p_ReplyLength = sizeof(uint32_t);
45885 + break;
45886 + case (FM_PCD_GET_COUNTER):
45887 + {
45888 + e_FmPcdCounters inCounter;
45889 + uint32_t outCounter;
45890 +
45891 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
45892 + outCounter = FM_PCD_GetCounter(h_FmPcd, inCounter);
45893 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
45894 + p_IpcReply->error = E_OK;
45895 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
45896 + break;
45897 + }
45898 + case (FM_PCD_ALLOC_KG_SCHEMES):
45899 + {
45900 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
45901 +
45902 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
45903 + err = FmPcdKgAllocSchemes(h_FmPcd,
45904 + ipcSchemesParams.numOfSchemes,
45905 + ipcSchemesParams.guestId,
45906 + p_IpcReply->replyBody);
45907 + p_IpcReply->error = err;
45908 + *p_ReplyLength = sizeof(uint32_t) + ipcSchemesParams.numOfSchemes*sizeof(uint8_t);
45909 + break;
45910 + }
45911 + case (FM_PCD_FREE_KG_SCHEMES):
45912 + {
45913 + t_FmPcdIpcKgSchemesParams ipcSchemesParams;
45914 +
45915 + memcpy((uint8_t*)&ipcSchemesParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgSchemesParams));
45916 + err = FmPcdKgFreeSchemes(h_FmPcd,
45917 + ipcSchemesParams.numOfSchemes,
45918 + ipcSchemesParams.guestId,
45919 + ipcSchemesParams.schemesIds);
45920 + p_IpcReply->error = err;
45921 + *p_ReplyLength = sizeof(uint32_t);
45922 + break;
45923 + }
45924 + case (FM_PCD_ALLOC_KG_CLSPLAN):
45925 + {
45926 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
45927 +
45928 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
45929 + err = KgAllocClsPlanEntries(h_FmPcd,
45930 + ipcKgClsPlanParams.numOfClsPlanEntries,
45931 + ipcKgClsPlanParams.guestId,
45932 + p_IpcReply->replyBody);
45933 + p_IpcReply->error = err;
45934 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
45935 + break;
45936 + }
45937 + case (FM_PCD_FREE_KG_CLSPLAN):
45938 + {
45939 + t_FmPcdIpcKgClsPlanParams ipcKgClsPlanParams;
45940 +
45941 + memcpy((uint8_t*)&ipcKgClsPlanParams, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcKgClsPlanParams));
45942 + KgFreeClsPlanEntries(h_FmPcd,
45943 + ipcKgClsPlanParams.numOfClsPlanEntries,
45944 + ipcKgClsPlanParams.guestId,
45945 + ipcKgClsPlanParams.clsPlanBase);
45946 + *p_ReplyLength = sizeof(uint32_t);
45947 + break;
45948 + }
45949 + case (FM_PCD_ALLOC_PROFILES):
45950 + {
45951 + t_FmIpcResourceAllocParams ipcAllocParams;
45952 + uint16_t base;
45953 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
45954 + base = PlcrAllocProfilesForPartition(h_FmPcd,
45955 + ipcAllocParams.base,
45956 + ipcAllocParams.num,
45957 + ipcAllocParams.guestId);
45958 + memcpy(p_IpcReply->replyBody, (uint16_t*)&base, sizeof(uint16_t));
45959 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint16_t);
45960 + break;
45961 + }
45962 + case (FM_PCD_FREE_PROFILES):
45963 + {
45964 + t_FmIpcResourceAllocParams ipcAllocParams;
45965 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
45966 + PlcrFreeProfilesForPartition(h_FmPcd,
45967 + ipcAllocParams.base,
45968 + ipcAllocParams.num,
45969 + ipcAllocParams.guestId);
45970 + break;
45971 + }
45972 + case (FM_PCD_SET_PORT_PROFILES):
45973 + {
45974 + t_FmIpcResourceAllocParams ipcAllocParams;
45975 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
45976 + PlcrSetPortProfiles(h_FmPcd,
45977 + ipcAllocParams.guestId,
45978 + ipcAllocParams.num,
45979 + ipcAllocParams.base);
45980 + break;
45981 + }
45982 + case (FM_PCD_CLEAR_PORT_PROFILES):
45983 + {
45984 + t_FmIpcResourceAllocParams ipcAllocParams;
45985 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
45986 + PlcrClearPortProfiles(h_FmPcd,
45987 + ipcAllocParams.guestId);
45988 + break;
45989 + }
45990 + case (FM_PCD_GET_SW_PRS_OFFSET):
45991 + {
45992 + t_FmPcdIpcSwPrsLable ipcSwPrsLable;
45993 + uint32_t swPrsOffset;
45994 +
45995 + memcpy((uint8_t*)&ipcSwPrsLable, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcSwPrsLable));
45996 + swPrsOffset =
45997 + FmPcdGetSwPrsOffset(h_FmPcd,
45998 + (e_NetHeaderType)ipcSwPrsLable.enumHdr,
45999 + ipcSwPrsLable.indexPerHdr);
46000 + memcpy(p_IpcReply->replyBody, (uint8_t*)&swPrsOffset, sizeof(uint32_t));
46001 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
46002 + break;
46003 + }
46004 + case (FM_PCD_PRS_INC_PORT_STATS):
46005 + {
46006 + t_FmPcdIpcPrsIncludePort ipcPrsIncludePort;
46007 +
46008 + memcpy((uint8_t*)&ipcPrsIncludePort, p_IpcMsg->msgBody, sizeof(t_FmPcdIpcPrsIncludePort));
46009 + PrsIncludePortInStatistics(h_FmPcd,
46010 + ipcPrsIncludePort.hardwarePortId,
46011 + ipcPrsIncludePort.include);
46012 + break;
46013 + }
46014 + default:
46015 + *p_ReplyLength = 0;
46016 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
46017 + }
46018 + return E_OK;
46019 +}
46020 +
46021 +static uint32_t NetEnvLock(t_Handle h_NetEnv)
46022 +{
46023 + ASSERT_COND(h_NetEnv);
46024 + return XX_LockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock);
46025 +}
46026 +
46027 +static void NetEnvUnlock(t_Handle h_NetEnv, uint32_t intFlags)
46028 +{
46029 + ASSERT_COND(h_NetEnv);
46030 + XX_UnlockIntrSpinlock(((t_FmPcdNetEnv*)h_NetEnv)->h_Spinlock, intFlags);
46031 +}
46032 +
46033 +static void EnqueueLockToFreeLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
46034 +{
46035 + uint32_t intFlags;
46036 +
46037 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
46038 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->freeLocksLst);
46039 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
46040 +}
46041 +
46042 +static t_FmPcdLock * DequeueLockFromFreeLst(t_FmPcd *p_FmPcd)
46043 +{
46044 + t_FmPcdLock *p_Lock = NULL;
46045 + uint32_t intFlags;
46046 +
46047 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
46048 + if (!LIST_IsEmpty(&p_FmPcd->freeLocksLst))
46049 + {
46050 + p_Lock = FM_PCD_LOCK_OBJ(p_FmPcd->freeLocksLst.p_Next);
46051 + LIST_DelAndInit(&p_Lock->node);
46052 + }
46053 + if (p_FmPcd->h_Spinlock)
46054 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
46055 +
46056 + return p_Lock;
46057 +}
46058 +
46059 +static void EnqueueLockToAcquiredLst(t_FmPcd *p_FmPcd, t_FmPcdLock *p_Lock)
46060 +{
46061 + uint32_t intFlags;
46062 +
46063 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
46064 + LIST_AddToTail(&p_Lock->node, &p_FmPcd->acquiredLocksLst);
46065 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
46066 +}
46067 +
46068 +static t_Error FillFreeLocksLst(t_FmPcd *p_FmPcd)
46069 +{
46070 + t_FmPcdLock *p_Lock;
46071 + int i;
46072 +
46073 + for (i=0; i<10; i++)
46074 + {
46075 + p_Lock = (t_FmPcdLock *)XX_Malloc(sizeof(t_FmPcdLock));
46076 + if (!p_Lock)
46077 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("FM-PCD lock obj!"));
46078 + memset(p_Lock, 0, sizeof(t_FmPcdLock));
46079 + INIT_LIST(&p_Lock->node);
46080 + p_Lock->h_Spinlock = XX_InitSpinlock();
46081 + if (!p_Lock->h_Spinlock)
46082 + {
46083 + XX_Free(p_Lock);
46084 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("FM-PCD spinlock obj!"));
46085 + }
46086 + EnqueueLockToFreeLst(p_FmPcd, p_Lock);
46087 + }
46088 +
46089 + return E_OK;
46090 +}
46091 +
46092 +static void ReleaseFreeLocksLst(t_FmPcd *p_FmPcd)
46093 +{
46094 + t_FmPcdLock *p_Lock;
46095 +
46096 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
46097 + while (p_Lock)
46098 + {
46099 + XX_FreeSpinlock(p_Lock->h_Spinlock);
46100 + XX_Free(p_Lock);
46101 + p_Lock = DequeueLockFromFreeLst(p_FmPcd);
46102 + }
46103 +}
46104 +
46105 +
46106 +
46107 +/*****************************************************************************/
46108 +/* Inter-module API routines */
46109 +/*****************************************************************************/
46110 +
46111 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId)
46112 +{
46113 + ASSERT_COND(p_FmPcd);
46114 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = clsPlanGrpId;
46115 +}
46116 +
46117 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams)
46118 +{
46119 + uint8_t netEnvId = p_GrpParams->netEnvId;
46120 + int i, k, j;
46121 +
46122 + ASSERT_COND(p_FmPcd);
46123 + if (p_FmPcd->netEnvs[netEnvId].clsPlanGrpId != ILLEGAL_CLS_PLAN)
46124 + {
46125 + p_GrpParams->grpExists = TRUE;
46126 + p_GrpParams->clsPlanGrpId = p_FmPcd->netEnvs[netEnvId].clsPlanGrpId;
46127 + return E_OK;
46128 + }
46129 +
46130 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
46131 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
46132 + {
46133 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
46134 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
46135 + {
46136 + /* if an option exists, add it to the opts list */
46137 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
46138 + {
46139 + /* check if this option already exists, add if it doesn't */
46140 + for (j = 0;j<p_GrpParams->numOfOptions;j++)
46141 + {
46142 + if (p_GrpParams->options[j] == p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
46143 + break;
46144 + }
46145 + p_GrpParams->optVectors[j] |= p_FmPcd->netEnvs[netEnvId].unitsVectors[i];
46146 + if (j == p_GrpParams->numOfOptions)
46147 + {
46148 + p_GrpParams->options[p_GrpParams->numOfOptions] = p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt;
46149 + p_GrpParams->numOfOptions++;
46150 + }
46151 + }
46152 + }
46153 + }
46154 +
46155 + if (p_GrpParams->numOfOptions == 0)
46156 + {
46157 + if (p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId != ILLEGAL_CLS_PLAN)
46158 + {
46159 + p_GrpParams->grpExists = TRUE;
46160 + p_GrpParams->clsPlanGrpId = p_FmPcd->p_FmPcdKg->emptyClsPlanGrpId;
46161 + }
46162 + }
46163 +
46164 + return E_OK;
46165 +
46166 +}
46167 +
46168 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector)
46169 +{
46170 + uint8_t j,k;
46171 +
46172 + *p_Vector = 0;
46173 +
46174 + ASSERT_COND(p_FmPcd);
46175 + for (j=0; ((j < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
46176 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[0].hdr != HEADER_TYPE_NONE)); j++)
46177 + {
46178 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
46179 + (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
46180 + {
46181 + if (p_FmPcd->netEnvs[netEnvId].units[j].hdrs[k].opt == opt)
46182 + *p_Vector |= p_FmPcd->netEnvs[netEnvId].unitsVectors[j];
46183 + }
46184 + }
46185 +
46186 + if (!*p_Vector)
46187 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested option was not defined for this Network Environment Characteristics module"));
46188 + else
46189 + return E_OK;
46190 +}
46191 +
46192 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params)
46193 +{
46194 + int i;
46195 +
46196 + ASSERT_COND(p_FmPcd);
46197 + ASSERT_COND(p_Params->netEnvId < FM_MAX_NUM_OF_PORTS);
46198 +
46199 + p_Params->vector = 0;
46200 + for (i=0; i<p_Params->numOfDistinctionUnits ;i++)
46201 + {
46202 + if (p_FmPcd->netEnvs[p_Params->netEnvId].units[p_Params->unitIds[i]].hdrs[0].hdr == HEADER_TYPE_NONE)
46203 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Requested unit was not defined for this Network Environment Characteristics module"));
46204 + ASSERT_COND(p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]]);
46205 + p_Params->vector |= p_FmPcd->netEnvs[p_Params->netEnvId].unitsVectors[p_Params->unitIds[i]];
46206 + }
46207 +
46208 + return E_OK;
46209 +}
46210 +
46211 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector)
46212 +{
46213 + int i=0, k;
46214 +
46215 + ASSERT_COND(p_FmPcd);
46216 + /* check whether a given unit may be used by non-clsPlan users. */
46217 + /* first, recognize the unit by its vector */
46218 + while (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)
46219 + {
46220 + if (p_FmPcd->netEnvs[netEnvId].unitsVectors[i] == unitVector)
46221 + {
46222 + for (k=0;
46223 + ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
46224 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE));
46225 + k++)
46226 + /* check that no option exists */
46227 + if ((protocolOpt_t)p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt)
46228 + return FALSE;
46229 + break;
46230 + }
46231 + i++;
46232 + }
46233 + /* assert that a unit was found to mach the vector */
46234 + ASSERT_COND(p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE);
46235 +
46236 + return TRUE;
46237 +}
46238 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
46239 +{
46240 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46241 + int i, k;
46242 +
46243 + ASSERT_COND(p_FmPcd);
46244 +
46245 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
46246 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE)); i++)
46247 + {
46248 + for (k=0; ((k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
46249 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE)); k++)
46250 + if (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr)
46251 + return TRUE;
46252 + }
46253 + for (i=0; ((i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
46254 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE)); i++)
46255 + {
46256 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
46257 + return TRUE;
46258 + }
46259 +
46260 + return FALSE;
46261 +}
46262 +
46263 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt)
46264 +{
46265 + uint8_t i, k;
46266 +
46267 + ASSERT_COND(p_FmPcd);
46268 +
46269 + if (interchangeable)
46270 + {
46271 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
46272 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
46273 + {
46274 + for (k=0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS) &&
46275 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
46276 + {
46277 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].hdr == hdr) &&
46278 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[k].opt == opt))
46279 +
46280 + return i;
46281 + }
46282 + }
46283 + }
46284 + else
46285 + {
46286 + for (i=0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS) &&
46287 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
46288 + if ((p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].hdr == hdr) &&
46289 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[0].opt == opt) &&
46290 + (p_FmPcd->netEnvs[netEnvId].units[i].hdrs[1].hdr == HEADER_TYPE_NONE))
46291 + return i;
46292 +
46293 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS) &&
46294 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
46295 + if ((p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr) &&
46296 + (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].opt == opt))
46297 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
46298 + }
46299 +
46300 + return FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS;
46301 +}
46302 +
46303 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_ReasmCommonPramTbl)
46304 +{
46305 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46306 + t_FmPcdCcReassmTimeoutParams ccReassmTimeoutParams = {0};
46307 + uint8_t result;
46308 + t_Error err = E_OK;
46309 +
46310 + ASSERT_COND(p_FmPcd);
46311 + ASSERT_COND(h_ReasmCommonPramTbl);
46312 +
46313 + ccReassmTimeoutParams.iprcpt = (uint32_t)(XX_VirtToPhys(h_ReasmCommonPramTbl) - p_FmPcd->physicalMuramBase);
46314 + ccReassmTimeoutParams.activate = FALSE; /*Disable Timeout Task*/
46315 +
46316 + if ((err = FmHcPcdCcTimeoutReassm(p_FmPcd->h_Hc, &ccReassmTimeoutParams, &result)) != E_OK)
46317 + RETURN_ERROR(MAJOR, err, NO_MSG);
46318 +
46319 + switch (result)
46320 + {
46321 + case (0):
46322 + return E_OK;
46323 + case (1):
46324 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
46325 + case (2):
46326 + RETURN_ERROR(MAJOR, E_INVALID_STATE, (""));
46327 + case (3):
46328 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Disable Timeout Task with invalid IPRCPT"));
46329 + default:
46330 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
46331 + }
46332 +
46333 + return E_OK;
46334 +}
46335 +
46336 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr)
46337 +{
46338 + int i;
46339 +
46340 + ASSERT_COND(p_FmPcd);
46341 + ASSERT_COND(netEnvId < FM_MAX_NUM_OF_PORTS);
46342 +
46343 + for (i=0; (i < FM_PCD_MAX_NUM_OF_ALIAS_HDRS)
46344 + && (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr != HEADER_TYPE_NONE); i++)
46345 + {
46346 + if (p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].hdr == hdr)
46347 + return p_FmPcd->netEnvs[netEnvId].aliasHdrs[i].aliasHdr;
46348 + }
46349 +
46350 + return HEADER_TYPE_NONE;
46351 +}
46352 +
46353 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId)
46354 +{
46355 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46356 + uint16_t swPortIndex = 0;
46357 +
46358 + ASSERT_COND(h_FmPcd);
46359 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
46360 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].h_FmPort = h_FmPort;
46361 +}
46362 +
46363 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum)
46364 +{
46365 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46366 +
46367 + ASSERT_COND(h_FmPcd);
46368 + return p_FmPcd->netEnvs[netEnvId].lcvs[hdrNum];
46369 +}
46370 +
46371 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId)
46372 +{
46373 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46374 +
46375 + ASSERT_COND(h_FmPcd);
46376 + return p_FmPcd->netEnvs[netEnvId].macsecVector;
46377 +}
46378 +
46379 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv)
46380 +{
46381 + return ((t_FmPcdNetEnv*)h_NetEnv)->netEnvId;
46382 +}
46383 +
46384 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
46385 +{
46386 + uint32_t intFlags;
46387 +
46388 + ASSERT_COND(h_FmPcd);
46389 +
46390 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
46391 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners++;
46392 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
46393 +}
46394 +
46395 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId)
46396 +{
46397 + uint32_t intFlags;
46398 +
46399 + ASSERT_COND(h_FmPcd);
46400 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners);
46401 +
46402 + intFlags = NetEnvLock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId]);
46403 + ((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId].owners--;
46404 + NetEnvUnlock(&((t_FmPcd*)h_FmPcd)->netEnvs[netEnvId], intFlags);
46405 +}
46406 +
46407 +uint32_t FmPcdLock(t_Handle h_FmPcd)
46408 +{
46409 + ASSERT_COND(h_FmPcd);
46410 + return XX_LockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock);
46411 +}
46412 +
46413 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags)
46414 +{
46415 + ASSERT_COND(h_FmPcd);
46416 + XX_UnlockIntrSpinlock(((t_FmPcd*)h_FmPcd)->h_Spinlock, intFlags);
46417 +}
46418 +
46419 +t_FmPcdLock * FmPcdAcquireLock(t_Handle h_FmPcd)
46420 +{
46421 + t_FmPcdLock *p_Lock;
46422 + ASSERT_COND(h_FmPcd);
46423 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
46424 + if (!p_Lock)
46425 + {
46426 + FillFreeLocksLst(h_FmPcd);
46427 + p_Lock = DequeueLockFromFreeLst((t_FmPcd*)h_FmPcd);
46428 + }
46429 +
46430 + if (p_Lock)
46431 + EnqueueLockToAcquiredLst((t_FmPcd*)h_FmPcd, p_Lock);
46432 + return p_Lock;
46433 +}
46434 +
46435 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock)
46436 +{
46437 + uint32_t intFlags;
46438 + ASSERT_COND(h_FmPcd);
46439 + intFlags = FmPcdLock(h_FmPcd);
46440 + LIST_DelAndInit(&p_Lock->node);
46441 + FmPcdUnlock(h_FmPcd, intFlags);
46442 + EnqueueLockToFreeLst((t_FmPcd*)h_FmPcd, p_Lock);
46443 +}
46444 +
46445 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd)
46446 +{
46447 + uint32_t intFlags;
46448 + t_List *p_Pos, *p_SavedPos=NULL;
46449 +
46450 + ASSERT_COND(h_FmPcd);
46451 + intFlags = FmPcdLock(h_FmPcd);
46452 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
46453 + {
46454 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
46455 + if (!FmPcdLockTryLock(p_Lock))
46456 + {
46457 + p_SavedPos = p_Pos;
46458 + break;
46459 + }
46460 + }
46461 + if (p_SavedPos)
46462 + {
46463 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
46464 + {
46465 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
46466 + if (p_Pos == p_SavedPos)
46467 + break;
46468 + FmPcdLockUnlock(p_Lock);
46469 + }
46470 + }
46471 + FmPcdUnlock(h_FmPcd, intFlags);
46472 +
46473 + CORE_MemoryBarrier();
46474 +
46475 + if (p_SavedPos)
46476 + return FALSE;
46477 +
46478 + return TRUE;
46479 +}
46480 +
46481 +void FmPcdLockUnlockAll(t_Handle h_FmPcd)
46482 +{
46483 + uint32_t intFlags;
46484 + t_List *p_Pos;
46485 +
46486 + ASSERT_COND(h_FmPcd);
46487 + intFlags = FmPcdLock(h_FmPcd);
46488 + LIST_FOR_EACH(p_Pos, &((t_FmPcd*)h_FmPcd)->acquiredLocksLst)
46489 + {
46490 + t_FmPcdLock *p_Lock = FM_PCD_LOCK_OBJ(p_Pos);
46491 + p_Lock->flag = FALSE;
46492 + }
46493 + FmPcdUnlock(h_FmPcd, intFlags);
46494 +
46495 + CORE_MemoryBarrier();
46496 +}
46497 +
46498 +t_Error FmPcdHcSync(t_Handle h_FmPcd)
46499 +{
46500 + ASSERT_COND(h_FmPcd);
46501 + ASSERT_COND(((t_FmPcd*)h_FmPcd)->h_Hc);
46502 +
46503 + return FmHcPcdSync(((t_FmPcd*)h_FmPcd)->h_Hc);
46504 +}
46505 +
46506 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd)
46507 +{
46508 + ASSERT_COND(h_FmPcd);
46509 + return ((t_FmPcd*)h_FmPcd)->h_Hc;
46510 +}
46511 +
46512 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd)
46513 +{
46514 + ASSERT_COND(h_FmPcd);
46515 + return ((t_FmPcd*)h_FmPcd)->advancedOffloadSupport;
46516 +}
46517 +/*********************** End of inter-module routines ************************/
46518 +
46519 +
46520 +/****************************************/
46521 +/* API Init unit functions */
46522 +/****************************************/
46523 +
46524 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams)
46525 +{
46526 + t_FmPcd *p_FmPcd = NULL;
46527 + t_FmPhysAddr physicalMuramBase;
46528 + uint8_t i;
46529 +
46530 + SANITY_CHECK_RETURN_VALUE(p_FmPcdParams, E_INVALID_HANDLE,NULL);
46531 +
46532 + p_FmPcd = (t_FmPcd *) XX_Malloc(sizeof(t_FmPcd));
46533 + if (!p_FmPcd)
46534 + {
46535 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD"));
46536 + return NULL;
46537 + }
46538 + memset(p_FmPcd, 0, sizeof(t_FmPcd));
46539 +
46540 + p_FmPcd->p_FmPcdDriverParam = (t_FmPcdDriverParam *) XX_Malloc(sizeof(t_FmPcdDriverParam));
46541 + if (!p_FmPcd->p_FmPcdDriverParam)
46542 + {
46543 + XX_Free(p_FmPcd);
46544 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Driver Param"));
46545 + return NULL;
46546 + }
46547 + memset(p_FmPcd->p_FmPcdDriverParam, 0, sizeof(t_FmPcdDriverParam));
46548 +
46549 + p_FmPcd->h_Fm = p_FmPcdParams->h_Fm;
46550 + p_FmPcd->guestId = FmGetGuestId(p_FmPcd->h_Fm);
46551 + p_FmPcd->h_FmMuram = FmGetMuramHandle(p_FmPcd->h_Fm);
46552 + if (p_FmPcd->h_FmMuram)
46553 + {
46554 + FmGetPhysicalMuramBase(p_FmPcdParams->h_Fm, &physicalMuramBase);
46555 + p_FmPcd->physicalMuramBase = (uint64_t)((uint64_t)(&physicalMuramBase)->low | ((uint64_t)(&physicalMuramBase)->high << 32));
46556 + }
46557 +
46558 + for (i = 0; i<FM_MAX_NUM_OF_PORTS; i++)
46559 + p_FmPcd->netEnvs[i].clsPlanGrpId = ILLEGAL_CLS_PLAN;
46560 +
46561 + if (p_FmPcdParams->useHostCommand)
46562 + {
46563 + t_FmHcParams hcParams;
46564 +
46565 + memset(&hcParams, 0, sizeof(hcParams));
46566 + hcParams.h_Fm = p_FmPcd->h_Fm;
46567 + hcParams.h_FmPcd = (t_Handle)p_FmPcd;
46568 + memcpy((uint8_t*)&hcParams.params, (uint8_t*)&p_FmPcdParams->hc, sizeof(t_FmPcdHcParams));
46569 + p_FmPcd->h_Hc = FmHcConfigAndInit(&hcParams);
46570 + if (!p_FmPcd->h_Hc)
46571 + {
46572 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD HC"));
46573 + FM_PCD_Free(p_FmPcd);
46574 + return NULL;
46575 + }
46576 + }
46577 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
46578 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("No Host Command defined for a guest partition."));
46579 +
46580 + if (p_FmPcdParams->kgSupport)
46581 + {
46582 + p_FmPcd->p_FmPcdKg = (t_FmPcdKg *)KgConfig(p_FmPcd, p_FmPcdParams);
46583 + if (!p_FmPcd->p_FmPcdKg)
46584 + {
46585 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Keygen"));
46586 + FM_PCD_Free(p_FmPcd);
46587 + return NULL;
46588 + }
46589 + }
46590 +
46591 + if (p_FmPcdParams->plcrSupport)
46592 + {
46593 + p_FmPcd->p_FmPcdPlcr = (t_FmPcdPlcr *)PlcrConfig(p_FmPcd, p_FmPcdParams);
46594 + if (!p_FmPcd->p_FmPcdPlcr)
46595 + {
46596 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Policer"));
46597 + FM_PCD_Free(p_FmPcd);
46598 + return NULL;
46599 + }
46600 + }
46601 +
46602 + if (p_FmPcdParams->prsSupport)
46603 + {
46604 + p_FmPcd->p_FmPcdPrs = (t_FmPcdPrs *)PrsConfig(p_FmPcd, p_FmPcdParams);
46605 + if (!p_FmPcd->p_FmPcdPrs)
46606 + {
46607 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD Parser"));
46608 + FM_PCD_Free(p_FmPcd);
46609 + return NULL;
46610 + }
46611 + }
46612 +
46613 + p_FmPcd->h_Spinlock = XX_InitSpinlock();
46614 + if (!p_FmPcd->h_Spinlock)
46615 + {
46616 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD spinlock"));
46617 + FM_PCD_Free(p_FmPcd);
46618 + return NULL;
46619 + }
46620 + INIT_LIST(&p_FmPcd->freeLocksLst);
46621 + INIT_LIST(&p_FmPcd->acquiredLocksLst);
46622 +
46623 + p_FmPcd->numOfEnabledGuestPartitionsPcds = 0;
46624 +
46625 + p_FmPcd->f_Exception = p_FmPcdParams->f_Exception;
46626 + p_FmPcd->f_FmPcdIndexedException = p_FmPcdParams->f_ExceptionId;
46627 + p_FmPcd->h_App = p_FmPcdParams->h_App;
46628 +
46629 + p_FmPcd->p_CcShadow = NULL;
46630 + p_FmPcd->ccShadowSize = 0;
46631 + p_FmPcd->ccShadowAlign = 0;
46632 +
46633 + p_FmPcd->h_ShadowSpinlock = XX_InitSpinlock();
46634 + if (!p_FmPcd->h_ShadowSpinlock)
46635 + {
46636 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM PCD shadow spinlock"));
46637 + FM_PCD_Free(p_FmPcd);
46638 + return NULL;
46639 + }
46640 +
46641 + return p_FmPcd;
46642 +}
46643 +
46644 +t_Error FM_PCD_Init(t_Handle h_FmPcd)
46645 +{
46646 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46647 + t_Error err = E_OK;
46648 + t_FmPcdIpcMsg msg;
46649 +
46650 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
46651 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
46652 +
46653 + FM_GetRevision(p_FmPcd->h_Fm, &p_FmPcd->fmRevInfo);
46654 +
46655 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
46656 + {
46657 + memset(p_FmPcd->fmPcdIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
46658 + if (Sprint (p_FmPcd->fmPcdIpcHandlerModuleName, "FM_PCD_%d_%d", FmGetId(p_FmPcd->h_Fm), NCSW_MASTER_ID) != 10)
46659 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
46660 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
46661 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm), p_FmPcd->guestId) != (p_FmPcd->guestId<10 ? 10:11))
46662 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
46663 +
46664 + p_FmPcd->h_IpcSession = XX_IpcInitSession(p_FmPcd->fmPcdIpcHandlerModuleName, p_FmPcd->fmPcdModuleName);
46665 + if (p_FmPcd->h_IpcSession)
46666 + {
46667 + t_FmPcdIpcReply reply;
46668 + uint32_t replyLength;
46669 + uint8_t isMasterAlive = 0;
46670 +
46671 + memset(&msg, 0, sizeof(msg));
46672 + memset(&reply, 0, sizeof(reply));
46673 + msg.msgId = FM_PCD_MASTER_IS_ALIVE;
46674 + msg.msgBody[0] = p_FmPcd->guestId;
46675 + blockingFlag = TRUE;
46676 +
46677 + do
46678 + {
46679 + replyLength = sizeof(uint32_t) + sizeof(isMasterAlive);
46680 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
46681 + (uint8_t*)&msg,
46682 + sizeof(msg.msgId)+sizeof(p_FmPcd->guestId),
46683 + (uint8_t*)&reply,
46684 + &replyLength,
46685 + IpcMsgCompletionCB,
46686 + h_FmPcd)) != E_OK)
46687 + REPORT_ERROR(MAJOR, err, NO_MSG);
46688 + while (blockingFlag) ;
46689 + if (replyLength != (sizeof(uint32_t) + sizeof(isMasterAlive)))
46690 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
46691 + isMasterAlive = *(uint8_t*)(reply.replyBody);
46692 + } while (!isMasterAlive);
46693 + }
46694 + }
46695 +
46696 + CHECK_INIT_PARAMETERS(p_FmPcd, CheckFmPcdParameters);
46697 +
46698 + if (p_FmPcd->p_FmPcdKg)
46699 + {
46700 + err = KgInit(p_FmPcd);
46701 + if (err)
46702 + RETURN_ERROR(MAJOR, err, NO_MSG);
46703 + }
46704 +
46705 + if (p_FmPcd->p_FmPcdPlcr)
46706 + {
46707 + err = PlcrInit(p_FmPcd);
46708 + if (err)
46709 + RETURN_ERROR(MAJOR, err, NO_MSG);
46710 + }
46711 +
46712 + if (p_FmPcd->p_FmPcdPrs)
46713 + {
46714 + err = PrsInit(p_FmPcd);
46715 + if (err)
46716 + RETURN_ERROR(MAJOR, err, NO_MSG);
46717 + }
46718 +
46719 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
46720 + {
46721 + /* register to inter-core messaging mechanism */
46722 + memset(p_FmPcd->fmPcdModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
46723 + if (Sprint (p_FmPcd->fmPcdModuleName, "FM_PCD_%d_%d",FmGetId(p_FmPcd->h_Fm),NCSW_MASTER_ID) != 10)
46724 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
46725 + err = XX_IpcRegisterMsgHandler(p_FmPcd->fmPcdModuleName, IpcMsgHandlerCB, p_FmPcd, FM_PCD_MAX_REPLY_SIZE);
46726 + if (err)
46727 + RETURN_ERROR(MAJOR, err, NO_MSG);
46728 + }
46729 +
46730 + /* IPv6 Frame-Id used for fragmentation */
46731 + p_FmPcd->ipv6FrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 4, 4));
46732 + if (!p_FmPcd->ipv6FrameIdAddr)
46733 + {
46734 + FM_PCD_Free(p_FmPcd);
46735 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for IPv6 Frame-Id"));
46736 + }
46737 + IOMemSet32(UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr), 0, 4);
46738 +
46739 + /* CAPWAP Frame-Id used for fragmentation */
46740 + p_FmPcd->capwapFrameIdAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_FmPcd->h_FmMuram, 2, 4));
46741 + if (!p_FmPcd->capwapFrameIdAddr)
46742 + {
46743 + FM_PCD_Free(p_FmPcd);
46744 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM allocation for CAPWAP Frame-Id"));
46745 + }
46746 + IOMemSet32(UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr), 0, 2);
46747 +
46748 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
46749 + p_FmPcd->p_FmPcdDriverParam = NULL;
46750 +
46751 + FmRegisterPcd(p_FmPcd->h_Fm, p_FmPcd);
46752 +
46753 + return E_OK;
46754 +}
46755 +
46756 +t_Error FM_PCD_Free(t_Handle h_FmPcd)
46757 +{
46758 + t_FmPcd *p_FmPcd =(t_FmPcd *)h_FmPcd;
46759 + t_Error err = E_OK;
46760 +
46761 + if (p_FmPcd->ipv6FrameIdAddr)
46762 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->ipv6FrameIdAddr));
46763 +
46764 + if (p_FmPcd->capwapFrameIdAddr)
46765 + FM_MURAM_FreeMem(p_FmPcd->h_FmMuram, UINT_TO_PTR(p_FmPcd->capwapFrameIdAddr));
46766 +
46767 + if (p_FmPcd->enabled)
46768 + FM_PCD_Disable(p_FmPcd);
46769 +
46770 + if (p_FmPcd->p_FmPcdDriverParam)
46771 + {
46772 + XX_Free(p_FmPcd->p_FmPcdDriverParam);
46773 + p_FmPcd->p_FmPcdDriverParam = NULL;
46774 + }
46775 +
46776 + if (p_FmPcd->p_FmPcdKg)
46777 + {
46778 + if ((err = KgFree(p_FmPcd)) != E_OK)
46779 + RETURN_ERROR(MINOR, err, NO_MSG);
46780 + XX_Free(p_FmPcd->p_FmPcdKg);
46781 + p_FmPcd->p_FmPcdKg = NULL;
46782 + }
46783 +
46784 + if (p_FmPcd->p_FmPcdPlcr)
46785 + {
46786 + PlcrFree(p_FmPcd);
46787 + XX_Free(p_FmPcd->p_FmPcdPlcr);
46788 + p_FmPcd->p_FmPcdPlcr = NULL;
46789 + }
46790 +
46791 + if (p_FmPcd->p_FmPcdPrs)
46792 + {
46793 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
46794 + PrsFree(p_FmPcd);
46795 + XX_Free(p_FmPcd->p_FmPcdPrs);
46796 + p_FmPcd->p_FmPcdPrs = NULL;
46797 + }
46798 +
46799 + if (p_FmPcd->h_Hc)
46800 + {
46801 + FmHcFree(p_FmPcd->h_Hc);
46802 + p_FmPcd->h_Hc = NULL;
46803 + }
46804 +
46805 + XX_IpcUnregisterMsgHandler(p_FmPcd->fmPcdModuleName);
46806 +
46807 + FmUnregisterPcd(p_FmPcd->h_Fm);
46808 +
46809 + ReleaseFreeLocksLst(p_FmPcd);
46810 +
46811 + if (p_FmPcd->h_Spinlock)
46812 + XX_FreeSpinlock(p_FmPcd->h_Spinlock);
46813 +
46814 + if (p_FmPcd->h_ShadowSpinlock)
46815 + XX_FreeSpinlock(p_FmPcd->h_ShadowSpinlock);
46816 +
46817 + XX_Free(p_FmPcd);
46818 +
46819 + return E_OK;
46820 +}
46821 +
46822 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
46823 +{
46824 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46825 + uint32_t bitMask = 0;
46826 +
46827 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
46828 +
46829 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
46830 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigException - guest mode!"));
46831 +
46832 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
46833 + if (bitMask)
46834 + {
46835 + if (enable)
46836 + p_FmPcd->exceptions |= bitMask;
46837 + else
46838 + p_FmPcd->exceptions &= ~bitMask;
46839 + }
46840 + else
46841 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
46842 +
46843 + return E_OK;
46844 +}
46845 +
46846 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId)
46847 +{
46848 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46849 +
46850 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
46851 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->h_Hc, E_INVALID_HANDLE);
46852 +
46853 + return FmHcSetFramesDataMemory(p_FmPcd->h_Hc, memId);
46854 +}
46855 +
46856 +t_Error FM_PCD_Enable(t_Handle h_FmPcd)
46857 +{
46858 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46859 + t_Error err = E_OK;
46860 +
46861 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
46862 +
46863 + if (p_FmPcd->enabled)
46864 + return E_OK;
46865 +
46866 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
46867 + p_FmPcd->h_IpcSession)
46868 + {
46869 + uint8_t enabled;
46870 + t_FmPcdIpcMsg msg;
46871 + t_FmPcdIpcReply reply;
46872 + uint32_t replyLength;
46873 +
46874 + memset(&reply, 0, sizeof(reply));
46875 + memset(&msg, 0, sizeof(msg));
46876 + msg.msgId = FM_PCD_MASTER_IS_ENABLED;
46877 + replyLength = sizeof(uint32_t) + sizeof(enabled);
46878 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
46879 + (uint8_t*)&msg,
46880 + sizeof(msg.msgId),
46881 + (uint8_t*)&reply,
46882 + &replyLength,
46883 + NULL,
46884 + NULL)) != E_OK)
46885 + RETURN_ERROR(MAJOR, err, NO_MSG);
46886 + if (replyLength != sizeof(uint32_t) + sizeof(enabled))
46887 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
46888 + p_FmPcd->enabled = (bool)!!(*(uint8_t*)(reply.replyBody));
46889 + if (!p_FmPcd->enabled)
46890 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-PCD master should be enabled first!"));
46891 +
46892 + return E_OK;
46893 + }
46894 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
46895 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
46896 + ("running in guest-mode without IPC!"));
46897 +
46898 + if (p_FmPcd->p_FmPcdKg)
46899 + KgEnable(p_FmPcd);
46900 +
46901 + if (p_FmPcd->p_FmPcdPlcr)
46902 + PlcrEnable(p_FmPcd);
46903 +
46904 + if (p_FmPcd->p_FmPcdPrs)
46905 + PrsEnable(p_FmPcd);
46906 +
46907 + p_FmPcd->enabled = TRUE;
46908 +
46909 + return E_OK;
46910 +}
46911 +
46912 +t_Error FM_PCD_Disable(t_Handle h_FmPcd)
46913 +{
46914 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46915 + t_Error err = E_OK;
46916 +
46917 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
46918 +
46919 + if (!p_FmPcd->enabled)
46920 + return E_OK;
46921 +
46922 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
46923 + p_FmPcd->h_IpcSession)
46924 + {
46925 + t_FmPcdIpcMsg msg;
46926 + t_FmPcdIpcReply reply;
46927 + uint32_t replyLength;
46928 +
46929 + memset(&reply, 0, sizeof(reply));
46930 + memset(&msg, 0, sizeof(msg));
46931 + msg.msgId = FM_PCD_GUEST_DISABLE;
46932 + replyLength = sizeof(uint32_t);
46933 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
46934 + (uint8_t*)&msg,
46935 + sizeof(msg.msgId),
46936 + (uint8_t*)&reply,
46937 + &replyLength,
46938 + NULL,
46939 + NULL)) != E_OK)
46940 + RETURN_ERROR(MAJOR, err, NO_MSG);
46941 + if (replyLength != sizeof(uint32_t))
46942 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
46943 + if (reply.error == E_OK)
46944 + p_FmPcd->enabled = FALSE;
46945 +
46946 + return (t_Error)(reply.error);
46947 + }
46948 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
46949 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
46950 + ("running in guest-mode without IPC!"));
46951 +
46952 + if (p_FmPcd->numOfEnabledGuestPartitionsPcds != 0)
46953 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
46954 + ("Trying to disable a master partition PCD while"
46955 + "guest partitions are still enabled!"));
46956 +
46957 + if (p_FmPcd->p_FmPcdKg)
46958 + KgDisable(p_FmPcd);
46959 +
46960 + if (p_FmPcd->p_FmPcdPlcr)
46961 + PlcrDisable(p_FmPcd);
46962 +
46963 + if (p_FmPcd->p_FmPcdPrs)
46964 + PrsDisable(p_FmPcd);
46965 +
46966 + p_FmPcd->enabled = FALSE;
46967 +
46968 + return E_OK;
46969 +}
46970 +
46971 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams)
46972 +{
46973 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
46974 + uint32_t intFlags, specialUnits = 0;
46975 + uint8_t bitId = 0;
46976 + uint8_t i, j, k;
46977 + uint8_t netEnvCurrId;
46978 + uint8_t ipsecAhUnit = 0,ipsecEspUnit = 0;
46979 + bool ipsecAhExists = FALSE, ipsecEspExists = FALSE, shim1Selected = FALSE;
46980 + uint8_t hdrNum;
46981 + t_FmPcdNetEnvParams *p_ModifiedNetEnvParams;
46982 +
46983 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_STATE, NULL);
46984 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
46985 + SANITY_CHECK_RETURN_VALUE(p_NetEnvParams, E_NULL_POINTER, NULL);
46986 +
46987 + intFlags = FmPcdLock(p_FmPcd);
46988 +
46989 + /* find a new netEnv */
46990 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++)
46991 + if (!p_FmPcd->netEnvs[i].used)
46992 + break;
46993 +
46994 + if (i== FM_MAX_NUM_OF_PORTS)
46995 + {
46996 + REPORT_ERROR(MAJOR, E_FULL,("No more than %d netEnv's allowed.", FM_MAX_NUM_OF_PORTS));
46997 + FmPcdUnlock(p_FmPcd, intFlags);
46998 + return NULL;
46999 + }
47000 +
47001 + p_FmPcd->netEnvs[i].used = TRUE;
47002 + FmPcdUnlock(p_FmPcd, intFlags);
47003 +
47004 + /* As anyone doesn't have handle of this netEnv yet, no need
47005 + to protect it with spinlocks */
47006 +
47007 + p_ModifiedNetEnvParams = (t_FmPcdNetEnvParams *)XX_Malloc(sizeof(t_FmPcdNetEnvParams));
47008 + if (!p_ModifiedNetEnvParams)
47009 + {
47010 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FmPcdNetEnvParams"));
47011 + return NULL;
47012 + }
47013 +
47014 + memcpy(p_ModifiedNetEnvParams, p_NetEnvParams, sizeof(t_FmPcdNetEnvParams));
47015 + p_NetEnvParams = p_ModifiedNetEnvParams;
47016 +
47017 + netEnvCurrId = (uint8_t)i;
47018 +
47019 + /* clear from previous use */
47020 + memset(&p_FmPcd->netEnvs[netEnvCurrId].units, 0, FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS * sizeof(t_FmPcdIntDistinctionUnit));
47021 + memset(&p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs, 0, FM_PCD_MAX_NUM_OF_ALIAS_HDRS * sizeof(t_FmPcdNetEnvAliases));
47022 + memcpy(&p_FmPcd->netEnvs[netEnvCurrId].units, p_NetEnvParams->units, p_NetEnvParams->numOfDistinctionUnits*sizeof(t_FmPcdIntDistinctionUnit));
47023 +
47024 + p_FmPcd->netEnvs[netEnvCurrId].netEnvId = netEnvCurrId;
47025 + p_FmPcd->netEnvs[netEnvCurrId].h_FmPcd = p_FmPcd;
47026 +
47027 + p_FmPcd->netEnvs[netEnvCurrId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
47028 +
47029 + /* check that header with opt is not interchanged with the same header */
47030 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
47031 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
47032 + {
47033 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
47034 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
47035 + {
47036 + /* if an option exists, check that other headers are not the same header
47037 + without option */
47038 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt)
47039 + {
47040 + for (j = 0; (j < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
47041 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr != HEADER_TYPE_NONE); j++)
47042 + {
47043 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].hdr == p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr) &&
47044 + !p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[j].opt)
47045 + {
47046 + REPORT_ERROR(MINOR, E_FULL,
47047 + ("Illegal unit - header with opt may not be interchangeable with the same header without opt"));
47048 + XX_Free(p_ModifiedNetEnvParams);
47049 + return NULL;
47050 + }
47051 + }
47052 + }
47053 + }
47054 + }
47055 +
47056 + /* Specific headers checking */
47057 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
47058 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
47059 + {
47060 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
47061 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
47062 + {
47063 + /* Some headers pairs may not be defined on different units as the parser
47064 + doesn't distinguish */
47065 + /* IPSEC_AH and IPSEC_SPI can't be 2 units, */
47066 + /* check that header with opt is not interchanged with the same header */
47067 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_AH)
47068 + {
47069 + if (ipsecEspExists && (ipsecEspUnit != i))
47070 + {
47071 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
47072 + XX_Free(p_ModifiedNetEnvParams);
47073 + return NULL;
47074 + }
47075 + else
47076 + {
47077 + ipsecAhUnit = i;
47078 + ipsecAhExists = TRUE;
47079 + }
47080 + }
47081 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPSEC_ESP)
47082 + {
47083 + if (ipsecAhExists && (ipsecAhUnit != i))
47084 + {
47085 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("HEADER_TYPE_IPSEC_AH and HEADER_TYPE_IPSEC_ESP may not be defined in separate units"));
47086 + XX_Free(p_ModifiedNetEnvParams);
47087 + return NULL;
47088 + }
47089 + else
47090 + {
47091 + ipsecEspUnit = i;
47092 + ipsecEspExists = TRUE;
47093 + }
47094 + }
47095 + /* ENCAP_ESP */
47096 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_ENCAP_ESP)
47097 + {
47098 + /* IPSec UDP encapsulation is currently set to use SHIM1 */
47099 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_ENCAP_ESP;
47100 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM1;
47101 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM1;
47102 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
47103 + }
47104 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
47105 + /* UDP_LITE */
47106 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_UDP_LITE)
47107 + {
47108 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_UDP_LITE;
47109 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_UDP;
47110 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_UDP;
47111 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
47112 + }
47113 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
47114 +
47115 + /* IP FRAG */
47116 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv4) &&
47117 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV4_FRAG_1))
47118 + {
47119 + /* If IPv4+Frag, we need to set 2 units - SHIM 2 and IPv4. We first set SHIM2, and than check if
47120 + * IPv4 exists. If so we don't need to set an extra unit
47121 + * We consider as "having IPv4" any IPv4 without interchangable headers
47122 + * but including any options. */
47123 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv4;
47124 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV4_FRAG_1;
47125 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
47126 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
47127 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
47128 +
47129 + /* check if IPv4 header exists by itself */
47130 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv4, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
47131 + {
47132 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv4;
47133 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
47134 + }
47135 + }
47136 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_IPv6) &&
47137 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == IPV6_FRAG_1))
47138 + {
47139 + /* If IPv6+Frag, we need to set 2 units - SHIM 2 and IPv6. We first set SHIM2, and than check if
47140 + * IPv4 exists. If so we don't need to set an extra unit
47141 + * We consider as "having IPv6" any IPv6 without interchangable headers
47142 + * but including any options. */
47143 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_IPv6;
47144 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = IPV6_FRAG_1;
47145 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
47146 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
47147 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
47148 +
47149 + /* check if IPv6 header exists by itself */
47150 + if (FmPcdNetEnvGetUnitId(p_FmPcd, netEnvCurrId, HEADER_TYPE_IPv6, FALSE, 0) == FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
47151 + {
47152 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits].hdrs[0].hdr = HEADER_TYPE_IPv6;
47153 + p_FmPcd->netEnvs[netEnvCurrId].units[p_NetEnvParams->numOfDistinctionUnits++].hdrs[0].opt = 0;
47154 + }
47155 + }
47156 +#if (DPAA_VERSION >= 11)
47157 + /* CAPWAP FRAG */
47158 + if ((p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr == HEADER_TYPE_CAPWAP) &&
47159 + (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt == CAPWAP_FRAG_1))
47160 + {
47161 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].hdr = HEADER_TYPE_CAPWAP;
47162 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits].opt = CAPWAP_FRAG_1;
47163 + p_FmPcd->netEnvs[netEnvCurrId].aliasHdrs[specialUnits++].aliasHdr = HEADER_TYPE_USER_DEFINED_SHIM2;
47164 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr = HEADER_TYPE_USER_DEFINED_SHIM2;
47165 + p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].opt = 0;
47166 + }
47167 +#endif /* (DPAA_VERSION >= 11) */
47168 + }
47169 + }
47170 +
47171 + /* if private header (shim), check that no other headers specified */
47172 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
47173 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
47174 + {
47175 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
47176 + if (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[1].hdr != HEADER_TYPE_NONE)
47177 + {
47178 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header may not be interchanged with other headers"));
47179 + XX_Free(p_ModifiedNetEnvParams);
47180 + return NULL;
47181 + }
47182 + }
47183 +
47184 + for (i = 0; i < p_NetEnvParams->numOfDistinctionUnits; i++)
47185 + {
47186 + if (IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
47187 + switch (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr)
47188 + {
47189 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
47190 + if (shim1Selected)
47191 + {
47192 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("SHIM header cannot be selected with UDP_IPSEC_ESP"));
47193 + XX_Free(p_ModifiedNetEnvParams);
47194 + return NULL;
47195 + }
47196 + shim1Selected = TRUE;
47197 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000001;
47198 + break;
47199 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
47200 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = 0x00000002;
47201 + break;
47202 + default:
47203 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested SHIM not supported"));
47204 + }
47205 + else
47206 + {
47207 + p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i] = (uint32_t)(0x80000000 >> bitId++);
47208 +
47209 + if (IS_SPECIAL_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
47210 + p_FmPcd->netEnvs[netEnvCurrId].macsecVector = p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
47211 + }
47212 + }
47213 +
47214 + /* define a set of hardware parser LCV's according to the defined netenv */
47215 +
47216 + /* set an array of LCV's for each header in the netEnv */
47217 + for (i = 0; (i < FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
47218 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr != HEADER_TYPE_NONE); i++)
47219 + {
47220 + /* private headers have no LCV in the hard parser */
47221 + if (!IS_PRIVATE_HEADER(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[0].hdr))
47222 + {
47223 + for (k = 0; (k < FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
47224 + && (p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr != HEADER_TYPE_NONE); k++)
47225 + {
47226 + hdrNum = GetPrsHdrNum(p_FmPcd->netEnvs[netEnvCurrId].units[i].hdrs[k].hdr);
47227 + if ((hdrNum == ILLEGAL_HDR_NUM) || (hdrNum == NO_HDR_NUM))
47228 + {
47229 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, NO_MSG);
47230 + XX_Free(p_ModifiedNetEnvParams);
47231 + return NULL;
47232 + }
47233 + p_FmPcd->netEnvs[netEnvCurrId].lcvs[hdrNum] |= p_FmPcd->netEnvs[netEnvCurrId].unitsVectors[i];
47234 + }
47235 + }
47236 + }
47237 + XX_Free(p_ModifiedNetEnvParams);
47238 +
47239 + p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock = XX_InitSpinlock();
47240 + if (!p_FmPcd->netEnvs[netEnvCurrId].h_Spinlock)
47241 + {
47242 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Pcd NetEnv spinlock"));
47243 + return NULL;
47244 + }
47245 + return &p_FmPcd->netEnvs[netEnvCurrId];
47246 +}
47247 +
47248 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv)
47249 +{
47250 + t_FmPcdNetEnv *p_NetEnv = (t_FmPcdNetEnv*)h_NetEnv;
47251 + t_FmPcd *p_FmPcd = p_NetEnv->h_FmPcd;
47252 + uint32_t intFlags;
47253 + uint8_t netEnvId = p_NetEnv->netEnvId;
47254 +
47255 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_STATE);
47256 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
47257 +
47258 + /* check that no port is bound to this netEnv */
47259 + if (p_FmPcd->netEnvs[netEnvId].owners)
47260 + {
47261 + RETURN_ERROR(MINOR, E_INVALID_STATE,
47262 + ("Trying to delete a netEnv that has ports/schemes/trees/clsPlanGrps bound to"));
47263 + }
47264 +
47265 + intFlags = FmPcdLock(p_FmPcd);
47266 +
47267 + p_FmPcd->netEnvs[netEnvId].used = FALSE;
47268 + p_FmPcd->netEnvs[netEnvId].clsPlanGrpId = ILLEGAL_CLS_PLAN;
47269 +
47270 + memset(p_FmPcd->netEnvs[netEnvId].units, 0, sizeof(t_FmPcdIntDistinctionUnit)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
47271 + memset(p_FmPcd->netEnvs[netEnvId].unitsVectors, 0, sizeof(uint32_t)*FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
47272 + memset(p_FmPcd->netEnvs[netEnvId].lcvs, 0, sizeof(uint32_t)*FM_PCD_PRS_NUM_OF_HDRS);
47273 +
47274 + if (p_FmPcd->netEnvs[netEnvId].h_Spinlock)
47275 + XX_FreeSpinlock(p_FmPcd->netEnvs[netEnvId].h_Spinlock);
47276 +
47277 + FmPcdUnlock(p_FmPcd, intFlags);
47278 + return E_OK;
47279 +}
47280 +
47281 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd)
47282 +{
47283 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47284 +
47285 + SANITY_CHECK_RETURN(h_FmPcd, E_INVALID_STATE);
47286 +
47287 + FmHcTxConf(p_FmPcd->h_Hc, p_Fd);
47288 +}
47289 +
47290 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd)
47291 +{
47292 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47293 + t_FmCtrlCodeRevisionInfo revInfo;
47294 + t_Error err;
47295 +
47296 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47297 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
47298 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_STATE);
47299 +
47300 + if ((err = FM_GetFmanCtrlCodeRevision(p_FmPcd->h_Fm, &revInfo)) != E_OK)
47301 + {
47302 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
47303 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
47304 + }
47305 + if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
47306 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
47307 +
47308 + if (!p_FmPcd->h_Hc)
47309 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("HC must be initialized in this mode"));
47310 +
47311 + p_FmPcd->advancedOffloadSupport = TRUE;
47312 +
47313 + return E_OK;
47314 +}
47315 +
47316 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter)
47317 +{
47318 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47319 + uint32_t outCounter = 0;
47320 + t_Error err;
47321 +
47322 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, 0);
47323 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, 0);
47324 +
47325 + switch (counter)
47326 + {
47327 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
47328 + if (!p_FmPcd->p_FmPcdKg)
47329 + {
47330 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("KeyGen is not activated"));
47331 + return 0;
47332 + }
47333 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47334 + !p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs &&
47335 + !p_FmPcd->h_IpcSession)
47336 + {
47337 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
47338 + ("running in guest-mode without neither IPC nor mapped register!"));
47339 + return 0;
47340 + }
47341 + break;
47342 +
47343 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
47344 + case (e_FM_PCD_PLCR_COUNTERS_RED):
47345 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
47346 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
47347 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
47348 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
47349 + if (!p_FmPcd->p_FmPcdPlcr)
47350 + {
47351 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Policer is not activated"));
47352 + return 0;
47353 + }
47354 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47355 + !p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
47356 + !p_FmPcd->h_IpcSession)
47357 + {
47358 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
47359 + ("running in \"guest-mode\" without neither IPC nor mapped register!"));
47360 + return 0;
47361 + }
47362 +
47363 + /* check that counters are enabled */
47364 + if (p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs &&
47365 + !(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
47366 + {
47367 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
47368 + return 0;
47369 + }
47370 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs ||
47371 + ((p_FmPcd->guestId != NCSW_MASTER_ID) && p_FmPcd->h_IpcSession));
47372 + break;
47373 +
47374 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
47375 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
47376 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
47377 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
47378 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
47379 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
47380 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
47381 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
47382 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
47383 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
47384 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
47385 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
47386 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
47387 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
47388 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
47389 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
47390 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
47391 + if (!p_FmPcd->p_FmPcdPrs)
47392 + {
47393 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Parser is not activated"));
47394 + return 0;
47395 + }
47396 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47397 + !p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs &&
47398 + !p_FmPcd->h_IpcSession)
47399 + {
47400 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
47401 + ("running in guest-mode without neither IPC nor mapped register!"));
47402 + return 0;
47403 + }
47404 + break;
47405 + default:
47406 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unsupported type of counter"));
47407 + return 0;
47408 + }
47409 +
47410 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
47411 + p_FmPcd->h_IpcSession)
47412 + {
47413 + t_FmPcdIpcMsg msg;
47414 + t_FmPcdIpcReply reply;
47415 + uint32_t replyLength;
47416 +
47417 + memset(&msg, 0, sizeof(msg));
47418 + memset(&reply, 0, sizeof(reply));
47419 + msg.msgId = FM_PCD_GET_COUNTER;
47420 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
47421 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
47422 + if ((err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
47423 + (uint8_t*)&msg,
47424 + sizeof(msg.msgId) +sizeof(uint32_t),
47425 + (uint8_t*)&reply,
47426 + &replyLength,
47427 + NULL,
47428 + NULL)) != E_OK)
47429 + RETURN_ERROR(MAJOR, err, NO_MSG);
47430 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
47431 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
47432 +
47433 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
47434 + return outCounter;
47435 + }
47436 +
47437 + switch (counter)
47438 + {
47439 + /* Parser statistics */
47440 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
47441 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds);
47442 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
47443 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs);
47444 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
47445 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs);
47446 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
47447 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs);
47448 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
47449 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs);
47450 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
47451 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres);
47452 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
47453 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres);
47454 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
47455 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres);
47456 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
47457 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres);
47458 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
47459 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs);
47460 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
47461 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs);
47462 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
47463 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs);
47464 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
47465 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs);
47466 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
47467 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs);
47468 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
47469 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs);
47470 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
47471 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs);
47472 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
47473 + return GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs);
47474 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
47475 + return GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc);
47476 +
47477 + /* Policer statistics */
47478 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
47479 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt);
47480 + case (e_FM_PCD_PLCR_COUNTERS_RED):
47481 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt);
47482 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
47483 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt);
47484 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
47485 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt);
47486 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
47487 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt);
47488 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
47489 + return GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt);
47490 + }
47491 + return 0;
47492 +}
47493 +
47494 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable)
47495 +{
47496 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47497 + uint32_t bitMask = 0, tmpReg;
47498 +
47499 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
47500 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
47501 +
47502 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47503 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetException - guest mode!"));
47504 +
47505 + GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception);
47506 +
47507 + if (bitMask)
47508 + {
47509 + if (enable)
47510 + p_FmPcd->exceptions |= bitMask;
47511 + else
47512 + p_FmPcd->exceptions &= ~bitMask;
47513 +
47514 + switch (exception)
47515 + {
47516 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
47517 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
47518 + if (!p_FmPcd->p_FmPcdKg)
47519 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
47520 + break;
47521 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
47522 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
47523 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
47524 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
47525 + if (!p_FmPcd->p_FmPcdPlcr)
47526 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
47527 + break;
47528 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
47529 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
47530 + if (!p_FmPcd->p_FmPcdPrs)
47531 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - parser is not working"));
47532 + break;
47533 + }
47534 +
47535 + switch (exception)
47536 + {
47537 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
47538 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
47539 + if (enable)
47540 + tmpReg |= FM_EX_KG_DOUBLE_ECC;
47541 + else
47542 + tmpReg &= ~FM_EX_KG_DOUBLE_ECC;
47543 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
47544 + break;
47545 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
47546 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer);
47547 + if (enable)
47548 + tmpReg |= FM_EX_KG_KEYSIZE_OVERFLOW;
47549 + else
47550 + tmpReg &= ~FM_EX_KG_KEYSIZE_OVERFLOW;
47551 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_eeer, tmpReg);
47552 + break;
47553 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
47554 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer);
47555 + if (enable)
47556 + tmpReg |= FM_PCD_PRS_DOUBLE_ECC;
47557 + else
47558 + tmpReg &= ~FM_PCD_PRS_DOUBLE_ECC;
47559 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_perer, tmpReg);
47560 + break;
47561 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
47562 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever);
47563 + if (enable)
47564 + tmpReg |= FM_PCD_PRS_SINGLE_ECC;
47565 + else
47566 + tmpReg &= ~FM_PCD_PRS_SINGLE_ECC;
47567 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pever, tmpReg);
47568 + break;
47569 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
47570 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47571 + if (enable)
47572 + tmpReg |= FM_PCD_PLCR_DOUBLE_ECC;
47573 + else
47574 + tmpReg &= ~FM_PCD_PLCR_DOUBLE_ECC;
47575 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
47576 + break;
47577 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
47578 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
47579 + if (enable)
47580 + tmpReg |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
47581 + else
47582 + tmpReg &= ~FM_PCD_PLCR_INIT_ENTRY_ERROR;
47583 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier, tmpReg);
47584 + break;
47585 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
47586 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47587 + if (enable)
47588 + tmpReg |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47589 + else
47590 + tmpReg &= ~FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
47591 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
47592 + break;
47593 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
47594 + tmpReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
47595 + if (enable)
47596 + tmpReg |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47597 + else
47598 + tmpReg &= ~FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
47599 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier, tmpReg);
47600 + break;
47601 + }
47602 + /* for ECC exceptions driver automatically enables ECC mechanism, if disabled.
47603 + Driver may disable them automatically, depending on driver's status */
47604 + if (enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
47605 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
47606 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
47607 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
47608 + FmEnableRamsEcc(p_FmPcd->h_Fm);
47609 + if (!enable && ((exception == e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC) |
47610 + (exception == e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC) |
47611 + (exception == e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC) |
47612 + (exception == e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC)))
47613 + FmDisableRamsEcc(p_FmPcd->h_Fm);
47614 + }
47615 +
47616 + return E_OK;
47617 +}
47618 +
47619 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception)
47620 +{
47621 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47622 +
47623 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
47624 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
47625 +
47626 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47627 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ForceIntr - guest mode!"));
47628 +
47629 + switch (exception)
47630 + {
47631 + case (e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC):
47632 + case (e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW):
47633 + if (!p_FmPcd->p_FmPcdKg)
47634 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - keygen is not working"));
47635 + break;
47636 + case (e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC):
47637 + case (e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR):
47638 + case (e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE):
47639 + case (e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE):
47640 + if (!p_FmPcd->p_FmPcdPlcr)
47641 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt - policer is not working"));
47642 + break;
47643 + case (e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC):
47644 + case (e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC):
47645 + if (!p_FmPcd->p_FmPcdPrs)
47646 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Can't ask for this interrupt -parsrer is not working"));
47647 + break;
47648 + default:
47649 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid interrupt requested"));
47650 + }
47651 + switch (exception)
47652 + {
47653 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC:
47654 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC))
47655 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47656 + break;
47657 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC:
47658 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC))
47659 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47660 + break;
47661 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC:
47662 + if (!(p_FmPcd->exceptions & FM_EX_KG_DOUBLE_ECC))
47663 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47664 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_DOUBLE_ECC);
47665 + break;
47666 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW:
47667 + if (!(p_FmPcd->exceptions & FM_EX_KG_KEYSIZE_OVERFLOW))
47668 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47669 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_feer, FM_EX_KG_KEYSIZE_OVERFLOW);
47670 + break;
47671 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC:
47672 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC))
47673 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47674 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_DOUBLE_ECC);
47675 + break;
47676 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR:
47677 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR))
47678 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47679 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, FM_PCD_PLCR_INIT_ENTRY_ERROR);
47680 + break;
47681 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE:
47682 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE))
47683 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47684 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE);
47685 + break;
47686 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE:
47687 + if (!(p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE))
47688 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
47689 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE);
47690 + break;
47691 + }
47692 +
47693 + return E_OK;
47694 +}
47695 +
47696 +
47697 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value)
47698 +{
47699 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47700 +
47701 + SANITY_CHECK_RETURN_ERROR(h_FmPcd, E_INVALID_HANDLE);
47702 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
47703 +
47704 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
47705 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ModifyCounter - guest mode!"));
47706 +
47707 + switch (counter)
47708 + {
47709 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
47710 + if (!p_FmPcd->p_FmPcdKg)
47711 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - KeyGen is not working"));
47712 + break;
47713 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
47714 + case (e_FM_PCD_PLCR_COUNTERS_RED):
47715 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
47716 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
47717 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
47718 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
47719 + if (!p_FmPcd->p_FmPcdPlcr)
47720 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Invalid counters - Policer is not working"));
47721 + if (!(GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr) & FM_PCD_PLCR_GCR_STEN))
47722 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
47723 + break;
47724 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
47725 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
47726 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
47727 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
47728 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
47729 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
47730 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
47731 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
47732 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
47733 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
47734 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
47735 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
47736 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
47737 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
47738 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
47739 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
47740 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
47741 + if (!p_FmPcd->p_FmPcdPrs)
47742 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
47743 + break;
47744 + default:
47745 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported type of counter"));
47746 + }
47747 + switch (counter)
47748 + {
47749 + case (e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH):
47750 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_pds, value);
47751 + break;
47752 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED):
47753 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rrs, value);
47754 + break;
47755 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED):
47756 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rrs, value);
47757 + break;
47758 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED):
47759 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rrs, value);
47760 + break;
47761 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED):
47762 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srrs, value);
47763 + break;
47764 + case (e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR):
47765 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l2rres, value);
47766 + break;
47767 + case (e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR):
47768 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l3rres, value);
47769 + break;
47770 + case (e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR):
47771 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_l4rres, value);
47772 + break;
47773 + case (e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR):
47774 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_srres, value);
47775 + break;
47776 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES):
47777 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spcs, value);
47778 + break;
47779 + case (e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES):
47780 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_spscs, value);
47781 + break;
47782 + case (e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES):
47783 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_hxscs, value);
47784 + break;
47785 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES):
47786 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrcs, value);
47787 + break;
47788 + case (e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES):
47789 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mrscs, value);
47790 + break;
47791 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES):
47792 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwcs, value);
47793 + break;
47794 + case (e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES):
47795 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_mwscs, value);
47796 + break;
47797 + case (e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES):
47798 + WRITE_UINT32(p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs->fmpr_fcscs, value);
47799 + break;
47800 + case (e_FM_PCD_KG_COUNTERS_TOTAL):
47801 + WRITE_UINT32(p_FmPcd->p_FmPcdKg->p_FmPcdKgRegs->fmkg_tpc,value);
47802 + break;
47803 +
47804 + /*Policer counters*/
47805 + case (e_FM_PCD_PLCR_COUNTERS_YELLOW):
47806 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ypcnt, value);
47807 + break;
47808 + case (e_FM_PCD_PLCR_COUNTERS_RED):
47809 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rpcnt, value);
47810 + break;
47811 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED):
47812 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rrpcnt, value);
47813 + break;
47814 + case (e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW):
47815 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_rypcnt, value);
47816 + break;
47817 + case (e_FM_PCD_PLCR_COUNTERS_TOTAL):
47818 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_tpcnt, value);
47819 + break;
47820 + case (e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH):
47821 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_flmcnt, value);
47822 + break;
47823 + }
47824 +
47825 + return E_OK;
47826 +}
47827 +
47828 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd)
47829 +{
47830 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
47831 + return FmHcGetPort(p_FmPcd->h_Hc);
47832 +}
47833 +
47834 --- /dev/null
47835 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd.h
47836 @@ -0,0 +1,543 @@
47837 +/*
47838 + * Copyright 2008-2012 Freescale Semiconductor Inc.
47839 + *
47840 + * Redistribution and use in source and binary forms, with or without
47841 + * modification, are permitted provided that the following conditions are met:
47842 + * * Redistributions of source code must retain the above copyright
47843 + * notice, this list of conditions and the following disclaimer.
47844 + * * Redistributions in binary form must reproduce the above copyright
47845 + * notice, this list of conditions and the following disclaimer in the
47846 + * documentation and/or other materials provided with the distribution.
47847 + * * Neither the name of Freescale Semiconductor nor the
47848 + * names of its contributors may be used to endorse or promote products
47849 + * derived from this software without specific prior written permission.
47850 + *
47851 + *
47852 + * ALTERNATIVELY, this software may be distributed under the terms of the
47853 + * GNU General Public License ("GPL") as published by the Free Software
47854 + * Foundation, either version 2 of that License or (at your option) any
47855 + * later version.
47856 + *
47857 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
47858 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47859 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47860 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
47861 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47862 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47863 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47864 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47865 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47866 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47867 + */
47868 +
47869 +
47870 +/******************************************************************************
47871 + @File fm_pcd.h
47872 +
47873 + @Description FM PCD ...
47874 +*//***************************************************************************/
47875 +#ifndef __FM_PCD_H
47876 +#define __FM_PCD_H
47877 +
47878 +#include "std_ext.h"
47879 +#include "error_ext.h"
47880 +#include "list_ext.h"
47881 +#include "fm_pcd_ext.h"
47882 +#include "fm_common.h"
47883 +#include "fsl_fman_prs.h"
47884 +#include "fsl_fman_kg.h"
47885 +
47886 +#define __ERR_MODULE__ MODULE_FM_PCD
47887 +
47888 +
47889 +/****************************/
47890 +/* Defaults */
47891 +/****************************/
47892 +#define DEFAULT_plcrAutoRefresh FALSE
47893 +#define DEFAULT_fmPcdKgErrorExceptions (FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW)
47894 +#define DEFAULT_fmPcdPlcrErrorExceptions (FM_PCD_EX_PLCR_DOUBLE_ECC | FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
47895 +#define DEFAULT_fmPcdPlcrExceptions 0
47896 +#define DEFAULT_fmPcdPrsErrorExceptions (FM_PCD_EX_PRS_DOUBLE_ECC)
47897 +
47898 +#define DEFAULT_fmPcdPrsExceptions FM_PCD_EX_PRS_SINGLE_ECC
47899 +#define DEFAULT_numOfUsedProfilesPerWindow 16
47900 +#define DEFAULT_numOfSharedPlcrProfiles 4
47901 +
47902 +/****************************/
47903 +/* Network defines */
47904 +/****************************/
47905 +#define UDP_HEADER_SIZE 8
47906 +
47907 +#define ESP_SPI_OFFSET 0
47908 +#define ESP_SPI_SIZE 4
47909 +#define ESP_SEQ_NUM_OFFSET ESP_SPI_SIZE
47910 +#define ESP_SEQ_NUM_SIZE 4
47911 +
47912 +/****************************/
47913 +/* General defines */
47914 +/****************************/
47915 +#define ILLEGAL_CLS_PLAN 0xff
47916 +#define ILLEGAL_NETENV 0xff
47917 +
47918 +#define FM_PCD_MAX_NUM_OF_ALIAS_HDRS 3
47919 +
47920 +/****************************/
47921 +/* Error defines */
47922 +/****************************/
47923 +
47924 +#define FM_PCD_EX_PLCR_DOUBLE_ECC 0x20000000
47925 +#define FM_PCD_EX_PLCR_INIT_ENTRY_ERROR 0x10000000
47926 +#define FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE 0x08000000
47927 +#define FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE 0x04000000
47928 +
47929 +#define GET_FM_PCD_EXCEPTION_FLAG(bitMask, exception) \
47930 +switch (exception){ \
47931 + case e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC: \
47932 + bitMask = FM_EX_KG_DOUBLE_ECC; break; \
47933 + case e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC: \
47934 + bitMask = FM_PCD_EX_PLCR_DOUBLE_ECC; break; \
47935 + case e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW: \
47936 + bitMask = FM_EX_KG_KEYSIZE_OVERFLOW; break; \
47937 + case e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR: \
47938 + bitMask = FM_PCD_EX_PLCR_INIT_ENTRY_ERROR; break; \
47939 + case e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE: \
47940 + bitMask = FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE; break; \
47941 + case e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE: \
47942 + bitMask = FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE; break; \
47943 + case e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC: \
47944 + bitMask = FM_PCD_EX_PRS_DOUBLE_ECC; break; \
47945 + case e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC: \
47946 + bitMask = FM_PCD_EX_PRS_SINGLE_ECC; break; \
47947 + default: bitMask = 0;break;}
47948 +
47949 +/***********************************************************************/
47950 +/* Policer defines */
47951 +/***********************************************************************/
47952 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
47953 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
47954 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
47955 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
47956 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
47957 +
47958 +/***********************************************************************/
47959 +/* Memory map */
47960 +/***********************************************************************/
47961 +#if defined(__MWERKS__) && !defined(__GNUC__)
47962 +#pragma pack(push,1)
47963 +#endif /* defined(__MWERKS__) && ... */
47964 +
47965 +
47966 +typedef struct {
47967 +/* General Configuration and Status Registers */
47968 + volatile uint32_t fmpl_gcr; /* 0x000 FMPL_GCR - FM Policer General Configuration */
47969 + volatile uint32_t fmpl_gsr; /* 0x004 FMPL_GSR - FM Policer Global Status Register */
47970 + volatile uint32_t fmpl_evr; /* 0x008 FMPL_EVR - FM Policer Event Register */
47971 + volatile uint32_t fmpl_ier; /* 0x00C FMPL_IER - FM Policer Interrupt Enable Register */
47972 + volatile uint32_t fmpl_ifr; /* 0x010 FMPL_IFR - FM Policer Interrupt Force Register */
47973 + volatile uint32_t fmpl_eevr; /* 0x014 FMPL_EEVR - FM Policer Error Event Register */
47974 + volatile uint32_t fmpl_eier; /* 0x018 FMPL_EIER - FM Policer Error Interrupt Enable Register */
47975 + volatile uint32_t fmpl_eifr; /* 0x01C FMPL_EIFR - FM Policer Error Interrupt Force Register */
47976 +/* Global Statistic Counters */
47977 + volatile uint32_t fmpl_rpcnt; /* 0x020 FMPL_RPC - FM Policer RED Packets Counter */
47978 + volatile uint32_t fmpl_ypcnt; /* 0x024 FMPL_YPC - FM Policer YELLOW Packets Counter */
47979 + volatile uint32_t fmpl_rrpcnt; /* 0x028 FMPL_RRPC - FM Policer Recolored RED Packet Counter */
47980 + volatile uint32_t fmpl_rypcnt; /* 0x02C FMPL_RYPC - FM Policer Recolored YELLOW Packet Counter */
47981 + volatile uint32_t fmpl_tpcnt; /* 0x030 FMPL_TPC - FM Policer Total Packet Counter */
47982 + volatile uint32_t fmpl_flmcnt; /* 0x034 FMPL_FLMC - FM Policer Frame Length Mismatch Counter */
47983 + volatile uint32_t fmpl_res0[21]; /* 0x038 - 0x08B Reserved */
47984 +/* Profile RAM Access Registers */
47985 + volatile uint32_t fmpl_par; /* 0x08C FMPL_PAR - FM Policer Profile Action Register*/
47986 + t_FmPcdPlcrProfileRegs profileRegs;
47987 +/* Error Capture Registers */
47988 + volatile uint32_t fmpl_serc; /* 0x100 FMPL_SERC - FM Policer Soft Error Capture */
47989 + volatile uint32_t fmpl_upcr; /* 0x104 FMPL_UPCR - FM Policer Uninitialized Profile Capture Register */
47990 + volatile uint32_t fmpl_res2; /* 0x108 Reserved */
47991 +/* Debug Registers */
47992 + volatile uint32_t fmpl_res3[61]; /* 0x10C-0x200 Reserved Debug*/
47993 +/* Profile Selection Mapping Registers Per Port-ID (n=1-11, 16) */
47994 + volatile uint32_t fmpl_dpmr; /* 0x200 FMPL_DPMR - FM Policer Default Mapping Register */
47995 + volatile uint32_t fmpl_pmr[63]; /*+default 0x204-0x2FF FMPL_PMR1 - FMPL_PMR63, - FM Policer Profile Mapping Registers.
47996 + (for port-ID 1-11, only for supported Port-ID registers) */
47997 +} t_FmPcdPlcrRegs;
47998 +
47999 +#if defined(__MWERKS__) && !defined(__GNUC__)
48000 +#pragma pack(pop)
48001 +#endif /* defined(__MWERKS__) && ... */
48002 +
48003 +
48004 +/***********************************************************************/
48005 +/* Driver's internal structures */
48006 +/***********************************************************************/
48007 +
48008 +typedef struct {
48009 + bool known;
48010 + uint8_t id;
48011 +} t_FmPcdKgSchemesExtractsEntry;
48012 +
48013 +typedef struct {
48014 + t_FmPcdKgSchemesExtractsEntry extractsArray[FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
48015 +} t_FmPcdKgSchemesExtracts;
48016 +
48017 +typedef struct {
48018 + t_Handle h_Manip;
48019 + bool keepRes;
48020 + e_FmPcdEngine nextEngine;
48021 + uint8_t parseCode;
48022 +} t_FmPcdInfoForManip;
48023 +
48024 +/**************************************************************************//**
48025 + @Description A structure of parameters to communicate
48026 + between the port and PCD regarding the KG scheme.
48027 +*//***************************************************************************/
48028 +typedef struct {
48029 + uint8_t netEnvId; /* in */
48030 + uint8_t numOfDistinctionUnits; /* in */
48031 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* in */
48032 + uint32_t vector; /* out */
48033 +} t_NetEnvParams;
48034 +
48035 +typedef struct {
48036 + bool allocated;
48037 + uint8_t ownerId; /* guestId for KG in multi-partition only.
48038 + portId for PLCR in any environment */
48039 +} t_FmPcdAllocMng;
48040 +
48041 +typedef struct {
48042 + volatile bool lock;
48043 + bool used;
48044 + uint8_t owners;
48045 + uint8_t netEnvId;
48046 + uint8_t guestId;
48047 + uint8_t baseEntry;
48048 + uint16_t sizeOfGrp;
48049 + protocolOpt_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
48050 +} t_FmPcdKgClsPlanGrp;
48051 +
48052 +typedef struct {
48053 + t_Handle h_FmPcd;
48054 + uint8_t schemeId;
48055 + t_FmPcdLock *p_Lock;
48056 + bool valid;
48057 + uint8_t netEnvId;
48058 + uint8_t owners;
48059 + uint32_t matchVector;
48060 + uint32_t ccUnits;
48061 + bool nextRelativePlcrProfile;
48062 + uint16_t relativeProfileId;
48063 + uint16_t numOfProfiles;
48064 + t_FmPcdKgKeyOrder orderedArray;
48065 + e_FmPcdEngine nextEngine;
48066 + e_FmPcdDoneAction doneAction;
48067 + bool requiredActionFlag;
48068 + uint32_t requiredAction;
48069 + bool extractedOrs;
48070 + uint8_t bitOffsetInPlcrProfile;
48071 + bool directPlcr;
48072 +#if (DPAA_VERSION >= 11)
48073 + bool vspe;
48074 +#endif
48075 +} t_FmPcdKgScheme;
48076 +
48077 +typedef union {
48078 + struct fman_kg_scheme_regs schemeRegs;
48079 + struct fman_kg_pe_regs portRegs;
48080 + struct fman_kg_cp_regs clsPlanRegs;
48081 +} u_FmPcdKgIndirectAccessRegs;
48082 +
48083 +typedef struct {
48084 + struct fman_kg_regs *p_FmPcdKgRegs;
48085 + uint32_t schemeExceptionsBitMask;
48086 + uint8_t numOfSchemes;
48087 + t_Handle h_HwSpinlock;
48088 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
48089 + t_FmPcdKgScheme schemes[FM_PCD_KG_NUM_OF_SCHEMES];
48090 + t_FmPcdKgClsPlanGrp clsPlanGrps[FM_MAX_NUM_OF_PORTS];
48091 + uint8_t emptyClsPlanGrpId;
48092 + t_FmPcdAllocMng schemesMng[FM_PCD_KG_NUM_OF_SCHEMES]; /* only for MASTER ! */
48093 + t_FmPcdAllocMng clsPlanBlocksMng[FM_PCD_MAX_NUM_OF_CLS_PLANS/CLS_PLAN_NUM_PER_GRP];
48094 + u_FmPcdKgIndirectAccessRegs *p_IndirectAccessRegs;
48095 +} t_FmPcdKg;
48096 +
48097 +typedef struct {
48098 + uint16_t profilesBase;
48099 + uint16_t numOfProfiles;
48100 + t_Handle h_FmPort;
48101 +} t_FmPcdPlcrMapParam;
48102 +
48103 +typedef struct {
48104 + uint16_t absoluteProfileId;
48105 + t_Handle h_FmPcd;
48106 + bool valid;
48107 + t_FmPcdLock *p_Lock;
48108 + t_FmPcdAllocMng profilesMng;
48109 + bool requiredActionFlag;
48110 + uint32_t requiredAction;
48111 + e_FmPcdEngine nextEngineOnGreen; /**< Green next engine type */
48112 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Green next engine params */
48113 +
48114 + e_FmPcdEngine nextEngineOnYellow; /**< Yellow next engine type */
48115 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Yellow next engine params */
48116 +
48117 + e_FmPcdEngine nextEngineOnRed; /**< Red next engine type */
48118 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Red next engine params */
48119 +} t_FmPcdPlcrProfile;
48120 +
48121 +typedef struct {
48122 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
48123 + uint16_t partPlcrProfilesBase;
48124 + uint16_t partNumOfPlcrProfiles;
48125 + t_FmPcdPlcrProfile profiles[FM_PCD_PLCR_NUM_ENTRIES];
48126 + uint16_t numOfSharedProfiles;
48127 + uint16_t sharedProfilesIds[FM_PCD_PLCR_NUM_ENTRIES];
48128 + t_FmPcdPlcrMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
48129 + t_Handle h_HwSpinlock;
48130 + t_Handle h_SwSpinlock;
48131 +} t_FmPcdPlcr;
48132 +
48133 +typedef struct {
48134 + uint32_t *p_SwPrsCode;
48135 + uint32_t *p_CurrSwPrs;
48136 + uint8_t currLabel;
48137 + struct fman_prs_regs *p_FmPcdPrsRegs;
48138 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
48139 + uint32_t fmPcdPrsPortIdStatistics;
48140 +} t_FmPcdPrs;
48141 +
48142 +typedef struct {
48143 + struct {
48144 + e_NetHeaderType hdr;
48145 + protocolOpt_t opt; /* only one option !! */
48146 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
48147 +} t_FmPcdIntDistinctionUnit;
48148 +
48149 +typedef struct {
48150 + e_NetHeaderType hdr;
48151 + protocolOpt_t opt; /* only one option !! */
48152 + e_NetHeaderType aliasHdr;
48153 +} t_FmPcdNetEnvAliases;
48154 +
48155 +typedef struct {
48156 + uint8_t netEnvId;
48157 + t_Handle h_FmPcd;
48158 + t_Handle h_Spinlock;
48159 + bool used;
48160 + uint8_t owners;
48161 + uint8_t clsPlanGrpId;
48162 + t_FmPcdIntDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
48163 + uint32_t unitsVectors[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
48164 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
48165 + uint32_t macsecVector;
48166 + t_FmPcdNetEnvAliases aliasHdrs[FM_PCD_MAX_NUM_OF_ALIAS_HDRS];
48167 +} t_FmPcdNetEnv;
48168 +
48169 +typedef struct {
48170 + struct fman_prs_cfg dfltCfg;
48171 + bool plcrAutoRefresh;
48172 + uint16_t prsMaxParseCycleLimit;
48173 +} t_FmPcdDriverParam;
48174 +
48175 +typedef struct {
48176 + t_Handle h_Fm;
48177 + t_Handle h_FmMuram;
48178 + t_FmRevisionInfo fmRevInfo;
48179 +
48180 + uint64_t physicalMuramBase;
48181 +
48182 + t_Handle h_Spinlock;
48183 + t_List freeLocksLst;
48184 + t_List acquiredLocksLst;
48185 +
48186 + t_Handle h_IpcSession; /* relevant for guest only */
48187 + bool enabled;
48188 + uint8_t guestId; /**< Guest Partition Id */
48189 + uint8_t numOfEnabledGuestPartitionsPcds;
48190 + char fmPcdModuleName[MODULE_NAME_SIZE];
48191 + char fmPcdIpcHandlerModuleName[MODULE_NAME_SIZE]; /* relevant for guest only - this is the master's name */
48192 + t_FmPcdNetEnv netEnvs[FM_MAX_NUM_OF_PORTS];
48193 + t_FmPcdKg *p_FmPcdKg;
48194 + t_FmPcdPlcr *p_FmPcdPlcr;
48195 + t_FmPcdPrs *p_FmPcdPrs;
48196 +
48197 + void *p_CcShadow; /**< CC MURAM shadow */
48198 + uint32_t ccShadowSize;
48199 + uint32_t ccShadowAlign;
48200 + volatile bool shadowLock;
48201 + t_Handle h_ShadowSpinlock;
48202 +
48203 + t_Handle h_Hc;
48204 +
48205 + uint32_t exceptions;
48206 + t_FmPcdExceptionCallback *f_Exception;
48207 + t_FmPcdIdExceptionCallback *f_FmPcdIndexedException;
48208 + t_Handle h_App;
48209 + uintptr_t ipv6FrameIdAddr;
48210 + uintptr_t capwapFrameIdAddr;
48211 + bool advancedOffloadSupport;
48212 +
48213 + t_FmPcdDriverParam *p_FmPcdDriverParam;
48214 +} t_FmPcd;
48215 +
48216 +#if (DPAA_VERSION >= 11)
48217 +typedef uint8_t t_FmPcdFrmReplicUpdateType;
48218 +#define FRM_REPLIC_UPDATE_COUNTER 0x01
48219 +#define FRM_REPLIC_UPDATE_INFO 0x02
48220 +#endif /* (DPAA_VERSION >= 11) */
48221 +/***********************************************************************/
48222 +/* PCD internal routines */
48223 +/***********************************************************************/
48224 +
48225 +t_Error PcdGetVectorForOpt(t_FmPcd *p_FmPcd, uint8_t netEnvId, protocolOpt_t opt, uint32_t *p_Vector);
48226 +t_Error PcdGetUnitsVector(t_FmPcd *p_FmPcd, t_NetEnvParams *p_Params);
48227 +bool PcdNetEnvIsUnitWithoutOpts(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint32_t unitVector);
48228 +t_Error PcdGetClsPlanGrpParams(t_FmPcd *p_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_GrpParams);
48229 +void FmPcdSetClsPlanGrpId(t_FmPcd *p_FmPcd, uint8_t netEnvId, uint8_t clsPlanGrpId);
48230 +e_NetHeaderType FmPcdGetAliasHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
48231 +uint8_t FmPcdNetEnvGetUnitIdForSingleHdr(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
48232 +uint8_t FmPcdNetEnvGetUnitId(t_FmPcd *p_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr, bool interchangeable, protocolOpt_t opt);
48233 +
48234 +t_Error FmPcdManipBuildIpReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, bool isIpv4, uint8_t groupId);
48235 +t_Error FmPcdManipDeleteIpReassmSchemes(t_Handle h_Manip);
48236 +t_Error FmPcdManipBuildCapwapReassmScheme(t_FmPcd *p_FmPcd, t_Handle h_NetEnv, t_Handle h_CcTree, t_Handle h_Manip, uint8_t groupId);
48237 +t_Error FmPcdManipDeleteCapwapReassmSchemes(t_Handle h_Manip);
48238 +bool FmPcdManipIpReassmIsIpv6Hdr(t_Handle h_Manip);
48239 +
48240 +t_Handle KgConfig( t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
48241 +t_Error KgInit(t_FmPcd *p_FmPcd);
48242 +t_Error KgFree(t_FmPcd *p_FmPcd);
48243 +void KgSetClsPlan(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanSet *p_Set);
48244 +bool KgIsSchemeAlwaysDirect(t_Handle h_FmPcd, uint8_t schemeId);
48245 +void KgEnable(t_FmPcd *p_FmPcd);
48246 +void KgDisable(t_FmPcd *p_FmPcd);
48247 +t_Error KgAllocClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t *p_First);
48248 +void KgFreeClsPlanEntries(t_Handle h_FmPcd, uint16_t numOfClsPlanEntries, uint8_t guestId, uint8_t base);
48249 +
48250 +/* only for MULTI partittion */
48251 +t_Error FmPcdKgAllocSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
48252 +t_Error FmPcdKgFreeSchemes(t_Handle h_FmPcd, uint8_t numOfSchemes, uint8_t guestId, uint8_t *p_SchemesIds);
48253 +/* only for SINGLE partittion */
48254 +t_Error KgBindPortToSchemes(t_Handle h_FmPcd , uint8_t hardwarePortId, uint32_t spReg);
48255 +
48256 +t_FmPcdLock *FmPcdAcquireLock(t_Handle h_FmPcd);
48257 +void FmPcdReleaseLock(t_Handle h_FmPcd, t_FmPcdLock *p_Lock);
48258 +
48259 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams);
48260 +t_Error PlcrInit(t_FmPcd *p_FmPcd);
48261 +t_Error PlcrFree(t_FmPcd *p_FmPcd);
48262 +void PlcrEnable(t_FmPcd *p_FmPcd);
48263 +void PlcrDisable(t_FmPcd *p_FmPcd);
48264 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
48265 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId);
48266 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
48267 + uint8_t hardwarePortId,
48268 + uint16_t numOfProfiles,
48269 + uint16_t base);
48270 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId);
48271 +
48272 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams);
48273 +t_Error PrsInit(t_FmPcd *p_FmPcd);
48274 +void PrsEnable(t_FmPcd *p_FmPcd);
48275 +void PrsDisable(t_FmPcd *p_FmPcd);
48276 +void PrsFree(t_FmPcd *p_FmPcd );
48277 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include);
48278 +
48279 +t_Error FmPcdCcGetGrpParams(t_Handle treeId, uint8_t grpId, uint32_t *p_GrpBits, uint8_t *p_GrpBase);
48280 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
48281 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
48282 +uint16_t FmPcdCcGetNumOfKeys(t_Handle h_CcNode);
48283 +t_Error ValidateNextEngineParams(t_Handle h_FmPcd, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams, e_FmPcdCcStatsMode supportedStatsMode);
48284 +
48285 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
48286 +t_Error FmPcdManipCheckParamsForCcNextEngine(t_FmPcdCcNextEngineParams *p_InfoForManip, uint32_t *requiredAction);
48287 +void FmPcdManipUpdateAdResultForCc(t_Handle h_Manip,
48288 + t_FmPcdCcNextEngineParams *p_CcNextEngineParams,
48289 + t_Handle p_Ad,
48290 + t_Handle *p_AdNewPtr);
48291 +void FmPcdManipUpdateAdContLookupForCc(t_Handle h_Manip, t_Handle p_Ad, t_Handle *p_AdNew, uint32_t adTableOffset);
48292 +void FmPcdManipUpdateOwner(t_Handle h_Manip, bool add);
48293 +t_Error FmPcdManipCheckParamsWithCcNodeParams(t_Handle h_Manip, t_Handle h_FmPcdCcNode);
48294 +#ifdef FM_CAPWAP_SUPPORT
48295 +t_Handle FmPcdManipApplSpecificBuild(void);
48296 +bool FmPcdManipIsCapwapApplSpecific(t_Handle h_Manip);
48297 +#endif /* FM_CAPWAP_SUPPORT */
48298 +#if (DPAA_VERSION >= 11)
48299 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup);
48300 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup, bool add);
48301 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup, void *p_Ad, t_Handle *h_AdNew);
48302 +
48303 +void FmPcdCcGetAdTablesThatPointOnReplicGroup(t_Handle h_Node,
48304 + t_Handle h_ReplicGroup,
48305 + t_List *p_AdTables,
48306 + uint32_t *p_NumOfAdTables);
48307 +#endif /* (DPAA_VERSION >= 11) */
48308 +
48309 +void EnqueueNodeInfoToRelevantLst(t_List *p_List, t_CcNodeInformation *p_CcInfo, t_Handle h_Spinlock);
48310 +void DequeueNodeInfoFromRelevantLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
48311 +t_CcNodeInformation* FindNodeInfoInReleventLst(t_List *p_List, t_Handle h_Info, t_Handle h_Spinlock);
48312 +t_List *FmPcdManipGetSpinlock(t_Handle h_Manip);
48313 +t_List *FmPcdManipGetNodeLstPointedOnThisManip(t_Handle h_Manip);
48314 +
48315 +typedef struct
48316 +{
48317 + t_Handle h_StatsAd;
48318 + t_Handle h_StatsCounters;
48319 +#if (DPAA_VERSION >= 11)
48320 + t_Handle h_StatsFLRs;
48321 +#endif /* (DPAA_VERSION >= 11) */
48322 +} t_FmPcdCcStatsParams;
48323 +
48324 +void NextStepAd(t_Handle h_Ad,
48325 + t_FmPcdCcStatsParams *p_FmPcdCcStatsParams,
48326 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams,
48327 + t_FmPcd *p_FmPcd);
48328 +void ReleaseLst(t_List *p_List);
48329 +
48330 +static __inline__ t_Handle FmPcdGetMuramHandle(t_Handle h_FmPcd)
48331 +{
48332 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48333 + ASSERT_COND(p_FmPcd);
48334 + return p_FmPcd->h_FmMuram;
48335 +}
48336 +
48337 +static __inline__ uint64_t FmPcdGetMuramPhysBase(t_Handle h_FmPcd)
48338 +{
48339 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48340 + ASSERT_COND(p_FmPcd);
48341 + return p_FmPcd->physicalMuramBase;
48342 +}
48343 +
48344 +static __inline__ uint32_t FmPcdLockSpinlock(t_FmPcdLock *p_Lock)
48345 +{
48346 + ASSERT_COND(p_Lock);
48347 + return XX_LockIntrSpinlock(p_Lock->h_Spinlock);
48348 +}
48349 +
48350 +static __inline__ void FmPcdUnlockSpinlock(t_FmPcdLock *p_Lock, uint32_t flags)
48351 +{
48352 + ASSERT_COND(p_Lock);
48353 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, flags);
48354 +}
48355 +
48356 +static __inline__ bool FmPcdLockTryLock(t_FmPcdLock *p_Lock)
48357 +{
48358 + uint32_t intFlags;
48359 +
48360 + ASSERT_COND(p_Lock);
48361 + intFlags = XX_LockIntrSpinlock(p_Lock->h_Spinlock);
48362 + if (p_Lock->flag)
48363 + {
48364 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
48365 + return FALSE;
48366 + }
48367 + p_Lock->flag = TRUE;
48368 + XX_UnlockIntrSpinlock(p_Lock->h_Spinlock, intFlags);
48369 + return TRUE;
48370 +}
48371 +
48372 +static __inline__ void FmPcdLockUnlock(t_FmPcdLock *p_Lock)
48373 +{
48374 + ASSERT_COND(p_Lock);
48375 + p_Lock->flag = FALSE;
48376 +}
48377 +
48378 +
48379 +#endif /* __FM_PCD_H */
48380 --- /dev/null
48381 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_pcd_ipc.h
48382 @@ -0,0 +1,280 @@
48383 +/*
48384 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48385 + *
48386 + * Redistribution and use in source and binary forms, with or without
48387 + * modification, are permitted provided that the following conditions are met:
48388 + * * Redistributions of source code must retain the above copyright
48389 + * notice, this list of conditions and the following disclaimer.
48390 + * * Redistributions in binary form must reproduce the above copyright
48391 + * notice, this list of conditions and the following disclaimer in the
48392 + * documentation and/or other materials provided with the distribution.
48393 + * * Neither the name of Freescale Semiconductor nor the
48394 + * names of its contributors may be used to endorse or promote products
48395 + * derived from this software without specific prior written permission.
48396 + *
48397 + *
48398 + * ALTERNATIVELY, this software may be distributed under the terms of the
48399 + * GNU General Public License ("GPL") as published by the Free Software
48400 + * Foundation, either version 2 of that License or (at your option) any
48401 + * later version.
48402 + *
48403 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48404 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48405 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48406 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48407 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48408 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48409 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48410 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48411 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48412 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48413 + */
48414 +
48415 +
48416 +/**************************************************************************//**
48417 + @File fm_pcd_ipc.h
48418 +
48419 + @Description FM PCD Inter-Partition prototypes, structures and definitions.
48420 +*//***************************************************************************/
48421 +#ifndef __FM_PCD_IPC_H
48422 +#define __FM_PCD_IPC_H
48423 +
48424 +#include "std_ext.h"
48425 +
48426 +
48427 +/**************************************************************************//**
48428 + @Group FM_grp Frame Manager API
48429 +
48430 + @Description FM API functions, definitions and enums
48431 +
48432 + @{
48433 +*//***************************************************************************/
48434 +
48435 +
48436 +#if defined(__MWERKS__) && !defined(__GNUC__)
48437 +#pragma pack(push,1)
48438 +#endif /* defined(__MWERKS__) && ... */
48439 +
48440 +/**************************************************************************//**
48441 + @Description Structure for getting a sw parser address according to a label
48442 + Fields commented 'IN' are passed by the port module to be used
48443 + by the FM module.
48444 + Fields commented 'OUT' will be filled by FM before returning to port.
48445 +*//***************************************************************************/
48446 +typedef _Packed struct t_FmPcdIpcSwPrsLable
48447 +{
48448 + uint32_t enumHdr; /**< IN. The existence of this header will invoke
48449 + the sw parser code. */
48450 + uint8_t indexPerHdr; /**< IN. Normally 0, if more than one sw parser
48451 + attachments for the same header, use this
48452 +
48453 + index to distinguish between them. */
48454 +} _PackedType t_FmPcdIpcSwPrsLable;
48455 +
48456 +/**************************************************************************//**
48457 + @Description Structure for port-PCD communication.
48458 + Fields commented 'IN' are passed by the port module to be used
48459 + by the FM module.
48460 + Fields commented 'OUT' will be filled by FM before returning to port.
48461 + Some fields are optional (depending on configuration) and
48462 + will be analized by the port and FM modules accordingly.
48463 +*//***************************************************************************/
48464 +
48465 +typedef struct t_FmPcdIpcKgSchemesParams
48466 +{
48467 + uint8_t guestId;
48468 + uint8_t numOfSchemes;
48469 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
48470 +} _PackedType t_FmPcdIpcKgSchemesParams;
48471 +
48472 +typedef struct t_FmPcdIpcKgClsPlanParams
48473 +{
48474 + uint8_t guestId;
48475 + uint16_t numOfClsPlanEntries;
48476 + uint8_t clsPlanBase;
48477 +} _PackedType t_FmPcdIpcKgClsPlanParams;
48478 +
48479 +typedef _Packed struct t_FmPcdIpcPrsIncludePort
48480 +{
48481 + uint8_t hardwarePortId;
48482 + bool include;
48483 +} _PackedType t_FmPcdIpcPrsIncludePort;
48484 +
48485 +
48486 +#define FM_PCD_MAX_REPLY_SIZE 16
48487 +#define FM_PCD_MAX_MSG_SIZE 36
48488 +#define FM_PCD_MAX_REPLY_BODY_SIZE 36
48489 +
48490 +typedef _Packed struct {
48491 + uint32_t msgId;
48492 + uint8_t msgBody[FM_PCD_MAX_MSG_SIZE];
48493 +} _PackedType t_FmPcdIpcMsg;
48494 +
48495 +typedef _Packed struct t_FmPcdIpcReply {
48496 + uint32_t error;
48497 + uint8_t replyBody[FM_PCD_MAX_REPLY_BODY_SIZE];
48498 +} _PackedType t_FmPcdIpcReply;
48499 +
48500 +typedef _Packed struct t_FmIpcResourceAllocParams {
48501 + uint8_t guestId;
48502 + uint16_t base;
48503 + uint16_t num;
48504 +}_PackedType t_FmIpcResourceAllocParams;
48505 +
48506 +#if defined(__MWERKS__) && !defined(__GNUC__)
48507 +#pragma pack(pop)
48508 +#endif /* defined(__MWERKS__) && ... */
48509 +
48510 +
48511 +
48512 +/**************************************************************************//**
48513 + @Function FM_PCD_ALLOC_KG_SCHEMES
48514 +
48515 + @Description Used by FM PCD front-end in order to allocate KG resources
48516 +
48517 + @Param[in/out] t_FmPcdIpcKgAllocParams Pointer
48518 +*//***************************************************************************/
48519 +#define FM_PCD_ALLOC_KG_SCHEMES 3
48520 +
48521 +/**************************************************************************//**
48522 + @Function FM_PCD_FREE_KG_SCHEMES
48523 +
48524 + @Description Used by FM PCD front-end in order to Free KG resources
48525 +
48526 + @Param[in/out] t_FmPcdIpcKgSchemesParams Pointer
48527 +*//***************************************************************************/
48528 +#define FM_PCD_FREE_KG_SCHEMES 4
48529 +
48530 +/**************************************************************************//**
48531 + @Function FM_PCD_ALLOC_PROFILES
48532 +
48533 + @Description Used by FM PCD front-end in order to allocate Policer profiles
48534 +
48535 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
48536 +*//***************************************************************************/
48537 +#define FM_PCD_ALLOC_PROFILES 5
48538 +
48539 +/**************************************************************************//**
48540 + @Function FM_PCD_FREE_PROFILES
48541 +
48542 + @Description Used by FM PCD front-end in order to Free Policer profiles
48543 +
48544 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
48545 +*//***************************************************************************/
48546 +#define FM_PCD_FREE_PROFILES 6
48547 +
48548 +/**************************************************************************//**
48549 + @Function FM_PCD_SET_PORT_PROFILES
48550 +
48551 + @Description Used by FM PCD front-end in order to allocate Policer profiles
48552 + for specific port
48553 +
48554 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
48555 +*//***************************************************************************/
48556 +#define FM_PCD_SET_PORT_PROFILES 7
48557 +
48558 +/**************************************************************************//**
48559 + @Function FM_PCD_CLEAR_PORT_PROFILES
48560 +
48561 + @Description Used by FM PCD front-end in order to allocate Policer profiles
48562 + for specific port
48563 +
48564 + @Param[in/out] t_FmIpcResourceAllocParams Pointer
48565 +*//***************************************************************************/
48566 +#define FM_PCD_CLEAR_PORT_PROFILES 8
48567 +
48568 +/**************************************************************************//**
48569 + @Function FM_PCD_GET_PHYS_MURAM_BASE
48570 +
48571 + @Description Used by FM PCD front-end in order to get MURAM base address
48572 +
48573 + @Param[in/out] t_FmPcdIcPhysAddr Pointer
48574 +*//***************************************************************************/
48575 +#define FM_PCD_GET_PHYS_MURAM_BASE 9
48576 +
48577 +/**************************************************************************//**
48578 + @Function FM_PCD_GET_SW_PRS_OFFSET
48579 +
48580 + @Description Used by FM front-end to get the SW parser offset of the start of
48581 + code relevant to a given label.
48582 +
48583 + @Param[in/out] t_FmPcdIpcSwPrsLable Pointer
48584 +*//***************************************************************************/
48585 +#define FM_PCD_GET_SW_PRS_OFFSET 10
48586 +
48587 +/**************************************************************************//**
48588 + @Function FM_PCD_MASTER_IS_ENABLED
48589 +
48590 + @Description Used by FM front-end in order to verify
48591 + PCD enablement.
48592 +
48593 + @Param[in] bool Pointer
48594 +*//***************************************************************************/
48595 +#define FM_PCD_MASTER_IS_ENABLED 15
48596 +
48597 +/**************************************************************************//**
48598 + @Function FM_PCD_GUEST_DISABLE
48599 +
48600 + @Description Used by FM front-end to inform back-end when
48601 + front-end PCD is disabled
48602 +
48603 + @Param[in] None
48604 +*//***************************************************************************/
48605 +#define FM_PCD_GUEST_DISABLE 16
48606 +
48607 +/**************************************************************************//**
48608 + @Function FM_PCD_FREE_KG_CLSPLAN
48609 +
48610 + @Description Used by FM PCD front-end in order to Free KG classification plan entries
48611 +
48612 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
48613 +*//***************************************************************************/
48614 +#define FM_PCD_FREE_KG_CLSPLAN 22
48615 +
48616 +/**************************************************************************//**
48617 + @Function FM_PCD_ALLOC_KG_CLSPLAN
48618 +
48619 + @Description Used by FM PCD front-end in order to allocate KG classification plan entries
48620 +
48621 + @Param[in/out] t_FmPcdIpcKgClsPlanParams Pointer
48622 +*//***************************************************************************/
48623 +#define FM_PCD_ALLOC_KG_CLSPLAN 23
48624 +
48625 +/**************************************************************************//**
48626 + @Function FM_PCD_MASTER_IS_ALIVE
48627 +
48628 + @Description Used by FM front-end to check that back-end exists
48629 +
48630 + @Param[in] None
48631 +*//***************************************************************************/
48632 +#define FM_PCD_MASTER_IS_ALIVE 24
48633 +
48634 +/**************************************************************************//**
48635 + @Function FM_PCD_GET_COUNTER
48636 +
48637 + @Description Used by FM front-end to read PCD counters
48638 +
48639 + @Param[in/out] t_FmPcdIpcGetCounter Pointer
48640 +*//***************************************************************************/
48641 +#define FM_PCD_GET_COUNTER 25
48642 +
48643 +/**************************************************************************//**
48644 + @Function FM_PCD_PRS_INC_PORT_STATS
48645 +
48646 + @Description Used by FM front-end to set/clear statistics for port
48647 +
48648 + @Param[in/out] t_FmPcdIpcPrsIncludePort Pointer
48649 +*//***************************************************************************/
48650 +#define FM_PCD_PRS_INC_PORT_STATS 26
48651 +
48652 +#if (DPAA_VERSION >= 11)
48653 +/* TODO - doc */
48654 +#define FM_PCD_ALLOC_SP 27
48655 +#endif /* (DPAA_VERSION >= 11) */
48656 +
48657 +
48658 +/** @} */ /* end of FM_PCD_IPC_grp group */
48659 +/** @} */ /* end of FM_grp group */
48660 +
48661 +
48662 +#endif /* __FM_PCD_IPC_H */
48663 --- /dev/null
48664 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.c
48665 @@ -0,0 +1,1847 @@
48666 +/*
48667 + * Copyright 2008-2012 Freescale Semiconductor Inc.
48668 + *
48669 + * Redistribution and use in source and binary forms, with or without
48670 + * modification, are permitted provided that the following conditions are met:
48671 + * * Redistributions of source code must retain the above copyright
48672 + * notice, this list of conditions and the following disclaimer.
48673 + * * Redistributions in binary form must reproduce the above copyright
48674 + * notice, this list of conditions and the following disclaimer in the
48675 + * documentation and/or other materials provided with the distribution.
48676 + * * Neither the name of Freescale Semiconductor nor the
48677 + * names of its contributors may be used to endorse or promote products
48678 + * derived from this software without specific prior written permission.
48679 + *
48680 + *
48681 + * ALTERNATIVELY, this software may be distributed under the terms of the
48682 + * GNU General Public License ("GPL") as published by the Free Software
48683 + * Foundation, either version 2 of that License or (at your option) any
48684 + * later version.
48685 + *
48686 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
48687 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48688 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48689 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
48690 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
48691 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48692 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48693 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48694 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
48695 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48696 + */
48697 +
48698 +
48699 +/******************************************************************************
48700 + @File fm_plcr.c
48701 +
48702 + @Description FM PCD POLICER...
48703 +*//***************************************************************************/
48704 +#include <linux/math64.h>
48705 +#include "std_ext.h"
48706 +#include "error_ext.h"
48707 +#include "string_ext.h"
48708 +#include "debug_ext.h"
48709 +#include "net_ext.h"
48710 +#include "fm_ext.h"
48711 +
48712 +#include "fm_common.h"
48713 +#include "fm_pcd.h"
48714 +#include "fm_hc.h"
48715 +#include "fm_pcd_ipc.h"
48716 +#include "fm_plcr.h"
48717 +
48718 +
48719 +/****************************************/
48720 +/* static functions */
48721 +/****************************************/
48722 +
48723 +static uint32_t PlcrProfileLock(t_Handle h_Profile)
48724 +{
48725 + ASSERT_COND(h_Profile);
48726 + return FmPcdLockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
48727 +}
48728 +
48729 +static void PlcrProfileUnlock(t_Handle h_Profile, uint32_t intFlags)
48730 +{
48731 + ASSERT_COND(h_Profile);
48732 + FmPcdUnlockSpinlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock, intFlags);
48733 +}
48734 +
48735 +static bool PlcrProfileFlagTryLock(t_Handle h_Profile)
48736 +{
48737 + ASSERT_COND(h_Profile);
48738 + return FmPcdLockTryLock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
48739 +}
48740 +
48741 +static void PlcrProfileFlagUnlock(t_Handle h_Profile)
48742 +{
48743 + ASSERT_COND(h_Profile);
48744 + FmPcdLockUnlock(((t_FmPcdPlcrProfile *)h_Profile)->p_Lock);
48745 +}
48746 +
48747 +static uint32_t PlcrHwLock(t_Handle h_FmPcdPlcr)
48748 +{
48749 + ASSERT_COND(h_FmPcdPlcr);
48750 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock);
48751 +}
48752 +
48753 +static void PlcrHwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
48754 +{
48755 + ASSERT_COND(h_FmPcdPlcr);
48756 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_HwSpinlock, intFlags);
48757 +}
48758 +
48759 +static uint32_t PlcrSwLock(t_Handle h_FmPcdPlcr)
48760 +{
48761 + ASSERT_COND(h_FmPcdPlcr);
48762 + return XX_LockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock);
48763 +}
48764 +
48765 +static void PlcrSwUnlock(t_Handle h_FmPcdPlcr, uint32_t intFlags)
48766 +{
48767 + ASSERT_COND(h_FmPcdPlcr);
48768 + XX_UnlockIntrSpinlock(((t_FmPcdPlcr*)h_FmPcdPlcr)->h_SwSpinlock, intFlags);
48769 +}
48770 +
48771 +static bool IsProfileShared(t_Handle h_FmPcd, uint16_t absoluteProfileId)
48772 +{
48773 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
48774 + uint16_t i;
48775 +
48776 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, FALSE);
48777 +
48778 + for (i=0;i<p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles;i++)
48779 + if (p_FmPcd->p_FmPcdPlcr->sharedProfilesIds[i] == absoluteProfileId)
48780 + return TRUE;
48781 + return FALSE;
48782 +}
48783 +
48784 +static t_Error SetProfileNia(t_FmPcd *p_FmPcd, e_FmPcdEngine nextEngine, u_FmPcdPlcrNextEngineParams *p_NextEngineParams, uint32_t *nextAction)
48785 +{
48786 + uint32_t nia;
48787 + uint16_t absoluteProfileId;
48788 + uint8_t relativeSchemeId, physicalSchemeId;
48789 +
48790 + nia = FM_PCD_PLCR_NIA_VALID;
48791 +
48792 + switch (nextEngine)
48793 + {
48794 + case e_FM_PCD_DONE :
48795 + switch (p_NextEngineParams->action)
48796 + {
48797 + case e_FM_PCD_DROP_FRAME :
48798 + nia |= GET_NIA_BMI_AC_DISCARD_FRAME(p_FmPcd);
48799 + break;
48800 + case e_FM_PCD_ENQ_FRAME:
48801 + nia |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
48802 + break;
48803 + default:
48804 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48805 + }
48806 + break;
48807 + case e_FM_PCD_KG:
48808 + physicalSchemeId = FmPcdKgGetSchemeId(p_NextEngineParams->h_DirectScheme);
48809 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPcd, physicalSchemeId);
48810 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
48811 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, NO_MSG);
48812 + if (!FmPcdKgIsSchemeValidSw(p_NextEngineParams->h_DirectScheme))
48813 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid direct scheme."));
48814 + if (!KgIsSchemeAlwaysDirect(p_FmPcd, relativeSchemeId))
48815 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Policer Profile may point only to a scheme that is always direct."));
48816 + nia |= NIA_ENG_KG | NIA_KG_DIRECT | physicalSchemeId;
48817 + break;
48818 + case e_FM_PCD_PLCR:
48819 + absoluteProfileId = ((t_FmPcdPlcrProfile *)p_NextEngineParams->h_Profile)->absoluteProfileId;
48820 + if (!IsProfileShared(p_FmPcd, absoluteProfileId))
48821 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next profile must be a shared profile"));
48822 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
48823 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid profile "));
48824 + nia |= NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId;
48825 + break;
48826 + default:
48827 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
48828 + }
48829 +
48830 + *nextAction = nia;
48831 +
48832 + return E_OK;
48833 +}
48834 +
48835 +static uint32_t CalcFPP(uint32_t fpp)
48836 +{
48837 + if (fpp > 15)
48838 + return 15 - (0x1f - fpp);
48839 + else
48840 + return 16 + fpp;
48841 +}
48842 +
48843 +static void GetInfoRateReg(e_FmPcdPlcrRateMode rateMode,
48844 + uint32_t rate,
48845 + uint64_t tsuInTenthNano,
48846 + uint32_t fppShift,
48847 + uint64_t *p_Integer,
48848 + uint64_t *p_Fraction)
48849 +{
48850 + uint64_t tmp, div;
48851 +
48852 + if (rateMode == e_FM_PCD_PLCR_BYTE_MODE)
48853 + {
48854 + /* now we calculate the initial integer for the bigger rate */
48855 + /* from Kbps to Bytes/TSU */
48856 + tmp = (uint64_t)rate;
48857 + tmp *= 1000; /* kb --> b */
48858 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
48859 +
48860 + div = 1000000000; /* nano */
48861 + div *= 10; /* 10 nano */
48862 + div *= 8; /* bit to byte */
48863 + }
48864 + else
48865 + {
48866 + /* now we calculate the initial integer for the bigger rate */
48867 + /* from Kbps to Bytes/TSU */
48868 + tmp = (uint64_t)rate;
48869 + tmp *= tsuInTenthNano; /* bps --> bpTsu(in 10nano) */
48870 +
48871 + div = 1000000000; /* nano */
48872 + div *= 10; /* 10 nano */
48873 + }
48874 + *p_Integer = div64_u64(tmp<<fppShift, div);
48875 +
48876 + /* for calculating the fraction, we will recalculate cir and deduct the integer.
48877 + * For precision, we will multiply by 2^16. we do not divid back, since we write
48878 + * this value as fraction - see spec.
48879 + */
48880 + *p_Fraction = div64_u64(((tmp<<fppShift)<<16) - ((*p_Integer<<16)*div), div);
48881 +}
48882 +
48883 +/* .......... */
48884 +
48885 +static void CalcRates(uint32_t bitFor1Micro,
48886 + t_FmPcdPlcrNonPassthroughAlgParams *p_NonPassthroughAlgParam,
48887 + uint32_t *cir,
48888 + uint32_t *cbs,
48889 + uint32_t *pir_eir,
48890 + uint32_t *pbs_ebs,
48891 + uint32_t *fpp)
48892 +{
48893 + uint64_t integer, fraction;
48894 + uint32_t temp, tsuInTenthNanos;
48895 + uint8_t fppShift=0;
48896 +
48897 + /* we want the tsu to count 10 nano for better precision normally tsu is 3.9 nano, now we will get 39 */
48898 + tsuInTenthNanos = (uint32_t)(1000*10/(1 << bitFor1Micro));
48899 +
48900 + /* we choose the faster rate to calibrate fpp */
48901 + /* The meaning of this step:
48902 + * when fppShift is 0 it means all TS bits are treated as integer and TSU is the TS LSB count.
48903 + * In this configuration we calculate the integer and fraction that represent the higher infoRate
48904 + * When this is done, we can tell where we have "spare" unused bits and optimize the division of TS
48905 + * into "integer" and "fraction" where the logic is - as many bits as possible for integer at
48906 + * high rate, as many bits as possible for fraction at low rate.
48907 + */
48908 + if (p_NonPassthroughAlgParam->committedInfoRate > p_NonPassthroughAlgParam->peakOrExcessInfoRate)
48909 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
48910 + else
48911 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, 0, &integer, &fraction);
48912 +
48913 + /* we shift integer, as in cir/pir it is represented by the MSB 16 bits, and
48914 + * the LSB bits are for the fraction */
48915 + temp = (uint32_t)((integer<<16) & 0x00000000FFFFFFFF);
48916 + /* temp is effected by the rate. For low rates it may be as low as 0, and then we'll
48917 + * take max FP = 31.
48918 + * For high rates it will never exceed the 32 bit reg (after the 16 shift), as it is
48919 + * limited by the 10G physical port.
48920 + */
48921 + if (temp != 0)
48922 + {
48923 + /* In this case, the largest rate integer is non 0, if it does not occupy all (high) 16
48924 + * bits of the PIR_EIR we can use this fact and enlarge it to occupy all 16 bits.
48925 + * The logic is to have as many bits for integer in the higher rates, but if we have "0"s
48926 + * in the integer part of the cir/pir register, than these bits are wasted. So we want
48927 + * to use these bits for the fraction. in this way we will have for fraction - the number
48928 + * of "0" bits and the rest - for integer.
48929 + * In other words: For each bit we shift it in PIR_EIR, we move the FP in the TS
48930 + * one bit to the left - preserving the relationship and achieving more bits
48931 + * for integer in the TS.
48932 + */
48933 +
48934 + /* count zeroes left of the higher used bit (in order to shift the value such that
48935 + * unused bits may be used for fraction).
48936 + */
48937 + while ((temp & 0x80000000) == 0)
48938 + {
48939 + temp = temp << 1;
48940 + fppShift++;
48941 + }
48942 + if (fppShift > 15)
48943 + {
48944 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, ("timeStampPeriod to Information rate ratio is too small"));
48945 + return;
48946 + }
48947 + }
48948 + else
48949 + {
48950 + temp = (uint32_t)fraction; /* fraction will alyas be smaller than 2^16 */
48951 + if (!temp)
48952 + /* integer and fraction are 0, we set FP to its max val */
48953 + fppShift = 31;
48954 + else
48955 + {
48956 + /* integer was 0 but fraction is not. FP is 16 for the fraction,
48957 + * + all left zeroes of the fraction. */
48958 + fppShift=16;
48959 + /* count zeroes left of the higher used bit (in order to shift the value such that
48960 + * unused bits may be used for fraction).
48961 + */
48962 + while ((temp & 0x8000) == 0)
48963 + {
48964 + temp = temp << 1;
48965 + fppShift++;
48966 + }
48967 + }
48968 + }
48969 +
48970 + /*
48971 + * This means that the FM TS register will now be used so that 'fppShift' bits are for
48972 + * fraction and the rest for integer */
48973 + /* now we re-calculate cir and pir_eir with the calculated FP */
48974 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->committedInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
48975 + *cir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
48976 + GetInfoRateReg(p_NonPassthroughAlgParam->rateMode, p_NonPassthroughAlgParam->peakOrExcessInfoRate, tsuInTenthNanos, fppShift, &integer, &fraction);
48977 + *pir_eir = (uint32_t)(integer << 16 | (fraction & 0xFFFF));
48978 +
48979 + *cbs = p_NonPassthroughAlgParam->committedBurstSize;
48980 + *pbs_ebs = p_NonPassthroughAlgParam->peakOrExcessBurstSize;
48981 +
48982 + /* convert FP as it should be written to reg.
48983 + * 0-15 --> 16-31
48984 + * 16-31 --> 0-15
48985 + */
48986 + *fpp = CalcFPP(fppShift);
48987 +}
48988 +
48989 +static void WritePar(t_FmPcd *p_FmPcd, uint32_t par)
48990 +{
48991 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
48992 +
48993 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
48994 + WRITE_UINT32(p_FmPcdPlcrRegs->fmpl_par, par);
48995 +
48996 + while (GET_UINT32(p_FmPcdPlcrRegs->fmpl_par) & FM_PCD_PLCR_PAR_GO) ;
48997 +}
48998 +
48999 +static t_Error BuildProfileRegs(t_FmPcd *p_FmPcd,
49000 + t_FmPcdPlcrProfileParams *p_ProfileParams,
49001 + t_FmPcdPlcrProfileRegs *p_PlcrRegs)
49002 +{
49003 + t_Error err = E_OK;
49004 + uint32_t pemode, gnia, ynia, rnia, bitFor1Micro;
49005 +
49006 + ASSERT_COND(p_FmPcd);
49007 +
49008 + bitFor1Micro = FmGetTimeStampScale(p_FmPcd->h_Fm);
49009 + if (bitFor1Micro == 0)
49010 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Timestamp scale"));
49011 +
49012 +/* Set G, Y, R Nia */
49013 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnGreen, &(p_ProfileParams->paramsOnGreen), &gnia);
49014 + if (err)
49015 + RETURN_ERROR(MAJOR, err, NO_MSG);
49016 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnYellow, &(p_ProfileParams->paramsOnYellow), &ynia);
49017 + if (err)
49018 + RETURN_ERROR(MAJOR, err, NO_MSG);
49019 + err = SetProfileNia(p_FmPcd, p_ProfileParams->nextEngineOnRed, &(p_ProfileParams->paramsOnRed), &rnia);
49020 + if (err)
49021 + RETURN_ERROR(MAJOR, err, NO_MSG);
49022 +
49023 +/* Mode fmpl_pemode */
49024 + pemode = FM_PCD_PLCR_PEMODE_PI;
49025 +
49026 + switch (p_ProfileParams->algSelection)
49027 + {
49028 + case e_FM_PCD_PLCR_PASS_THROUGH:
49029 + p_PlcrRegs->fmpl_pecir = 0;
49030 + p_PlcrRegs->fmpl_pecbs = 0;
49031 + p_PlcrRegs->fmpl_pepepir_eir = 0;
49032 + p_PlcrRegs->fmpl_pepbs_ebs = 0;
49033 + p_PlcrRegs->fmpl_pelts = 0;
49034 + p_PlcrRegs->fmpl_pects = 0;
49035 + p_PlcrRegs->fmpl_pepts_ets = 0;
49036 + pemode &= ~FM_PCD_PLCR_PEMODE_ALG_MASK;
49037 + switch (p_ProfileParams->colorMode)
49038 + {
49039 + case e_FM_PCD_PLCR_COLOR_BLIND:
49040 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
49041 + switch (p_ProfileParams->color.dfltColor)
49042 + {
49043 + case e_FM_PCD_PLCR_GREEN:
49044 + pemode &= ~FM_PCD_PLCR_PEMODE_DEFC_MASK;
49045 + break;
49046 + case e_FM_PCD_PLCR_YELLOW:
49047 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_Y;
49048 + break;
49049 + case e_FM_PCD_PLCR_RED:
49050 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_R;
49051 + break;
49052 + case e_FM_PCD_PLCR_OVERRIDE:
49053 + pemode |= FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE;
49054 + break;
49055 + default:
49056 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49057 + }
49058 +
49059 + break;
49060 + case e_FM_PCD_PLCR_COLOR_AWARE:
49061 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
49062 + break;
49063 + default:
49064 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49065 + }
49066 + break;
49067 +
49068 + case e_FM_PCD_PLCR_RFC_2698:
49069 + /* Select algorithm MODE[ALG] = "01" */
49070 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC2698;
49071 + if (p_ProfileParams->nonPassthroughAlgParams.committedInfoRate > p_ProfileParams->nonPassthroughAlgParams.peakOrExcessInfoRate)
49072 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("in RFC2698 Peak rate must be equal or larger than committedInfoRate."));
49073 + goto cont_rfc;
49074 + case e_FM_PCD_PLCR_RFC_4115:
49075 + /* Select algorithm MODE[ALG] = "10" */
49076 + pemode |= FM_PCD_PLCR_PEMODE_ALG_RFC4115;
49077 +cont_rfc:
49078 + /* Select Color-Blind / Color-Aware operation (MODE[CBLND]) */
49079 + switch (p_ProfileParams->colorMode)
49080 + {
49081 + case e_FM_PCD_PLCR_COLOR_BLIND:
49082 + pemode |= FM_PCD_PLCR_PEMODE_CBLND;
49083 + break;
49084 + case e_FM_PCD_PLCR_COLOR_AWARE:
49085 + pemode &= ~FM_PCD_PLCR_PEMODE_CBLND;
49086 + /*In color aware more select override color interpretation (MODE[OVCLR]) */
49087 + switch (p_ProfileParams->color.override)
49088 + {
49089 + case e_FM_PCD_PLCR_GREEN:
49090 + pemode &= ~FM_PCD_PLCR_PEMODE_OVCLR_MASK;
49091 + break;
49092 + case e_FM_PCD_PLCR_YELLOW:
49093 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_Y;
49094 + break;
49095 + case e_FM_PCD_PLCR_RED:
49096 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_R;
49097 + break;
49098 + case e_FM_PCD_PLCR_OVERRIDE:
49099 + pemode |= FM_PCD_PLCR_PEMODE_OVCLR_G_NC;
49100 + break;
49101 + default:
49102 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49103 + }
49104 + break;
49105 + default:
49106 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49107 + }
49108 + /* Select Measurement Unit Mode to BYTE or PACKET (MODE[PKT]) */
49109 + switch (p_ProfileParams->nonPassthroughAlgParams.rateMode)
49110 + {
49111 + case e_FM_PCD_PLCR_BYTE_MODE :
49112 + pemode &= ~FM_PCD_PLCR_PEMODE_PKT;
49113 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.frameLengthSelection)
49114 + {
49115 + case e_FM_PCD_PLCR_L2_FRM_LEN:
49116 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L2;
49117 + break;
49118 + case e_FM_PCD_PLCR_L3_FRM_LEN:
49119 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L3;
49120 + break;
49121 + case e_FM_PCD_PLCR_L4_FRM_LEN:
49122 + pemode |= FM_PCD_PLCR_PEMODE_FLS_L4;
49123 + break;
49124 + case e_FM_PCD_PLCR_FULL_FRM_LEN:
49125 + pemode |= FM_PCD_PLCR_PEMODE_FLS_FULL;
49126 + break;
49127 + default:
49128 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49129 + }
49130 + switch (p_ProfileParams->nonPassthroughAlgParams.byteModeParams.rollBackFrameSelection)
49131 + {
49132 + case e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN:
49133 + pemode &= ~FM_PCD_PLCR_PEMODE_RBFLS;
49134 + break;
49135 + case e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN:
49136 + pemode |= FM_PCD_PLCR_PEMODE_RBFLS;
49137 + break;
49138 + default:
49139 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49140 + }
49141 + break;
49142 + case e_FM_PCD_PLCR_PACKET_MODE :
49143 + pemode |= FM_PCD_PLCR_PEMODE_PKT;
49144 + break;
49145 + default:
49146 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49147 + }
49148 + /* Select timeStamp floating point position (MODE[FPP]) to fit the actual traffic rates. For PACKET
49149 + mode with low traffic rates move the fixed point to the left to increase fraction accuracy. For BYTE
49150 + mode with high traffic rates move the fixed point to the right to increase integer accuracy. */
49151 +
49152 + /* Configure Traffic Parameters*/
49153 + {
49154 + uint32_t cir=0, cbs=0, pir_eir=0, pbs_ebs=0, fpp=0;
49155 +
49156 + CalcRates(bitFor1Micro, &p_ProfileParams->nonPassthroughAlgParams, &cir, &cbs, &pir_eir, &pbs_ebs, &fpp);
49157 +
49158 + /* Set Committed Information Rate (CIR) */
49159 + p_PlcrRegs->fmpl_pecir = cir;
49160 + /* Set Committed Burst Size (CBS). */
49161 + p_PlcrRegs->fmpl_pecbs = cbs;
49162 + /* Set Peak Information Rate (PIR_EIR used as PIR) */
49163 + p_PlcrRegs->fmpl_pepepir_eir = pir_eir;
49164 + /* Set Peak Burst Size (PBS_EBS used as PBS) */
49165 + p_PlcrRegs->fmpl_pepbs_ebs = pbs_ebs;
49166 +
49167 + /* Initialize the Metering Buckets to be full (write them with 0xFFFFFFFF. */
49168 + /* Peak Rate Token Bucket Size (PTS_ETS used as PTS) */
49169 + p_PlcrRegs->fmpl_pepts_ets = 0xFFFFFFFF;
49170 + /* Committed Rate Token Bucket Size (CTS) */
49171 + p_PlcrRegs->fmpl_pects = 0xFFFFFFFF;
49172 +
49173 + /* Set the FPP based on calculation */
49174 + pemode |= (fpp << FM_PCD_PLCR_PEMODE_FPP_SHIFT);
49175 + }
49176 + break; /* FM_PCD_PLCR_PEMODE_ALG_RFC2698 , FM_PCD_PLCR_PEMODE_ALG_RFC4115 */
49177 + default:
49178 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
49179 + }
49180 +
49181 + p_PlcrRegs->fmpl_pemode = pemode;
49182 +
49183 + p_PlcrRegs->fmpl_pegnia = gnia;
49184 + p_PlcrRegs->fmpl_peynia = ynia;
49185 + p_PlcrRegs->fmpl_pernia = rnia;
49186 +
49187 + /* Zero Counters */
49188 + p_PlcrRegs->fmpl_pegpc = 0;
49189 + p_PlcrRegs->fmpl_peypc = 0;
49190 + p_PlcrRegs->fmpl_perpc = 0;
49191 + p_PlcrRegs->fmpl_perypc = 0;
49192 + p_PlcrRegs->fmpl_perrpc = 0;
49193 +
49194 + return E_OK;
49195 +}
49196 +
49197 +static t_Error AllocSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
49198 +{
49199 + uint32_t profilesFound;
49200 + uint16_t i, k=0;
49201 + uint32_t intFlags;
49202 +
49203 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49204 +
49205 + if (!numOfProfiles)
49206 + return E_OK;
49207 +
49208 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
49209 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
49210 +
49211 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
49212 + /* Find numOfProfiles free profiles (may be spread) */
49213 + profilesFound = 0;
49214 + for (i=0;i<FM_PCD_PLCR_NUM_ENTRIES; i++)
49215 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
49216 + {
49217 + profilesFound++;
49218 + profilesIds[k] = i;
49219 + k++;
49220 + if (profilesFound == numOfProfiles)
49221 + break;
49222 + }
49223 +
49224 + if (profilesFound != numOfProfiles)
49225 + {
49226 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49227 + RETURN_ERROR(MAJOR, E_INVALID_STATE,NO_MSG);
49228 + }
49229 +
49230 + for (i = 0;i<k;i++)
49231 + {
49232 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = TRUE;
49233 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = 0;
49234 + }
49235 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49236 +
49237 + return E_OK;
49238 +}
49239 +
49240 +static void FreeSharedProfiles(t_FmPcd *p_FmPcd, uint16_t numOfProfiles, uint16_t *profilesIds)
49241 +{
49242 + uint16_t i;
49243 +
49244 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
49245 +
49246 + ASSERT_COND(numOfProfiles);
49247 +
49248 + for (i=0; i < numOfProfiles; i++)
49249 + {
49250 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated);
49251 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.allocated = FALSE;
49252 + p_FmPcd->p_FmPcdPlcr->profiles[profilesIds[i]].profilesMng.ownerId = p_FmPcd->guestId;
49253 + }
49254 +}
49255 +
49256 +static void UpdateRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId, bool set)
49257 +{
49258 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49259 +
49260 + /* this routine is protected by calling routine */
49261 +
49262 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49263 +
49264 + if (set)
49265 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = TRUE;
49266 + else
49267 + {
49268 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction = 0;
49269 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag = FALSE;
49270 + }
49271 +}
49272 +
49273 +/*********************************************/
49274 +/*............Policer Exception..............*/
49275 +/*********************************************/
49276 +static void EventsCB(t_Handle h_FmPcd)
49277 +{
49278 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49279 + uint32_t event, mask, force;
49280 +
49281 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
49282 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr);
49283 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ier);
49284 +
49285 + event &= mask;
49286 +
49287 + /* clear the forced events */
49288 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr);
49289 + if (force & event)
49290 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_ifr, force & ~event);
49291 +
49292 +
49293 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_evr, event);
49294 +
49295 + if (event & FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE)
49296 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE);
49297 + if (event & FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE)
49298 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE);
49299 +}
49300 +
49301 +/* ..... */
49302 +
49303 +static void ErrorExceptionsCB(t_Handle h_FmPcd)
49304 +{
49305 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49306 + uint32_t event, force, captureReg, mask;
49307 +
49308 + ASSERT_COND(FmIsMaster(p_FmPcd->h_Fm));
49309 + event = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr);
49310 + mask = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eier);
49311 +
49312 + event &= mask;
49313 +
49314 + /* clear the forced events */
49315 + force = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr);
49316 + if (force & event)
49317 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eifr, force & ~event);
49318 +
49319 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_eevr, event);
49320 +
49321 + if (event & FM_PCD_PLCR_DOUBLE_ECC)
49322 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC);
49323 + if (event & FM_PCD_PLCR_INIT_ENTRY_ERROR)
49324 + {
49325 + captureReg = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr);
49326 + /*ASSERT_COND(captureReg & PLCR_ERR_UNINIT_CAP);
49327 + p_UnInitCapt->profileNum = (uint8_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK);
49328 + p_UnInitCapt->portId = (uint8_t)((captureReg & PLCR_ERR_UNINIT_PID_MASK) >>PLCR_ERR_UNINIT_PID_SHIFT) ;
49329 + p_UnInitCapt->absolute = (bool)(captureReg & PLCR_ERR_UNINIT_ABSOLUTE_MASK);*/
49330 + p_FmPcd->f_FmPcdIndexedException(p_FmPcd->h_App,e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,(uint16_t)(captureReg & PLCR_ERR_UNINIT_NUM_MASK));
49331 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_upcr, PLCR_ERR_UNINIT_CAP);
49332 + }
49333 +}
49334 +
49335 +
49336 +/*****************************************************************************/
49337 +/* Inter-module API routines */
49338 +/*****************************************************************************/
49339 +
49340 +t_Handle PlcrConfig(t_FmPcd *p_FmPcd, t_FmPcdParams *p_FmPcdParams)
49341 +{
49342 + t_FmPcdPlcr *p_FmPcdPlcr;
49343 + uint16_t i=0;
49344 +
49345 + UNUSED(p_FmPcd);
49346 + UNUSED(p_FmPcdParams);
49347 +
49348 + p_FmPcdPlcr = (t_FmPcdPlcr *) XX_Malloc(sizeof(t_FmPcdPlcr));
49349 + if (!p_FmPcdPlcr)
49350 + {
49351 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer structure allocation FAILED"));
49352 + return NULL;
49353 + }
49354 + memset(p_FmPcdPlcr, 0, sizeof(t_FmPcdPlcr));
49355 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
49356 + {
49357 + p_FmPcdPlcr->p_FmPcdPlcrRegs = (t_FmPcdPlcrRegs *)UINT_TO_PTR(FmGetPcdPlcrBaseAddr(p_FmPcdParams->h_Fm));
49358 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = DEFAULT_plcrAutoRefresh;
49359 + p_FmPcd->exceptions |= (DEFAULT_fmPcdPlcrExceptions | DEFAULT_fmPcdPlcrErrorExceptions);
49360 + }
49361 +
49362 + p_FmPcdPlcr->numOfSharedProfiles = DEFAULT_numOfSharedPlcrProfiles;
49363 +
49364 + p_FmPcdPlcr->partPlcrProfilesBase = p_FmPcdParams->partPlcrProfilesBase;
49365 + p_FmPcdPlcr->partNumOfPlcrProfiles = p_FmPcdParams->partNumOfPlcrProfiles;
49366 + /* for backward compatabilty. if no policer profile, will set automatically to the max */
49367 + if ((p_FmPcd->guestId == NCSW_MASTER_ID) &&
49368 + (p_FmPcdPlcr->partNumOfPlcrProfiles == 0))
49369 + p_FmPcdPlcr->partNumOfPlcrProfiles = FM_PCD_PLCR_NUM_ENTRIES;
49370 +
49371 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; i++)
49372 + p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
49373 +
49374 + return p_FmPcdPlcr;
49375 +}
49376 +
49377 +t_Error PlcrInit(t_FmPcd *p_FmPcd)
49378 +{
49379 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
49380 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
49381 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49382 + t_Error err = E_OK;
49383 + uint32_t tmpReg32 = 0;
49384 + uint16_t base;
49385 +
49386 + if ((p_FmPcdPlcr->partPlcrProfilesBase + p_FmPcdPlcr->partNumOfPlcrProfiles) > FM_PCD_PLCR_NUM_ENTRIES)
49387 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partPlcrProfilesBase+partNumOfPlcrProfiles out of range!!!"));
49388 +
49389 + p_FmPcdPlcr->h_HwSpinlock = XX_InitSpinlock();
49390 + if (!p_FmPcdPlcr->h_HwSpinlock)
49391 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer HW spinlock"));
49392 +
49393 + p_FmPcdPlcr->h_SwSpinlock = XX_InitSpinlock();
49394 + if (!p_FmPcdPlcr->h_SwSpinlock)
49395 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("FM Policer SW spinlock"));
49396 +
49397 + base = PlcrAllocProfilesForPartition(p_FmPcd,
49398 + p_FmPcdPlcr->partPlcrProfilesBase,
49399 + p_FmPcdPlcr->partNumOfPlcrProfiles,
49400 + p_FmPcd->guestId);
49401 + if (base == (uint16_t)ILLEGAL_BASE)
49402 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
49403 +
49404 + if (p_FmPcdPlcr->numOfSharedProfiles)
49405 + {
49406 + err = AllocSharedProfiles(p_FmPcd,
49407 + p_FmPcdPlcr->numOfSharedProfiles,
49408 + p_FmPcdPlcr->sharedProfilesIds);
49409 + if (err)
49410 + RETURN_ERROR(MAJOR, err,NO_MSG);
49411 + }
49412 +
49413 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
49414 + return E_OK;
49415 +
49416 + /**********************FMPL_GCR******************/
49417 + tmpReg32 = 0;
49418 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
49419 + if (p_Param->plcrAutoRefresh)
49420 + tmpReg32 |= FM_PCD_PLCR_GCR_DAR;
49421 + tmpReg32 |= GET_NIA_BMI_AC_ENQ_FRAME(p_FmPcd);
49422 +
49423 + WRITE_UINT32(p_Regs->fmpl_gcr, tmpReg32);
49424 + /**********************FMPL_GCR******************/
49425 +
49426 + /**********************FMPL_EEVR******************/
49427 + WRITE_UINT32(p_Regs->fmpl_eevr, (FM_PCD_PLCR_DOUBLE_ECC | FM_PCD_PLCR_INIT_ENTRY_ERROR));
49428 + /**********************FMPL_EEVR******************/
49429 + /**********************FMPL_EIER******************/
49430 + tmpReg32 = 0;
49431 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_DOUBLE_ECC)
49432 + {
49433 + FmEnableRamsEcc(p_FmPcd->h_Fm);
49434 + tmpReg32 |= FM_PCD_PLCR_DOUBLE_ECC;
49435 + }
49436 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_INIT_ENTRY_ERROR)
49437 + tmpReg32 |= FM_PCD_PLCR_INIT_ENTRY_ERROR;
49438 + WRITE_UINT32(p_Regs->fmpl_eier, tmpReg32);
49439 + /**********************FMPL_EIER******************/
49440 +
49441 + /**********************FMPL_EVR******************/
49442 + WRITE_UINT32(p_Regs->fmpl_evr, (FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE | FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE));
49443 + /**********************FMPL_EVR******************/
49444 + /**********************FMPL_IER******************/
49445 + tmpReg32 = 0;
49446 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_PRAM_SELF_INIT_COMPLETE)
49447 + tmpReg32 |= FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE;
49448 + if (p_FmPcd->exceptions & FM_PCD_EX_PLCR_ATOMIC_ACTION_COMPLETE)
49449 + tmpReg32 |= FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE;
49450 + WRITE_UINT32(p_Regs->fmpl_ier, tmpReg32);
49451 + /**********************FMPL_IER******************/
49452 +
49453 + /* register even if no interrupts enabled, to allow future enablement */
49454 + FmRegisterIntr(p_FmPcd->h_Fm,
49455 + e_FM_MOD_PLCR,
49456 + 0,
49457 + e_FM_INTR_TYPE_ERR,
49458 + ErrorExceptionsCB,
49459 + p_FmPcd);
49460 + FmRegisterIntr(p_FmPcd->h_Fm,
49461 + e_FM_MOD_PLCR,
49462 + 0,
49463 + e_FM_INTR_TYPE_NORMAL,
49464 + EventsCB,
49465 + p_FmPcd);
49466 +
49467 + /* driver initializes one DFLT profile at the last entry*/
49468 + /**********************FMPL_DPMR******************/
49469 + tmpReg32 = 0;
49470 + WRITE_UINT32(p_Regs->fmpl_dpmr, tmpReg32);
49471 + p_FmPcd->p_FmPcdPlcr->profiles[0].profilesMng.allocated = TRUE;
49472 +
49473 + return E_OK;
49474 +}
49475 +
49476 +t_Error PlcrFree(t_FmPcd *p_FmPcd)
49477 +{
49478 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_ERR);
49479 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PLCR, 0, e_FM_INTR_TYPE_NORMAL);
49480 +
49481 + if (p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles)
49482 + FreeSharedProfiles(p_FmPcd,
49483 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles,
49484 + p_FmPcd->p_FmPcdPlcr->sharedProfilesIds);
49485 +
49486 + if (p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles)
49487 + PlcrFreeProfilesForPartition(p_FmPcd,
49488 + p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase,
49489 + p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles,
49490 + p_FmPcd->guestId);
49491 +
49492 + if (p_FmPcd->p_FmPcdPlcr->h_SwSpinlock)
49493 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_SwSpinlock);
49494 +
49495 + if (p_FmPcd->p_FmPcdPlcr->h_HwSpinlock)
49496 + XX_FreeSpinlock(p_FmPcd->p_FmPcdPlcr->h_HwSpinlock);
49497 +
49498 + return E_OK;
49499 +}
49500 +
49501 +void PlcrEnable(t_FmPcd *p_FmPcd)
49502 +{
49503 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49504 +
49505 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) | FM_PCD_PLCR_GCR_EN);
49506 +}
49507 +
49508 +void PlcrDisable(t_FmPcd *p_FmPcd)
49509 +{
49510 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49511 +
49512 + WRITE_UINT32(p_Regs->fmpl_gcr, GET_UINT32(p_Regs->fmpl_gcr) & ~FM_PCD_PLCR_GCR_EN);
49513 +}
49514 +
49515 +uint16_t PlcrAllocProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
49516 +{
49517 + uint32_t intFlags;
49518 + uint16_t profilesFound = 0;
49519 + int i = 0;
49520 +
49521 + ASSERT_COND(p_FmPcd);
49522 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
49523 +
49524 + if (!numOfProfiles)
49525 + return 0;
49526 +
49527 + if ((numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES) ||
49528 + (base + numOfProfiles > FM_PCD_PLCR_NUM_ENTRIES))
49529 + return (uint16_t)ILLEGAL_BASE;
49530 +
49531 + if (p_FmPcd->h_IpcSession)
49532 + {
49533 + t_FmIpcResourceAllocParams ipcAllocParams;
49534 + t_FmPcdIpcMsg msg;
49535 + t_FmPcdIpcReply reply;
49536 + t_Error err;
49537 + uint32_t replyLength;
49538 +
49539 + memset(&msg, 0, sizeof(msg));
49540 + memset(&reply, 0, sizeof(reply));
49541 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
49542 + ipcAllocParams.guestId = p_FmPcd->guestId;
49543 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
49544 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
49545 + msg.msgId = FM_PCD_ALLOC_PROFILES;
49546 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
49547 + replyLength = sizeof(uint32_t) + sizeof(uint16_t);
49548 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49549 + (uint8_t*)&msg,
49550 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
49551 + (uint8_t*)&reply,
49552 + &replyLength,
49553 + NULL,
49554 + NULL);
49555 + if ((err != E_OK) ||
49556 + (replyLength != (sizeof(uint32_t) + sizeof(uint16_t))))
49557 + {
49558 + REPORT_ERROR(MAJOR, err, NO_MSG);
49559 + return (uint16_t)ILLEGAL_BASE;
49560 + }
49561 + else
49562 + memcpy((uint8_t*)&p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase, reply.replyBody, sizeof(uint16_t));
49563 + if (p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase == (uint16_t)ILLEGAL_BASE)
49564 + {
49565 + REPORT_ERROR(MAJOR, err, NO_MSG);
49566 + return (uint16_t)ILLEGAL_BASE;
49567 + }
49568 + }
49569 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49570 + {
49571 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
49572 + return (uint16_t)ILLEGAL_BASE;
49573 + }
49574 +
49575 + intFlags = XX_LockIntrSpinlock(p_FmPcd->h_Spinlock);
49576 + for (i=base; i<(base+numOfProfiles); i++)
49577 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
49578 + profilesFound++;
49579 + else
49580 + break;
49581 +
49582 + if (profilesFound == numOfProfiles)
49583 + for (i=base; i<(base+numOfProfiles); i++)
49584 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = guestId;
49585 + else
49586 + {
49587 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
49588 + return (uint16_t)ILLEGAL_BASE;
49589 + }
49590 + XX_UnlockIntrSpinlock(p_FmPcd->h_Spinlock, intFlags);
49591 +
49592 + return base;
49593 +}
49594 +
49595 +void PlcrFreeProfilesForPartition(t_FmPcd *p_FmPcd, uint16_t base, uint16_t numOfProfiles, uint8_t guestId)
49596 +{
49597 + int i = 0;
49598 +
49599 + ASSERT_COND(p_FmPcd);
49600 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr);
49601 +
49602 + if (p_FmPcd->h_IpcSession)
49603 + {
49604 + t_FmIpcResourceAllocParams ipcAllocParams;
49605 + t_FmPcdIpcMsg msg;
49606 + t_Error err;
49607 +
49608 + memset(&msg, 0, sizeof(msg));
49609 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
49610 + ipcAllocParams.guestId = p_FmPcd->guestId;
49611 + ipcAllocParams.num = p_FmPcd->p_FmPcdPlcr->partNumOfPlcrProfiles;
49612 + ipcAllocParams.base = p_FmPcd->p_FmPcdPlcr->partPlcrProfilesBase;
49613 + msg.msgId = FM_PCD_FREE_PROFILES;
49614 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
49615 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49616 + (uint8_t*)&msg,
49617 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
49618 + NULL,
49619 + NULL,
49620 + NULL,
49621 + NULL);
49622 + if (err != E_OK)
49623 + REPORT_ERROR(MAJOR, err, NO_MSG);
49624 + return;
49625 + }
49626 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
49627 + {
49628 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate Policer-profiles range!"));
49629 + return;
49630 + }
49631 +
49632 + for (i=base; i<(base+numOfProfiles); i++)
49633 + {
49634 + if (p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == guestId)
49635 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
49636 + else
49637 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
49638 + }
49639 +}
49640 +
49641 +t_Error PlcrSetPortProfiles(t_FmPcd *p_FmPcd,
49642 + uint8_t hardwarePortId,
49643 + uint16_t numOfProfiles,
49644 + uint16_t base)
49645 +{
49646 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49647 + uint32_t log2Num, tmpReg32;
49648 +
49649 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49650 + !p_Regs &&
49651 + p_FmPcd->h_IpcSession)
49652 + {
49653 + t_FmIpcResourceAllocParams ipcAllocParams;
49654 + t_FmPcdIpcMsg msg;
49655 + t_Error err;
49656 +
49657 + memset(&msg, 0, sizeof(msg));
49658 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
49659 + ipcAllocParams.guestId = hardwarePortId;
49660 + ipcAllocParams.num = numOfProfiles;
49661 + ipcAllocParams.base = base;
49662 + msg.msgId = FM_PCD_SET_PORT_PROFILES;
49663 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
49664 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49665 + (uint8_t*)&msg,
49666 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
49667 + NULL,
49668 + NULL,
49669 + NULL,
49670 + NULL);
49671 + if (err != E_OK)
49672 + RETURN_ERROR(MAJOR, err, NO_MSG);
49673 + return E_OK;
49674 + }
49675 + else if (!p_Regs)
49676 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49677 + ("Either IPC or 'baseAddress' is required!"));
49678 +
49679 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
49680 +
49681 + if (GET_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1]) & FM_PCD_PLCR_PMR_V)
49682 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
49683 + ("The requesting port has already an allocated profiles window."));
49684 +
49685 + /**********************FMPL_PMRx******************/
49686 + LOG2((uint64_t)numOfProfiles, log2Num);
49687 + tmpReg32 = base;
49688 + tmpReg32 |= log2Num << 16;
49689 + tmpReg32 |= FM_PCD_PLCR_PMR_V;
49690 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], tmpReg32);
49691 +
49692 + return E_OK;
49693 +}
49694 +
49695 +t_Error PlcrClearPortProfiles(t_FmPcd *p_FmPcd, uint8_t hardwarePortId)
49696 +{
49697 + t_FmPcdPlcrRegs *p_Regs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
49698 +
49699 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
49700 + !p_Regs &&
49701 + p_FmPcd->h_IpcSession)
49702 + {
49703 + t_FmIpcResourceAllocParams ipcAllocParams;
49704 + t_FmPcdIpcMsg msg;
49705 + t_Error err;
49706 +
49707 + memset(&msg, 0, sizeof(msg));
49708 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
49709 + ipcAllocParams.guestId = hardwarePortId;
49710 + msg.msgId = FM_PCD_CLEAR_PORT_PROFILES;
49711 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
49712 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
49713 + (uint8_t*)&msg,
49714 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
49715 + NULL,
49716 + NULL,
49717 + NULL,
49718 + NULL);
49719 + if (err != E_OK)
49720 + RETURN_ERROR(MAJOR, err, NO_MSG);
49721 + return E_OK;
49722 + }
49723 + else if (!p_Regs)
49724 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
49725 + ("Either IPC or 'baseAddress' is required!"));
49726 +
49727 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
49728 + WRITE_UINT32(p_Regs->fmpl_pmr[hardwarePortId-1], 0);
49729 +
49730 + return E_OK;
49731 +}
49732 +
49733 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles)
49734 +{
49735 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49736 + t_Error err = E_OK;
49737 + uint32_t profilesFound;
49738 + uint32_t intFlags;
49739 + uint16_t i, first, swPortIndex = 0;
49740 +
49741 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49742 +
49743 + if (!numOfProfiles)
49744 + return E_OK;
49745 +
49746 + ASSERT_COND(hardwarePortId);
49747 +
49748 + if (numOfProfiles>FM_PCD_PLCR_NUM_ENTRIES)
49749 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles is too big."));
49750 +
49751 + if (!POWER_OF_2(numOfProfiles))
49752 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
49753 +
49754 + first = 0;
49755 + profilesFound = 0;
49756 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
49757 +
49758 + for (i=0; i<FM_PCD_PLCR_NUM_ENTRIES; )
49759 + {
49760 + if (!p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated)
49761 + {
49762 + profilesFound++;
49763 + i++;
49764 + if (profilesFound == numOfProfiles)
49765 + break;
49766 + }
49767 + else
49768 + {
49769 + profilesFound = 0;
49770 + /* advance i to the next aligned address */
49771 + i = first = (uint16_t)(first + numOfProfiles);
49772 + }
49773 + }
49774 +
49775 + if (profilesFound == numOfProfiles)
49776 + {
49777 + for (i=first; i<first + numOfProfiles; i++)
49778 + {
49779 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = TRUE;
49780 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = hardwarePortId;
49781 + }
49782 + }
49783 + else
49784 + {
49785 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49786 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
49787 + }
49788 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49789 +
49790 + err = PlcrSetPortProfiles(p_FmPcd, hardwarePortId, numOfProfiles, first);
49791 + if (err)
49792 + {
49793 + RETURN_ERROR(MAJOR, err, NO_MSG);
49794 + }
49795 +
49796 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
49797 +
49798 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = numOfProfiles;
49799 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = first;
49800 +
49801 + return E_OK;
49802 +}
49803 +
49804 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
49805 +{
49806 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49807 + t_Error err = E_OK;
49808 + uint32_t intFlags;
49809 + uint16_t i, swPortIndex = 0;
49810 +
49811 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
49812 +
49813 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
49814 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
49815 +
49816 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
49817 +
49818 + err = PlcrClearPortProfiles(p_FmPcd, hardwarePortId);
49819 + if (err)
49820 + RETURN_ERROR(MAJOR, err,NO_MSG);
49821 +
49822 + intFlags = PlcrSwLock(p_FmPcd->p_FmPcdPlcr);
49823 + for (i=p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
49824 + i<(p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase +
49825 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles);
49826 + i++)
49827 + {
49828 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId == hardwarePortId);
49829 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated);
49830 +
49831 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.allocated = FALSE;
49832 + p_FmPcd->p_FmPcdPlcr->profiles[i].profilesMng.ownerId = p_FmPcd->guestId;
49833 + }
49834 + PlcrSwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
49835 +
49836 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles = 0;
49837 + p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase = 0;
49838 +
49839 + return E_OK;
49840 +}
49841 +
49842 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx ,uint32_t requiredAction)
49843 +{
49844 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
49845 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
49846 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs = p_FmPcdPlcr->p_FmPcdPlcrRegs;
49847 + uint32_t tmpReg32, intFlags;
49848 + t_Error err;
49849 +
49850 + /* Calling function locked all PCD modules, so no need to lock here */
49851 +
49852 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
49853 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile out of range"));
49854 +
49855 + if (!FmPcdPlcrIsProfileValid(p_FmPcd, profileIndx))
49856 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,("Policer profile is not valid"));
49857 +
49858 + /*intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx]);*/
49859 +
49860 + if (p_FmPcd->h_Hc)
49861 + {
49862 + err = FmHcPcdPlcrCcGetSetParams(p_FmPcd->h_Hc, profileIndx, requiredAction);
49863 +
49864 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
49865 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
49866 +
49867 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49868 + return err;
49869 + }
49870 +
49871 + /* lock the HW because once we read the registers we don't want them to be changed
49872 + * by another access. (We can copy to a tmp location and release the lock!) */
49873 +
49874 + intFlags = PlcrHwLock(p_FmPcdPlcr);
49875 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
49876 +
49877 + if (!p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredActionFlag ||
49878 + !(p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].requiredAction & requiredAction))
49879 + {
49880 + if (requiredAction & UPDATE_NIA_ENQ_WITHOUT_DMA)
49881 + {
49882 + if ((p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnGreen!= e_FM_PCD_DONE) ||
49883 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnYellow!= e_FM_PCD_DONE) ||
49884 + (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].nextEngineOnRed!= e_FM_PCD_DONE))
49885 + {
49886 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49887 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49888 + RETURN_ERROR (MAJOR, E_OK, ("In this case the next engine can be e_FM_PCD_DONE"));
49889 + }
49890 +
49891 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnGreen.action == e_FM_PCD_ENQ_FRAME)
49892 + {
49893 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia);
49894 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
49895 + {
49896 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49897 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49898 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
49899 + }
49900 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
49901 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia, tmpReg32);
49902 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
49903 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
49904 + WritePar(p_FmPcd, tmpReg32);
49905 + }
49906 +
49907 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnYellow.action == e_FM_PCD_ENQ_FRAME)
49908 + {
49909 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia);
49910 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
49911 + {
49912 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49913 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49914 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
49915 + }
49916 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
49917 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia, tmpReg32);
49918 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
49919 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
49920 + WritePar(p_FmPcd, tmpReg32);
49921 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49922 + }
49923 +
49924 + if (p_FmPcd->p_FmPcdPlcr->profiles[profileIndx].paramsOnRed.action == e_FM_PCD_ENQ_FRAME)
49925 + {
49926 + tmpReg32 = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia);
49927 + if (!(tmpReg32 & (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)))
49928 + {
49929 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49930 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49931 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Next engine of this policer profile has to be assigned to FM_PCD_DONE"));
49932 + }
49933 + tmpReg32 |= NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA;
49934 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia, tmpReg32);
49935 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
49936 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
49937 + WritePar(p_FmPcd, tmpReg32);
49938 +
49939 + }
49940 + }
49941 + }
49942 + PlcrHwUnlock(p_FmPcdPlcr, intFlags);
49943 +
49944 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, TRUE);
49945 + FmPcdPlcrUpdateRequiredAction(p_FmPcd, profileIndx, requiredAction);
49946 +
49947 + /*PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[profileIndx], intFlags);*/
49948 +
49949 + return E_OK;
49950 +}
49951 +
49952 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49953 +{
49954 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49955 +
49956 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49957 +
49958 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredActionFlag;
49959 +}
49960 +
49961 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49962 +{
49963 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49964 +
49965 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49966 +
49967 + return p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction;
49968 +}
49969 +
49970 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49971 +{
49972 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49973 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
49974 +
49975 + ASSERT_COND(absoluteProfileId < FM_PCD_PLCR_NUM_ENTRIES);
49976 +
49977 + return p_FmPcdPlcr->profiles[absoluteProfileId].valid;
49978 +}
49979 +
49980 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49981 +{
49982 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49983 + uint32_t intFlags;
49984 +
49985 + ASSERT_COND(!p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49986 +
49987 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
49988 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = TRUE;
49989 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
49990 +}
49991 +
49992 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId)
49993 +{
49994 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
49995 + uint32_t intFlags;
49996 +
49997 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
49998 +
49999 + intFlags = PlcrProfileLock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId]);
50000 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid = FALSE;
50001 + PlcrProfileUnlock(&p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId], intFlags);
50002 +}
50003 +
50004 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile)
50005 +{
50006 + return ((t_FmPcdPlcrProfile*)h_Profile)->absoluteProfileId;
50007 +}
50008 +
50009 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
50010 + e_FmPcdProfileTypeSelection profileType,
50011 + t_Handle h_FmPort,
50012 + uint16_t relativeProfile,
50013 + uint16_t *p_AbsoluteId)
50014 +{
50015 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
50016 + t_FmPcdPlcr *p_FmPcdPlcr = p_FmPcd->p_FmPcdPlcr;
50017 + uint8_t i;
50018 +
50019 + switch (profileType)
50020 + {
50021 + case e_FM_PCD_PLCR_PORT_PRIVATE:
50022 + /* get port PCD id from port handle */
50023 + for (i=0;i<FM_MAX_NUM_OF_PORTS;i++)
50024 + if (p_FmPcd->p_FmPcdPlcr->portsMapping[i].h_FmPort == h_FmPort)
50025 + break;
50026 + if (i == FM_MAX_NUM_OF_PORTS)
50027 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Invalid port handle."));
50028 +
50029 + if (!p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
50030 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Port has no allocated profiles"));
50031 + if (relativeProfile >= p_FmPcd->p_FmPcdPlcr->portsMapping[i].numOfProfiles)
50032 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
50033 + *p_AbsoluteId = (uint16_t)(p_FmPcd->p_FmPcdPlcr->portsMapping[i].profilesBase + relativeProfile);
50034 + break;
50035 + case e_FM_PCD_PLCR_SHARED:
50036 + if (relativeProfile >= p_FmPcdPlcr->numOfSharedProfiles)
50037 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION , ("Profile id is out of range"));
50038 + *p_AbsoluteId = (uint16_t)(p_FmPcdPlcr->sharedProfilesIds[relativeProfile]);
50039 + break;
50040 + default:
50041 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Invalid policer profile type"));
50042 + }
50043 +
50044 + return E_OK;
50045 +}
50046 +
50047 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId)
50048 +{
50049 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50050 + uint16_t swPortIndex = 0;
50051 +
50052 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
50053 +
50054 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].profilesBase;
50055 +}
50056 +
50057 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId)
50058 +{
50059 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50060 + uint16_t swPortIndex = 0;
50061 +
50062 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
50063 +
50064 + return p_FmPcd->p_FmPcdPlcr->portsMapping[swPortIndex].numOfProfiles;
50065 +
50066 +}
50067 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId)
50068 +{
50069 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
50070 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT));
50071 +}
50072 +
50073 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId)
50074 +{
50075 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
50076 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
50077 + FM_PCD_PLCR_PAR_PWSEL_MASK);
50078 +}
50079 +
50080 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg)
50081 +{
50082 +
50083 + if (profileModeReg & FM_PCD_PLCR_PEMODE_PI)
50084 + return TRUE;
50085 + else
50086 + return FALSE;
50087 +}
50088 +
50089 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId)
50090 +{
50091 + return (uint32_t)(FM_PCD_PLCR_PAR_GO |
50092 + FM_PCD_PLCR_PAR_R |
50093 + ((uint32_t)absoluteProfileId << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
50094 + FM_PCD_PLCR_PAR_PWSEL_MASK);
50095 +}
50096 +
50097 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter)
50098 +{
50099 + switch (counter)
50100 + {
50101 + case (e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER):
50102 + return FM_PCD_PLCR_PAR_PWSEL_PEGPC;
50103 + case (e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER):
50104 + return FM_PCD_PLCR_PAR_PWSEL_PEYPC;
50105 + case (e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER) :
50106 + return FM_PCD_PLCR_PAR_PWSEL_PERPC;
50107 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER) :
50108 + return FM_PCD_PLCR_PAR_PWSEL_PERYPC;
50109 + case (e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER) :
50110 + return FM_PCD_PLCR_PAR_PWSEL_PERRPC;
50111 + default:
50112 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
50113 + return 0;
50114 + }
50115 +}
50116 +
50117 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red)
50118 +{
50119 +
50120 + uint32_t tmpReg32 = 0;
50121 +
50122 + if (green)
50123 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEGNIA;
50124 + if (yellow)
50125 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PEYNIA;
50126 + if (red)
50127 + tmpReg32 |= FM_PCD_PLCR_PAR_PWSEL_PERNIA;
50128 +
50129 + return tmpReg32;
50130 +}
50131 +
50132 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction)
50133 +{
50134 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
50135 +
50136 + /* this routine is protected by calling routine */
50137 +
50138 + ASSERT_COND(p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].valid);
50139 +
50140 + p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId].requiredAction |= requiredAction;
50141 +}
50142 +
50143 +/*********************** End of inter-module routines ************************/
50144 +
50145 +
50146 +/**************************************************/
50147 +/*............Policer API.........................*/
50148 +/**************************************************/
50149 +
50150 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable)
50151 +{
50152 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
50153 +
50154 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50155 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
50156 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
50157 +
50158 + if (!FmIsMaster(p_FmPcd->h_Fm))
50159 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPlcrAutoRefreshMode - guest mode!"));
50160 +
50161 + p_FmPcd->p_FmPcdDriverParam->plcrAutoRefresh = enable;
50162 +
50163 + return E_OK;
50164 +}
50165 +
50166 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles)
50167 +{
50168 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
50169 +
50170 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50171 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
50172 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
50173 +
50174 + p_FmPcd->p_FmPcdPlcr->numOfSharedProfiles = numOfSharedPlcrProfiles;
50175 +
50176 + return E_OK;
50177 +}
50178 +
50179 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable)
50180 +{
50181 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
50182 + uint32_t tmpReg32;
50183 +
50184 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50185 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
50186 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE);
50187 +
50188 + if (!FmIsMaster(p_FmPcd->h_Fm))
50189 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPlcrStatistics - guest mode!"));
50190 +
50191 + tmpReg32 = GET_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr);
50192 + if (enable)
50193 + tmpReg32 |= FM_PCD_PLCR_GCR_STEN;
50194 + else
50195 + tmpReg32 &= ~FM_PCD_PLCR_GCR_STEN;
50196 +
50197 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_gcr, tmpReg32);
50198 + return E_OK;
50199 +}
50200 +
50201 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
50202 + t_FmPcdPlcrProfileParams *p_ProfileParams)
50203 +{
50204 + t_FmPcd *p_FmPcd;
50205 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
50206 + t_FmPcdPlcrProfileRegs plcrProfileReg;
50207 + uint32_t intFlags;
50208 + uint16_t absoluteProfileId;
50209 + t_Error err = E_OK;
50210 + uint32_t tmpReg32;
50211 + t_FmPcdPlcrProfile *p_Profile;
50212 +
50213 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
50214 +
50215 + if (p_ProfileParams->modify)
50216 + {
50217 + p_Profile = (t_FmPcdPlcrProfile *)p_ProfileParams->id.h_Profile;
50218 + p_FmPcd = p_Profile->h_FmPcd;
50219 + absoluteProfileId = p_Profile->absoluteProfileId;
50220 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
50221 + {
50222 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
50223 + return NULL;
50224 + }
50225 +
50226 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
50227 +
50228 + /* Try lock profile using flag */
50229 + if (!PlcrProfileFlagTryLock(p_Profile))
50230 + {
50231 + DBG(TRACE, ("Profile Try Lock - BUSY"));
50232 + /* Signal to caller BUSY condition */
50233 + p_ProfileParams->id.h_Profile = NULL;
50234 + return NULL;
50235 + }
50236 + }
50237 + else
50238 + {
50239 + p_FmPcd = (t_FmPcd*)h_FmPcd;
50240 +
50241 + SANITY_CHECK_RETURN_VALUE(p_FmPcd->p_FmPcdPlcr, E_INVALID_HANDLE, NULL);
50242 +
50243 + /* SMP: needs to be protected only if another core now changes the windows */
50244 + err = FmPcdPlcrGetAbsoluteIdByProfileParams(h_FmPcd,
50245 + p_ProfileParams->id.newParams.profileType,
50246 + p_ProfileParams->id.newParams.h_FmPort,
50247 + p_ProfileParams->id.newParams.relativeProfileId,
50248 + &absoluteProfileId);
50249 + if (err)
50250 + {
50251 + REPORT_ERROR(MAJOR, err, NO_MSG);
50252 + return NULL;
50253 + }
50254 +
50255 + if (absoluteProfileId >= FM_PCD_PLCR_NUM_ENTRIES)
50256 + {
50257 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
50258 + return NULL;
50259 + }
50260 +
50261 + if (FmPcdPlcrIsProfileValid(p_FmPcd, absoluteProfileId))
50262 + {
50263 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("Policer Profile is already used"));
50264 + return NULL;
50265 + }
50266 +
50267 + /* initialize profile struct */
50268 + p_Profile = &p_FmPcd->p_FmPcdPlcr->profiles[absoluteProfileId];
50269 +
50270 + p_Profile->h_FmPcd = p_FmPcd;
50271 + p_Profile->absoluteProfileId = absoluteProfileId;
50272 +
50273 + p_Profile->p_Lock = FmPcdAcquireLock(p_FmPcd);
50274 + if (!p_Profile->p_Lock)
50275 + REPORT_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Policer Profile lock obj!"));
50276 + }
50277 +
50278 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE, NULL);
50279 +
50280 + p_Profile->nextEngineOnGreen = p_ProfileParams->nextEngineOnGreen;
50281 + memcpy(&p_Profile->paramsOnGreen, &(p_ProfileParams->paramsOnGreen), sizeof(u_FmPcdPlcrNextEngineParams));
50282 +
50283 + p_Profile->nextEngineOnYellow = p_ProfileParams->nextEngineOnYellow;
50284 + memcpy(&p_Profile->paramsOnYellow, &(p_ProfileParams->paramsOnYellow), sizeof(u_FmPcdPlcrNextEngineParams));
50285 +
50286 + p_Profile->nextEngineOnRed = p_ProfileParams->nextEngineOnRed;
50287 + memcpy(&p_Profile->paramsOnRed, &(p_ProfileParams->paramsOnRed), sizeof(u_FmPcdPlcrNextEngineParams));
50288 +
50289 + memset(&plcrProfileReg, 0, sizeof(t_FmPcdPlcrProfileRegs));
50290 +
50291 + /* build the policer profile registers */
50292 + err = BuildProfileRegs(h_FmPcd, p_ProfileParams, &plcrProfileReg);
50293 + if (err)
50294 + {
50295 + REPORT_ERROR(MAJOR, err, NO_MSG);
50296 + if (p_ProfileParams->modify)
50297 + /* unlock */
50298 + PlcrProfileFlagUnlock(p_Profile);
50299 + if (!p_ProfileParams->modify &&
50300 + p_Profile->p_Lock)
50301 + /* release allocated Profile lock */
50302 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
50303 + return NULL;
50304 + }
50305 +
50306 + if (p_FmPcd->h_Hc)
50307 + {
50308 + err = FmHcPcdPlcrSetProfile(p_FmPcd->h_Hc, (t_Handle)p_Profile, &plcrProfileReg);
50309 + if (p_ProfileParams->modify)
50310 + PlcrProfileFlagUnlock(p_Profile);
50311 + if (err)
50312 + {
50313 + /* release the allocated scheme lock */
50314 + if (!p_ProfileParams->modify &&
50315 + p_Profile->p_Lock)
50316 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
50317 +
50318 + return NULL;
50319 + }
50320 + if (!p_ProfileParams->modify)
50321 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
50322 + return (t_Handle)p_Profile;
50323 + }
50324 +
50325 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
50326 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, NULL);
50327 +
50328 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
50329 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pemode , plcrProfileReg.fmpl_pemode);
50330 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegnia , plcrProfileReg.fmpl_pegnia);
50331 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peynia , plcrProfileReg.fmpl_peynia);
50332 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pernia , plcrProfileReg.fmpl_pernia);
50333 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecir , plcrProfileReg.fmpl_pecir);
50334 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pecbs , plcrProfileReg.fmpl_pecbs);
50335 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepepir_eir,plcrProfileReg.fmpl_pepepir_eir);
50336 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepbs_ebs,plcrProfileReg.fmpl_pepbs_ebs);
50337 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pelts , plcrProfileReg.fmpl_pelts);
50338 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pects , plcrProfileReg.fmpl_pects);
50339 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pepts_ets,plcrProfileReg.fmpl_pepts_ets);
50340 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc , plcrProfileReg.fmpl_pegpc);
50341 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc , plcrProfileReg.fmpl_peypc);
50342 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc , plcrProfileReg.fmpl_perpc);
50343 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc , plcrProfileReg.fmpl_perypc);
50344 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc , plcrProfileReg.fmpl_perrpc);
50345 +
50346 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(absoluteProfileId);
50347 + WritePar(p_FmPcd, tmpReg32);
50348 +
50349 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50350 +
50351 + if (!p_ProfileParams->modify)
50352 + FmPcdPlcrValidateProfileSw(p_FmPcd,absoluteProfileId);
50353 + else
50354 + PlcrProfileFlagUnlock(p_Profile);
50355 +
50356 + return (t_Handle)p_Profile;
50357 +}
50358 +
50359 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile)
50360 +{
50361 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
50362 + t_FmPcd *p_FmPcd;
50363 + uint16_t profileIndx;
50364 + uint32_t tmpReg32, intFlags;
50365 + t_Error err;
50366 +
50367 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
50368 + p_FmPcd = p_Profile->h_FmPcd;
50369 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50370 +
50371 + profileIndx = p_Profile->absoluteProfileId;
50372 +
50373 + UpdateRequiredActionFlag(p_FmPcd, profileIndx, FALSE);
50374 +
50375 + FmPcdPlcrInvalidateProfileSw(p_FmPcd,profileIndx);
50376 +
50377 + if (p_FmPcd->h_Hc)
50378 + {
50379 + err = FmHcPcdPlcrDeleteProfile(p_FmPcd->h_Hc, h_Profile);
50380 + if (p_Profile->p_Lock)
50381 + /* release allocated Profile lock */
50382 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
50383 +
50384 + return err;
50385 + }
50386 +
50387 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
50388 + WRITE_UINT32(p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs.fmpl_pemode, ~FM_PCD_PLCR_PEMODE_PI);
50389 +
50390 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionRegs(profileIndx);
50391 + WritePar(p_FmPcd, tmpReg32);
50392 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50393 +
50394 +
50395 + if (p_Profile->p_Lock)
50396 + /* release allocated Profile lock */
50397 + FmPcdReleaseLock(p_FmPcd, p_Profile->p_Lock);
50398 +
50399 + /* we do not memset profile as all its fields are being re-initialized at "set",
50400 + * plus its allocation information is still valid. */
50401 + return E_OK;
50402 +}
50403 +
50404 +/***************************************************/
50405 +/*............Policer Profile Counter..............*/
50406 +/***************************************************/
50407 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter)
50408 +{
50409 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
50410 + t_FmPcd *p_FmPcd;
50411 + uint16_t profileIndx;
50412 + uint32_t intFlags, counterVal = 0;
50413 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
50414 +
50415 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
50416 + p_FmPcd = p_Profile->h_FmPcd;
50417 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50418 +
50419 + if (p_FmPcd->h_Hc)
50420 + return FmHcPcdPlcrGetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter);
50421 +
50422 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
50423 + SANITY_CHECK_RETURN_VALUE(p_FmPcdPlcrRegs, E_INVALID_HANDLE, 0);
50424 +
50425 + profileIndx = p_Profile->absoluteProfileId;
50426 +
50427 + if (profileIndx >= FM_PCD_PLCR_NUM_ENTRIES)
50428 + {
50429 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("profileId too Big "));
50430 + return 0;
50431 + }
50432 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
50433 + WritePar(p_FmPcd, FmPcdPlcrBuildReadPlcrActionReg(profileIndx));
50434 +
50435 + switch (counter)
50436 + {
50437 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
50438 + counterVal = (GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc));
50439 + break;
50440 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
50441 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc);
50442 + break;
50443 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
50444 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc);
50445 + break;
50446 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
50447 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc);
50448 + break;
50449 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
50450 + counterVal = GET_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc);
50451 + break;
50452 + default:
50453 + REPORT_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
50454 + break;
50455 + }
50456 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50457 +
50458 + return counterVal;
50459 +}
50460 +
50461 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value)
50462 +{
50463 + t_FmPcdPlcrProfile *p_Profile = (t_FmPcdPlcrProfile*)h_Profile;
50464 + t_FmPcd *p_FmPcd;
50465 + uint16_t profileIndx;
50466 + uint32_t tmpReg32, intFlags;
50467 + t_FmPcdPlcrRegs *p_FmPcdPlcrRegs;
50468 +
50469 + SANITY_CHECK_RETURN_ERROR(p_Profile, E_INVALID_HANDLE);
50470 +
50471 + p_FmPcd = p_Profile->h_FmPcd;
50472 + profileIndx = p_Profile->absoluteProfileId;
50473 +
50474 + if (p_FmPcd->h_Hc)
50475 + return FmHcPcdPlcrSetProfileCounter(p_FmPcd->h_Hc, h_Profile, counter, value);
50476 +
50477 + p_FmPcdPlcrRegs = p_FmPcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
50478 + SANITY_CHECK_RETURN_ERROR(p_FmPcdPlcrRegs, E_INVALID_HANDLE);
50479 +
50480 + intFlags = PlcrHwLock(p_FmPcd->p_FmPcdPlcr);
50481 + switch (counter)
50482 + {
50483 + case e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER:
50484 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_pegpc, value);
50485 + break;
50486 + case e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER:
50487 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_peypc, value);
50488 + break;
50489 + case e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER:
50490 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perpc, value);
50491 + break;
50492 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER:
50493 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perypc ,value);
50494 + break;
50495 + case e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER:
50496 + WRITE_UINT32(p_FmPcdPlcrRegs->profileRegs.fmpl_perrpc ,value);
50497 + break;
50498 + default:
50499 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50500 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
50501 + }
50502 +
50503 + /* Activate the atomic write action by writing FMPL_PAR with: GO=1, RW=1, PSI=0, PNUM =
50504 + * Profile Number, PWSEL=0xFFFF (select all words).
50505 + */
50506 + tmpReg32 = FmPcdPlcrBuildWritePlcrActionReg(profileIndx);
50507 + tmpReg32 |= FmPcdPlcrBuildCounterProfileReg(counter);
50508 + WritePar(p_FmPcd, tmpReg32);
50509 + PlcrHwUnlock(p_FmPcd->p_FmPcdPlcr, intFlags);
50510 +
50511 + return E_OK;
50512 +}
50513 --- /dev/null
50514 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_plcr.h
50515 @@ -0,0 +1,165 @@
50516 +/*
50517 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50518 + *
50519 + * Redistribution and use in source and binary forms, with or without
50520 + * modification, are permitted provided that the following conditions are met:
50521 + * * Redistributions of source code must retain the above copyright
50522 + * notice, this list of conditions and the following disclaimer.
50523 + * * Redistributions in binary form must reproduce the above copyright
50524 + * notice, this list of conditions and the following disclaimer in the
50525 + * documentation and/or other materials provided with the distribution.
50526 + * * Neither the name of Freescale Semiconductor nor the
50527 + * names of its contributors may be used to endorse or promote products
50528 + * derived from this software without specific prior written permission.
50529 + *
50530 + *
50531 + * ALTERNATIVELY, this software may be distributed under the terms of the
50532 + * GNU General Public License ("GPL") as published by the Free Software
50533 + * Foundation, either version 2 of that License or (at your option) any
50534 + * later version.
50535 + *
50536 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50537 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50538 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50539 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50540 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50541 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50542 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50543 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50544 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50545 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50546 + */
50547 +
50548 +
50549 +/******************************************************************************
50550 + @File fm_plcr.h
50551 +
50552 + @Description FM Policer private header
50553 +*//***************************************************************************/
50554 +#ifndef __FM_PLCR_H
50555 +#define __FM_PLCR_H
50556 +
50557 +#include "std_ext.h"
50558 +
50559 +
50560 +/***********************************************************************/
50561 +/* Policer defines */
50562 +/***********************************************************************/
50563 +
50564 +#define FM_PCD_PLCR_PAR_GO 0x80000000
50565 +#define FM_PCD_PLCR_PAR_PWSEL_MASK 0x0000FFFF
50566 +#define FM_PCD_PLCR_PAR_R 0x40000000
50567 +
50568 +/* shifts */
50569 +#define FM_PCD_PLCR_PAR_PNUM_SHIFT 16
50570 +
50571 +/* masks */
50572 +#define FM_PCD_PLCR_PEMODE_PI 0x80000000
50573 +#define FM_PCD_PLCR_PEMODE_CBLND 0x40000000
50574 +#define FM_PCD_PLCR_PEMODE_ALG_MASK 0x30000000
50575 +#define FM_PCD_PLCR_PEMODE_ALG_RFC2698 0x10000000
50576 +#define FM_PCD_PLCR_PEMODE_ALG_RFC4115 0x20000000
50577 +#define FM_PCD_PLCR_PEMODE_DEFC_MASK 0x0C000000
50578 +#define FM_PCD_PLCR_PEMODE_DEFC_Y 0x04000000
50579 +#define FM_PCD_PLCR_PEMODE_DEFC_R 0x08000000
50580 +#define FM_PCD_PLCR_PEMODE_DEFC_OVERRIDE 0x0C000000
50581 +#define FM_PCD_PLCR_PEMODE_OVCLR_MASK 0x03000000
50582 +#define FM_PCD_PLCR_PEMODE_OVCLR_Y 0x01000000
50583 +#define FM_PCD_PLCR_PEMODE_OVCLR_R 0x02000000
50584 +#define FM_PCD_PLCR_PEMODE_OVCLR_G_NC 0x03000000
50585 +#define FM_PCD_PLCR_PEMODE_PKT 0x00800000
50586 +#define FM_PCD_PLCR_PEMODE_FPP_MASK 0x001F0000
50587 +#define FM_PCD_PLCR_PEMODE_FPP_SHIFT 16
50588 +#define FM_PCD_PLCR_PEMODE_FLS_MASK 0x0000F000
50589 +#define FM_PCD_PLCR_PEMODE_FLS_L2 0x00003000
50590 +#define FM_PCD_PLCR_PEMODE_FLS_L3 0x0000B000
50591 +#define FM_PCD_PLCR_PEMODE_FLS_L4 0x0000E000
50592 +#define FM_PCD_PLCR_PEMODE_FLS_FULL 0x0000F000
50593 +#define FM_PCD_PLCR_PEMODE_RBFLS 0x00000800
50594 +#define FM_PCD_PLCR_PEMODE_TRA 0x00000004
50595 +#define FM_PCD_PLCR_PEMODE_TRB 0x00000002
50596 +#define FM_PCD_PLCR_PEMODE_TRC 0x00000001
50597 +#define FM_PCD_PLCR_DOUBLE_ECC 0x80000000
50598 +#define FM_PCD_PLCR_INIT_ENTRY_ERROR 0x40000000
50599 +#define FM_PCD_PLCR_PRAM_SELF_INIT_COMPLETE 0x80000000
50600 +#define FM_PCD_PLCR_ATOMIC_ACTION_COMPLETE 0x40000000
50601 +
50602 +#define FM_PCD_PLCR_NIA_VALID 0x80000000
50603 +
50604 +#define FM_PCD_PLCR_GCR_EN 0x80000000
50605 +#define FM_PCD_PLCR_GCR_STEN 0x40000000
50606 +#define FM_PCD_PLCR_GCR_DAR 0x20000000
50607 +#define FM_PCD_PLCR_GCR_DEFNIA 0x00FFFFFF
50608 +#define FM_PCD_PLCR_NIA_ABS 0x00000100
50609 +
50610 +#define FM_PCD_PLCR_GSR_BSY 0x80000000
50611 +#define FM_PCD_PLCR_GSR_DQS 0x60000000
50612 +#define FM_PCD_PLCR_GSR_RPB 0x20000000
50613 +#define FM_PCD_PLCR_GSR_FQS 0x0C000000
50614 +#define FM_PCD_PLCR_GSR_LPALG 0x0000C000
50615 +#define FM_PCD_PLCR_GSR_LPCA 0x00003000
50616 +#define FM_PCD_PLCR_GSR_LPNUM 0x000000FF
50617 +
50618 +#define FM_PCD_PLCR_EVR_PSIC 0x80000000
50619 +#define FM_PCD_PLCR_EVR_AAC 0x40000000
50620 +
50621 +#define FM_PCD_PLCR_PAR_PSI 0x20000000
50622 +#define FM_PCD_PLCR_PAR_PNUM 0x00FF0000
50623 +/* PWSEL Selctive select options */
50624 +#define FM_PCD_PLCR_PAR_PWSEL_PEMODE 0x00008000 /* 0 */
50625 +#define FM_PCD_PLCR_PAR_PWSEL_PEGNIA 0x00004000 /* 1 */
50626 +#define FM_PCD_PLCR_PAR_PWSEL_PEYNIA 0x00002000 /* 2 */
50627 +#define FM_PCD_PLCR_PAR_PWSEL_PERNIA 0x00001000 /* 3 */
50628 +#define FM_PCD_PLCR_PAR_PWSEL_PECIR 0x00000800 /* 4 */
50629 +#define FM_PCD_PLCR_PAR_PWSEL_PECBS 0x00000400 /* 5 */
50630 +#define FM_PCD_PLCR_PAR_PWSEL_PEPIR_EIR 0x00000200 /* 6 */
50631 +#define FM_PCD_PLCR_PAR_PWSEL_PEPBS_EBS 0x00000100 /* 7 */
50632 +#define FM_PCD_PLCR_PAR_PWSEL_PELTS 0x00000080 /* 8 */
50633 +#define FM_PCD_PLCR_PAR_PWSEL_PECTS 0x00000040 /* 9 */
50634 +#define FM_PCD_PLCR_PAR_PWSEL_PEPTS_ETS 0x00000020 /* 10 */
50635 +#define FM_PCD_PLCR_PAR_PWSEL_PEGPC 0x00000010 /* 11 */
50636 +#define FM_PCD_PLCR_PAR_PWSEL_PEYPC 0x00000008 /* 12 */
50637 +#define FM_PCD_PLCR_PAR_PWSEL_PERPC 0x00000004 /* 13 */
50638 +#define FM_PCD_PLCR_PAR_PWSEL_PERYPC 0x00000002 /* 14 */
50639 +#define FM_PCD_PLCR_PAR_PWSEL_PERRPC 0x00000001 /* 15 */
50640 +
50641 +#define FM_PCD_PLCR_PAR_PMR_BRN_1TO1 0x0000 /* - Full bit replacement. {PBNUM[0:N-1]
50642 + 1-> 2^N specific locations. */
50643 +#define FM_PCD_PLCR_PAR_PMR_BRN_2TO2 0x1 /* - {PBNUM[0:N-2],PNUM[N-1]}.
50644 + 2-> 2^(N-1) base locations. */
50645 +#define FM_PCD_PLCR_PAR_PMR_BRN_4TO4 0x2 /* - {PBNUM[0:N-3],PNUM[N-2:N-1]}.
50646 + 4-> 2^(N-2) base locations. */
50647 +#define FM_PCD_PLCR_PAR_PMR_BRN_8TO8 0x3 /* - {PBNUM[0:N-4],PNUM[N-3:N-1]}.
50648 + 8->2^(N-3) base locations. */
50649 +#define FM_PCD_PLCR_PAR_PMR_BRN_16TO16 0x4 /* - {PBNUM[0:N-5],PNUM[N-4:N-1]}.
50650 + 16-> 2^(N-4) base locations. */
50651 +#define FM_PCD_PLCR_PAR_PMR_BRN_32TO32 0x5 /* {PBNUM[0:N-6],PNUM[N-5:N-1]}.
50652 + 32-> 2^(N-5) base locations. */
50653 +#define FM_PCD_PLCR_PAR_PMR_BRN_64TO64 0x6 /* {PBNUM[0:N-7],PNUM[N-6:N-1]}.
50654 + 64-> 2^(N-6) base locations. */
50655 +#define FM_PCD_PLCR_PAR_PMR_BRN_128TO128 0x7 /* {PBNUM[0:N-8],PNUM[N-7:N-1]}.
50656 + 128-> 2^(N-7) base locations. */
50657 +#define FM_PCD_PLCR_PAR_PMR_BRN_256TO256 0x8 /* - No bit replacement for N=8. {PNUM[N-8:N-1]}.
50658 + When N=8 this option maps all 256 profiles by the DISPATCH bus into one group. */
50659 +
50660 +#define FM_PCD_PLCR_PMR_V 0x80000000
50661 +#define PLCR_ERR_ECC_CAP 0x80000000
50662 +#define PLCR_ERR_ECC_TYPE_DOUBLE 0x40000000
50663 +#define PLCR_ERR_ECC_PNUM_MASK 0x00000FF0
50664 +#define PLCR_ERR_ECC_OFFSET_MASK 0x0000000F
50665 +
50666 +#define PLCR_ERR_UNINIT_CAP 0x80000000
50667 +#define PLCR_ERR_UNINIT_NUM_MASK 0x000000FF
50668 +#define PLCR_ERR_UNINIT_PID_MASK 0x003f0000
50669 +#define PLCR_ERR_UNINIT_ABSOLUTE_MASK 0x00008000
50670 +
50671 +/* shifts */
50672 +#define PLCR_ERR_ECC_PNUM_SHIFT 4
50673 +#define PLCR_ERR_UNINIT_PID_SHIFT 16
50674 +
50675 +#define FM_PCD_PLCR_PMR_BRN_SHIFT 16
50676 +
50677 +#define PLCR_PORT_WINDOW_SIZE(hardwarePortId)
50678 +
50679 +
50680 +#endif /* __FM_PLCR_H */
50681 --- /dev/null
50682 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.c
50683 @@ -0,0 +1,423 @@
50684 +/*
50685 + * Copyright 2008-2012 Freescale Semiconductor Inc.
50686 + *
50687 + * Redistribution and use in source and binary forms, with or without
50688 + * modification, are permitted provided that the following conditions are met:
50689 + * * Redistributions of source code must retain the above copyright
50690 + * notice, this list of conditions and the following disclaimer.
50691 + * * Redistributions in binary form must reproduce the above copyright
50692 + * notice, this list of conditions and the following disclaimer in the
50693 + * documentation and/or other materials provided with the distribution.
50694 + * * Neither the name of Freescale Semiconductor nor the
50695 + * names of its contributors may be used to endorse or promote products
50696 + * derived from this software without specific prior written permission.
50697 + *
50698 + *
50699 + * ALTERNATIVELY, this software may be distributed under the terms of the
50700 + * GNU General Public License ("GPL") as published by the Free Software
50701 + * Foundation, either version 2 of that License or (at your option) any
50702 + * later version.
50703 + *
50704 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
50705 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50706 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50707 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
50708 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50709 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
50710 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
50711 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50712 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50713 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50714 + */
50715 +
50716 +
50717 +/******************************************************************************
50718 + @File fm_pcd.c
50719 +
50720 + @Description FM PCD ...
50721 +*//***************************************************************************/
50722 +#include <linux/math64.h>
50723 +#include "std_ext.h"
50724 +#include "error_ext.h"
50725 +#include "string_ext.h"
50726 +#include "debug_ext.h"
50727 +#include "net_ext.h"
50728 +
50729 +#include "fm_common.h"
50730 +#include "fm_pcd.h"
50731 +#include "fm_pcd_ipc.h"
50732 +#include "fm_prs.h"
50733 +#include "fsl_fman_prs.h"
50734 +
50735 +
50736 +static void PcdPrsErrorException(t_Handle h_FmPcd)
50737 +{
50738 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50739 + uint32_t event, ev_mask;
50740 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50741 +
50742 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50743 + ev_mask = fman_prs_get_err_ev_mask(PrsRegs);
50744 +
50745 + event = fman_prs_get_err_event(PrsRegs, ev_mask);
50746 +
50747 + fman_prs_ack_err_event(PrsRegs, event);
50748 +
50749 + DBG(TRACE, ("parser error - 0x%08x\n",event));
50750 +
50751 + if(event & FM_PCD_PRS_DOUBLE_ECC)
50752 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC);
50753 +}
50754 +
50755 +static void PcdPrsException(t_Handle h_FmPcd)
50756 +{
50757 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50758 + uint32_t event, ev_mask;
50759 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50760 +
50761 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50762 + ev_mask = fman_prs_get_expt_ev_mask(PrsRegs);
50763 + event = fman_prs_get_expt_event(PrsRegs, ev_mask);
50764 +
50765 + ASSERT_COND(event & FM_PCD_PRS_SINGLE_ECC);
50766 +
50767 + DBG(TRACE, ("parser event - 0x%08x\n",event));
50768 +
50769 + fman_prs_ack_expt_event(PrsRegs, event);
50770 +
50771 + p_FmPcd->f_Exception(p_FmPcd->h_App,e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
50772 +}
50773 +
50774 +t_Handle PrsConfig(t_FmPcd *p_FmPcd,t_FmPcdParams *p_FmPcdParams)
50775 +{
50776 + t_FmPcdPrs *p_FmPcdPrs;
50777 + uintptr_t baseAddr;
50778 +
50779 + UNUSED(p_FmPcd);
50780 + UNUSED(p_FmPcdParams);
50781 +
50782 + p_FmPcdPrs = (t_FmPcdPrs *) XX_Malloc(sizeof(t_FmPcdPrs));
50783 + if (!p_FmPcdPrs)
50784 + {
50785 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Parser structure allocation FAILED"));
50786 + return NULL;
50787 + }
50788 + memset(p_FmPcdPrs, 0, sizeof(t_FmPcdPrs));
50789 + fman_prs_defconfig(&p_FmPcd->p_FmPcdDriverParam->dfltCfg);
50790 +
50791 + if (p_FmPcd->guestId == NCSW_MASTER_ID)
50792 + {
50793 + baseAddr = FmGetPcdPrsBaseAddr(p_FmPcdParams->h_Fm);
50794 + p_FmPcdPrs->p_SwPrsCode = (uint32_t *)UINT_TO_PTR(baseAddr);
50795 + p_FmPcdPrs->p_FmPcdPrsRegs = (struct fman_prs_regs *)UINT_TO_PTR(baseAddr + PRS_REGS_OFFSET);
50796 + }
50797 +
50798 + p_FmPcdPrs->fmPcdPrsPortIdStatistics = p_FmPcd->p_FmPcdDriverParam->dfltCfg.port_id_stat;
50799 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = p_FmPcd->p_FmPcdDriverParam->dfltCfg.max_prs_cyc_lim;
50800 + p_FmPcd->exceptions |= p_FmPcd->p_FmPcdDriverParam->dfltCfg.prs_exceptions;
50801 +
50802 + return p_FmPcdPrs;
50803 +}
50804 +
50805 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
50806 + static uint8_t swPrsPatch[] = SW_PRS_UDP_LITE_PATCH;
50807 +#else
50808 + static uint8_t swPrsPatch[] = SW_PRS_OFFLOAD_PATCH;
50809 +#endif /* FM_CAPWAP_SUPPORT */
50810 +
50811 +t_Error PrsInit(t_FmPcd *p_FmPcd)
50812 +{
50813 + t_FmPcdDriverParam *p_Param = p_FmPcd->p_FmPcdDriverParam;
50814 + uint32_t *p_TmpCode;
50815 + uint32_t *p_LoadTarget = (uint32_t *)PTR_MOVE(p_FmPcd->p_FmPcdPrs->p_SwPrsCode,
50816 + FM_PCD_SW_PRS_SIZE-FM_PCD_PRS_SW_PATCHES_SIZE);
50817 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50818 + uint32_t i;
50819 +
50820 + ASSERT_COND(sizeof(swPrsPatch) <= (FM_PCD_PRS_SW_PATCHES_SIZE-FM_PCD_PRS_SW_TAIL_SIZE));
50821 +
50822 + /* nothing to do in guest-partition */
50823 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
50824 + return E_OK;
50825 +
50826 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(sizeof(swPrsPatch),4), 0, sizeof(uint32_t));
50827 + if (!p_TmpCode)
50828 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
50829 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(sizeof(swPrsPatch),4));
50830 + memcpy((uint8_t *)p_TmpCode, (uint8_t *)swPrsPatch, sizeof(swPrsPatch));
50831 +
50832 + fman_prs_init(PrsRegs, &p_Param->dfltCfg);
50833 +
50834 + /* register even if no interrupts enabled, to allow future enablement */
50835 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR, PcdPrsErrorException, p_FmPcd);
50836 +
50837 + /* register even if no interrupts enabled, to allow future enablement */
50838 + FmRegisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL, PcdPrsException, p_FmPcd);
50839 +
50840 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
50841 + FmEnableRamsEcc(p_FmPcd->h_Fm);
50842 +
50843 + if(p_FmPcd->exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
50844 + FmEnableRamsEcc(p_FmPcd->h_Fm);
50845 +
50846 + /* load sw parser Ip-Frag patch */
50847 + for (i=0; i<DIV_CEIL(sizeof(swPrsPatch), 4); i++)
50848 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
50849 +
50850 + XX_FreeSmart(p_TmpCode);
50851 +
50852 + return E_OK;
50853 +}
50854 +
50855 +void PrsFree(t_FmPcd *p_FmPcd)
50856 +{
50857 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50858 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_ERR);
50859 + /* register even if no interrupts enabled, to allow future enablement */
50860 + FmUnregisterIntr(p_FmPcd->h_Fm, e_FM_MOD_PRS, 0, e_FM_INTR_TYPE_NORMAL);
50861 +}
50862 +
50863 +void PrsEnable(t_FmPcd *p_FmPcd)
50864 +{
50865 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50866 +
50867 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50868 + fman_prs_enable(PrsRegs);
50869 +}
50870 +
50871 +void PrsDisable(t_FmPcd *p_FmPcd)
50872 +{
50873 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50874 +
50875 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50876 + fman_prs_disable(PrsRegs);
50877 +}
50878 +
50879 +int PrsIsEnabled(t_FmPcd *p_FmPcd)
50880 +{
50881 + struct fman_prs_regs *PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50882 +
50883 + ASSERT_COND(p_FmPcd->guestId == NCSW_MASTER_ID);
50884 + return fman_prs_is_enabled(PrsRegs);
50885 +}
50886 +
50887 +t_Error PrsIncludePortInStatistics(t_FmPcd *p_FmPcd, uint8_t hardwarePortId, bool include)
50888 +{
50889 + struct fman_prs_regs *PrsRegs;
50890 + uint32_t bitMask = 0;
50891 + uint8_t prsPortId;
50892 +
50893 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
50894 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50895 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
50896 +
50897 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
50898 +
50899 + GET_FM_PCD_PRS_PORT_ID(prsPortId, hardwarePortId);
50900 + GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId);
50901 +
50902 + if (include)
50903 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics |= bitMask;
50904 + else
50905 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics &= ~bitMask;
50906 +
50907 + fman_prs_set_stst_port_msk(PrsRegs,
50908 + p_FmPcd->p_FmPcdPrs->fmPcdPrsPortIdStatistics);
50909 +
50910 + return E_OK;
50911 +}
50912 +
50913 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle h_FmPcd, uint8_t hardwarePortId, bool include)
50914 +{
50915 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50916 + t_Error err;
50917 +
50918 + SANITY_CHECK_RETURN_ERROR((hardwarePortId >=1 && hardwarePortId <= 16), E_INVALID_VALUE);
50919 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
50920 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
50921 +
50922 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
50923 + p_FmPcd->h_IpcSession)
50924 + {
50925 + t_FmPcdIpcPrsIncludePort prsIncludePortParams;
50926 + t_FmPcdIpcMsg msg;
50927 +
50928 + prsIncludePortParams.hardwarePortId = hardwarePortId;
50929 + prsIncludePortParams.include = include;
50930 + memset(&msg, 0, sizeof(msg));
50931 + msg.msgId = FM_PCD_PRS_INC_PORT_STATS;
50932 + memcpy(msg.msgBody, &prsIncludePortParams, sizeof(prsIncludePortParams));
50933 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
50934 + (uint8_t*)&msg,
50935 + sizeof(msg.msgId) +sizeof(prsIncludePortParams),
50936 + NULL,
50937 + NULL,
50938 + NULL,
50939 + NULL);
50940 + if (err != E_OK)
50941 + RETURN_ERROR(MAJOR, err, NO_MSG);
50942 + return E_OK;
50943 + }
50944 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
50945 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
50946 + ("running in guest-mode without IPC!"));
50947 +
50948 + return PrsIncludePortInStatistics(p_FmPcd, hardwarePortId, include);
50949 +}
50950 +
50951 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr)
50952 +{
50953 + t_FmPcd *p_FmPcd = (t_FmPcd *)h_FmPcd;
50954 + t_FmPcdPrsLabelParams *p_Label;
50955 + int i;
50956 +
50957 + SANITY_CHECK_RETURN_VALUE(p_FmPcd, E_INVALID_HANDLE, 0);
50958 + SANITY_CHECK_RETURN_VALUE(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE, 0);
50959 +
50960 + if ((p_FmPcd->guestId != NCSW_MASTER_ID) &&
50961 + p_FmPcd->h_IpcSession)
50962 + {
50963 + t_Error err = E_OK;
50964 + t_FmPcdIpcSwPrsLable labelParams;
50965 + t_FmPcdIpcMsg msg;
50966 + uint32_t prsOffset = 0;
50967 + t_FmPcdIpcReply reply;
50968 + uint32_t replyLength;
50969 +
50970 + memset(&reply, 0, sizeof(reply));
50971 + memset(&msg, 0, sizeof(msg));
50972 + labelParams.enumHdr = (uint32_t)hdr;
50973 + labelParams.indexPerHdr = indexPerHdr;
50974 + msg.msgId = FM_PCD_GET_SW_PRS_OFFSET;
50975 + memcpy(msg.msgBody, &labelParams, sizeof(labelParams));
50976 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
50977 + err = XX_IpcSendMessage(p_FmPcd->h_IpcSession,
50978 + (uint8_t*)&msg,
50979 + sizeof(msg.msgId) +sizeof(labelParams),
50980 + (uint8_t*)&reply,
50981 + &replyLength,
50982 + NULL,
50983 + NULL);
50984 + if (err != E_OK)
50985 + RETURN_ERROR(MAJOR, err, NO_MSG);
50986 + if (replyLength != sizeof(uint32_t) + sizeof(uint32_t))
50987 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
50988 +
50989 + memcpy((uint8_t*)&prsOffset, reply.replyBody, sizeof(uint32_t));
50990 + return prsOffset;
50991 + }
50992 + else if (p_FmPcd->guestId != NCSW_MASTER_ID)
50993 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
50994 + ("running in guest-mode without IPC!"));
50995 +
50996 + ASSERT_COND(p_FmPcd->p_FmPcdPrs->currLabel < FM_PCD_PRS_NUM_OF_LABELS);
50997 +
50998 + for (i=0; i<p_FmPcd->p_FmPcdPrs->currLabel; i++)
50999 + {
51000 + p_Label = &p_FmPcd->p_FmPcdPrs->labelsTable[i];
51001 +
51002 + if ((hdr == p_Label->hdr) && (indexPerHdr == p_Label->indexPerHdr))
51003 + return p_Label->instructionOffset;
51004 + }
51005 +
51006 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Sw Parser attachment Not found"));
51007 + return (uint32_t)ILLEGAL_BASE;
51008 +}
51009 +
51010 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable)
51011 +{
51012 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
51013 + struct fman_prs_regs *PrsRegs;
51014 +
51015 + SANITY_CHECK_RETURN(p_FmPcd, E_INVALID_HANDLE);
51016 + SANITY_CHECK_RETURN(p_FmPcd->p_FmPcdPrs, E_INVALID_HANDLE);
51017 +
51018 + PrsRegs = (struct fman_prs_regs *)p_FmPcd->p_FmPcdPrs->p_FmPcdPrsRegs;
51019 +
51020 +
51021 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
51022 + {
51023 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_SetPrsStatistics - guest mode!"));
51024 + return;
51025 + }
51026 +
51027 + fman_prs_set_stst(PrsRegs, enable);
51028 +}
51029 +
51030 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs)
51031 +{
51032 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
51033 + uint32_t *p_LoadTarget;
51034 + uint32_t *p_TmpCode;
51035 + int i;
51036 +
51037 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
51038 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->p_FmPcdDriverParam, E_INVALID_STATE);
51039 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdPrs, E_INVALID_STATE);
51040 + SANITY_CHECK_RETURN_ERROR(p_SwPrs, E_INVALID_HANDLE);
51041 + SANITY_CHECK_RETURN_ERROR(!p_FmPcd->enabled, E_INVALID_HANDLE);
51042 +
51043 + if (p_FmPcd->guestId != NCSW_MASTER_ID)
51044 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode!"));
51045 +
51046 + if (!p_SwPrs->override)
51047 + {
51048 + if(p_FmPcd->p_FmPcdPrs->p_CurrSwPrs > p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4)
51049 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("SW parser base must be larger than current loaded code"));
51050 + }
51051 + else
51052 + p_FmPcd->p_FmPcdPrs->currLabel = 0;
51053 +
51054 + if (p_SwPrs->size > FM_PCD_SW_PRS_SIZE - FM_PCD_PRS_SW_TAIL_SIZE - p_SwPrs->base*2)
51055 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_SwPrs->size may not be larger than MAX_SW_PRS_CODE_SIZE"));
51056 +
51057 + if (p_FmPcd->p_FmPcdPrs->currLabel + p_SwPrs->numOfLabels > FM_PCD_PRS_NUM_OF_LABELS)
51058 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceeded number of labels allowed "));
51059 +
51060 + p_TmpCode = (uint32_t *)XX_MallocSmart(ROUND_UP(p_SwPrs->size,4), 0, sizeof(uint32_t));
51061 + if (!p_TmpCode)
51062 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Tmp Sw-Parser code allocation FAILED"));
51063 + memset((uint8_t *)p_TmpCode, 0, ROUND_UP(p_SwPrs->size,4));
51064 + memcpy((uint8_t *)p_TmpCode, p_SwPrs->p_Code, p_SwPrs->size);
51065 +
51066 + /* save sw parser labels */
51067 + memcpy(&p_FmPcd->p_FmPcdPrs->labelsTable[p_FmPcd->p_FmPcdPrs->currLabel],
51068 + p_SwPrs->labelsTable,
51069 + p_SwPrs->numOfLabels*sizeof(t_FmPcdPrsLabelParams));
51070 + p_FmPcd->p_FmPcdPrs->currLabel += p_SwPrs->numOfLabels;
51071 +
51072 + /* load sw parser code */
51073 + p_LoadTarget = p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4;
51074 +
51075 + for(i=0; i<DIV_CEIL(p_SwPrs->size, 4); i++)
51076 + WRITE_UINT32(p_LoadTarget[i], GET_UINT32(p_TmpCode[i]));
51077 +
51078 + p_FmPcd->p_FmPcdPrs->p_CurrSwPrs =
51079 + p_FmPcd->p_FmPcdPrs->p_SwPrsCode + p_SwPrs->base*2/4 + ROUND_UP(p_SwPrs->size,4);
51080 +
51081 + /* copy data parameters */
51082 + for (i=0;i<FM_PCD_PRS_NUM_OF_HDRS;i++)
51083 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+PRS_SW_DATA/4+i), p_SwPrs->swPrsDataParams[i]);
51084 +
51085 + /* Clear last 4 bytes */
51086 + WRITE_UINT32(*(p_FmPcd->p_FmPcdPrs->p_SwPrsCode+(PRS_SW_DATA-FM_PCD_PRS_SW_TAIL_SIZE)/4), 0);
51087 +
51088 + XX_FreeSmart(p_TmpCode);
51089 +
51090 + return E_OK;
51091 +}
51092 +
51093 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value)
51094 +{
51095 + t_FmPcd *p_FmPcd = (t_FmPcd*)h_FmPcd;
51096 +
51097 + SANITY_CHECK_RETURN_ERROR(p_FmPcd, E_INVALID_HANDLE);
51098 + SANITY_CHECK_RETURN_ERROR(p_FmPcd->p_FmPcdDriverParam, E_INVALID_HANDLE);
51099 +
51100 + if(p_FmPcd->guestId != NCSW_MASTER_ID)
51101 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM_PCD_ConfigPrsMaxCycleLimit - guest mode!"));
51102 +
51103 + p_FmPcd->p_FmPcdDriverParam->prsMaxParseCycleLimit = value;
51104 +
51105 + return E_OK;
51106 +}
51107 --- /dev/null
51108 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_prs.h
51109 @@ -0,0 +1,316 @@
51110 +/*
51111 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51112 + *
51113 + * Redistribution and use in source and binary forms, with or without
51114 + * modification, are permitted provided that the following conditions are met:
51115 + * * Redistributions of source code must retain the above copyright
51116 + * notice, this list of conditions and the following disclaimer.
51117 + * * Redistributions in binary form must reproduce the above copyright
51118 + * notice, this list of conditions and the following disclaimer in the
51119 + * documentation and/or other materials provided with the distribution.
51120 + * * Neither the name of Freescale Semiconductor nor the
51121 + * names of its contributors may be used to endorse or promote products
51122 + * derived from this software without specific prior written permission.
51123 + *
51124 + *
51125 + * ALTERNATIVELY, this software may be distributed under the terms of the
51126 + * GNU General Public License ("GPL") as published by the Free Software
51127 + * Foundation, either version 2 of that License or (at your option) any
51128 + * later version.
51129 + *
51130 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51131 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51132 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51133 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51134 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51135 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51136 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51137 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51138 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51139 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51140 + */
51141 +
51142 +
51143 +/******************************************************************************
51144 + @File fm_prs.h
51145 +
51146 + @Description FM Parser private header
51147 + *//***************************************************************************/
51148 +#ifndef __FM_PRS_H
51149 +#define __FM_PRS_H
51150 +
51151 +#include "std_ext.h"
51152 +
51153 +/***********************************************************************/
51154 +/* SW parser IP_FRAG patch */
51155 +/***********************************************************************/
51156 +
51157 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
51158 +#define SW_PRS_UDP_LITE_PATCH \
51159 +{\
51160 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
51161 + 0x00,0x00,0x50,0x2C,0x40,0x00,0x31,0x92,0x50,0x2C, \
51162 + 0x00,0x88,0x18,0x2F,0x00,0x01,0x1B,0xFE,0x18,0x71, \
51163 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
51164 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x60,0x4F, \
51165 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
51166 + 0x00,0x01,0x07,0x01,0x60,0x3B,0x00,0x00,0x30,0xD0, \
51167 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
51168 + 0x40,0x4C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
51169 + 0x00,0x06,0x18,0x5D,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
51170 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
51171 + 0x00,0x08,0x28,0x1A,0x60,0x37,0x00,0x00,0x30,0xF2, \
51172 + 0x18,0x5D,0x06,0x00,0x29,0x1E,0x30,0xF2,0x2F,0x0E, \
51173 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x2F,0x0E, \
51174 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
51175 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
51176 + 0x2F,0x0E,0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80, \
51177 + 0x00,0x02,0x00,0x00,0x97,0x9E,0x40,0x7E,0x00,0x08, \
51178 + 0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE,0x00,0x00, \
51179 + 0x9F,0x9E,0x40,0xB3,0x00,0x00,0x02,0x1F,0x00,0x08, \
51180 + 0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0,0x60,0x9F, \
51181 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
51182 + 0x00,0x01,0x07,0x01,0x60,0x8B,0x00,0x00,0x30,0xD0, \
51183 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
51184 + 0x40,0x9C,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
51185 + 0x00,0x06,0x18,0xAD,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
51186 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
51187 + 0x00,0x08,0x28,0x1A,0x60,0x87,0x00,0x00,0x30,0xF2, \
51188 + 0x18,0xAD,0x06,0x00,0x29,0x1E,0x30,0xF2,0x50,0xB3, \
51189 + 0xFF,0xFF,0x18,0xB8,0x08,0x16,0x00,0x54,0x00,0x01, \
51190 + 0x1B,0xFE,0x18,0xC5,0x32,0xF1,0x28,0x5D,0x32,0xF1, \
51191 + 0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00,0x8F,0x9F, \
51192 + 0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01,0x1B,0xFF, \
51193 + 0x00,0x01,0x1B,0xFF \
51194 +}
51195 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
51196 +
51197 +#if (DPAA_VERSION == 10)
51198 +/* Version: 106.1.9 */
51199 +#define SW_PRS_OFFLOAD_PATCH \
51200 +{ \
51201 + 0x31,0x52,0x00,0xDA,0x0A,0x00,0x00,0x00,0x00,0x00, \
51202 + 0x00,0x00,0x43,0x0A,0x00,0x00,0x00,0x01,0x1B,0xFE, \
51203 + 0x00,0x00,0x99,0x00,0x53,0x13,0x00,0x00,0x00,0x00, \
51204 + 0x9F,0x98,0x53,0x13,0x00,0x00,0x1B,0x23,0x33,0xF1, \
51205 + 0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
51206 + 0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00,0x00,0x01, \
51207 + 0x32,0xC1,0x32,0xF0,0x00,0x4A,0x00,0x80,0x1F,0xFF, \
51208 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x06,0x00, \
51209 + 0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x2F,0x00,0x00, \
51210 + 0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA,0x00,0x40, \
51211 + 0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x95,0x00,0x00, \
51212 + 0x00,0x00,0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55, \
51213 + 0x00,0x28,0x28,0x43,0x30,0x7E,0x43,0x45,0x00,0x00, \
51214 + 0x30,0x7E,0x43,0x45,0x00,0x3C,0x1B,0x5D,0x32,0x11, \
51215 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x83,0x8F, \
51216 + 0x2F,0x0F,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
51217 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
51218 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
51219 + 0x28,0x43,0x06,0x00,0x1B,0x3E,0x30,0x7E,0x53,0x79, \
51220 + 0x00,0x2B,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
51221 + 0x00,0x00,0x87,0x8F,0x28,0x23,0x06,0x00,0x32,0x11, \
51222 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
51223 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
51224 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x00,0x01, \
51225 + 0x1B,0xFE,0x00,0x00,0x9B,0x8E,0x53,0x90,0x00,0x00, \
51226 + 0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23,0x06,0x00, \
51227 + 0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28,0x00,0x00, \
51228 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
51229 + 0x28,0x43,0x06,0x00,0x00,0x01,0x1B,0xFE,0x32,0xC1, \
51230 + 0x00,0x55,0x00,0x28,0x28,0x43,0x1B,0xCF,0x00,0x00, \
51231 + 0x9B,0x8F,0x2F,0x0F,0x32,0xC1,0x00,0x55,0x00,0x28, \
51232 + 0x28,0x43,0x30,0x7E,0x43,0xBF,0x00,0x2C,0x32,0x11, \
51233 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
51234 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
51235 + 0x00,0x81,0x00,0x00,0x83,0x8F,0x2F,0x0F,0x06,0x00, \
51236 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01, \
51237 + 0x00,0x81,0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50, \
51238 + 0x00,0x01,0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00, \
51239 + 0x1B,0x9C,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
51240 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
51241 + 0x00,0x00,0x00,0x01,0x32,0xC1,0x32,0xF0,0x00,0x4A, \
51242 + 0x00,0x80,0x1F,0xFF,0x00,0x01,0x1B,0xFE, \
51243 +}
51244 +
51245 +#else
51246 +#define SW_PRS_OFFLOAD_PATCH \
51247 +{ \
51248 + 0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00,0x00,0x00, \
51249 + 0x00,0x00,0x51,0x16,0x08,0x4B,0x31,0x53,0x00,0xFB, \
51250 + 0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x2B, \
51251 + 0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00,0x00,0x00, \
51252 + 0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA,0x0A,0x00, \
51253 + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x20,0x00,0x00, \
51254 + 0x00,0x01,0x1B,0xFE,0x00,0x00,0x99,0x00,0x51,0x29, \
51255 + 0x00,0x00,0x00,0x00,0x9F,0x98,0x51,0x29,0x00,0x00, \
51256 + 0x19,0x44,0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F, \
51257 + 0x00,0x20,0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00, \
51258 + 0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3, \
51259 + 0x29,0x8F,0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00, \
51260 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02, \
51261 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x00,0x01,0x1B,0xFE, \
51262 + 0x31,0x52,0x00,0xDA,0xFC,0x00,0x00,0x00,0x00,0x00, \
51263 + 0x00,0x00,0x51,0x52,0x40,0x00,0x31,0x92,0x51,0x52, \
51264 + 0x00,0x88,0x19,0x55,0x08,0x05,0x00,0x00,0x19,0x99, \
51265 + 0x02,0x1F,0x00,0x08,0x00,0x83,0x02,0x1F,0x00,0x20, \
51266 + 0x28,0x1B,0x00,0x05,0x29,0x1F,0x30,0xD0,0x61,0x75, \
51267 + 0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F,0x00,0x52, \
51268 + 0x00,0x01,0x07,0x01,0x61,0x61,0x00,0x00,0x30,0xD0, \
51269 + 0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, \
51270 + 0x41,0x72,0x00,0x00,0x02,0x8F,0x00,0x00,0x30,0xF2, \
51271 + 0x00,0x06,0x19,0x83,0x00,0x00,0x9F,0xFF,0x30,0xF2, \
51272 + 0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0,0x00,0x52, \
51273 + 0x00,0x08,0x28,0x1A,0x61,0x5D,0x00,0x00,0x30,0xF2, \
51274 + 0x19,0x83,0x06,0x00,0x29,0x1E,0x30,0xF2,0x29,0x0E, \
51275 + 0x30,0x72,0x00,0x00,0x9B,0x8F,0x00,0x06,0x29,0x0E, \
51276 + 0x32,0xF1,0x32,0xB0,0x00,0x4F,0x00,0x57,0x00,0x28, \
51277 + 0x00,0x00,0x97,0x9E,0x00,0x4E,0x30,0x72,0x00,0x06, \
51278 + 0x29,0x0E,0x08,0x05,0x00,0x01,0x31,0x52,0x00,0xDA, \
51279 + 0x0E,0x4F,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0xAF, \
51280 + 0x04,0x4B,0x31,0x53,0x00,0xFB,0xFF,0xF0,0x00,0x00, \
51281 + 0x00,0x00,0x00,0x00,0x29,0x2B,0x33,0xF1,0x00,0xFB, \
51282 + 0x00,0xDF,0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7F, \
51283 + 0x31,0x52,0x00,0xDA,0x06,0x00,0x00,0x00,0x00,0x00, \
51284 + 0x00,0x00,0x41,0xB9,0x00,0x00,0x00,0x01,0x1B,0xFE, \
51285 + 0x31,0x52,0x00,0xDA,0x00,0x40,0x00,0x00,0x00,0x00, \
51286 + 0x00,0x00,0x42,0x06,0x00,0x00,0x00,0x00,0x9B,0x8F, \
51287 + 0x28,0x01,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
51288 + 0x30,0x00,0x41,0xEB,0x00,0x2C,0x32,0x11,0x32,0xC0, \
51289 + 0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F,0x28,0x23, \
51290 + 0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81, \
51291 + 0x00,0x00,0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11, \
51292 + 0x32,0xC0,0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81, \
51293 + 0x32,0x11,0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01, \
51294 + 0x01,0x04,0x00,0x4D,0x28,0x43,0x06,0x00,0x19,0xC8, \
51295 + 0x09,0x5F,0x00,0x20,0x00,0x00,0x09,0x4F,0x00,0x20, \
51296 + 0x00,0x00,0x34,0xB7,0x00,0xF9,0x00,0x00,0x01,0x00, \
51297 + 0x00,0x00,0x00,0x00,0x2B,0x97,0x31,0xB3,0x29,0x8F, \
51298 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
51299 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
51300 + 0x00,0x01,0x1B,0xFE,0x30,0x50,0x52,0x0B,0x00,0x00, \
51301 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
51302 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x42,0x18, \
51303 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
51304 + 0x00,0x00,0x9F,0x9E,0x42,0x4D,0x00,0x00,0x02,0x1F, \
51305 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
51306 + 0x62,0x39,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
51307 + 0x00,0x52,0x00,0x01,0x07,0x01,0x62,0x25,0x00,0x00, \
51308 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
51309 + 0x00,0x00,0x42,0x36,0x00,0x00,0x02,0x8F,0x00,0x00, \
51310 + 0x30,0xF2,0x00,0x06,0x1A,0x47,0x00,0x00,0x9F,0xFF, \
51311 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
51312 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x62,0x21,0x00,0x00, \
51313 + 0x30,0xF2,0x1A,0x47,0x06,0x00,0x29,0x1E,0x30,0xF2, \
51314 + 0x52,0x4D,0xFF,0xFF,0x1A,0x52,0x08,0x16,0x00,0x54, \
51315 + 0x00,0x01,0x1B,0xFE,0x1A,0x5F,0x32,0xF1,0x28,0x5D, \
51316 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
51317 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
51318 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x31,0x52,0x00,0xDA, \
51319 + 0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x6D, \
51320 + 0x40,0x00,0x31,0x92,0x52,0x6D,0x00,0x88,0x1A,0x70, \
51321 + 0x08,0x05,0x00,0x00,0x1A,0xB4,0x02,0x1F,0x00,0x08, \
51322 + 0x00,0x83,0x02,0x1F,0x00,0x20,0x28,0x1B,0x00,0x05, \
51323 + 0x29,0x1F,0x30,0xD0,0x62,0x90,0x00,0x07,0x00,0x05, \
51324 + 0x00,0x00,0xC3,0x8F,0x00,0x52,0x00,0x01,0x07,0x01, \
51325 + 0x62,0x7C,0x00,0x00,0x30,0xD0,0x00,0xDA,0x00,0x01, \
51326 + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x8D,0x00,0x00, \
51327 + 0x02,0x8F,0x00,0x00,0x30,0xF2,0x00,0x06,0x1A,0x9E, \
51328 + 0x00,0x00,0x9F,0xFF,0x30,0xF2,0x00,0x06,0x29,0x1E, \
51329 + 0x07,0x08,0x30,0xD0,0x00,0x52,0x00,0x08,0x28,0x1A, \
51330 + 0x62,0x78,0x00,0x00,0x30,0xF2,0x1A,0x9E,0x06,0x00, \
51331 + 0x29,0x1E,0x30,0xF2,0x29,0x0E,0x30,0x72,0x00,0x00, \
51332 + 0x9B,0x8F,0x00,0x06,0x29,0x0E,0x32,0xF1,0x32,0xB0, \
51333 + 0x00,0x4F,0x00,0x57,0x00,0x28,0x00,0x00,0x97,0x9E, \
51334 + 0x00,0x4E,0x30,0x72,0x00,0x06,0x29,0x0E,0x08,0x05, \
51335 + 0x00,0x01,0x31,0x52,0x00,0xDA,0x0E,0x4F,0x00,0x00, \
51336 + 0x00,0x00,0x00,0x00,0x52,0xCA,0x04,0x4B,0x31,0x53, \
51337 + 0x00,0xFB,0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, \
51338 + 0x29,0x2B,0x33,0xF1,0x00,0xFB,0x00,0xDF,0x00,0x00, \
51339 + 0x00,0x00,0x00,0x00,0x28,0x7F,0x31,0x52,0x00,0xDA, \
51340 + 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0xD4, \
51341 + 0x00,0x00,0x00,0x01,0x1B,0xFE,0x31,0x52,0x00,0xDA, \
51342 + 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x53,0x37, \
51343 + 0x00,0x00,0x00,0x00,0x9B,0x8F,0x28,0x01,0x32,0xC1, \
51344 + 0x00,0x55,0x00,0x28,0x28,0x43,0x30,0x00,0x42,0xEA, \
51345 + 0x00,0x00,0x30,0x00,0x42,0xEA,0x00,0x3C,0x1B,0x02, \
51346 + 0x32,0x11,0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00, \
51347 + 0x83,0x8F,0x28,0x01,0x06,0x00,0x32,0x11,0x32,0xC0, \
51348 + 0x00,0x4F,0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11, \
51349 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
51350 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1A,0xE3,0x30,0x00, \
51351 + 0x43,0x20,0x00,0x2B,0x00,0x00,0x9B,0x8E,0x43,0x0E, \
51352 + 0x00,0x00,0x32,0xC1,0x00,0x55,0x00,0x28,0x28,0x43, \
51353 + 0x1B,0x1F,0x06,0x29,0x00,0x00,0x83,0x8F,0x28,0x23, \
51354 + 0x06,0x00,0x06,0x29,0x32,0xC1,0x00,0x55,0x00,0x28, \
51355 + 0x00,0x00,0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04, \
51356 + 0x00,0x4D,0x28,0x43,0x06,0x00,0x1B,0x37,0x32,0x11, \
51357 + 0x32,0xC0,0x00,0x4F,0x00,0x81,0x00,0x00,0x87,0x8F, \
51358 + 0x28,0x23,0x06,0x00,0x32,0x11,0x32,0xC0,0x00,0x4F, \
51359 + 0x00,0x55,0x00,0x01,0x00,0x81,0x32,0x11,0x00,0x00, \
51360 + 0x83,0x8E,0x00,0x50,0x00,0x01,0x01,0x04,0x00,0x4D, \
51361 + 0x28,0x43,0x06,0x00,0x30,0x50,0x53,0x3C,0x00,0x00, \
51362 + 0x00,0x01,0x1B,0xFE,0x32,0xF1,0x32,0xC0,0x00,0x4F, \
51363 + 0x00,0x81,0x00,0x02,0x00,0x00,0x97,0x9E,0x43,0x49, \
51364 + 0x00,0x08,0x08,0x16,0x00,0x54,0x00,0x01,0x1B,0xFE, \
51365 + 0x00,0x00,0x9F,0x9E,0x43,0x7E,0x00,0x00,0x02,0x1F, \
51366 + 0x00,0x08,0x28,0x1B,0x30,0x73,0x29,0x1F,0x30,0xD0, \
51367 + 0x63,0x6A,0x00,0x07,0x00,0x05,0x00,0x00,0xC3,0x8F, \
51368 + 0x00,0x52,0x00,0x01,0x07,0x01,0x63,0x56,0x00,0x00, \
51369 + 0x30,0xD0,0x00,0xDA,0x00,0x01,0x00,0x00,0x00,0x00, \
51370 + 0x00,0x00,0x43,0x67,0x00,0x00,0x02,0x8F,0x00,0x00, \
51371 + 0x30,0xF2,0x00,0x06,0x1B,0x78,0x00,0x00,0x9F,0xFF, \
51372 + 0x30,0xF2,0x00,0x06,0x29,0x1E,0x07,0x08,0x30,0xD0, \
51373 + 0x00,0x52,0x00,0x08,0x28,0x1A,0x63,0x52,0x00,0x00, \
51374 + 0x30,0xF2,0x1B,0x78,0x06,0x00,0x29,0x1E,0x30,0xF2, \
51375 + 0x53,0x7E,0xFF,0xFF,0x1B,0x83,0x08,0x16,0x00,0x54, \
51376 + 0x00,0x01,0x1B,0xFE,0x1B,0x90,0x32,0xF1,0x28,0x5D, \
51377 + 0x32,0xF1,0x00,0x55,0x00,0x08,0x28,0x5F,0x00,0x00, \
51378 + 0x8F,0x9F,0x29,0x33,0x08,0x16,0x00,0x49,0x00,0x01, \
51379 + 0x1B,0xFF,0x00,0x01,0x1B,0xFF,0x08,0x07,0x00,0x02, \
51380 + 0x00,0x00,0x8D,0x80,0x53,0x9C,0x00,0x01,0x30,0x71, \
51381 + 0x00,0x55,0x00,0x01,0x28,0x0F,0x00,0x00,0x8D,0x00, \
51382 + 0x53,0xA4,0x00,0x01,0x30,0x71,0x00,0x55,0x00,0x01, \
51383 + 0x28,0x0F,0x00,0x00,0x83,0x8E,0x53,0xB9,0x00,0x00, \
51384 + 0x00,0x00,0x86,0x08,0x30,0x71,0x00,0x7B,0x03,0xB9, \
51385 + 0x33,0xB4,0x00,0xDA,0xFF,0xFF,0x00,0x0F,0x00,0x00, \
51386 + 0x00,0x00,0x00,0x00,0x86,0x09,0x01,0x03,0x00,0x7D, \
51387 + 0x03,0xB9,0x1B,0xC8,0x33,0xD1,0x00,0xF9,0x00,0x10, \
51388 + 0x00,0x00,0x00,0x00,0x00,0x00,0x28,0x7B,0x09,0x5F, \
51389 + 0x00,0x1A,0x00,0x00,0x09,0x4F,0x00,0x1A,0x00,0x00, \
51390 + 0x00,0x01,0x1B,0xFF,0x00,0x00,0x8C,0x00,0x53,0xF0, \
51391 + 0x00,0x01,0x34,0xF5,0x00,0xFB,0xFF,0xFF,0x00,0x7F, \
51392 + 0x00,0x00,0x00,0x00,0x2A,0x9F,0x00,0x00,0x93,0x8F, \
51393 + 0x28,0x49,0x00,0x00,0x97,0x8F,0x28,0x4B,0x34,0x61, \
51394 + 0x28,0x4D,0x34,0x71,0x28,0x4F,0x34,0xB7,0x00,0xF9, \
51395 + 0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x2B,0x97, \
51396 + 0x33,0xF1,0x00,0xF9,0x00,0x01,0x00,0x00,0x00,0x00, \
51397 + 0x00,0x00,0x28,0x7F,0x00,0x03,0x00,0x02,0x00,0x00, \
51398 + 0x00,0x01,0x1B,0xFF,0x00,0x01,0x1B,0xFF, \
51399 +}
51400 +#endif /* (DPAA_VERSION == 10) */
51401 +
51402 +/****************************/
51403 +/* Parser defines */
51404 +/****************************/
51405 +#define FM_PCD_PRS_SW_TAIL_SIZE 4 /**< Number of bytes that must be cleared at
51406 + the end of the SW parser area */
51407 +
51408 +/* masks */
51409 +#define PRS_ERR_CAP 0x80000000
51410 +#define PRS_ERR_TYPE_DOUBLE 0x40000000
51411 +#define PRS_ERR_SINGLE_ECC_CNT_MASK 0x00FF0000
51412 +#define PRS_ERR_ADDR_MASK 0x000001FF
51413 +
51414 +/* others */
51415 +#define PRS_MAX_CYCLE_LIMIT 8191
51416 +#define PRS_SW_DATA 0x00000800
51417 +#define PRS_REGS_OFFSET 0x00000840
51418 +
51419 +#define GET_FM_PCD_PRS_PORT_ID(prsPortId,hardwarePortId) \
51420 + prsPortId = (uint8_t)(hardwarePortId & 0x0f)
51421 +
51422 +#define GET_FM_PCD_INDEX_FLAG(bitMask, prsPortId) \
51423 + bitMask = 0x80000000>>prsPortId
51424 +
51425 +#endif /* __FM_PRS_H */
51426 --- /dev/null
51427 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.c
51428 @@ -0,0 +1,984 @@
51429 +/*
51430 + * Copyright 2008-2012 Freescale Semiconductor Inc.
51431 + *
51432 + * Redistribution and use in source and binary forms, with or without
51433 + * modification, are permitted provided that the following conditions are met:
51434 + * * Redistributions of source code must retain the above copyright
51435 + * notice, this list of conditions and the following disclaimer.
51436 + * * Redistributions in binary form must reproduce the above copyright
51437 + * notice, this list of conditions and the following disclaimer in the
51438 + * documentation and/or other materials provided with the distribution.
51439 + * * Neither the name of Freescale Semiconductor nor the
51440 + * names of its contributors may be used to endorse or promote products
51441 + * derived from this software without specific prior written permission.
51442 + *
51443 + *
51444 + * ALTERNATIVELY, this software may be distributed under the terms of the
51445 + * GNU General Public License ("GPL") as published by the Free Software
51446 + * Foundation, either version 2 of that License or (at your option) any
51447 + * later version.
51448 + *
51449 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
51450 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
51451 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51452 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
51453 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51454 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51455 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
51456 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51457 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
51458 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51459 + */
51460 +
51461 +
51462 +/******************************************************************************
51463 + @File fm_replic.c
51464 +
51465 + @Description FM frame replicator
51466 +*//***************************************************************************/
51467 +#include "std_ext.h"
51468 +#include "error_ext.h"
51469 +#include "string_ext.h"
51470 +#include "debug_ext.h"
51471 +#include "fm_pcd_ext.h"
51472 +#include "fm_muram_ext.h"
51473 +#include "fm_common.h"
51474 +#include "fm_hc.h"
51475 +#include "fm_replic.h"
51476 +#include "fm_cc.h"
51477 +#include "list_ext.h"
51478 +
51479 +
51480 +/****************************************/
51481 +/* static functions */
51482 +/****************************************/
51483 +static uint8_t GetMemberPosition(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51484 + uint32_t memberIndex,
51485 + bool isAddOperation)
51486 +{
51487 + uint8_t memberPosition;
51488 + uint32_t lastMemberIndex;
51489 +
51490 + ASSERT_COND(p_ReplicGroup);
51491 +
51492 + /* the last member index is different between add and remove operation -
51493 + in case of remove - this is exactly the last member index
51494 + in case of add - this is the last member index + 1 - e.g.
51495 + if we have 4 members, the index of the actual last member is 3(because the
51496 + index starts from 0) therefore in order to add a new member as the last
51497 + member we shall use memberIndex = 4 and not 3
51498 + */
51499 + if (isAddOperation)
51500 + lastMemberIndex = p_ReplicGroup->numOfEntries;
51501 + else
51502 + lastMemberIndex = p_ReplicGroup->numOfEntries-1;
51503 +
51504 + /* last */
51505 + if (memberIndex == lastMemberIndex)
51506 + memberPosition = FRM_REPLIC_LAST_MEMBER_INDEX;
51507 + else
51508 + {
51509 + /* first */
51510 + if (memberIndex == 0)
51511 + memberPosition = FRM_REPLIC_FIRST_MEMBER_INDEX;
51512 + else
51513 + {
51514 + /* middle */
51515 + ASSERT_COND(memberIndex < lastMemberIndex);
51516 + memberPosition = FRM_REPLIC_MIDDLE_MEMBER_INDEX;
51517 + }
51518 + }
51519 + return memberPosition;
51520 +}
51521 +
51522 +static t_Error MemberCheckParams(t_Handle h_FmPcd,
51523 + t_FmPcdCcNextEngineParams *p_MemberParams)
51524 +{
51525 + t_Error err;
51526 +
51527 +
51528 + if ((p_MemberParams->nextEngine != e_FM_PCD_DONE) &&
51529 + (p_MemberParams->nextEngine != e_FM_PCD_KG) &&
51530 + (p_MemberParams->nextEngine != e_FM_PCD_PLCR))
51531 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Next engine of a member should be MatchTable(cc) or Done or Policer"));
51532 +
51533 + /* check the regular parameters of the next engine */
51534 + err = ValidateNextEngineParams(h_FmPcd, p_MemberParams, e_FM_PCD_CC_STATS_MODE_NONE);
51535 + if (err)
51536 + RETURN_ERROR(MAJOR, err, ("member next engine parameters"));
51537 +
51538 + return E_OK;
51539 +}
51540 +
51541 +static t_Error CheckParams(t_Handle h_FmPcd,
51542 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
51543 +{
51544 + int i;
51545 + t_Error err;
51546 +
51547 + /* check that max num of entries is at least 2 */
51548 + if (!IN_RANGE(2, p_ReplicGroupParam->maxNumOfEntries, FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES))
51549 + 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));
51550 +
51551 + /* check that number of entries is greater than zero */
51552 + if (!p_ReplicGroupParam->numOfEntries)
51553 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOFEntries in the frame replicator group should be greater than zero"));
51554 +
51555 + /* check that max num of entries is equal or greater than number of entries */
51556 + if (p_ReplicGroupParam->maxNumOfEntries < p_ReplicGroupParam->numOfEntries)
51557 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfEntries should be equal or greater than numOfEntries"));
51558 +
51559 + for (i=0; i<p_ReplicGroupParam->numOfEntries; i++)
51560 + {
51561 + err = MemberCheckParams(h_FmPcd, &p_ReplicGroupParam->nextEngineParams[i]);
51562 + if (err)
51563 + RETURN_ERROR(MAJOR, err, ("member check parameters"));
51564 + }
51565 + return E_OK;
51566 +}
51567 +
51568 +static t_FmPcdFrmReplicMember *GetAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
51569 +{
51570 + t_FmPcdFrmReplicMember *p_ReplicMember = NULL;
51571 + t_List *p_Next;
51572 +
51573 + if (!LIST_IsEmpty(&p_ReplicGroup->availableMembersList))
51574 + {
51575 + p_Next = LIST_FIRST(&p_ReplicGroup->availableMembersList);
51576 + p_ReplicMember = LIST_OBJECT(p_Next, t_FmPcdFrmReplicMember, node);
51577 + ASSERT_COND(p_ReplicMember);
51578 + LIST_DelAndInit(p_Next);
51579 + }
51580 + return p_ReplicMember;
51581 +}
51582 +
51583 +static void PutAvailableMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51584 + t_FmPcdFrmReplicMember *p_ReplicMember)
51585 +{
51586 + LIST_AddToTail(&p_ReplicMember->node, &p_ReplicGroup->availableMembersList);
51587 +}
51588 +
51589 +static void AddMemberToList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51590 + t_FmPcdFrmReplicMember *p_CurrentMember,
51591 + t_List *p_ListHead)
51592 +{
51593 + LIST_Add(&p_CurrentMember->node, p_ListHead);
51594 +
51595 + p_ReplicGroup->numOfEntries++;
51596 +}
51597 +
51598 +static void RemoveMemberFromList(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51599 + t_FmPcdFrmReplicMember *p_CurrentMember)
51600 +{
51601 + ASSERT_COND(p_ReplicGroup->numOfEntries);
51602 + LIST_DelAndInit(&p_CurrentMember->node);
51603 + p_ReplicGroup->numOfEntries--;
51604 +}
51605 +
51606 +static void LinkSourceToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51607 + t_AdOfTypeContLookup *p_SourceTd,
51608 + t_FmPcdFrmReplicMember *p_ReplicMember)
51609 +{
51610 + t_FmPcd *p_FmPcd;
51611 +
51612 + ASSERT_COND(p_SourceTd);
51613 + ASSERT_COND(p_ReplicMember);
51614 + ASSERT_COND(p_ReplicGroup);
51615 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
51616 +
51617 + /* Link the first member in the group to the source TD */
51618 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51619 +
51620 + WRITE_UINT32(p_SourceTd->matchTblPtr,
51621 + (uint32_t)(XX_VirtToPhys(p_ReplicMember->p_MemberAd) -
51622 + p_FmPcd->physicalMuramBase));
51623 +}
51624 +
51625 +static void LinkMemberToMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51626 + t_FmPcdFrmReplicMember *p_CurrentMember,
51627 + t_FmPcdFrmReplicMember *p_NextMember)
51628 +{
51629 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_CurrentMember->p_MemberAd;
51630 + t_AdOfTypeResult *p_NextReplicAd = NULL;
51631 + t_FmPcd *p_FmPcd;
51632 + uint32_t offset = 0;
51633 +
51634 + /* Check if the next member exists or it's NULL (- means that this is the last member) */
51635 + if (p_NextMember)
51636 + {
51637 + p_NextReplicAd = (t_AdOfTypeResult*)p_NextMember->p_MemberAd;
51638 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51639 + offset = (XX_VirtToPhys(p_NextReplicAd) - (p_FmPcd->physicalMuramBase));
51640 + offset = ((offset>>NEXT_FRM_REPLIC_ADDR_SHIFT)<< NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT);
51641 + }
51642 +
51643 + /* link the current AD to point to the AD of the next member */
51644 + WRITE_UINT32(p_CurrReplicAd->res, offset);
51645 +}
51646 +
51647 +static t_Error ModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51648 + void *p_OldDescriptor,
51649 + void *p_NewDescriptor)
51650 +{
51651 + t_Handle h_Hc;
51652 + t_Error err;
51653 + t_FmPcd *p_FmPcd;
51654 +
51655 + ASSERT_COND(p_ReplicGroup);
51656 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
51657 + ASSERT_COND(p_OldDescriptor);
51658 + ASSERT_COND(p_NewDescriptor);
51659 +
51660 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51661 + h_Hc = FmPcdGetHcHandle(p_FmPcd);
51662 + if (!h_Hc)
51663 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("Host command"));
51664 +
51665 + err = FmHcPcdCcDoDynamicChange(h_Hc,
51666 + (uint32_t)(XX_VirtToPhys(p_OldDescriptor) - p_FmPcd->physicalMuramBase),
51667 + (uint32_t)(XX_VirtToPhys(p_NewDescriptor) - p_FmPcd->physicalMuramBase));
51668 + if (err)
51669 + RETURN_ERROR(MAJOR, err, ("Dynamic change host command"));
51670 +
51671 + return E_OK;
51672 +}
51673 +
51674 +static void FillReplicAdOfTypeResult(void *p_ReplicAd, bool last)
51675 +{
51676 + t_AdOfTypeResult *p_CurrReplicAd = (t_AdOfTypeResult*)p_ReplicAd;
51677 + uint32_t tmp;
51678 +
51679 + tmp = GET_UINT32(p_CurrReplicAd->plcrProfile);
51680 + if (last)
51681 + /* clear the NL bit in case it's the last member in the group*/
51682 + WRITE_UINT32(p_CurrReplicAd->plcrProfile,(tmp & ~FRM_REPLIC_NL_BIT));
51683 + else
51684 + /* set the NL bit in case it's not the last member in the group */
51685 + WRITE_UINT32(p_CurrReplicAd->plcrProfile, (tmp |FRM_REPLIC_NL_BIT));
51686 +
51687 + /* set FR bit in the action descriptor */
51688 + tmp = GET_UINT32(p_CurrReplicAd->nia);
51689 + WRITE_UINT32(p_CurrReplicAd->nia,
51690 + (tmp | FRM_REPLIC_FR_BIT | FM_PCD_AD_RESULT_EXTENDED_MODE ));
51691 +}
51692 +
51693 +static void BuildSourceTd(void *p_Ad)
51694 +{
51695 + t_AdOfTypeContLookup *p_SourceTd;
51696 +
51697 + ASSERT_COND(p_Ad);
51698 +
51699 + p_SourceTd = (t_AdOfTypeContLookup *)p_Ad;
51700 +
51701 + IOMemSet32((uint8_t*)p_SourceTd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
51702 +
51703 + /* initialize the source table descriptor */
51704 + WRITE_UINT32(p_SourceTd->ccAdBase, FM_PCD_AD_CONT_LOOKUP_TYPE);
51705 + WRITE_UINT32(p_SourceTd->pcAndOffsets, FRM_REPLIC_SOURCE_TD_OPCODE);
51706 +}
51707 +
51708 +static t_Error BuildShadowAndModifyDescriptor(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51709 + t_FmPcdFrmReplicMember *p_NextMember,
51710 + t_FmPcdFrmReplicMember *p_CurrentMember,
51711 + bool sourceDescriptor,
51712 + bool last)
51713 +{
51714 + t_FmPcd *p_FmPcd;
51715 + t_FmPcdFrmReplicMember shadowMember;
51716 + t_Error err;
51717 +
51718 + ASSERT_COND(p_ReplicGroup);
51719 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
51720 +
51721 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51722 + ASSERT_COND(p_FmPcd->p_CcShadow);
51723 +
51724 + if (!TRY_LOCK(p_FmPcd->h_ShadowSpinlock, &p_FmPcd->shadowLock))
51725 + return ERROR_CODE(E_BUSY);
51726 +
51727 + if (sourceDescriptor)
51728 + {
51729 + BuildSourceTd(p_FmPcd->p_CcShadow);
51730 + LinkSourceToMember(p_ReplicGroup, p_FmPcd->p_CcShadow, p_NextMember);
51731 +
51732 + /* Modify the source table descriptor according to the prepared shadow descriptor */
51733 + err = ModifyDescriptor(p_ReplicGroup,
51734 + p_ReplicGroup->p_SourceTd,
51735 + p_FmPcd->p_CcShadow/* new prepared source td */);
51736 +
51737 + RELEASE_LOCK(p_FmPcd->shadowLock);
51738 + if (err)
51739 + RETURN_ERROR(MAJOR, err, ("Modify source Descriptor in BuildShadowAndModifyDescriptor"));
51740 +
51741 + }
51742 + else
51743 + {
51744 + IO2IOCpy32(p_FmPcd->p_CcShadow,
51745 + p_CurrentMember->p_MemberAd,
51746 + FM_PCD_CC_AD_ENTRY_SIZE);
51747 +
51748 + /* update the last bit in the shadow ad */
51749 + FillReplicAdOfTypeResult(p_FmPcd->p_CcShadow, last);
51750 +
51751 + shadowMember.p_MemberAd = p_FmPcd->p_CcShadow;
51752 +
51753 + /* update the next FR member index */
51754 + LinkMemberToMember(p_ReplicGroup, &shadowMember, p_NextMember);
51755 +
51756 + /* Modify the next member according to the prepared shadow descriptor */
51757 + err = ModifyDescriptor(p_ReplicGroup,
51758 + p_CurrentMember->p_MemberAd,
51759 + p_FmPcd->p_CcShadow);
51760 +
51761 + RELEASE_LOCK(p_FmPcd->shadowLock);
51762 + if (err)
51763 + RETURN_ERROR(MAJOR, err, ("Modify Descriptor in BuildShadowAndModifyDescriptor"));
51764 + }
51765 +
51766 +
51767 + return E_OK;
51768 +}
51769 +
51770 +static t_FmPcdFrmReplicMember* GetMemberByIndex(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51771 + uint16_t memberIndex)
51772 +{
51773 + int i=0;
51774 + t_List *p_Pos;
51775 + t_FmPcdFrmReplicMember *p_Member = NULL;
51776 +
51777 + LIST_FOR_EACH(p_Pos, &p_ReplicGroup->membersList)
51778 + {
51779 + if (i == memberIndex)
51780 + {
51781 + p_Member = LIST_OBJECT(p_Pos, t_FmPcdFrmReplicMember, node);
51782 + return p_Member;
51783 + }
51784 + i++;
51785 + }
51786 + return p_Member;
51787 +}
51788 +
51789 +static t_Error AllocMember(t_FmPcdFrmReplicGroup *p_ReplicGroup)
51790 +{
51791 + t_FmPcdFrmReplicMember *p_CurrentMember;
51792 + t_Handle h_Muram;
51793 +
51794 + ASSERT_COND(p_ReplicGroup);
51795 +
51796 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
51797 + ASSERT_COND(h_Muram);
51798 +
51799 + /* Initialize an internal structure of a member to add to the available members list */
51800 + p_CurrentMember = (t_FmPcdFrmReplicMember *)XX_Malloc(sizeof(t_FmPcdFrmReplicMember));
51801 + if (!p_CurrentMember)
51802 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Frame replicator member"));
51803 +
51804 + memset(p_CurrentMember, 0 ,sizeof(t_FmPcdFrmReplicMember));
51805 +
51806 + /* Allocate the member AD */
51807 + p_CurrentMember->p_MemberAd =
51808 + (t_AdOfTypeResult*)FM_MURAM_AllocMem(h_Muram,
51809 + FM_PCD_CC_AD_ENTRY_SIZE,
51810 + FM_PCD_CC_AD_TABLE_ALIGN);
51811 + if (!p_CurrentMember->p_MemberAd)
51812 + {
51813 + XX_Free(p_CurrentMember);
51814 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("member AD table"));
51815 + }
51816 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
51817 +
51818 + /* Add the new member to the available members list */
51819 + LIST_AddToTail(&p_CurrentMember->node, &(p_ReplicGroup->availableMembersList));
51820 +
51821 + return E_OK;
51822 +}
51823 +
51824 +static t_FmPcdFrmReplicMember* InitMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51825 + t_FmPcdCcNextEngineParams *p_MemberParams,
51826 + bool last)
51827 +{
51828 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL;
51829 +
51830 + ASSERT_COND(p_ReplicGroup);
51831 +
51832 + /* Get an available member from the internal members list */
51833 + p_CurrentMember = GetAvailableMember(p_ReplicGroup);
51834 + if (!p_CurrentMember)
51835 + {
51836 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("Available member"));
51837 + return NULL;
51838 + }
51839 + p_CurrentMember->h_Manip = NULL;
51840 +
51841 + /* clear the Ad of the new member */
51842 + IOMemSet32((uint8_t*)p_CurrentMember->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
51843 +
51844 + INIT_LIST(&p_CurrentMember->node);
51845 +
51846 + /* Initialize the Ad of the member */
51847 + NextStepAd(p_CurrentMember->p_MemberAd,
51848 + NULL,
51849 + p_MemberParams,
51850 + p_ReplicGroup->h_FmPcd);
51851 +
51852 + /* save Manip handle (for free needs) */
51853 + if (p_MemberParams->h_Manip)
51854 + p_CurrentMember->h_Manip = p_MemberParams->h_Manip;
51855 +
51856 + /* Initialize the relevant frame replicator fields in the AD */
51857 + FillReplicAdOfTypeResult(p_CurrentMember->p_MemberAd, last);
51858 +
51859 + return p_CurrentMember;
51860 +}
51861 +
51862 +static void FreeMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51863 + t_FmPcdFrmReplicMember *p_Member)
51864 +{
51865 + /* Note: Can't free the member AD just returns the member to the available
51866 + member list - therefore only memset the AD */
51867 +
51868 + /* zero the AD */
51869 + IOMemSet32(p_Member->p_MemberAd, 0, FM_PCD_CC_AD_ENTRY_SIZE);
51870 +
51871 +
51872 + /* return the member to the available members list */
51873 + PutAvailableMember(p_ReplicGroup, p_Member);
51874 +}
51875 +
51876 +static t_Error RemoveMember(t_FmPcdFrmReplicGroup *p_ReplicGroup,
51877 + uint16_t memberIndex)
51878 +{
51879 + t_FmPcd *p_FmPcd = NULL;
51880 + t_FmPcdFrmReplicMember *p_CurrentMember = NULL, *p_PreviousMember = NULL, *p_NextMember = NULL;
51881 + t_Error err;
51882 + uint8_t memberPosition;
51883 +
51884 + p_FmPcd = p_ReplicGroup->h_FmPcd;
51885 + ASSERT_COND(p_FmPcd);
51886 + UNUSED(p_FmPcd);
51887 +
51888 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
51889 + ASSERT_COND(p_CurrentMember);
51890 +
51891 + /* determine the member position in the group */
51892 + memberPosition = GetMemberPosition(p_ReplicGroup,
51893 + memberIndex,
51894 + FALSE/*remove operation*/);
51895 +
51896 + switch (memberPosition)
51897 + {
51898 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
51899 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
51900 + ASSERT_COND(p_NextMember);
51901 +
51902 + /* update the source td itself by using a host command */
51903 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
51904 + p_NextMember,
51905 + NULL,
51906 + TRUE/*sourceDescriptor*/,
51907 + FALSE/*last*/);
51908 + break;
51909 +
51910 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
51911 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
51912 + ASSERT_COND(p_PreviousMember);
51913 +
51914 + p_NextMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex+1));
51915 + ASSERT_COND(p_NextMember);
51916 +
51917 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
51918 + p_NextMember,
51919 + p_PreviousMember,
51920 + FALSE/*sourceDescriptor*/,
51921 + FALSE/*last*/);
51922 +
51923 + break;
51924 +
51925 + case FRM_REPLIC_LAST_MEMBER_INDEX:
51926 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
51927 + ASSERT_COND(p_PreviousMember);
51928 +
51929 + err = BuildShadowAndModifyDescriptor(p_ReplicGroup,
51930 + NULL,
51931 + p_PreviousMember,
51932 + FALSE/*sourceDescriptor*/,
51933 + TRUE/*last*/);
51934 + break;
51935 +
51936 + default:
51937 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in remove member"));
51938 + }
51939 +
51940 + if (err)
51941 + RETURN_ERROR(MAJOR, err, NO_MSG);
51942 +
51943 + if (p_CurrentMember->h_Manip)
51944 + {
51945 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
51946 + p_CurrentMember->h_Manip = NULL;
51947 + }
51948 +
51949 + /* remove the member from the driver internal members list */
51950 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
51951 +
51952 + /* return the member to the available members list */
51953 + FreeMember(p_ReplicGroup, p_CurrentMember);
51954 +
51955 + return E_OK;
51956 +}
51957 +
51958 +static void DeleteGroup(t_FmPcdFrmReplicGroup *p_ReplicGroup)
51959 +{
51960 + int i, j;
51961 + t_Handle h_Muram;
51962 + t_FmPcdFrmReplicMember *p_Member, *p_CurrentMember;
51963 +
51964 + if (p_ReplicGroup)
51965 + {
51966 + ASSERT_COND(p_ReplicGroup->h_FmPcd);
51967 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
51968 + ASSERT_COND(h_Muram);
51969 +
51970 + /* free the source table descriptor */
51971 + if (p_ReplicGroup->p_SourceTd)
51972 + {
51973 + FM_MURAM_FreeMem(h_Muram, p_ReplicGroup->p_SourceTd);
51974 + p_ReplicGroup->p_SourceTd = NULL;
51975 + }
51976 +
51977 + /* Remove all members from the members linked list (hw and sw) and
51978 + return the members to the available members list */
51979 + if (p_ReplicGroup->numOfEntries)
51980 + {
51981 + j = p_ReplicGroup->numOfEntries-1;
51982 +
51983 + /* manually removal of the member because there are no owners of
51984 + this group */
51985 + for (i=j; i>=0; i--)
51986 + {
51987 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)i/*memberIndex*/);
51988 + ASSERT_COND(p_CurrentMember);
51989 +
51990 + if (p_CurrentMember->h_Manip)
51991 + {
51992 + FmPcdManipUpdateOwner(p_CurrentMember->h_Manip, FALSE);
51993 + p_CurrentMember->h_Manip = NULL;
51994 + }
51995 +
51996 + /* remove the member from the internal driver members list */
51997 + RemoveMemberFromList(p_ReplicGroup, p_CurrentMember);
51998 +
51999 + /* return the member to the available members list */
52000 + FreeMember(p_ReplicGroup, p_CurrentMember);
52001 + }
52002 + }
52003 +
52004 + /* Free members AD */
52005 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
52006 + {
52007 + p_Member = GetAvailableMember(p_ReplicGroup);
52008 + ASSERT_COND(p_Member);
52009 + if (p_Member->p_MemberAd)
52010 + {
52011 + FM_MURAM_FreeMem(h_Muram, p_Member->p_MemberAd);
52012 + p_Member->p_MemberAd = NULL;
52013 + }
52014 + XX_Free(p_Member);
52015 + }
52016 +
52017 + /* release the group lock */
52018 + if (p_ReplicGroup->p_Lock)
52019 + FmPcdReleaseLock(p_ReplicGroup->h_FmPcd, p_ReplicGroup->p_Lock);
52020 +
52021 + /* free the replicator group */
52022 + XX_Free(p_ReplicGroup);
52023 + }
52024 +}
52025 +
52026 +
52027 +/*****************************************************************************/
52028 +/* Inter-module API routines */
52029 +/*****************************************************************************/
52030 +
52031 +/* NOTE: the inter-module routines are locked by cc in case of using them */
52032 +void * FrmReplicGroupGetSourceTableDescriptor(t_Handle h_ReplicGroup)
52033 +{
52034 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
52035 + ASSERT_COND(p_ReplicGroup);
52036 +
52037 + return (p_ReplicGroup->p_SourceTd);
52038 +}
52039 +
52040 +void FrmReplicGroupUpdateAd(t_Handle h_ReplicGroup,
52041 + void *p_Ad,
52042 + t_Handle *h_AdNew)
52043 +{
52044 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
52045 + t_AdOfTypeResult *p_AdResult = (t_AdOfTypeResult*)p_Ad;
52046 + t_FmPcd *p_FmPcd;
52047 +
52048 + ASSERT_COND(p_ReplicGroup);
52049 + p_FmPcd = p_ReplicGroup->h_FmPcd;
52050 +
52051 + /* build a bypass ad */
52052 + WRITE_UINT32(p_AdResult->fqid, FM_PCD_AD_BYPASS_TYPE |
52053 + (uint32_t)((XX_VirtToPhys(p_ReplicGroup->p_SourceTd)) - p_FmPcd->physicalMuramBase));
52054 +
52055 + *h_AdNew = NULL;
52056 +}
52057 +
52058 +void FrmReplicGroupUpdateOwner(t_Handle h_ReplicGroup,
52059 + bool add)
52060 +{
52061 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
52062 + ASSERT_COND(p_ReplicGroup);
52063 +
52064 + /* update the group owner counter */
52065 + if (add)
52066 + p_ReplicGroup->owners++;
52067 + else
52068 + {
52069 + ASSERT_COND(p_ReplicGroup->owners);
52070 + p_ReplicGroup->owners--;
52071 + }
52072 +}
52073 +
52074 +t_Error FrmReplicGroupTryLock(t_Handle h_ReplicGroup)
52075 +{
52076 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
52077 +
52078 + ASSERT_COND(h_ReplicGroup);
52079 +
52080 + if (FmPcdLockTryLock(p_ReplicGroup->p_Lock))
52081 + return E_OK;
52082 +
52083 + return ERROR_CODE(E_BUSY);
52084 +}
52085 +
52086 +void FrmReplicGroupUnlock(t_Handle h_ReplicGroup)
52087 +{
52088 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
52089 +
52090 + ASSERT_COND(h_ReplicGroup);
52091 +
52092 + FmPcdLockUnlock(p_ReplicGroup->p_Lock);
52093 +}
52094 +/*********************** End of inter-module routines ************************/
52095 +
52096 +
52097 +/****************************************/
52098 +/* API Init unit functions */
52099 +/****************************************/
52100 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd,
52101 + t_FmPcdFrmReplicGroupParams *p_ReplicGroupParam)
52102 +{
52103 + t_FmPcdFrmReplicGroup *p_ReplicGroup;
52104 + t_FmPcdFrmReplicMember *p_CurrentMember, *p_NextMember = NULL;
52105 + int i;
52106 + t_Error err;
52107 + bool last = FALSE;
52108 + t_Handle h_Muram;
52109 +
52110 + SANITY_CHECK_RETURN_VALUE(h_FmPcd, E_INVALID_HANDLE, NULL);
52111 + SANITY_CHECK_RETURN_VALUE(p_ReplicGroupParam, E_INVALID_HANDLE, NULL);
52112 +
52113 + if (!FmPcdIsAdvancedOffloadSupported(h_FmPcd))
52114 + {
52115 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Advanced-offload must be enabled"));
52116 + return NULL;
52117 + }
52118 +
52119 + err = CheckParams(h_FmPcd, p_ReplicGroupParam);
52120 + if (err)
52121 + {
52122 + REPORT_ERROR(MAJOR, err, (NO_MSG));
52123 + return NULL;
52124 + }
52125 +
52126 + p_ReplicGroup = (t_FmPcdFrmReplicGroup*)XX_Malloc(sizeof(t_FmPcdFrmReplicGroup));
52127 + if (!p_ReplicGroup)
52128 + {
52129 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("No memory"));
52130 + return NULL;
52131 + }
52132 + memset(p_ReplicGroup, 0, sizeof(t_FmPcdFrmReplicGroup));
52133 +
52134 + /* initialize lists for internal driver use */
52135 + INIT_LIST(&p_ReplicGroup->availableMembersList);
52136 + INIT_LIST(&p_ReplicGroup->membersList);
52137 +
52138 + p_ReplicGroup->h_FmPcd = h_FmPcd;
52139 +
52140 + h_Muram = FmPcdGetMuramHandle(p_ReplicGroup->h_FmPcd);
52141 + ASSERT_COND(h_Muram);
52142 +
52143 + /* initialize the group lock */
52144 + p_ReplicGroup->p_Lock = FmPcdAcquireLock(p_ReplicGroup->h_FmPcd);
52145 + if (!p_ReplicGroup->p_Lock)
52146 + {
52147 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Replic group lock"));
52148 + DeleteGroup(p_ReplicGroup);
52149 + return NULL;
52150 + }
52151 +
52152 + /* Allocate the frame replicator source table descriptor */
52153 + p_ReplicGroup->p_SourceTd =
52154 + (t_Handle)FM_MURAM_AllocMem(h_Muram,
52155 + FM_PCD_CC_AD_ENTRY_SIZE,
52156 + FM_PCD_CC_AD_TABLE_ALIGN);
52157 + if (!p_ReplicGroup->p_SourceTd)
52158 + {
52159 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("frame replicator source table descriptor"));
52160 + DeleteGroup(p_ReplicGroup);
52161 + return NULL;
52162 + }
52163 +
52164 + /* update the shadow size - required for the host commands */
52165 + err = FmPcdUpdateCcShadow(p_ReplicGroup->h_FmPcd,
52166 + FM_PCD_CC_AD_ENTRY_SIZE,
52167 + FM_PCD_CC_AD_TABLE_ALIGN);
52168 + if (err)
52169 + {
52170 + REPORT_ERROR(MAJOR, err, ("Update CC shadow"));
52171 + DeleteGroup(p_ReplicGroup);
52172 + return NULL;
52173 + }
52174 +
52175 + p_ReplicGroup->maxNumOfEntries = p_ReplicGroupParam->maxNumOfEntries;
52176 +
52177 + /* Allocate the maximal number of members ADs and Statistics AD for the group
52178 + It prevents allocation of Muram in run-time */
52179 + for (i=0; i<p_ReplicGroup->maxNumOfEntries; i++)
52180 + {
52181 + err = AllocMember(p_ReplicGroup);
52182 + if (err)
52183 + {
52184 + REPORT_ERROR(MAJOR, err, ("allocate a new member"));
52185 + DeleteGroup(p_ReplicGroup);
52186 + return NULL;
52187 + }
52188 + }
52189 +
52190 + /* Initialize the members linked lists:
52191 + (hw - the one that is used by the FMan controller and
52192 + sw - the one that is managed by the driver internally) */
52193 + for (i=(p_ReplicGroupParam->numOfEntries-1); i>=0; i--)
52194 + {
52195 + /* check if this is the last member in the group */
52196 + if (i == (p_ReplicGroupParam->numOfEntries-1))
52197 + last = TRUE;
52198 + else
52199 + last = FALSE;
52200 +
52201 + /* Initialize a new member */
52202 + p_CurrentMember = InitMember(p_ReplicGroup,
52203 + &(p_ReplicGroupParam->nextEngineParams[i]),
52204 + last);
52205 + if (!p_CurrentMember)
52206 + {
52207 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
52208 + DeleteGroup(p_ReplicGroup);
52209 + return NULL;
52210 + }
52211 +
52212 + /* Build the members group - link two consecutive members in the hw linked list */
52213 + LinkMemberToMember(p_ReplicGroup, p_CurrentMember, p_NextMember);
52214 +
52215 + /* update the driver internal members list to be compatible to the hw members linked list */
52216 + AddMemberToList(p_ReplicGroup, p_CurrentMember, &p_ReplicGroup->membersList);
52217 +
52218 + p_NextMember = p_CurrentMember;
52219 + }
52220 +
52221 + /* initialize the source table descriptor */
52222 + BuildSourceTd(p_ReplicGroup->p_SourceTd);
52223 +
52224 + /* link the source table descriptor to point to the first member in the group */
52225 + LinkSourceToMember(p_ReplicGroup, p_ReplicGroup->p_SourceTd, p_NextMember);
52226 +
52227 + return p_ReplicGroup;
52228 +}
52229 +
52230 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_ReplicGroup)
52231 +{
52232 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup *)h_ReplicGroup;
52233 +
52234 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
52235 +
52236 + if (p_ReplicGroup->owners)
52237 + RETURN_ERROR(MAJOR,
52238 + E_INVALID_STATE,
52239 + ("the group has owners and can't be deleted"));
52240 +
52241 + DeleteGroup(p_ReplicGroup);
52242 +
52243 + return E_OK;
52244 +}
52245 +
52246 +
52247 +/*****************************************************************************/
52248 +/* API Run-time Frame replicator Control unit functions */
52249 +/*****************************************************************************/
52250 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_ReplicGroup,
52251 + uint16_t memberIndex,
52252 + t_FmPcdCcNextEngineParams *p_MemberParams)
52253 +{
52254 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
52255 + t_FmPcdFrmReplicMember *p_NewMember, *p_CurrentMember = NULL, *p_PreviousMember = NULL;
52256 + t_Error err;
52257 + uint8_t memberPosition;
52258 +
52259 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
52260 + SANITY_CHECK_RETURN_ERROR(p_MemberParams, E_INVALID_HANDLE);
52261 +
52262 + /* group lock */
52263 + err = FrmReplicGroupTryLock(p_ReplicGroup);
52264 + if (GET_ERROR_TYPE(err) == E_BUSY)
52265 + return ERROR_CODE(E_BUSY);
52266 +
52267 + if (memberIndex > p_ReplicGroup->numOfEntries)
52268 + {
52269 + /* unlock */
52270 + FrmReplicGroupUnlock(p_ReplicGroup);
52271 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
52272 + ("memberIndex is greater than the members in the list"));
52273 + }
52274 +
52275 + if (memberIndex >= p_ReplicGroup->maxNumOfEntries)
52276 + {
52277 + /* unlock */
52278 + FrmReplicGroupUnlock(p_ReplicGroup);
52279 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("memberIndex is greater than the allowed number of members in the group"));
52280 + }
52281 +
52282 + if ((p_ReplicGroup->numOfEntries + 1) > FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
52283 + {
52284 + /* unlock */
52285 + FrmReplicGroupUnlock(p_ReplicGroup);
52286 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
52287 + ("numOfEntries with new entry can not be larger than %d\n",
52288 + FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES));
52289 + }
52290 +
52291 + err = MemberCheckParams(p_ReplicGroup->h_FmPcd, p_MemberParams);
52292 + if (err)
52293 + {
52294 + /* unlock */
52295 + FrmReplicGroupUnlock(p_ReplicGroup);
52296 + RETURN_ERROR(MAJOR, err, ("member check parameters in add operation"));
52297 + }
52298 + /* determine the member position in the group */
52299 + memberPosition = GetMemberPosition(p_ReplicGroup,
52300 + memberIndex,
52301 + TRUE/* add operation */);
52302 +
52303 + /* Initialize a new member */
52304 + p_NewMember = InitMember(p_ReplicGroup,
52305 + p_MemberParams,
52306 + (memberPosition == FRM_REPLIC_LAST_MEMBER_INDEX ? TRUE : FALSE));
52307 + if (!p_NewMember)
52308 + {
52309 + /* unlock */
52310 + FrmReplicGroupUnlock(p_ReplicGroup);
52311 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("No available member"));
52312 + }
52313 +
52314 + switch (memberPosition)
52315 + {
52316 + case FRM_REPLIC_FIRST_MEMBER_INDEX:
52317 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
52318 + ASSERT_COND(p_CurrentMember);
52319 +
52320 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
52321 +
52322 + /* update the internal group source TD */
52323 + LinkSourceToMember(p_ReplicGroup,
52324 + p_ReplicGroup->p_SourceTd,
52325 + p_NewMember);
52326 +
52327 + /* add member to the internal sw member list */
52328 + AddMemberToList(p_ReplicGroup,
52329 + p_NewMember,
52330 + &p_ReplicGroup->membersList);
52331 + break;
52332 +
52333 + case FRM_REPLIC_MIDDLE_MEMBER_INDEX:
52334 + p_CurrentMember = GetMemberByIndex(p_ReplicGroup, memberIndex);
52335 + ASSERT_COND(p_CurrentMember);
52336 +
52337 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
52338 + ASSERT_COND(p_PreviousMember);
52339 +
52340 + LinkMemberToMember(p_ReplicGroup, p_NewMember, p_CurrentMember);
52341 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
52342 +
52343 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
52344 + break;
52345 +
52346 + case FRM_REPLIC_LAST_MEMBER_INDEX:
52347 + p_PreviousMember = GetMemberByIndex(p_ReplicGroup, (uint16_t)(memberIndex-1));
52348 + ASSERT_COND(p_PreviousMember);
52349 +
52350 + LinkMemberToMember(p_ReplicGroup, p_PreviousMember, p_NewMember);
52351 + FillReplicAdOfTypeResult(p_PreviousMember->p_MemberAd, FALSE/*last*/);
52352 +
52353 + /* add the new member to the internal sw member list */
52354 + AddMemberToList(p_ReplicGroup, p_NewMember, &p_PreviousMember->node);
52355 + break;
52356 +
52357 + default:
52358 + /* unlock */
52359 + FrmReplicGroupUnlock(p_ReplicGroup);
52360 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member position in add member"));
52361 +
52362 + }
52363 +
52364 + /* unlock */
52365 + FrmReplicGroupUnlock(p_ReplicGroup);
52366 +
52367 + return E_OK;
52368 +}
52369 +
52370 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_ReplicGroup,
52371 + uint16_t memberIndex)
52372 +{
52373 + t_FmPcdFrmReplicGroup *p_ReplicGroup = (t_FmPcdFrmReplicGroup*) h_ReplicGroup;
52374 + t_Error err;
52375 +
52376 + SANITY_CHECK_RETURN_ERROR(p_ReplicGroup, E_INVALID_HANDLE);
52377 +
52378 + /* lock */
52379 + err = FrmReplicGroupTryLock(p_ReplicGroup);
52380 + if (GET_ERROR_TYPE(err) == E_BUSY)
52381 + return ERROR_CODE(E_BUSY);
52382 +
52383 + if (memberIndex >= p_ReplicGroup->numOfEntries)
52384 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("member index to remove"));
52385 +
52386 + /* Design decision: group must contain at least one member
52387 + No possibility to remove the last member from the group */
52388 + if (p_ReplicGroup->numOfEntries == 1)
52389 + RETURN_ERROR(MAJOR, E_CONFLICT, ("Can't remove the last member. At least one member should be related to a group."));
52390 +
52391 + err = RemoveMember(p_ReplicGroup, memberIndex);
52392 +
52393 + /* unlock */
52394 + FrmReplicGroupUnlock(p_ReplicGroup);
52395 +
52396 + switch (GET_ERROR_TYPE(err))
52397 + {
52398 + case E_OK:
52399 + return E_OK;
52400 +
52401 + case E_BUSY:
52402 + DBG(TRACE, ("E_BUSY error"));
52403 + return ERROR_CODE(E_BUSY);
52404 +
52405 + default:
52406 + RETURN_ERROR(MAJOR, err, NO_MSG);
52407 + }
52408 +}
52409 +
52410 +/*********************** End of API routines ************************/
52411 +
52412 +
52413 --- /dev/null
52414 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fm_replic.h
52415 @@ -0,0 +1,101 @@
52416 +/*
52417 + * Copyright 2008-2012 Freescale Semiconductor Inc.
52418 + *
52419 + * Redistribution and use in source and binary forms, with or without
52420 + * modification, are permitted provided that the following conditions are met:
52421 + * * Redistributions of source code must retain the above copyright
52422 + * notice, this list of conditions and the following disclaimer.
52423 + * * Redistributions in binary form must reproduce the above copyright
52424 + * notice, this list of conditions and the following disclaimer in the
52425 + * documentation and/or other materials provided with the distribution.
52426 + * * Neither the name of Freescale Semiconductor nor the
52427 + * names of its contributors may be used to endorse or promote products
52428 + * derived from this software without specific prior written permission.
52429 + *
52430 + *
52431 + * ALTERNATIVELY, this software may be distributed under the terms of the
52432 + * GNU General Public License ("GPL") as published by the Free Software
52433 + * Foundation, either version 2 of that License or (at your option) any
52434 + * later version.
52435 + *
52436 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
52437 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52438 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52439 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
52440 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52441 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52442 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52443 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52444 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52445 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52446 + */
52447 +
52448 +
52449 +/******************************************************************************
52450 + @File fm_replic.h
52451 +
52452 + @Description FM frame replicator
52453 +*//***************************************************************************/
52454 +#ifndef __FM_REPLIC_H
52455 +#define __FM_REPLIC_H
52456 +
52457 +#include "std_ext.h"
52458 +#include "error_ext.h"
52459 +
52460 +
52461 +#define FRM_REPLIC_SOURCE_TD_OPCODE 0x75
52462 +#define NEXT_FRM_REPLIC_ADDR_SHIFT 4
52463 +#define NEXT_FRM_REPLIC_MEMBER_INDEX_SHIFT 16
52464 +#define FRM_REPLIC_FR_BIT 0x08000000
52465 +#define FRM_REPLIC_NL_BIT 0x10000000
52466 +#define FRM_REPLIC_INVALID_MEMBER_INDEX 0xffff
52467 +#define FRM_REPLIC_FIRST_MEMBER_INDEX 0
52468 +
52469 +#define FRM_REPLIC_MIDDLE_MEMBER_INDEX 1
52470 +#define FRM_REPLIC_LAST_MEMBER_INDEX 2
52471 +
52472 +#define SOURCE_TD_ITSELF_OPTION 0x01
52473 +#define SOURCE_TD_COPY_OPTION 0x02
52474 +#define SOURCE_TD_ITSELF_AND_COPY_OPTION SOURCE_TD_ITSELF_OPTION | SOURCE_TD_COPY_OPTION
52475 +#define SOURCE_TD_NONE 0x04
52476 +
52477 +/*typedef enum e_SourceTdOption
52478 +{
52479 + e_SOURCE_TD_NONE = 0,
52480 + e_SOURCE_TD_ITSELF_OPTION = 1,
52481 + e_SOURCE_TD_COPY_OPTION = 2,
52482 + e_SOURCE_TD_ITSELF_AND_COPY_OPTION = e_SOURCE_TD_ITSELF_OPTION | e_SOURCE_TD_COPY_OPTION
52483 +} e_SourceTdOption;
52484 +*/
52485 +
52486 +typedef struct
52487 +{
52488 + volatile uint32_t type;
52489 + volatile uint32_t frGroupPointer;
52490 + volatile uint32_t operationCode;
52491 + volatile uint32_t reserved;
52492 +} t_FrmReplicGroupSourceAd;
52493 +
52494 +typedef struct t_FmPcdFrmReplicMember
52495 +{
52496 + void *p_MemberAd; /**< pointer to the member AD */
52497 + void *p_StatisticsAd;/**< pointer to the statistics AD of the member */
52498 + t_Handle h_Manip; /**< manip handle - need for free routines */
52499 + t_List node;
52500 +} t_FmPcdFrmReplicMember;
52501 +
52502 +typedef struct t_FmPcdFrmReplicGroup
52503 +{
52504 + t_Handle h_FmPcd;
52505 +
52506 + uint8_t maxNumOfEntries;/**< maximal number of members in the group */
52507 + uint8_t numOfEntries; /**< actual number of members in the group */
52508 + uint16_t owners; /**< how many keys share this frame replicator group */
52509 + void *p_SourceTd; /**< pointer to the frame replicator source table descriptor */
52510 + t_List membersList; /**< the members list - should reflect the order of the members as in the hw linked list*/
52511 + t_List availableMembersList;/**< list of all the available members in the group */
52512 + t_FmPcdLock *p_Lock;
52513 +} t_FmPcdFrmReplicGroup;
52514 +
52515 +
52516 +#endif /* __FM_REPLIC_H */
52517 --- /dev/null
52518 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_kg.c
52519 @@ -0,0 +1,890 @@
52520 +/*
52521 + * Copyright 2008-2012 Freescale Semiconductor Inc.
52522 + *
52523 + * Redistribution and use in source and binary forms, with or without
52524 + * modification, are permitted provided that the following conditions are met:
52525 + * * Redistributions of source code must retain the above copyright
52526 + * notice, this list of conditions and the following disclaimer.
52527 + * * Redistributions in binary form must reproduce the above copyright
52528 + * notice, this list of conditions and the following disclaimer in the
52529 + * documentation and/or other materials provided with the distribution.
52530 + * * Neither the name of Freescale Semiconductor nor the
52531 + * names of its contributors may be used to endorse or promote products
52532 + * derived from this software without specific prior written permission.
52533 + *
52534 + *
52535 + * ALTERNATIVELY, this software may be distributed under the terms of the
52536 + * GNU General Public License ("GPL") as published by the Free Software
52537 + * Foundation, either version 2 of that License or (at your option) any
52538 + * later version.
52539 + *
52540 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
52541 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52542 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
52543 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
52544 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52545 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52546 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
52547 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52548 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
52549 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52550 + */
52551 +
52552 +#include "std_ext.h"
52553 +#include "error_ext.h"
52554 +#include "fsl_fman_kg.h"
52555 +
52556 +/****************************************/
52557 +/* static functions */
52558 +/****************************************/
52559 +
52560 +
52561 +static uint32_t build_ar_bind_scheme(uint8_t hwport_id, bool write)
52562 +{
52563 + uint32_t rw;
52564 +
52565 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
52566 +
52567 + return (uint32_t)(FM_KG_KGAR_GO |
52568 + rw |
52569 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
52570 + hwport_id |
52571 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP);
52572 +}
52573 +
52574 +static void clear_pe_all_scheme(struct fman_kg_regs *regs, uint8_t hwport_id)
52575 +{
52576 + uint32_t ar;
52577 +
52578 + fman_kg_write_sp(regs, 0xffffffff, 0);
52579 +
52580 + ar = build_ar_bind_scheme(hwport_id, TRUE);
52581 + fman_kg_write_ar_wait(regs, ar);
52582 +}
52583 +
52584 +static uint32_t build_ar_bind_cls_plan(uint8_t hwport_id, bool write)
52585 +{
52586 + uint32_t rw;
52587 +
52588 + rw = write ? (uint32_t)FM_KG_KGAR_WRITE : (uint32_t)FM_KG_KGAR_READ;
52589 +
52590 + return (uint32_t)(FM_KG_KGAR_GO |
52591 + rw |
52592 + FM_PCD_KG_KGAR_SEL_PORT_ENTRY |
52593 + hwport_id |
52594 + FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP);
52595 +}
52596 +
52597 +static void clear_pe_all_cls_plan(struct fman_kg_regs *regs, uint8_t hwport_id)
52598 +{
52599 + uint32_t ar;
52600 +
52601 + fman_kg_write_cpp(regs, 0);
52602 +
52603 + ar = build_ar_bind_cls_plan(hwport_id, TRUE);
52604 + fman_kg_write_ar_wait(regs, ar);
52605 +}
52606 +
52607 +static uint8_t get_gen_ht_code(enum fman_kg_gen_extract_src src,
52608 + bool no_validation,
52609 + uint8_t *offset)
52610 +{
52611 + int code;
52612 +
52613 + switch (src) {
52614 + case E_FMAN_KG_GEN_EXTRACT_ETH:
52615 + code = no_validation ? 0x73 : 0x3;
52616 + break;
52617 +
52618 + case E_FMAN_KG_GEN_EXTRACT_ETYPE:
52619 + code = no_validation ? 0x77 : 0x7;
52620 + break;
52621 +
52622 + case E_FMAN_KG_GEN_EXTRACT_SNAP:
52623 + code = no_validation ? 0x74 : 0x4;
52624 + break;
52625 +
52626 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1:
52627 + code = no_validation ? 0x75 : 0x5;
52628 + break;
52629 +
52630 + case E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N:
52631 + code = no_validation ? 0x76 : 0x6;
52632 + break;
52633 +
52634 + case E_FMAN_KG_GEN_EXTRACT_PPPoE:
52635 + code = no_validation ? 0x78 : 0x8;
52636 + break;
52637 +
52638 + case E_FMAN_KG_GEN_EXTRACT_MPLS_1:
52639 + code = no_validation ? 0x79 : 0x9;
52640 + break;
52641 +
52642 + case E_FMAN_KG_GEN_EXTRACT_MPLS_2:
52643 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x19;
52644 + break;
52645 +
52646 + case E_FMAN_KG_GEN_EXTRACT_MPLS_3:
52647 + code = no_validation ? FM_KG_SCH_GEN_HT_INVALID : 0x29;
52648 + break;
52649 +
52650 + case E_FMAN_KG_GEN_EXTRACT_MPLS_N:
52651 + code = no_validation ? 0x7a : 0xa;
52652 + break;
52653 +
52654 + case E_FMAN_KG_GEN_EXTRACT_IPv4_1:
52655 + code = no_validation ? 0x7b : 0xb;
52656 + break;
52657 +
52658 + case E_FMAN_KG_GEN_EXTRACT_IPv6_1:
52659 + code = no_validation ? 0x7b : 0x1b;
52660 + break;
52661 +
52662 + case E_FMAN_KG_GEN_EXTRACT_IPv4_2:
52663 + code = no_validation ? 0x7c : 0xc;
52664 + break;
52665 +
52666 + case E_FMAN_KG_GEN_EXTRACT_IPv6_2:
52667 + code = no_validation ? 0x7c : 0x1c;
52668 + break;
52669 +
52670 + case E_FMAN_KG_GEN_EXTRACT_MINENCAP:
52671 + code = no_validation ? 0x7c : 0x2c;
52672 + break;
52673 +
52674 + case E_FMAN_KG_GEN_EXTRACT_IP_PID:
52675 + code = no_validation ? 0x72 : 0x2;
52676 + break;
52677 +
52678 + case E_FMAN_KG_GEN_EXTRACT_GRE:
52679 + code = no_validation ? 0x7d : 0xd;
52680 + break;
52681 +
52682 + case E_FMAN_KG_GEN_EXTRACT_TCP:
52683 + code = no_validation ? 0x7e : 0xe;
52684 + break;
52685 +
52686 + case E_FMAN_KG_GEN_EXTRACT_UDP:
52687 + code = no_validation ? 0x7e : 0x1e;
52688 + break;
52689 +
52690 + case E_FMAN_KG_GEN_EXTRACT_SCTP:
52691 + code = no_validation ? 0x7e : 0x3e;
52692 + break;
52693 +
52694 + case E_FMAN_KG_GEN_EXTRACT_DCCP:
52695 + code = no_validation ? 0x7e : 0x4e;
52696 + break;
52697 +
52698 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_AH:
52699 + code = no_validation ? 0x7e : 0x2e;
52700 + break;
52701 +
52702 + case E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP:
52703 + code = no_validation ? 0x7e : 0x6e;
52704 + break;
52705 +
52706 + case E_FMAN_KG_GEN_EXTRACT_SHIM_1:
52707 + code = 0x70;
52708 + break;
52709 +
52710 + case E_FMAN_KG_GEN_EXTRACT_SHIM_2:
52711 + code = 0x71;
52712 + break;
52713 +
52714 + case E_FMAN_KG_GEN_EXTRACT_FROM_DFLT:
52715 + code = 0x10;
52716 + break;
52717 +
52718 + case E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START:
52719 + code = 0x40;
52720 + break;
52721 +
52722 + case E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT:
52723 + code = 0x20;
52724 + break;
52725 +
52726 + case E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE:
52727 + code = 0x7f;
52728 + break;
52729 +
52730 + case E_FMAN_KG_GEN_EXTRACT_FROM_FQID:
52731 + code = 0x20;
52732 + *offset += 0x20;
52733 + break;
52734 +
52735 + default:
52736 + code = FM_KG_SCH_GEN_HT_INVALID;
52737 + }
52738 +
52739 + return (uint8_t)code;
52740 +}
52741 +
52742 +static uint32_t build_ar_scheme(uint8_t scheme,
52743 + uint8_t hwport_id,
52744 + bool update_counter,
52745 + bool write)
52746 +{
52747 + uint32_t rw;
52748 +
52749 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
52750 +
52751 + return (uint32_t)(FM_KG_KGAR_GO |
52752 + rw |
52753 + FM_KG_KGAR_SEL_SCHEME_ENTRY |
52754 + hwport_id |
52755 + ((uint32_t)scheme << FM_KG_KGAR_NUM_SHIFT) |
52756 + (update_counter ? FM_KG_KGAR_SCM_WSEL_UPDATE_CNT : 0));
52757 +}
52758 +
52759 +static uint32_t build_ar_cls_plan(uint8_t grp,
52760 + uint8_t entries_mask,
52761 + uint8_t hwport_id,
52762 + bool write)
52763 +{
52764 + uint32_t rw;
52765 +
52766 + rw = (uint32_t)(write ? FM_KG_KGAR_WRITE : FM_KG_KGAR_READ);
52767 +
52768 + return (uint32_t)(FM_KG_KGAR_GO |
52769 + rw |
52770 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
52771 + hwport_id |
52772 + ((uint32_t)grp << FM_KG_KGAR_NUM_SHIFT) |
52773 + ((uint32_t)entries_mask << FM_KG_KGAR_WSEL_SHIFT));
52774 +}
52775 +
52776 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar)
52777 +{
52778 + iowrite32be(fmkg_ar, &regs->fmkg_ar);
52779 + /* Wait for GO to be idle and read error */
52780 + while ((fmkg_ar = ioread32be(&regs->fmkg_ar)) & FM_KG_KGAR_GO) ;
52781 + if (fmkg_ar & FM_PCD_KG_KGAR_ERR)
52782 + return -EINVAL;
52783 + return 0;
52784 +}
52785 +
52786 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add)
52787 +{
52788 +
52789 + struct fman_kg_pe_regs *kgpe_regs;
52790 + uint32_t tmp;
52791 +
52792 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
52793 + tmp = ioread32be(&kgpe_regs->fmkg_pe_sp);
52794 +
52795 + if (add)
52796 + tmp |= sp;
52797 + else /* clear */
52798 + tmp &= ~sp;
52799 +
52800 + iowrite32be(tmp, &kgpe_regs->fmkg_pe_sp);
52801 +
52802 +}
52803 +
52804 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp)
52805 +{
52806 + struct fman_kg_pe_regs *kgpe_regs;
52807 +
52808 + kgpe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
52809 +
52810 + iowrite32be(cpp, &kgpe_regs->fmkg_pe_cpp);
52811 +}
52812 +
52813 +void fman_kg_get_event(struct fman_kg_regs *regs,
52814 + uint32_t *event,
52815 + uint32_t *scheme_idx)
52816 +{
52817 + uint32_t mask, force;
52818 +
52819 + *event = ioread32be(&regs->fmkg_eer);
52820 + mask = ioread32be(&regs->fmkg_eeer);
52821 + *scheme_idx = ioread32be(&regs->fmkg_seer);
52822 + *scheme_idx &= ioread32be(&regs->fmkg_seeer);
52823 +
52824 + *event &= mask;
52825 +
52826 + /* clear the forced events */
52827 + force = ioread32be(&regs->fmkg_feer);
52828 + if (force & *event)
52829 + iowrite32be(force & ~*event ,&regs->fmkg_feer);
52830 +
52831 + iowrite32be(*event, &regs->fmkg_eer);
52832 + iowrite32be(*scheme_idx, &regs->fmkg_seer);
52833 +}
52834 +
52835 +
52836 +void fman_kg_init(struct fman_kg_regs *regs,
52837 + uint32_t exceptions,
52838 + uint32_t dflt_nia)
52839 +{
52840 + uint32_t tmp;
52841 + int i;
52842 +
52843 + iowrite32be(FM_EX_KG_DOUBLE_ECC | FM_EX_KG_KEYSIZE_OVERFLOW,
52844 + &regs->fmkg_eer);
52845 +
52846 + tmp = 0;
52847 + if (exceptions & FM_EX_KG_DOUBLE_ECC)
52848 + tmp |= FM_EX_KG_DOUBLE_ECC;
52849 +
52850 + if (exceptions & FM_EX_KG_KEYSIZE_OVERFLOW)
52851 + tmp |= FM_EX_KG_KEYSIZE_OVERFLOW;
52852 +
52853 + iowrite32be(tmp, &regs->fmkg_eeer);
52854 + iowrite32be(0, &regs->fmkg_fdor);
52855 + iowrite32be(0, &regs->fmkg_gdv0r);
52856 + iowrite32be(0, &regs->fmkg_gdv1r);
52857 + iowrite32be(dflt_nia, &regs->fmkg_gcr);
52858 +
52859 + /* Clear binding between ports to schemes and classification plans
52860 + * so that all ports are not bound to any scheme/classification plan */
52861 + for (i = 0; i < FMAN_MAX_NUM_OF_HW_PORTS; i++) {
52862 + clear_pe_all_scheme(regs, (uint8_t)i);
52863 + clear_pe_all_cls_plan(regs, (uint8_t)i);
52864 + }
52865 +}
52866 +
52867 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs)
52868 +{
52869 + /* enable and enable all scheme interrupts */
52870 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seer);
52871 + iowrite32be(0xFFFFFFFF, &regs->fmkg_seeer);
52872 +}
52873 +
52874 +void fman_kg_enable(struct fman_kg_regs *regs)
52875 +{
52876 + iowrite32be(ioread32be(&regs->fmkg_gcr) | FM_KG_KGGCR_EN,
52877 + &regs->fmkg_gcr);
52878 +}
52879 +
52880 +void fman_kg_disable(struct fman_kg_regs *regs)
52881 +{
52882 + iowrite32be(ioread32be(&regs->fmkg_gcr) & ~FM_KG_KGGCR_EN,
52883 + &regs->fmkg_gcr);
52884 +}
52885 +
52886 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset)
52887 +{
52888 + iowrite32be(offset, &regs->fmkg_fdor);
52889 +}
52890 +
52891 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
52892 + uint8_t def_id,
52893 + uint32_t val)
52894 +{
52895 + if(def_id == 0)
52896 + iowrite32be(val, &regs->fmkg_gdv0r);
52897 + else
52898 + iowrite32be(val, &regs->fmkg_gdv1r);
52899 +}
52900 +
52901 +
52902 +void fman_kg_set_exception(struct fman_kg_regs *regs,
52903 + uint32_t exception,
52904 + bool enable)
52905 +{
52906 + uint32_t tmp;
52907 +
52908 + tmp = ioread32be(&regs->fmkg_eeer);
52909 +
52910 + if (enable) {
52911 + tmp |= exception;
52912 + } else {
52913 + tmp &= ~exception;
52914 + }
52915 +
52916 + iowrite32be(tmp, &regs->fmkg_eeer);
52917 +}
52918 +
52919 +void fman_kg_get_exception(struct fman_kg_regs *regs,
52920 + uint32_t *events,
52921 + uint32_t *scheme_ids,
52922 + bool clear)
52923 +{
52924 + uint32_t mask;
52925 +
52926 + *events = ioread32be(&regs->fmkg_eer);
52927 + mask = ioread32be(&regs->fmkg_eeer);
52928 + *events &= mask;
52929 +
52930 + *scheme_ids = 0;
52931 +
52932 + if (*events & FM_EX_KG_KEYSIZE_OVERFLOW) {
52933 + *scheme_ids = ioread32be(&regs->fmkg_seer);
52934 + mask = ioread32be(&regs->fmkg_seeer);
52935 + *scheme_ids &= mask;
52936 + }
52937 +
52938 + if (clear) {
52939 + iowrite32be(*scheme_ids, &regs->fmkg_seer);
52940 + iowrite32be(*events, &regs->fmkg_eer);
52941 + }
52942 +}
52943 +
52944 +void fman_kg_get_capture(struct fman_kg_regs *regs,
52945 + struct fman_kg_ex_ecc_attr *ecc_attr,
52946 + bool clear)
52947 +{
52948 + uint32_t tmp;
52949 +
52950 + tmp = ioread32be(&regs->fmkg_serc);
52951 +
52952 + if (tmp & KG_FMKG_SERC_CAP) {
52953 + /* Captured data is valid */
52954 + ecc_attr->valid = TRUE;
52955 + ecc_attr->double_ecc =
52956 + (bool)((tmp & KG_FMKG_SERC_CET) ? TRUE : FALSE);
52957 + ecc_attr->single_ecc_count =
52958 + (uint8_t)((tmp & KG_FMKG_SERC_CNT_MSK) >>
52959 + KG_FMKG_SERC_CNT_SHIFT);
52960 + ecc_attr->addr = (uint16_t)(tmp & KG_FMKG_SERC_ADDR_MSK);
52961 +
52962 + if (clear)
52963 + iowrite32be(KG_FMKG_SERC_CAP, &regs->fmkg_serc);
52964 + } else {
52965 + /* No ECC error is captured */
52966 + ecc_attr->valid = FALSE;
52967 + }
52968 +}
52969 +
52970 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
52971 + struct fman_kg_scheme_regs *scheme_regs)
52972 +{
52973 + struct fman_kg_extract_params *extract_params;
52974 + struct fman_kg_gen_extract_params *gen_params;
52975 + uint32_t tmp_reg, i, select, mask, fqb;
52976 + uint8_t offset, shift, ht;
52977 +
52978 + /* Zero out all registers so no need to care about unused ones */
52979 + memset(scheme_regs, 0, sizeof(struct fman_kg_scheme_regs));
52980 +
52981 + /* Mode register */
52982 + tmp_reg = fm_kg_build_nia(params->next_engine,
52983 + params->next_engine_action);
52984 + if (tmp_reg == KG_NIA_INVALID) {
52985 + return -EINVAL;
52986 + }
52987 +
52988 + if (params->next_engine == E_FMAN_PCD_PLCR) {
52989 + tmp_reg |= FMAN_KG_SCH_MODE_NIA_PLCR;
52990 + }
52991 + else if (params->next_engine == E_FMAN_PCD_CC) {
52992 + tmp_reg |= (uint32_t)params->cc_params.base_offset <<
52993 + FMAN_KG_SCH_MODE_CCOBASE_SHIFT;
52994 + }
52995 +
52996 + tmp_reg |= FMAN_KG_SCH_MODE_EN;
52997 + scheme_regs->kgse_mode = tmp_reg;
52998 +
52999 + /* Match vector */
53000 + scheme_regs->kgse_mv = params->match_vector;
53001 +
53002 + extract_params = &params->extract_params;
53003 +
53004 + /* Scheme default values registers */
53005 + scheme_regs->kgse_dv0 = extract_params->def_scheme_0;
53006 + scheme_regs->kgse_dv1 = extract_params->def_scheme_1;
53007 +
53008 + /* Extract Known Fields Command register */
53009 + scheme_regs->kgse_ekfc = extract_params->known_fields;
53010 +
53011 + /* Entry Extract Known Default Value register */
53012 + tmp_reg = 0;
53013 + tmp_reg |= extract_params->known_fields_def.mac_addr <<
53014 + FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT;
53015 + tmp_reg |= extract_params->known_fields_def.vlan_tci <<
53016 + FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT;
53017 + tmp_reg |= extract_params->known_fields_def.etype <<
53018 + FMAN_KG_SCH_DEF_ETYPE_SHIFT;
53019 + tmp_reg |= extract_params->known_fields_def.ppp_sid <<
53020 + FMAN_KG_SCH_DEF_PPP_SID_SHIFT;
53021 + tmp_reg |= extract_params->known_fields_def.ppp_pid <<
53022 + FMAN_KG_SCH_DEF_PPP_PID_SHIFT;
53023 + tmp_reg |= extract_params->known_fields_def.mpls <<
53024 + FMAN_KG_SCH_DEF_MPLS_SHIFT;
53025 + tmp_reg |= extract_params->known_fields_def.ip_addr <<
53026 + FMAN_KG_SCH_DEF_IP_ADDR_SHIFT;
53027 + tmp_reg |= extract_params->known_fields_def.ptype <<
53028 + FMAN_KG_SCH_DEF_PTYPE_SHIFT;
53029 + tmp_reg |= extract_params->known_fields_def.ip_tos_tc <<
53030 + FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT;
53031 + tmp_reg |= extract_params->known_fields_def.ipv6_fl <<
53032 + FMAN_KG_SCH_DEF_IPv6_FL_SHIFT;
53033 + tmp_reg |= extract_params->known_fields_def.ipsec_spi <<
53034 + FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT;
53035 + tmp_reg |= extract_params->known_fields_def.l4_port <<
53036 + FMAN_KG_SCH_DEF_L4_PORT_SHIFT;
53037 + tmp_reg |= extract_params->known_fields_def.tcp_flg <<
53038 + FMAN_KG_SCH_DEF_TCP_FLG_SHIFT;
53039 +
53040 + scheme_regs->kgse_ekdv = tmp_reg;
53041 +
53042 + /* Generic extract registers */
53043 + if (extract_params->gen_extract_num > FM_KG_NUM_OF_GENERIC_REGS) {
53044 + return -EINVAL;
53045 + }
53046 +
53047 + for (i = 0; i < extract_params->gen_extract_num; i++) {
53048 + gen_params = extract_params->gen_extract + i;
53049 +
53050 + tmp_reg = FMAN_KG_SCH_GEN_VALID;
53051 + tmp_reg |= (uint32_t)gen_params->def_val <<
53052 + FMAN_KG_SCH_GEN_DEF_SHIFT;
53053 +
53054 + if (gen_params->type == E_FMAN_KG_HASH_EXTRACT) {
53055 + if ((gen_params->extract > FMAN_KG_SCH_GEN_SIZE_MAX) ||
53056 + (gen_params->extract == 0)) {
53057 + return -EINVAL;
53058 + }
53059 + } else {
53060 + tmp_reg |= FMAN_KG_SCH_GEN_OR;
53061 + }
53062 +
53063 + tmp_reg |= (uint32_t)gen_params->extract <<
53064 + FMAN_KG_SCH_GEN_SIZE_SHIFT;
53065 + tmp_reg |= (uint32_t)gen_params->mask <<
53066 + FMAN_KG_SCH_GEN_MASK_SHIFT;
53067 +
53068 + offset = gen_params->offset;
53069 + ht = get_gen_ht_code(gen_params->src,
53070 + gen_params->no_validation,
53071 + &offset);
53072 + tmp_reg |= (uint32_t)ht << FMAN_KG_SCH_GEN_HT_SHIFT;
53073 + tmp_reg |= offset;
53074 +
53075 + scheme_regs->kgse_gec[i] = tmp_reg;
53076 + }
53077 +
53078 + /* Masks registers */
53079 + if (extract_params->masks_num > FM_KG_EXTRACT_MASKS_NUM) {
53080 + return -EINVAL;
53081 + }
53082 +
53083 + select = 0;
53084 + mask = 0;
53085 + fqb = 0;
53086 + for (i = 0; i < extract_params->masks_num; i++) {
53087 + /* MCSx fields */
53088 + KG_GET_MASK_SEL_SHIFT(shift, i);
53089 + if (extract_params->masks[i].is_known) {
53090 + /* Mask known field */
53091 + select |= extract_params->masks[i].field_or_gen_idx <<
53092 + shift;
53093 + } else {
53094 + /* Mask generic extract */
53095 + select |= (extract_params->masks[i].field_or_gen_idx +
53096 + FM_KG_MASK_SEL_GEN_BASE) << shift;
53097 + }
53098 +
53099 + /* MOx fields - spread between se_bmch and se_fqb registers */
53100 + KG_GET_MASK_OFFSET_SHIFT(shift, i);
53101 + if (i < 2) {
53102 + select |= (uint32_t)extract_params->masks[i].offset <<
53103 + shift;
53104 + } else {
53105 + fqb |= (uint32_t)extract_params->masks[i].offset <<
53106 + shift;
53107 + }
53108 +
53109 + /* BMx fields */
53110 + KG_GET_MASK_SHIFT(shift, i);
53111 + mask |= (uint32_t)extract_params->masks[i].mask << shift;
53112 + }
53113 +
53114 + /* Finish with rest of BMx fileds -
53115 + * don't mask bits for unused masks by setting
53116 + * corresponding BMx field = 0xFF */
53117 + for (i = extract_params->masks_num; i < FM_KG_EXTRACT_MASKS_NUM; i++) {
53118 + KG_GET_MASK_SHIFT(shift, i);
53119 + mask |= 0xFF << shift;
53120 + }
53121 +
53122 + scheme_regs->kgse_bmch = select;
53123 + scheme_regs->kgse_bmcl = mask;
53124 +
53125 + /* Finish with FQB register initialization.
53126 + * Check fqid is 24-bit value. */
53127 + if (params->base_fqid & ~0x00FFFFFF) {
53128 + return -EINVAL;
53129 + }
53130 +
53131 + fqb |= params->base_fqid;
53132 + scheme_regs->kgse_fqb = fqb;
53133 +
53134 + /* Hash Configuration register */
53135 + tmp_reg = 0;
53136 + if (params->hash_params.use_hash) {
53137 + /* Check hash mask is 24-bit value */
53138 + if (params->hash_params.mask & ~0x00FFFFFF) {
53139 + return -EINVAL;
53140 + }
53141 +
53142 + /* Hash function produces 64-bit value, 24 bits of that
53143 + * are used to generate fq_id and policer profile.
53144 + * Thus, maximal shift is 40 bits to allow 24 bits out of 64.
53145 + */
53146 + if (params->hash_params.shift_r > FMAN_KG_SCH_HASH_HSHIFT_MAX) {
53147 + return -EINVAL;
53148 + }
53149 +
53150 + tmp_reg |= params->hash_params.mask;
53151 + tmp_reg |= (uint32_t)params->hash_params.shift_r <<
53152 + FMAN_KG_SCH_HASH_HSHIFT_SHIFT;
53153 +
53154 + if (params->hash_params.sym) {
53155 + tmp_reg |= FMAN_KG_SCH_HASH_SYM;
53156 + }
53157 +
53158 + }
53159 +
53160 + if (params->bypass_fqid_gen) {
53161 + tmp_reg |= FMAN_KG_SCH_HASH_NO_FQID_GEN;
53162 + }
53163 +
53164 + scheme_regs->kgse_hc = tmp_reg;
53165 +
53166 + /* Policer Profile register */
53167 + if (params->policer_params.bypass_pp_gen) {
53168 + tmp_reg = 0;
53169 + } else {
53170 + /* Lower 8 bits of 24-bits extracted from hash result
53171 + * are used for policer profile generation.
53172 + * That leaves maximum shift value = 23. */
53173 + if (params->policer_params.shift > FMAN_KG_SCH_PP_SHIFT_MAX) {
53174 + return -EINVAL;
53175 + }
53176 +
53177 + tmp_reg = params->policer_params.base;
53178 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
53179 + FMAN_KG_SCH_PP_SH_SHIFT) &
53180 + FMAN_KG_SCH_PP_SH_MASK;
53181 + tmp_reg |= ((uint32_t)params->policer_params.shift <<
53182 + FMAN_KG_SCH_PP_SL_SHIFT) &
53183 + FMAN_KG_SCH_PP_SL_MASK;
53184 + tmp_reg |= (uint32_t)params->policer_params.mask <<
53185 + FMAN_KG_SCH_PP_MASK_SHIFT;
53186 + }
53187 +
53188 + scheme_regs->kgse_ppc = tmp_reg;
53189 +
53190 + /* Coarse Classification Bit Select register */
53191 + if (params->next_engine == E_FMAN_PCD_CC) {
53192 + scheme_regs->kgse_ccbs = params->cc_params.qlcv_bits_sel;
53193 + }
53194 +
53195 + /* Packets Counter register */
53196 + if (params->update_counter) {
53197 + scheme_regs->kgse_spc = params->counter_value;
53198 + }
53199 +
53200 + return 0;
53201 +}
53202 +
53203 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
53204 + uint8_t scheme_id,
53205 + uint8_t hwport_id,
53206 + struct fman_kg_scheme_regs *scheme_regs,
53207 + bool update_counter)
53208 +{
53209 + struct fman_kg_scheme_regs *kgse_regs;
53210 + uint32_t tmp_reg;
53211 + int err, i;
53212 +
53213 + /* Write indirect scheme registers */
53214 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
53215 +
53216 + iowrite32be(scheme_regs->kgse_mode, &kgse_regs->kgse_mode);
53217 + iowrite32be(scheme_regs->kgse_ekfc, &kgse_regs->kgse_ekfc);
53218 + iowrite32be(scheme_regs->kgse_ekdv, &kgse_regs->kgse_ekdv);
53219 + iowrite32be(scheme_regs->kgse_bmch, &kgse_regs->kgse_bmch);
53220 + iowrite32be(scheme_regs->kgse_bmcl, &kgse_regs->kgse_bmcl);
53221 + iowrite32be(scheme_regs->kgse_fqb, &kgse_regs->kgse_fqb);
53222 + iowrite32be(scheme_regs->kgse_hc, &kgse_regs->kgse_hc);
53223 + iowrite32be(scheme_regs->kgse_ppc, &kgse_regs->kgse_ppc);
53224 + iowrite32be(scheme_regs->kgse_spc, &kgse_regs->kgse_spc);
53225 + iowrite32be(scheme_regs->kgse_dv0, &kgse_regs->kgse_dv0);
53226 + iowrite32be(scheme_regs->kgse_dv1, &kgse_regs->kgse_dv1);
53227 + iowrite32be(scheme_regs->kgse_ccbs, &kgse_regs->kgse_ccbs);
53228 + iowrite32be(scheme_regs->kgse_mv, &kgse_regs->kgse_mv);
53229 +
53230 + for (i = 0 ; i < FM_KG_NUM_OF_GENERIC_REGS ; i++)
53231 + iowrite32be(scheme_regs->kgse_gec[i], &kgse_regs->kgse_gec[i]);
53232 +
53233 + /* Write AR (Action register) */
53234 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, update_counter, TRUE);
53235 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53236 + return err;
53237 +}
53238 +
53239 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
53240 + uint8_t scheme_id,
53241 + uint8_t hwport_id)
53242 +{
53243 + struct fman_kg_scheme_regs *kgse_regs;
53244 + uint32_t tmp_reg;
53245 + int err, i;
53246 +
53247 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
53248 +
53249 + /* Clear all registers including enable bit in mode register */
53250 + for (i = 0; i < (sizeof(struct fman_kg_scheme_regs)) / 4; ++i) {
53251 + iowrite32be(0, ((uint32_t *)kgse_regs + i));
53252 + }
53253 +
53254 + /* Write AR (Action register) */
53255 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, FALSE, TRUE);
53256 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53257 + return err;
53258 +}
53259 +
53260 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
53261 + uint8_t scheme_id,
53262 + uint8_t hwport_id,
53263 + uint32_t *counter)
53264 +{
53265 + struct fman_kg_scheme_regs *kgse_regs;
53266 + uint32_t tmp_reg;
53267 + int err;
53268 +
53269 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
53270 +
53271 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
53272 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53273 +
53274 + if (err != 0)
53275 + return err;
53276 +
53277 + *counter = ioread32be(&kgse_regs->kgse_spc);
53278 +
53279 + return 0;
53280 +}
53281 +
53282 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
53283 + uint8_t scheme_id,
53284 + uint8_t hwport_id,
53285 + uint32_t counter)
53286 +{
53287 + struct fman_kg_scheme_regs *kgse_regs;
53288 + uint32_t tmp_reg;
53289 + int err;
53290 +
53291 + kgse_regs = (struct fman_kg_scheme_regs *)&(regs->fmkg_indirect[0]);
53292 +
53293 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, FALSE);
53294 +
53295 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53296 + if (err != 0)
53297 + return err;
53298 +
53299 + /* Keygen indirect access memory contains all scheme_id registers
53300 + * by now. Change only counter value. */
53301 + iowrite32be(counter, &kgse_regs->kgse_spc);
53302 +
53303 + /* Write back scheme registers */
53304 + tmp_reg = build_ar_scheme(scheme_id, hwport_id, TRUE, TRUE);
53305 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53306 +
53307 + return err;
53308 +}
53309 +
53310 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs)
53311 +{
53312 + return ioread32be(&regs->fmkg_tpc);
53313 +}
53314 +
53315 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
53316 + struct fman_kg_cp_regs *cls_plan_regs)
53317 +{
53318 + uint8_t entries_set, entry_bit;
53319 + int i;
53320 +
53321 + /* Zero out all group's register */
53322 + memset(cls_plan_regs, 0, sizeof(struct fman_kg_cp_regs));
53323 +
53324 + /* Go over all classification entries in params->entries_mask and
53325 + * configure the corresponding cpe register */
53326 + entries_set = params->entries_mask;
53327 + for (i = 0; entries_set; i++) {
53328 + entry_bit = (uint8_t)(0x80 >> i);
53329 + if ((entry_bit & entries_set) == 0)
53330 + continue;
53331 + entries_set ^= entry_bit;
53332 + cls_plan_regs->kgcpe[i] = params->mask_vector[i];
53333 + }
53334 +
53335 + return 0;
53336 +}
53337 +
53338 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
53339 + uint8_t grp_id,
53340 + uint8_t entries_mask,
53341 + uint8_t hwport_id,
53342 + struct fman_kg_cp_regs *cls_plan_regs)
53343 +{
53344 + struct fman_kg_cp_regs *kgcpe_regs;
53345 + uint32_t tmp_reg;
53346 + int i, err;
53347 +
53348 + /* Check group index is valid and the group isn't empty */
53349 + if (grp_id >= FM_KG_CLS_PLAN_GRPS_NUM)
53350 + return -EINVAL;
53351 +
53352 + /* Write indirect classification plan registers */
53353 + kgcpe_regs = (struct fman_kg_cp_regs *)&(regs->fmkg_indirect[0]);
53354 +
53355 + for (i = 0; i < FM_KG_NUM_CLS_PLAN_ENTR; i++) {
53356 + iowrite32be(cls_plan_regs->kgcpe[i], &kgcpe_regs->kgcpe[i]);
53357 + }
53358 +
53359 + tmp_reg = build_ar_cls_plan(grp_id, entries_mask, hwport_id, TRUE);
53360 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53361 + return err;
53362 +}
53363 +
53364 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
53365 + uint8_t hwport_id,
53366 + uint32_t schemes)
53367 +{
53368 + struct fman_kg_pe_regs *kg_pe_regs;
53369 + uint32_t tmp_reg;
53370 + int err;
53371 +
53372 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
53373 +
53374 + iowrite32be(schemes, &kg_pe_regs->fmkg_pe_sp);
53375 +
53376 + tmp_reg = build_ar_bind_scheme(hwport_id, TRUE);
53377 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53378 + return err;
53379 +}
53380 +
53381 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
53382 + uint8_t grp_mask,
53383 + uint32_t *bind_cls_plans)
53384 +{
53385 + /* Check grp_base and grp_mask are 5-bits values */
53386 + if ((grp_base & ~0x0000001F) || (grp_mask & ~0x0000001F))
53387 + return -EINVAL;
53388 +
53389 + *bind_cls_plans = (uint32_t) ((grp_mask << FMAN_KG_PE_CPP_MASK_SHIFT) | grp_base);
53390 + return 0;
53391 +}
53392 +
53393 +
53394 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
53395 + uint8_t hwport_id,
53396 + uint32_t bind_cls_plans)
53397 +{
53398 + struct fman_kg_pe_regs *kg_pe_regs;
53399 + uint32_t tmp_reg;
53400 + int err;
53401 +
53402 + kg_pe_regs = (struct fman_kg_pe_regs *)&(regs->fmkg_indirect[0]);
53403 +
53404 + iowrite32be(bind_cls_plans, &kg_pe_regs->fmkg_pe_cpp);
53405 +
53406 + tmp_reg = build_ar_bind_cls_plan(hwport_id, TRUE);
53407 + err = fman_kg_write_ar_wait(regs, tmp_reg);
53408 + return err;
53409 +}
53410 --- /dev/null
53411 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Pcd/fman_prs.c
53412 @@ -0,0 +1,129 @@
53413 +/*
53414 + * Copyright 2012 Freescale Semiconductor Inc.
53415 + *
53416 + * Redistribution and use in source and binary forms, with or without
53417 + * modification, are permitted provided that the following conditions are met:
53418 + * * Redistributions of source code must retain the above copyright
53419 + * notice, this list of conditions and the following disclaimer.
53420 + * * Redistributions in binary form must reproduce the above copyright
53421 + * notice, this list of conditions and the following disclaimer in the
53422 + * documentation and/or other materials provided with the distribution.
53423 + * * Neither the name of Freescale Semiconductor nor the
53424 + * names of its contributors may be used to endorse or promote products
53425 + * derived from this software without specific prior written permission.
53426 + *
53427 + *
53428 + * ALTERNATIVELY, this software may be distributed under the terms of the
53429 + * GNU General Public License ("GPL") as published by the Free Software
53430 + * Foundation, either version 2 of that License or (at your option) any
53431 + * later version.
53432 + *
53433 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
53434 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53435 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53436 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
53437 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53438 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53439 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53440 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53441 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53442 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53443 + */
53444 +
53445 +#include "fsl_fman_prs.h"
53446 +
53447 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask)
53448 +{
53449 + return ioread32be(&regs->fmpr_perr) & ev_mask;
53450 +}
53451 +
53452 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs)
53453 +{
53454 + return ioread32be(&regs->fmpr_perer);
53455 +}
53456 +
53457 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event)
53458 +{
53459 + iowrite32be(event, &regs->fmpr_perr);
53460 +}
53461 +
53462 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask)
53463 +{
53464 + return ioread32be(&regs->fmpr_pevr) & ev_mask;
53465 +}
53466 +
53467 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs)
53468 +{
53469 + return ioread32be(&regs->fmpr_pever);
53470 +}
53471 +
53472 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event)
53473 +{
53474 + iowrite32be(event, &regs->fmpr_pevr);
53475 +}
53476 +
53477 +void fman_prs_defconfig(struct fman_prs_cfg *cfg)
53478 +{
53479 + cfg->port_id_stat = 0;
53480 + cfg->max_prs_cyc_lim = DEFAULT_MAX_PRS_CYC_LIM;
53481 + cfg->prs_exceptions = 0x03000000;
53482 +}
53483 +
53484 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg)
53485 +{
53486 + uint32_t tmp;
53487 +
53488 + iowrite32be(cfg->max_prs_cyc_lim, &regs->fmpr_rpclim);
53489 + iowrite32be((FM_PCD_PRS_SINGLE_ECC | FM_PCD_PRS_PORT_IDLE_STS),
53490 + &regs->fmpr_pevr);
53491 +
53492 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_SINGLE_ECC)
53493 + iowrite32be(FM_PCD_PRS_SINGLE_ECC, &regs->fmpr_pever);
53494 + else
53495 + iowrite32be(0, &regs->fmpr_pever);
53496 +
53497 + iowrite32be(FM_PCD_PRS_DOUBLE_ECC, &regs->fmpr_perr);
53498 +
53499 + tmp = 0;
53500 + if (cfg->prs_exceptions & FM_PCD_EX_PRS_DOUBLE_ECC)
53501 + tmp |= FM_PCD_PRS_DOUBLE_ECC;
53502 + iowrite32be(tmp, &regs->fmpr_perer);
53503 +
53504 + iowrite32be(cfg->port_id_stat, &regs->fmpr_ppsc);
53505 +
53506 + return 0;
53507 +}
53508 +
53509 +void fman_prs_enable(struct fman_prs_regs *regs)
53510 +{
53511 + uint32_t tmp;
53512 +
53513 + tmp = ioread32be(&regs->fmpr_rpimac) | FM_PCD_PRS_RPIMAC_EN;
53514 + iowrite32be(tmp, &regs->fmpr_rpimac);
53515 +}
53516 +
53517 +void fman_prs_disable(struct fman_prs_regs *regs)
53518 +{
53519 + uint32_t tmp;
53520 +
53521 + tmp = ioread32be(&regs->fmpr_rpimac) & ~FM_PCD_PRS_RPIMAC_EN;
53522 + iowrite32be(tmp, &regs->fmpr_rpimac);
53523 +}
53524 +
53525 +int fman_prs_is_enabled(struct fman_prs_regs *regs)
53526 +{
53527 + return ioread32be(&regs->fmpr_rpimac) & FM_PCD_PRS_RPIMAC_EN;
53528 +}
53529 +
53530 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk)
53531 +{
53532 + iowrite32be(pid_msk, &regs->fmpr_ppsc);
53533 +}
53534 +
53535 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable)
53536 +{
53537 + if (enable)
53538 + iowrite32be(FM_PCD_PRS_PPSC_ALL_PORTS, &regs->fmpr_ppsc);
53539 + else
53540 + iowrite32be(0, &regs->fmpr_ppsc);
53541 +}
53542 --- /dev/null
53543 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/Makefile
53544 @@ -0,0 +1,15 @@
53545 +#
53546 +# Makefile for the Freescale Ethernet controllers
53547 +#
53548 +ccflags-y += -DVERSION=\"\"
53549 +#
53550 +#Include netcomm SW specific definitions
53551 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
53552 +
53553 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
53554 +
53555 +ccflags-y += -I$(NCSW_FM_INC)
53556 +
53557 +obj-y += fsl-ncsw-Pcd.o
53558 +
53559 +fsl-ncsw-Pcd-objs := fm_port.o fm_port_im.o fman_port.o
53560 --- /dev/null
53561 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.c
53562 @@ -0,0 +1,6437 @@
53563 +/*
53564 + * Copyright 2008-2012 Freescale Semiconductor Inc.
53565 + *
53566 + * Redistribution and use in source and binary forms, with or without
53567 + * modification, are permitted provided that the following conditions are met:
53568 + * * Redistributions of source code must retain the above copyright
53569 + * notice, this list of conditions and the following disclaimer.
53570 + * * Redistributions in binary form must reproduce the above copyright
53571 + * notice, this list of conditions and the following disclaimer in the
53572 + * documentation and/or other materials provided with the distribution.
53573 + * * Neither the name of Freescale Semiconductor nor the
53574 + * names of its contributors may be used to endorse or promote products
53575 + * derived from this software without specific prior written permission.
53576 + *
53577 + *
53578 + * ALTERNATIVELY, this software may be distributed under the terms of the
53579 + * GNU General Public License ("GPL") as published by the Free Software
53580 + * Foundation, either version 2 of that License or (at your option) any
53581 + * later version.
53582 + *
53583 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
53584 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53585 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53586 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
53587 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53588 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53589 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53590 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
53591 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
53592 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53593 + */
53594 +
53595 +
53596 +/******************************************************************************
53597 + @File fm_port.c
53598 +
53599 + @Description FM driver routines implementation.
53600 + *//***************************************************************************/
53601 +#include "error_ext.h"
53602 +#include "std_ext.h"
53603 +#include "string_ext.h"
53604 +#include "sprint_ext.h"
53605 +#include "debug_ext.h"
53606 +#include "fm_muram_ext.h"
53607 +
53608 +#include "fman_common.h"
53609 +#include "fm_port.h"
53610 +#include "fm_port_dsar.h"
53611 +#include "common/general.h"
53612 +
53613 +/****************************************/
53614 +/* static functions */
53615 +/****************************************/
53616 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort);
53617 +
53618 +static t_Error CheckInitParameters(t_FmPort *p_FmPort)
53619 +{
53620 + t_FmPortDriverParam *p_Params = p_FmPort->p_FmPortDriverParam;
53621 + struct fman_port_cfg *p_DfltConfig = &p_Params->dfltCfg;
53622 + t_Error ans = E_OK;
53623 + uint32_t unusedMask;
53624 +
53625 + if (p_FmPort->imEn)
53626 + {
53627 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
53628 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53629 + > 2)
53630 + RETURN_ERROR(
53631 + MAJOR,
53632 + E_INVALID_VALUE,
53633 + ("fifoDeqPipelineDepth for IM 10G can't be larger than 2"));
53634 +
53635 + if ((ans = FmPortImCheckInitParameters(p_FmPort)) != E_OK)
53636 + return ERROR_CODE(ans);
53637 + }
53638 + else
53639 + {
53640 + /****************************************/
53641 + /* Rx only */
53642 + /****************************************/
53643 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53644 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
53645 + {
53646 + /* external buffer pools */
53647 + if (!p_Params->extBufPools.numOfPoolsUsed)
53648 + RETURN_ERROR(
53649 + MAJOR,
53650 + E_INVALID_VALUE,
53651 + ("extBufPools.numOfPoolsUsed=0. At least one buffer pool must be defined"));
53652 +
53653 + if (FmSpCheckBufPoolsParams(&p_Params->extBufPools,
53654 + p_Params->p_BackupBmPools,
53655 + &p_Params->bufPoolDepletion) != E_OK)
53656 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53657 +
53658 + /* Check that part of IC that needs copying is small enough to enter start margin */
53659 + if (p_Params->intContext.size
53660 + && (p_Params->intContext.size
53661 + + p_Params->intContext.extBufOffset
53662 + > p_Params->bufMargins.startMargins))
53663 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53664 + ("intContext.size is larger than start margins"));
53665 +
53666 + if ((p_Params->liodnOffset != (uint16_t)DPAA_LIODN_DONT_OVERRIDE)
53667 + && (p_Params->liodnOffset & ~FM_LIODN_OFFSET_MASK))
53668 + RETURN_ERROR(
53669 + MAJOR,
53670 + E_INVALID_VALUE,
53671 + ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
53672 +
53673 +#ifdef FM_NO_BACKUP_POOLS
53674 + if ((p_FmPort->fmRevInfo.majorRev != 4) && (p_FmPort->fmRevInfo.majorRev < 6))
53675 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
53676 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("BackupBmPools"));
53677 +#endif /* FM_NO_BACKUP_POOLS */
53678 + }
53679 +
53680 + /****************************************/
53681 + /* Non Rx ports */
53682 + /****************************************/
53683 + else
53684 + {
53685 + if (p_Params->deqSubPortal >= FM_MAX_NUM_OF_SUB_PORTALS)
53686 + RETURN_ERROR(
53687 + MAJOR,
53688 + E_INVALID_VALUE,
53689 + (" deqSubPortal has to be in the range of 0 - %d", FM_MAX_NUM_OF_SUB_PORTALS));
53690 +
53691 + /* to protect HW internal-context from overwrite */
53692 + if ((p_Params->intContext.size)
53693 + && (p_Params->intContext.intContextOffset
53694 + < MIN_TX_INT_OFFSET))
53695 + RETURN_ERROR(
53696 + MAJOR,
53697 + E_INVALID_VALUE,
53698 + ("non-Rx intContext.intContextOffset can't be smaller than %d", MIN_TX_INT_OFFSET));
53699 +
53700 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
53701 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
53702 + /* in O/H DEFAULT_notSupported indicates that it is not supported and should not be checked */
53703 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53704 + != DEFAULT_notSupported))
53705 + {
53706 + /* Check that not larger than 8 */
53707 + if ((!p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth)
53708 + || (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53709 + > MAX_FIFO_PIPELINE_DEPTH))
53710 + RETURN_ERROR(
53711 + MAJOR,
53712 + E_INVALID_VALUE,
53713 + ("fifoDeqPipelineDepth can't be larger than %d", MAX_FIFO_PIPELINE_DEPTH));
53714 + }
53715 + }
53716 +
53717 + /****************************************/
53718 + /* Rx Or Offline Parsing */
53719 + /****************************************/
53720 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53721 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
53722 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53723 + {
53724 + if (!p_Params->dfltFqid)
53725 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53726 + ("dfltFqid must be between 1 and 2^24-1"));
53727 +#if defined(FM_CAPWAP_SUPPORT) && defined(FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004)
53728 + if (p_FmPort->p_FmPortDriverParam->bufferPrefixContent.manipExtraSpace % 16)
53729 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufferPrefixContent.manipExtraSpace has to be devidable by 16"));
53730 +#endif /* defined(FM_CAPWAP_SUPPORT) && ... */
53731 + }
53732 +
53733 + /****************************************/
53734 + /* All ports */
53735 + /****************************************/
53736 + /* common BMI registers values */
53737 + /* Check that Queue Id is not larger than 2^24, and is not 0 */
53738 + if ((p_Params->errFqid & ~0x00FFFFFF) || !p_Params->errFqid)
53739 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53740 + ("errFqid must be between 1 and 2^24-1"));
53741 + if (p_Params->dfltFqid & ~0x00FFFFFF)
53742 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53743 + ("dfltFqid must be between 1 and 2^24-1"));
53744 + }
53745 +
53746 + /****************************************/
53747 + /* Rx only */
53748 + /****************************************/
53749 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53750 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
53751 + {
53752 + if (p_DfltConfig->rx_pri_elevation % BMI_FIFO_UNITS)
53753 + RETURN_ERROR(
53754 + MAJOR,
53755 + E_INVALID_VALUE,
53756 + ("rxFifoPriElevationLevel has to be divisible by %d", BMI_FIFO_UNITS));
53757 + if ((p_DfltConfig->rx_pri_elevation < BMI_FIFO_UNITS)
53758 + || (p_DfltConfig->rx_pri_elevation > MAX_PORT_FIFO_SIZE))
53759 + RETURN_ERROR(
53760 + MAJOR,
53761 + E_INVALID_VALUE,
53762 + ("rxFifoPriElevationLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
53763 + if (p_DfltConfig->rx_fifo_thr % BMI_FIFO_UNITS)
53764 + RETURN_ERROR(
53765 + MAJOR,
53766 + E_INVALID_VALUE,
53767 + ("rxFifoThreshold has to be divisible by %d", BMI_FIFO_UNITS));
53768 + if ((p_DfltConfig->rx_fifo_thr < BMI_FIFO_UNITS)
53769 + || (p_DfltConfig->rx_fifo_thr > MAX_PORT_FIFO_SIZE))
53770 + RETURN_ERROR(
53771 + MAJOR,
53772 + E_INVALID_VALUE,
53773 + ("rxFifoThreshold has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
53774 +
53775 + /* Check that not larger than 16 */
53776 + if (p_DfltConfig->rx_cut_end_bytes > FRAME_END_DATA_SIZE)
53777 + RETURN_ERROR(
53778 + MAJOR,
53779 + E_INVALID_VALUE,
53780 + ("cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
53781 +
53782 + if (FmSpCheckBufMargins(&p_Params->bufMargins) != E_OK)
53783 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53784 +
53785 + /* extra FIFO size (allowed only to Rx ports) */
53786 + if (p_Params->setSizeOfFifo
53787 + && (p_FmPort->fifoBufs.extra % BMI_FIFO_UNITS))
53788 + RETURN_ERROR(
53789 + MAJOR,
53790 + E_INVALID_VALUE,
53791 + ("fifoBufs.extra has to be divisible by %d", BMI_FIFO_UNITS));
53792 +
53793 + if (p_Params->bufPoolDepletion.poolsGrpModeEnable
53794 + && !p_Params->bufPoolDepletion.numOfPools)
53795 + RETURN_ERROR(
53796 + MAJOR,
53797 + E_INVALID_VALUE,
53798 + ("bufPoolDepletion.numOfPools can not be 0 when poolsGrpModeEnable=TRUE"));
53799 +#ifdef FM_CSI_CFED_LIMIT
53800 + if (p_FmPort->fmRevInfo.majorRev == 4)
53801 + {
53802 + /* Check that not larger than 16 */
53803 + if (p_DfltConfig->rx_cut_end_bytes + p_DfltConfig->checksum_bytes_ignore > FRAME_END_DATA_SIZE)
53804 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("cheksumLastBytesIgnore + cutBytesFromEnd can't be larger than %d", FRAME_END_DATA_SIZE));
53805 + }
53806 +#endif /* FM_CSI_CFED_LIMIT */
53807 + }
53808 +
53809 + /****************************************/
53810 + /* Non Rx ports */
53811 + /****************************************/
53812 + /* extra FIFO size (allowed only to Rx ports) */
53813 + else
53814 + if (p_FmPort->fifoBufs.extra)
53815 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53816 + (" No fifoBufs.extra for non Rx ports"));
53817 +
53818 + /****************************************/
53819 + /* Tx only */
53820 + /****************************************/
53821 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
53822 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
53823 + {
53824 + if (p_DfltConfig->tx_fifo_min_level % BMI_FIFO_UNITS)
53825 + RETURN_ERROR(
53826 + MAJOR,
53827 + E_INVALID_VALUE,
53828 + ("txFifoMinFillLevel has to be divisible by %d", BMI_FIFO_UNITS));
53829 + if (p_DfltConfig->tx_fifo_min_level > (MAX_PORT_FIFO_SIZE - 256))
53830 + RETURN_ERROR(
53831 + MAJOR,
53832 + E_INVALID_VALUE,
53833 + ("txFifoMinFillLevel has to be in the range of 0 - %d", (MAX_PORT_FIFO_SIZE - 256)));
53834 + if (p_DfltConfig->tx_fifo_low_comf_level % BMI_FIFO_UNITS)
53835 + RETURN_ERROR(
53836 + MAJOR,
53837 + E_INVALID_VALUE,
53838 + ("txFifoLowComfLevel has to be divisible by %d", BMI_FIFO_UNITS));
53839 + if ((p_DfltConfig->tx_fifo_low_comf_level < BMI_FIFO_UNITS)
53840 + || (p_DfltConfig->tx_fifo_low_comf_level > MAX_PORT_FIFO_SIZE))
53841 + RETURN_ERROR(
53842 + MAJOR,
53843 + E_INVALID_VALUE,
53844 + ("txFifoLowComfLevel has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
53845 +
53846 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX)
53847 + if (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53848 + > 2)
53849 + RETURN_ERROR(
53850 + MAJOR, E_INVALID_VALUE,
53851 + ("fifoDeqPipelineDepth for 1G can't be larger than 2"));
53852 + }
53853 +
53854 + /****************************************/
53855 + /* Non Tx Ports */
53856 + /****************************************/
53857 + /* If discard override was selected , no frames may be discarded. */
53858 + else
53859 + if (p_DfltConfig->discard_override && p_Params->errorsToDiscard)
53860 + RETURN_ERROR(
53861 + MAJOR,
53862 + E_CONFLICT,
53863 + ("errorsToDiscard is not empty, but frmDiscardOverride selected (all discarded frames to be enqueued to error queue)."));
53864 +
53865 + /****************************************/
53866 + /* Rx and Offline parsing */
53867 + /****************************************/
53868 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
53869 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
53870 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
53871 + {
53872 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53873 + unusedMask = BMI_STATUS_OP_MASK_UNUSED;
53874 + else
53875 + unusedMask = BMI_STATUS_RX_MASK_UNUSED;
53876 +
53877 + /* Check that no common bits with BMI_STATUS_MASK_UNUSED */
53878 + if (p_Params->errorsToDiscard & unusedMask)
53879 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
53880 + ("errorsToDiscard contains undefined bits"));
53881 + }
53882 +
53883 + /****************************************/
53884 + /* Offline Ports */
53885 + /****************************************/
53886 +#ifdef FM_OP_OPEN_DMA_MIN_LIMIT
53887 + if ((p_FmPort->fmRevInfo.majorRev >= 6)
53888 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53889 + && p_Params->setNumOfOpenDmas
53890 + && (p_FmPort->openDmas.num < MIN_NUM_OF_OP_DMAS))
53891 + RETURN_ERROR(
53892 + MAJOR,
53893 + E_INVALID_VALUE,
53894 + ("For Offline port, openDmas.num can't be smaller than %d", MIN_NUM_OF_OP_DMAS));
53895 +#endif /* FM_OP_OPEN_DMA_MIN_LIMIT */
53896 +
53897 + /****************************************/
53898 + /* Offline & HC Ports */
53899 + /****************************************/
53900 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
53901 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
53902 + {
53903 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
53904 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
53905 + (p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore != DEFAULT_notSupported))
53906 + /* this is an indication that user called config for this mode which is not supported in this integration */
53907 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("cheksumLastBytesIgnore is available for Rx & Tx ports only"));
53908 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
53909 +
53910 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
53911 + if ((!((p_FmPort->fmRevInfo.majorRev == 4) ||
53912 + (p_FmPort->fmRevInfo.majorRev >= 6))) &&
53913 + (p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth != DEFAULT_notSupported))
53914 + /* this is an indication that user called config for this mode which is not supported in this integration */
53915 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("fifoDeqPipelineDepth is available for Tx ports only"));
53916 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
53917 + }
53918 +
53919 + /****************************************/
53920 + /* All ports */
53921 + /****************************************/
53922 + /* Check that not larger than 16 */
53923 + if ((p_Params->cheksumLastBytesIgnore > FRAME_END_DATA_SIZE)
53924 + && ((p_Params->cheksumLastBytesIgnore != DEFAULT_notSupported)))
53925 + RETURN_ERROR(
53926 + MAJOR,
53927 + E_INVALID_VALUE,
53928 + ("cheksumLastBytesIgnore can't be larger than %d", FRAME_END_DATA_SIZE));
53929 +
53930 + if (FmSpCheckIntContextParams(&p_Params->intContext) != E_OK)
53931 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
53932 +
53933 + /* common BMI registers values */
53934 + if (p_Params->setNumOfTasks
53935 + && ((!p_FmPort->tasks.num)
53936 + || (p_FmPort->tasks.num > MAX_NUM_OF_TASKS)))
53937 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53938 + ("tasks.num can't be larger than %d", MAX_NUM_OF_TASKS));
53939 + if (p_Params->setNumOfTasks
53940 + && (p_FmPort->tasks.extra > MAX_NUM_OF_EXTRA_TASKS))
53941 + RETURN_ERROR(
53942 + MAJOR,
53943 + E_INVALID_VALUE,
53944 + ("tasks.extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
53945 + if (p_Params->setNumOfOpenDmas
53946 + && ((!p_FmPort->openDmas.num)
53947 + || (p_FmPort->openDmas.num > MAX_NUM_OF_DMAS)))
53948 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
53949 + ("openDmas.num can't be larger than %d", MAX_NUM_OF_DMAS));
53950 + if (p_Params->setNumOfOpenDmas
53951 + && (p_FmPort->openDmas.extra > MAX_NUM_OF_EXTRA_DMAS))
53952 + RETURN_ERROR(
53953 + MAJOR,
53954 + E_INVALID_VALUE,
53955 + ("openDmas.extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
53956 + if (p_Params->setSizeOfFifo
53957 + && (!p_FmPort->fifoBufs.num
53958 + || (p_FmPort->fifoBufs.num > MAX_PORT_FIFO_SIZE)))
53959 + RETURN_ERROR(
53960 + MAJOR,
53961 + E_INVALID_VALUE,
53962 + ("fifoBufs.num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
53963 + if (p_Params->setSizeOfFifo && (p_FmPort->fifoBufs.num % BMI_FIFO_UNITS))
53964 + RETURN_ERROR(
53965 + MAJOR, E_INVALID_VALUE,
53966 + ("fifoBufs.num has to be divisible by %d", BMI_FIFO_UNITS));
53967 +
53968 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
53969 + if (p_FmPort->fmRevInfo.majorRev == 4)
53970 + if (p_FmPort->p_FmPortDriverParam->deqPrefetchOption != DEFAULT_notSupported)
53971 + /* this is an indication that user called config for this mode which is not supported in this integration */
53972 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("deqPrefetchOption"));
53973 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
53974 +
53975 + return E_OK;
53976 +}
53977 +
53978 +static t_Error VerifySizeOfFifo(t_FmPort *p_FmPort)
53979 +{
53980 + uint32_t minFifoSizeRequired = 0, optFifoSizeForB2B = 0;
53981 +
53982 + /*************************/
53983 + /* TX PORTS */
53984 + /*************************/
53985 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
53986 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
53987 + {
53988 + minFifoSizeRequired =
53989 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
53990 + + (3 * BMI_FIFO_UNITS));
53991 + if (!p_FmPort->imEn)
53992 + minFifoSizeRequired +=
53993 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
53994 + * BMI_FIFO_UNITS;
53995 +
53996 + optFifoSizeForB2B = minFifoSizeRequired;
53997 +
53998 + /* Add some margin for back-to-back capability to improve performance,
53999 + allows the hardware to pipeline new frame dma while the previous
54000 + frame not yet transmitted. */
54001 + if (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54002 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
54003 + else
54004 + optFifoSizeForB2B += 2 * BMI_FIFO_UNITS;
54005 + }
54006 +
54007 + /*************************/
54008 + /* RX IM PORTS */
54009 + /*************************/
54010 + else
54011 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
54012 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
54013 + && p_FmPort->imEn)
54014 + {
54015 + optFifoSizeForB2B =
54016 + minFifoSizeRequired =
54017 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
54018 + + (4 * BMI_FIFO_UNITS));
54019 + }
54020 +
54021 + /*************************/
54022 + /* RX non-IM PORTS */
54023 + /*************************/
54024 + else
54025 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX)
54026 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
54027 + && !p_FmPort->imEn)
54028 + {
54029 + if (p_FmPort->fmRevInfo.majorRev == 4)
54030 + {
54031 + if (p_FmPort->rxPoolsParams.numOfPools == 1)
54032 + minFifoSizeRequired = 8 * BMI_FIFO_UNITS;
54033 + else
54034 + minFifoSizeRequired =
54035 + (uint32_t)(ROUND_UP(p_FmPort->rxPoolsParams.secondLargestBufSize, BMI_FIFO_UNITS)
54036 + + (7 * BMI_FIFO_UNITS));
54037 + }
54038 + else
54039 + {
54040 +#if (DPAA_VERSION >= 11)
54041 + minFifoSizeRequired =
54042 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
54043 + + (5 * BMI_FIFO_UNITS));
54044 + /* 4 according to spec + 1 for FOF>0 */
54045 +#else
54046 + minFifoSizeRequired = (uint32_t)
54047 + (ROUND_UP(MIN(p_FmPort->maxFrameLength, p_FmPort->rxPoolsParams.largestBufSize), BMI_FIFO_UNITS)
54048 + + (7*BMI_FIFO_UNITS));
54049 +#endif /* (DPAA_VERSION >= 11) */
54050 + }
54051 +
54052 + optFifoSizeForB2B = minFifoSizeRequired;
54053 +
54054 + /* Add some margin for back-to-back capability to improve performance,
54055 + allows the hardware to pipeline new frame dma while the previous
54056 + frame not yet transmitted. */
54057 + if (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
54058 + optFifoSizeForB2B += 8 * BMI_FIFO_UNITS;
54059 + else
54060 + optFifoSizeForB2B += 3 * BMI_FIFO_UNITS;
54061 + }
54062 +
54063 + /* For O/H ports, check fifo size and update if necessary */
54064 + else
54065 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54066 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
54067 + {
54068 +#if (DPAA_VERSION >= 11)
54069 + optFifoSizeForB2B =
54070 + minFifoSizeRequired =
54071 + (uint32_t)(ROUND_UP(p_FmPort->maxFrameLength, BMI_FIFO_UNITS)
54072 + + ((p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth
54073 + + 5) * BMI_FIFO_UNITS));
54074 + /* 4 according to spec + 1 for FOF>0 */
54075 +#else
54076 + optFifoSizeForB2B = minFifoSizeRequired = (uint32_t)((p_FmPort->tasks.num + 2) * BMI_FIFO_UNITS);
54077 +#endif /* (DPAA_VERSION >= 11) */
54078 + }
54079 +
54080 + ASSERT_COND(minFifoSizeRequired > 0);
54081 + ASSERT_COND(optFifoSizeForB2B >= minFifoSizeRequired);
54082 +
54083 + /* Verify the size */
54084 + if (p_FmPort->fifoBufs.num < minFifoSizeRequired)
54085 + DBG(INFO,
54086 + ("FIFO size is %d and should be enlarged to %d bytes",p_FmPort->fifoBufs.num, minFifoSizeRequired));
54087 + else if (p_FmPort->fifoBufs.num < optFifoSizeForB2B)
54088 + DBG(INFO,
54089 + ("For back-to-back frames processing, FIFO size is %d and needs to enlarge to %d bytes", p_FmPort->fifoBufs.num, optFifoSizeForB2B));
54090 +
54091 + return E_OK;
54092 +}
54093 +
54094 +static void FmPortDriverParamFree(t_FmPort *p_FmPort)
54095 +{
54096 + if (p_FmPort->p_FmPortDriverParam)
54097 + {
54098 + XX_Free(p_FmPort->p_FmPortDriverParam);
54099 + p_FmPort->p_FmPortDriverParam = NULL;
54100 + }
54101 +}
54102 +
54103 +static t_Error SetExtBufferPools(t_FmPort *p_FmPort)
54104 +{
54105 + t_FmExtPools *p_ExtBufPools = &p_FmPort->p_FmPortDriverParam->extBufPools;
54106 + t_FmBufPoolDepletion *p_BufPoolDepletion =
54107 + &p_FmPort->p_FmPortDriverParam->bufPoolDepletion;
54108 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
54109 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
54110 + int i = 0, j = 0, err;
54111 + struct fman_port_bpools bpools;
54112 +
54113 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
54114 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
54115 + memcpy(&p_FmPort->extBufPools, p_ExtBufPools, sizeof(t_FmExtPools));
54116 +
54117 + FmSpSetBufPoolsInAscOrderOfBufSizes(p_ExtBufPools, orderedArray,
54118 + sizesArray);
54119 +
54120 + /* Prepare flibs bpools structure */
54121 + memset(&bpools, 0, sizeof(struct fman_port_bpools));
54122 + bpools.count = p_ExtBufPools->numOfPoolsUsed;
54123 + bpools.counters_enable = TRUE;
54124 + for (i = 0; i < p_ExtBufPools->numOfPoolsUsed; i++)
54125 + {
54126 + bpools.bpool[i].bpid = orderedArray[i];
54127 + bpools.bpool[i].size = sizesArray[orderedArray[i]];
54128 + /* functionality available only for some derivatives (limited by config) */
54129 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
54130 + for (j = 0;
54131 + j
54132 + < p_FmPort->p_FmPortDriverParam->p_BackupBmPools->numOfBackupPools;
54133 + j++)
54134 + if (orderedArray[i]
54135 + == p_FmPort->p_FmPortDriverParam->p_BackupBmPools->poolIds[j])
54136 + {
54137 + bpools.bpool[i].is_backup = TRUE;
54138 + break;
54139 + }
54140 + }
54141 +
54142 + /* save pools parameters for later use */
54143 + p_FmPort->rxPoolsParams.numOfPools = p_ExtBufPools->numOfPoolsUsed;
54144 + p_FmPort->rxPoolsParams.largestBufSize =
54145 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 1]];
54146 + if (p_ExtBufPools->numOfPoolsUsed > 1)
54147 + p_FmPort->rxPoolsParams.secondLargestBufSize =
54148 + sizesArray[orderedArray[p_ExtBufPools->numOfPoolsUsed - 2]];
54149 +
54150 + /* FMBM_RMPD reg. - pool depletion */
54151 + if (p_BufPoolDepletion->poolsGrpModeEnable)
54152 + {
54153 + bpools.grp_bp_depleted_num = p_BufPoolDepletion->numOfPools;
54154 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
54155 + {
54156 + if (p_BufPoolDepletion->poolsToConsider[i])
54157 + {
54158 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
54159 + {
54160 + if (i == orderedArray[j])
54161 + {
54162 + bpools.bpool[j].grp_bp_depleted = TRUE;
54163 + break;
54164 + }
54165 + }
54166 + }
54167 + }
54168 + }
54169 +
54170 + if (p_BufPoolDepletion->singlePoolModeEnable)
54171 + {
54172 + for (i = 0; i < BM_MAX_NUM_OF_POOLS; i++)
54173 + {
54174 + if (p_BufPoolDepletion->poolsToConsiderForSingleMode[i])
54175 + {
54176 + for (j = 0; j < p_ExtBufPools->numOfPoolsUsed; j++)
54177 + {
54178 + if (i == orderedArray[j])
54179 + {
54180 + bpools.bpool[j].single_bp_depleted = TRUE;
54181 + break;
54182 + }
54183 + }
54184 + }
54185 + }
54186 + }
54187 +
54188 +#if (DPAA_VERSION >= 11)
54189 + /* fill QbbPEV */
54190 + if (p_BufPoolDepletion->poolsGrpModeEnable
54191 + || p_BufPoolDepletion->singlePoolModeEnable)
54192 + {
54193 + for (i = 0; i < FM_MAX_NUM_OF_PFC_PRIORITIES; i++)
54194 + {
54195 + if (p_BufPoolDepletion->pfcPrioritiesEn[i] == TRUE)
54196 + {
54197 + bpools.bpool[i].pfc_priorities_en = TRUE;
54198 + }
54199 + }
54200 + }
54201 +#endif /* (DPAA_VERSION >= 11) */
54202 +
54203 + /* Issue flibs function */
54204 + err = fman_port_set_bpools(&p_FmPort->port, &bpools);
54205 + if (err != 0)
54206 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpools"));
54207 +
54208 + if (p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
54209 + XX_Free(p_FmPort->p_FmPortDriverParam->p_BackupBmPools);
54210 +
54211 + return E_OK;
54212 +}
54213 +
54214 +static t_Error ClearPerfCnts(t_FmPort *p_FmPort)
54215 +{
54216 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54217 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL, 0);
54218 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL, 0);
54219 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL, 0);
54220 + FM_PORT_ModifyCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL, 0);
54221 + return E_OK;
54222 +}
54223 +
54224 +static t_Error InitLowLevelDriver(t_FmPort *p_FmPort)
54225 +{
54226 + t_FmPortDriverParam *p_DriverParams = p_FmPort->p_FmPortDriverParam;
54227 + struct fman_port_params portParams;
54228 + uint32_t tmpVal;
54229 + t_Error err;
54230 +
54231 + /* Set up flibs parameters and issue init function */
54232 +
54233 + memset(&portParams, 0, sizeof(struct fman_port_params));
54234 + portParams.discard_mask = p_DriverParams->errorsToDiscard;
54235 + portParams.dflt_fqid = p_DriverParams->dfltFqid;
54236 + portParams.err_fqid = p_DriverParams->errFqid;
54237 + portParams.deq_sp = p_DriverParams->deqSubPortal;
54238 + portParams.dont_release_buf = p_DriverParams->dontReleaseBuf;
54239 + switch (p_FmPort->portType)
54240 + {
54241 + case (e_FM_PORT_TYPE_RX_10G):
54242 + case (e_FM_PORT_TYPE_RX):
54243 + portParams.err_mask = (RX_ERRS_TO_ENQ & ~portParams.discard_mask);
54244 + if (!p_FmPort->imEn)
54245 + {
54246 + if (p_DriverParams->forwardReuseIntContext)
54247 + p_DriverParams->dfltCfg.rx_fd_bits =
54248 + (uint8_t)(BMI_PORT_RFNE_FRWD_RPD >> 24);
54249 + }
54250 + break;
54251 +
54252 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54253 + portParams.err_mask = (OP_ERRS_TO_ENQ & ~portParams.discard_mask);
54254 + break;
54255 + break;
54256 +
54257 + default:
54258 + break;
54259 + }
54260 +
54261 + tmpVal =
54262 + (uint32_t)(
54263 + (p_FmPort->internalBufferOffset % OFFSET_UNITS) ? (p_FmPort->internalBufferOffset
54264 + / OFFSET_UNITS + 1) :
54265 + (p_FmPort->internalBufferOffset / OFFSET_UNITS));
54266 + p_FmPort->internalBufferOffset = (uint8_t)(tmpVal * OFFSET_UNITS);
54267 + p_DriverParams->dfltCfg.int_buf_start_margin =
54268 + p_FmPort->internalBufferOffset;
54269 +
54270 + p_DriverParams->dfltCfg.ext_buf_start_margin =
54271 + p_DriverParams->bufMargins.startMargins;
54272 + p_DriverParams->dfltCfg.ext_buf_end_margin =
54273 + p_DriverParams->bufMargins.endMargins;
54274 +
54275 + p_DriverParams->dfltCfg.ic_ext_offset =
54276 + p_DriverParams->intContext.extBufOffset;
54277 + p_DriverParams->dfltCfg.ic_int_offset =
54278 + p_DriverParams->intContext.intContextOffset;
54279 + p_DriverParams->dfltCfg.ic_size = p_DriverParams->intContext.size;
54280 +
54281 + p_DriverParams->dfltCfg.stats_counters_enable = TRUE;
54282 + p_DriverParams->dfltCfg.perf_counters_enable = TRUE;
54283 + p_DriverParams->dfltCfg.queue_counters_enable = TRUE;
54284 +
54285 + p_DriverParams->dfltCfg.perf_cnt_params.task_val =
54286 + (uint8_t)p_FmPort->tasks.num;
54287 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING ||
54288 + p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 0;
54289 + else
54290 + p_DriverParams->dfltCfg.perf_cnt_params.queue_val = 1;
54291 + p_DriverParams->dfltCfg.perf_cnt_params.dma_val =
54292 + (uint8_t)p_FmPort->openDmas.num;
54293 + p_DriverParams->dfltCfg.perf_cnt_params.fifo_val = p_FmPort->fifoBufs.num;
54294 +
54295 + if (0
54296 + != fman_port_init(&p_FmPort->port, &p_DriverParams->dfltCfg,
54297 + &portParams))
54298 + RETURN_ERROR(MAJOR, E_NO_DEVICE, ("fman_port_init"));
54299 +
54300 + if (p_FmPort->imEn && ((err = FmPortImInit(p_FmPort)) != E_OK))
54301 + RETURN_ERROR(MAJOR, err, NO_MSG);
54302 + else
54303 + {
54304 + // from QMIInit
54305 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54306 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54307 + {
54308 + if (p_DriverParams->deqPrefetchOption == e_FM_PORT_DEQ_NO_PREFETCH)
54309 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
54310 + FALSE);
54311 + else
54312 + FmSetPortPreFetchConfiguration(p_FmPort->h_Fm, p_FmPort->portId,
54313 + TRUE);
54314 + }
54315 + }
54316 + /* The code bellow is a trick so the FM will not release the buffer
54317 + to BM nor will try to enqueue the frame to QM */
54318 + if (((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
54319 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)) && (!p_FmPort->imEn))
54320 + {
54321 + if (!p_DriverParams->dfltFqid && p_DriverParams->dontReleaseBuf)
54322 + {
54323 + /* override fmbm_tcfqid 0 with a false non-0 value. This will force FM to
54324 + * act according to tfene. Otherwise, if fmbm_tcfqid is 0 the FM will release
54325 + * buffers to BM regardless of fmbm_tfene
54326 + */
54327 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tcfqid, 0xFFFFFF);
54328 + WRITE_UINT32(p_FmPort->port.bmi_regs->tx.fmbm_tfene,
54329 + NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE);
54330 + }
54331 + }
54332 +
54333 + return E_OK;
54334 +}
54335 +
54336 +static bool CheckRxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
54337 +{
54338 + UNUSED(p_FmPort);
54339 +
54340 + switch (counter)
54341 + {
54342 + case (e_FM_PORT_COUNTERS_CYCLE):
54343 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54344 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
54345 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54346 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54347 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
54348 + case (e_FM_PORT_COUNTERS_FRAME):
54349 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54350 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
54351 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
54352 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
54353 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
54354 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
54355 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54356 + case (e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER):
54357 + return TRUE;
54358 + default:
54359 + return FALSE;
54360 + }
54361 +}
54362 +
54363 +static bool CheckTxBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
54364 +{
54365 + UNUSED(p_FmPort);
54366 +
54367 + switch (counter)
54368 + {
54369 + case (e_FM_PORT_COUNTERS_CYCLE):
54370 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54371 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
54372 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54373 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54374 + case (e_FM_PORT_COUNTERS_FRAME):
54375 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54376 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
54377 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
54378 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54379 + return TRUE;
54380 + default:
54381 + return FALSE;
54382 + }
54383 +}
54384 +
54385 +static bool CheckOhBmiCounter(t_FmPort *p_FmPort, e_FmPortCounters counter)
54386 +{
54387 + switch (counter)
54388 + {
54389 + case (e_FM_PORT_COUNTERS_CYCLE):
54390 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54391 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54392 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54393 + case (e_FM_PORT_COUNTERS_FRAME):
54394 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54395 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
54396 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
54397 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
54398 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
54399 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54400 + return TRUE;
54401 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
54402 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
54403 + return FALSE;
54404 + else
54405 + return TRUE;
54406 + default:
54407 + return FALSE;
54408 + }
54409 +}
54410 +
54411 +static t_Error BmiPortCheckAndGetCounterType(
54412 + t_FmPort *p_FmPort, e_FmPortCounters counter,
54413 + enum fman_port_stats_counters *p_StatsType,
54414 + enum fman_port_perf_counters *p_PerfType, bool *p_IsStats)
54415 +{
54416 + volatile uint32_t *p_Reg;
54417 + bool isValid;
54418 +
54419 + switch (p_FmPort->portType)
54420 + {
54421 + case (e_FM_PORT_TYPE_RX_10G):
54422 + case (e_FM_PORT_TYPE_RX):
54423 + p_Reg = &p_FmPort->port.bmi_regs->rx.fmbm_rstc;
54424 + isValid = CheckRxBmiCounter(p_FmPort, counter);
54425 + break;
54426 + case (e_FM_PORT_TYPE_TX_10G):
54427 + case (e_FM_PORT_TYPE_TX):
54428 + p_Reg = &p_FmPort->port.bmi_regs->tx.fmbm_tstc;
54429 + isValid = CheckTxBmiCounter(p_FmPort, counter);
54430 + break;
54431 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54432 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
54433 + p_Reg = &p_FmPort->port.bmi_regs->oh.fmbm_ostc;
54434 + isValid = CheckOhBmiCounter(p_FmPort, counter);
54435 + break;
54436 + default:
54437 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Unsupported port type"));
54438 + }
54439 +
54440 + if (!isValid)
54441 + RETURN_ERROR(MINOR, E_INVALID_STATE,
54442 + ("Requested counter is not available for this port type"));
54443 +
54444 + /* check that counters are enabled */
54445 + switch (counter)
54446 + {
54447 + case (e_FM_PORT_COUNTERS_CYCLE):
54448 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54449 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
54450 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54451 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54452 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
54453 + /* performance counters - may be read when disabled */
54454 + *p_IsStats = FALSE;
54455 + break;
54456 + case (e_FM_PORT_COUNTERS_FRAME):
54457 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54458 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54459 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
54460 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
54461 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
54462 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
54463 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
54464 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
54465 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
54466 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
54467 + *p_IsStats = TRUE;
54468 + if (!(GET_UINT32(*p_Reg) & BMI_COUNTERS_EN))
54469 + RETURN_ERROR(MINOR, E_INVALID_STATE,
54470 + ("Requested counter was not enabled"));
54471 + break;
54472 + default:
54473 + break;
54474 + }
54475 +
54476 + /* Set counter */
54477 + switch (counter)
54478 + {
54479 + case (e_FM_PORT_COUNTERS_CYCLE):
54480 + *p_PerfType = E_FMAN_PORT_PERF_CNT_CYCLE;
54481 + break;
54482 + case (e_FM_PORT_COUNTERS_TASK_UTIL):
54483 + *p_PerfType = E_FMAN_PORT_PERF_CNT_TASK_UTIL;
54484 + break;
54485 + case (e_FM_PORT_COUNTERS_QUEUE_UTIL):
54486 + *p_PerfType = E_FMAN_PORT_PERF_CNT_QUEUE_UTIL;
54487 + break;
54488 + case (e_FM_PORT_COUNTERS_DMA_UTIL):
54489 + *p_PerfType = E_FMAN_PORT_PERF_CNT_DMA_UTIL;
54490 + break;
54491 + case (e_FM_PORT_COUNTERS_FIFO_UTIL):
54492 + *p_PerfType = E_FMAN_PORT_PERF_CNT_FIFO_UTIL;
54493 + break;
54494 + case (e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION):
54495 + *p_PerfType = E_FMAN_PORT_PERF_CNT_RX_PAUSE;
54496 + break;
54497 + case (e_FM_PORT_COUNTERS_FRAME):
54498 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FRAME;
54499 + break;
54500 + case (e_FM_PORT_COUNTERS_DISCARD_FRAME):
54501 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DISCARD;
54502 + break;
54503 + case (e_FM_PORT_COUNTERS_DEALLOC_BUF):
54504 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DEALLOC_BUF;
54505 + break;
54506 + case (e_FM_PORT_COUNTERS_RX_BAD_FRAME):
54507 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME;
54508 + break;
54509 + case (e_FM_PORT_COUNTERS_RX_LARGE_FRAME):
54510 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME;
54511 + break;
54512 + case (e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD):
54513 + *p_StatsType = E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF;
54514 + break;
54515 + case (e_FM_PORT_COUNTERS_RX_FILTER_FRAME):
54516 + *p_StatsType = E_FMAN_PORT_STATS_CNT_FILTERED_FRAME;
54517 + break;
54518 + case (e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR):
54519 + *p_StatsType = E_FMAN_PORT_STATS_CNT_DMA_ERR;
54520 + break;
54521 + case (e_FM_PORT_COUNTERS_WRED_DISCARD):
54522 + *p_StatsType = E_FMAN_PORT_STATS_CNT_WRED_DISCARD;
54523 + break;
54524 + case (e_FM_PORT_COUNTERS_LENGTH_ERR):
54525 + *p_StatsType = E_FMAN_PORT_STATS_CNT_LEN_ERR;
54526 + break;
54527 + case (e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT):
54528 + *p_StatsType = E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT;
54529 + break;
54530 + default:
54531 + break;
54532 + }
54533 +
54534 + return E_OK;
54535 +}
54536 +
54537 +static t_Error AdditionalPrsParams(t_FmPort *p_FmPort,
54538 + t_FmPcdPrsAdditionalHdrParams *p_HdrParams,
54539 + uint32_t *p_SoftSeqAttachReg)
54540 +{
54541 + uint8_t hdrNum, Ipv4HdrNum;
54542 + u_FmPcdHdrPrsOpts *p_prsOpts;
54543 + uint32_t tmpReg = *p_SoftSeqAttachReg, tmpPrsOffset;
54544 +
54545 + if (IS_PRIVATE_HEADER(p_HdrParams->hdr)
54546 + || IS_SPECIAL_HEADER(p_HdrParams->hdr))
54547 + RETURN_ERROR(
54548 + MAJOR, E_NOT_SUPPORTED,
54549 + ("No additional parameters for private or special headers."));
54550 +
54551 + if (p_HdrParams->errDisable)
54552 + tmpReg |= PRS_HDR_ERROR_DIS;
54553 +
54554 + /* Set parser options */
54555 + if (p_HdrParams->usePrsOpts)
54556 + {
54557 + p_prsOpts = &p_HdrParams->prsOpts;
54558 + switch (p_HdrParams->hdr)
54559 + {
54560 + case (HEADER_TYPE_MPLS):
54561 + if (p_prsOpts->mplsPrsOptions.labelInterpretationEnable)
54562 + tmpReg |= PRS_HDR_MPLS_LBL_INTER_EN;
54563 + hdrNum = GetPrsHdrNum(p_prsOpts->mplsPrsOptions.nextParse);
54564 + if (hdrNum == ILLEGAL_HDR_NUM)
54565 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
54566 + Ipv4HdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
54567 + if (hdrNum < Ipv4HdrNum)
54568 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
54569 + ("Header must be equal or higher than IPv4"));
54570 + tmpReg |= ((uint32_t)hdrNum * PRS_HDR_ENTRY_SIZE)
54571 + << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
54572 + break;
54573 + case (HEADER_TYPE_PPPoE):
54574 + if (p_prsOpts->pppoePrsOptions.enableMTUCheck)
54575 + tmpReg |= PRS_HDR_PPPOE_MTU_CHECK_EN;
54576 + break;
54577 + case (HEADER_TYPE_IPv6):
54578 + if (p_prsOpts->ipv6PrsOptions.routingHdrEnable)
54579 + tmpReg |= PRS_HDR_IPV6_ROUTE_HDR_EN;
54580 + break;
54581 + case (HEADER_TYPE_TCP):
54582 + if (p_prsOpts->tcpPrsOptions.padIgnoreChecksum)
54583 + tmpReg |= PRS_HDR_TCP_PAD_REMOVAL;
54584 + else
54585 + tmpReg &= ~PRS_HDR_TCP_PAD_REMOVAL;
54586 + break;
54587 + case (HEADER_TYPE_UDP):
54588 + if (p_prsOpts->udpPrsOptions.padIgnoreChecksum)
54589 + tmpReg |= PRS_HDR_UDP_PAD_REMOVAL;
54590 + else
54591 + tmpReg &= ~PRS_HDR_UDP_PAD_REMOVAL;
54592 + break;
54593 + default:
54594 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid header"));
54595 + }
54596 + }
54597 +
54598 + /* set software parsing (address is divided in 2 since parser uses 2 byte access. */
54599 + if (p_HdrParams->swPrsEnable)
54600 + {
54601 + tmpPrsOffset = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, p_HdrParams->hdr,
54602 + p_HdrParams->indexPerHdr);
54603 + if (tmpPrsOffset == ILLEGAL_BASE)
54604 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
54605 + tmpReg |= (PRS_HDR_SW_PRS_EN | tmpPrsOffset);
54606 + }
54607 + *p_SoftSeqAttachReg = tmpReg;
54608 +
54609 + return E_OK;
54610 +}
54611 +
54612 +static uint32_t GetPortSchemeBindParams(
54613 + t_Handle h_FmPort, t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind)
54614 +{
54615 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54616 + uint32_t walking1Mask = 0x80000000, tmp;
54617 + uint8_t idx = 0;
54618 +
54619 + p_SchemeBind->netEnvId = p_FmPort->netEnvId;
54620 + p_SchemeBind->hardwarePortId = p_FmPort->hardwarePortId;
54621 + p_SchemeBind->useClsPlan = p_FmPort->useClsPlan;
54622 + p_SchemeBind->numOfSchemes = 0;
54623 + tmp = p_FmPort->schemesPerPortVector;
54624 + if (tmp)
54625 + {
54626 + while (tmp)
54627 + {
54628 + if (tmp & walking1Mask)
54629 + {
54630 + p_SchemeBind->schemesIds[p_SchemeBind->numOfSchemes] = idx;
54631 + p_SchemeBind->numOfSchemes++;
54632 + tmp &= ~walking1Mask;
54633 + }
54634 + walking1Mask >>= 1;
54635 + idx++;
54636 + }
54637 + }
54638 +
54639 + return tmp;
54640 +}
54641 +
54642 +static void FmPortCheckNApplyMacsec(t_Handle h_FmPort)
54643 +{
54644 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
54645 + volatile uint32_t *p_BmiCfgReg = NULL;
54646 + uint32_t macsecEn = BMI_PORT_CFG_EN_MACSEC;
54647 + uint32_t lcv, walking1Mask = 0x80000000;
54648 + uint8_t cnt = 0;
54649 +
54650 + ASSERT_COND(p_FmPort);
54651 + ASSERT_COND(p_FmPort->h_FmPcd);
54652 + ASSERT_COND(!p_FmPort->p_FmPortDriverParam);
54653 +
54654 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54655 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
54656 + return;
54657 +
54658 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->rx.fmbm_rcfg;
54659 + /* get LCV for MACSEC */
54660 + if ((lcv = FmPcdGetMacsecLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId))
54661 + != 0)
54662 + {
54663 + while (!(lcv & walking1Mask))
54664 + {
54665 + cnt++;
54666 + walking1Mask >>= 1;
54667 + }
54668 +
54669 + macsecEn |= (uint32_t)cnt << BMI_PORT_CFG_MS_SEL_SHIFT;
54670 + WRITE_UINT32(*p_BmiCfgReg, GET_UINT32(*p_BmiCfgReg) | macsecEn);
54671 + }
54672 +}
54673 +
54674 +static t_Error SetPcd(t_FmPort *p_FmPort, t_FmPortPcdParams *p_PcdParams)
54675 +{
54676 + t_Error err = E_OK;
54677 + uint32_t tmpReg;
54678 + volatile uint32_t *p_BmiNia = NULL;
54679 + volatile uint32_t *p_BmiPrsNia = NULL;
54680 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
54681 + volatile uint32_t *p_BmiInitPrsResult = NULL;
54682 + volatile uint32_t *p_BmiCcBase = NULL;
54683 + uint16_t hdrNum, L3HdrNum, greHdrNum;
54684 + int i;
54685 + bool isEmptyClsPlanGrp;
54686 + uint32_t tmpHxs[FM_PCD_PRS_NUM_OF_HDRS];
54687 + uint16_t absoluteProfileId;
54688 + uint8_t physicalSchemeId;
54689 + uint32_t ccTreePhysOffset;
54690 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
54691 + uint32_t initialSwPrs = 0;
54692 +
54693 + ASSERT_COND(p_FmPort);
54694 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
54695 +
54696 + if (p_FmPort->imEn)
54697 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54698 + ("available for non-independant mode ports only"));
54699 +
54700 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
54701 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
54702 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
54703 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
54704 + ("available for Rx and offline parsing ports only"));
54705 +
54706 + p_FmPort->netEnvId = FmPcdGetNetEnvId(p_PcdParams->h_NetEnv);
54707 +
54708 + p_FmPort->pcdEngines = 0;
54709 +
54710 + /* initialize p_FmPort->pcdEngines field in port's structure */
54711 + switch (p_PcdParams->pcdSupport)
54712 + {
54713 + case (e_FM_PORT_PCD_SUPPORT_NONE):
54714 + RETURN_ERROR(
54715 + MAJOR,
54716 + E_INVALID_STATE,
54717 + ("No PCD configuration required if e_FM_PORT_PCD_SUPPORT_NONE selected"));
54718 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
54719 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54720 + break;
54721 + case (e_FM_PORT_PCD_SUPPORT_PLCR_ONLY):
54722 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54723 + break;
54724 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
54725 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54726 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54727 + break;
54728 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
54729 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54730 + p_FmPort->pcdEngines |= FM_PCD_KG;
54731 + break;
54732 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
54733 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54734 + p_FmPort->pcdEngines |= FM_PCD_CC;
54735 + p_FmPort->pcdEngines |= FM_PCD_KG;
54736 + break;
54737 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
54738 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54739 + p_FmPort->pcdEngines |= FM_PCD_KG;
54740 + p_FmPort->pcdEngines |= FM_PCD_CC;
54741 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54742 + break;
54743 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
54744 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54745 + p_FmPort->pcdEngines |= FM_PCD_CC;
54746 + break;
54747 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
54748 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54749 + p_FmPort->pcdEngines |= FM_PCD_CC;
54750 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54751 + break;
54752 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
54753 + p_FmPort->pcdEngines |= FM_PCD_PRS;
54754 + p_FmPort->pcdEngines |= FM_PCD_KG;
54755 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54756 + break;
54757 + case (e_FM_PORT_PCD_SUPPORT_CC_ONLY):
54758 + p_FmPort->pcdEngines |= FM_PCD_CC;
54759 + break;
54760 +#ifdef FM_CAPWAP_SUPPORT
54761 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG):
54762 + p_FmPort->pcdEngines |= FM_PCD_CC;
54763 + p_FmPort->pcdEngines |= FM_PCD_KG;
54764 + break;
54765 + case (e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR):
54766 + p_FmPort->pcdEngines |= FM_PCD_CC;
54767 + p_FmPort->pcdEngines |= FM_PCD_KG;
54768 + p_FmPort->pcdEngines |= FM_PCD_PLCR;
54769 + break;
54770 +#endif /* FM_CAPWAP_SUPPORT */
54771 +
54772 + default:
54773 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("invalid pcdSupport"));
54774 + }
54775 +
54776 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
54777 + && (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams
54778 + > FM_PCD_PRS_NUM_OF_HDRS))
54779 + RETURN_ERROR(
54780 + MAJOR,
54781 + E_INVALID_VALUE,
54782 + ("Port parser numOfHdrsWithAdditionalParams may not exceed %d", FM_PCD_PRS_NUM_OF_HDRS));
54783 +
54784 + /* check that parameters exist for each and only each defined engine */
54785 + if ((!!(p_FmPort->pcdEngines & FM_PCD_PRS) != !!p_PcdParams->p_PrsParams)
54786 + || (!!(p_FmPort->pcdEngines & FM_PCD_KG)
54787 + != !!p_PcdParams->p_KgParams)
54788 + || (!!(p_FmPort->pcdEngines & FM_PCD_CC)
54789 + != !!p_PcdParams->p_CcParams))
54790 + RETURN_ERROR(
54791 + MAJOR,
54792 + E_INVALID_STATE,
54793 + ("PCD initialization structure is not consistent with pcdSupport"));
54794 +
54795 + /* get PCD registers pointers */
54796 + switch (p_FmPort->portType)
54797 + {
54798 + case (e_FM_PORT_TYPE_RX_10G):
54799 + case (e_FM_PORT_TYPE_RX):
54800 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
54801 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
54802 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
54803 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->rx.fmbm_rprai[0];
54804 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
54805 + break;
54806 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
54807 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
54808 + p_BmiPrsNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
54809 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
54810 + p_BmiInitPrsResult = &p_FmPort->port.bmi_regs->oh.fmbm_oprai[0];
54811 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
54812 + break;
54813 + default:
54814 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
54815 + }
54816 +
54817 + /* set PCD port parameter */
54818 + if (p_FmPort->pcdEngines & FM_PCD_CC)
54819 + {
54820 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, p_PcdParams,
54821 + p_PcdParams->p_CcParams->h_CcTree,
54822 + &ccTreePhysOffset, p_FmPort);
54823 + if (err)
54824 + RETURN_ERROR(MAJOR, err, NO_MSG);
54825 +
54826 + WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
54827 + p_FmPort->ccTreeId = p_PcdParams->p_CcParams->h_CcTree;
54828 + }
54829 +
54830 + if (p_FmPort->pcdEngines & FM_PCD_KG)
54831 + {
54832 + if (p_PcdParams->p_KgParams->numOfSchemes == 0)
54833 + RETURN_ERROR(
54834 + MAJOR,
54835 + E_INVALID_VALUE,
54836 + ("For ports using Keygen, at least one scheme must be bound. "));
54837 +
54838 + err = FmPcdKgSetOrBindToClsPlanGrp(p_FmPort->h_FmPcd,
54839 + p_FmPort->hardwarePortId,
54840 + p_FmPort->netEnvId,
54841 + p_FmPort->optArray,
54842 + &p_FmPort->clsPlanGrpId,
54843 + &isEmptyClsPlanGrp);
54844 + if (err)
54845 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
54846 + ("FmPcdKgSetOrBindToClsPlanGrp failed. "));
54847 +
54848 + p_FmPort->useClsPlan = !isEmptyClsPlanGrp;
54849 +
54850 + schemeBind.netEnvId = p_FmPort->netEnvId;
54851 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
54852 + schemeBind.numOfSchemes = p_PcdParams->p_KgParams->numOfSchemes;
54853 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
54854 +
54855 + /* for each scheme */
54856 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
54857 + {
54858 + ASSERT_COND(p_PcdParams->p_KgParams->h_Schemes[i]);
54859 + physicalSchemeId = FmPcdKgGetSchemeId(
54860 + p_PcdParams->p_KgParams->h_Schemes[i]);
54861 + schemeBind.schemesIds[i] = physicalSchemeId;
54862 + /* build vector */
54863 + p_FmPort->schemesPerPortVector |= 1
54864 + << (31 - (uint32_t)physicalSchemeId);
54865 +#if (DPAA_VERSION >= 11)
54866 + /*because of the state that VSPE is defined per port - all PCD path should be according to this requirement
54867 + if !VSPE - in port, for relevant scheme VSPE can not be set*/
54868 + if (!p_FmPort->vspe
54869 + && FmPcdKgGetVspe((p_PcdParams->p_KgParams->h_Schemes[i])))
54870 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
54871 + ("VSPE is not at port level"));
54872 +#endif /* (DPAA_VERSION >= 11) */
54873 + }
54874 +
54875 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
54876 + if (err)
54877 + RETURN_ERROR(MAJOR, err, NO_MSG);
54878 + }
54879 +
54880 + /***************************/
54881 + /* configure NIA after BMI */
54882 + /***************************/
54883 + /* rfne may contain FDCS bits, so first we read them. */
54884 + p_FmPort->savedBmiNia = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
54885 +
54886 + /* If policer is used directly after BMI or PRS */
54887 + if ((p_FmPort->pcdEngines & FM_PCD_PLCR)
54888 + && ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PLCR_ONLY)
54889 + || (p_PcdParams->pcdSupport
54890 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR)))
54891 + {
54892 + if (!p_PcdParams->p_PlcrParams->h_Profile)
54893 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
54894 + ("Profile should be initialized"));
54895 +
54896 + absoluteProfileId = (uint16_t)FmPcdPlcrProfileGetAbsoluteId(
54897 + p_PcdParams->p_PlcrParams->h_Profile);
54898 +
54899 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
54900 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
54901 + ("Private port profile not valid."));
54902 +
54903 + tmpReg = (uint32_t)(absoluteProfileId | NIA_PLCR_ABSOLUTE);
54904 +
54905 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
54906 + /* update BMI HPNIA */
54907 + WRITE_UINT32(*p_BmiPrsNia, (uint32_t)(NIA_ENG_PLCR | tmpReg));
54908 + else
54909 + /* e_FM_PCD_SUPPORT_PLCR_ONLY */
54910 + /* update BMI NIA */
54911 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PLCR);
54912 + }
54913 +
54914 + /* if CC is used directly after BMI */
54915 + if ((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_ONLY)
54916 +#ifdef FM_CAPWAP_SUPPORT
54917 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG)
54918 + || (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR)
54919 +#endif /* FM_CAPWAP_SUPPORT */
54920 + )
54921 + {
54922 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
54923 + RETURN_ERROR(
54924 + MAJOR,
54925 + E_INVALID_OPERATION,
54926 + ("e_FM_PORT_PCD_SUPPORT_CC_xx available for offline parsing ports only"));
54927 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC);
54928 + /* check that prs start offset == RIM[FOF] */
54929 + }
54930 +
54931 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
54932 + {
54933 + ASSERT_COND(p_PcdParams->p_PrsParams);
54934 +#if (DPAA_VERSION >= 11)
54935 + if (p_PcdParams->p_PrsParams->firstPrsHdr == HEADER_TYPE_CAPWAP)
54936 + hdrNum = OFFLOAD_SW_PATCH_CAPWAP_LABEL;
54937 + else
54938 + {
54939 +#endif /* (DPAA_VERSION >= 11) */
54940 + /* if PRS is used it is always first */
54941 + hdrNum = GetPrsHdrNum(p_PcdParams->p_PrsParams->firstPrsHdr);
54942 + if (hdrNum == ILLEGAL_HDR_NUM)
54943 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unsupported header."));
54944 +#if (DPAA_VERSION >= 11)
54945 + }
54946 +#endif /* (DPAA_VERSION >= 11) */
54947 + p_FmPort->savedBmiNia |= (uint32_t)(NIA_ENG_PRS | (uint32_t)(hdrNum));
54948 + /* set after parser NIA */
54949 + tmpReg = 0;
54950 + switch (p_PcdParams->pcdSupport)
54951 + {
54952 + case (e_FM_PORT_PCD_SUPPORT_PRS_ONLY):
54953 + WRITE_UINT32(*p_BmiPrsNia,
54954 + GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd));
54955 + break;
54956 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC):
54957 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR):
54958 + tmpReg = NIA_KG_CC_EN;
54959 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG):
54960 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR):
54961 + if (p_PcdParams->p_KgParams->directScheme)
54962 + {
54963 + physicalSchemeId = FmPcdKgGetSchemeId(
54964 + p_PcdParams->p_KgParams->h_DirectScheme);
54965 + /* check that this scheme was bound to this port */
54966 + for (i = 0; i < p_PcdParams->p_KgParams->numOfSchemes; i++)
54967 + if (p_PcdParams->p_KgParams->h_DirectScheme
54968 + == p_PcdParams->p_KgParams->h_Schemes[i])
54969 + break;
54970 + if (i == p_PcdParams->p_KgParams->numOfSchemes)
54971 + RETURN_ERROR(
54972 + MAJOR,
54973 + E_INVALID_VALUE,
54974 + ("Direct scheme is not one of the port selected schemes."));
54975 + tmpReg |= (uint32_t)(NIA_KG_DIRECT | physicalSchemeId);
54976 + }
54977 + WRITE_UINT32(*p_BmiPrsNia, NIA_ENG_KG | tmpReg);
54978 + break;
54979 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC):
54980 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR):
54981 + WRITE_UINT32(*p_BmiPrsNia,
54982 + (uint32_t)(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_CC));
54983 + break;
54984 + case (e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR):
54985 + break;
54986 + default:
54987 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid PCD support"));
54988 + }
54989 +
54990 + /* set start parsing offset */
54991 + WRITE_UINT32(*p_BmiPrsStartOffset,
54992 + p_PcdParams->p_PrsParams->parsingOffset);
54993 +
54994 + /************************************/
54995 + /* Parser port parameters */
54996 + /************************************/
54997 + /* stop before configuring */
54998 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
54999 + /* wait for parser to be in idle state */
55000 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
55001 + ;
55002 +
55003 + /* set soft seq attachment register */
55004 + memset(tmpHxs, 0, FM_PCD_PRS_NUM_OF_HDRS * sizeof(uint32_t));
55005 +
55006 + /* set protocol options */
55007 + for (i = 0; p_FmPort->optArray[i]; i++)
55008 + switch (p_FmPort->optArray[i])
55009 + {
55010 + case (ETH_BROADCAST):
55011 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
55012 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_BC_SHIFT;
55013 + break;
55014 + case (ETH_MULTICAST):
55015 + hdrNum = GetPrsHdrNum(HEADER_TYPE_ETH);
55016 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_ETH_MC_SHIFT;
55017 + break;
55018 + case (VLAN_STACKED):
55019 + hdrNum = GetPrsHdrNum(HEADER_TYPE_VLAN);
55020 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_VLAN_STACKED_SHIFT;
55021 + break;
55022 + case (MPLS_STACKED):
55023 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
55024 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_MPLS_STACKED_SHIFT;
55025 + break;
55026 + case (IPV4_BROADCAST_1):
55027 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
55028 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_BC_SHIFT;
55029 + break;
55030 + case (IPV4_MULTICAST_1):
55031 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
55032 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_1_MC_SHIFT;
55033 + break;
55034 + case (IPV4_UNICAST_2):
55035 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
55036 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_UC_SHIFT;
55037 + break;
55038 + case (IPV4_MULTICAST_BROADCAST_2):
55039 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
55040 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV4_2_MC_BC_SHIFT;
55041 + break;
55042 + case (IPV6_MULTICAST_1):
55043 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
55044 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_1_MC_SHIFT;
55045 + break;
55046 + case (IPV6_UNICAST_2):
55047 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
55048 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_UC_SHIFT;
55049 + break;
55050 + case (IPV6_MULTICAST_2):
55051 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
55052 + tmpHxs[hdrNum] |= (i + 1) << PRS_HDR_IPV6_2_MC_SHIFT;
55053 + break;
55054 + }
55055 +
55056 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
55057 + HEADER_TYPE_UDP_ENCAP_ESP))
55058 + {
55059 + if (p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams == FM_PCD_PRS_NUM_OF_HDRS)
55060 + RETURN_ERROR(
55061 + MINOR, E_INVALID_VALUE,
55062 + ("If HEADER_TYPE_UDP_ENCAP_ESP is used, numOfHdrsWithAdditionalParams may be up to FM_PCD_PRS_NUM_OF_HDRS - 1"));
55063 +
55064 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].hdr =
55065 + HEADER_TYPE_UDP;
55066 + p_PcdParams->p_PrsParams->additionalParams[p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams].swPrsEnable =
55067 + TRUE;
55068 + p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams++;
55069 + }
55070 +
55071 + /* set MPLS default next header - HW reset workaround */
55072 + hdrNum = GetPrsHdrNum(HEADER_TYPE_MPLS);
55073 + tmpHxs[hdrNum] |= PRS_HDR_MPLS_LBL_INTER_EN;
55074 + L3HdrNum = GetPrsHdrNum(HEADER_TYPE_USER_DEFINED_L3);
55075 + tmpHxs[hdrNum] |= (uint32_t)L3HdrNum << PRS_HDR_MPLS_NEXT_HDR_SHIFT;
55076 +
55077 + /* for GRE, disable errors */
55078 + greHdrNum = GetPrsHdrNum(HEADER_TYPE_GRE);
55079 + tmpHxs[greHdrNum] |= PRS_HDR_ERROR_DIS;
55080 +
55081 + /* For UDP remove PAD from L4 checksum calculation */
55082 + hdrNum = GetPrsHdrNum(HEADER_TYPE_UDP);
55083 + tmpHxs[hdrNum] |= PRS_HDR_UDP_PAD_REMOVAL;
55084 + /* For TCP remove PAD from L4 checksum calculation */
55085 + hdrNum = GetPrsHdrNum(HEADER_TYPE_TCP);
55086 + tmpHxs[hdrNum] |= PRS_HDR_TCP_PAD_REMOVAL;
55087 +
55088 + /* config additional params for specific headers */
55089 + for (i = 0; i < p_PcdParams->p_PrsParams->numOfHdrsWithAdditionalParams;
55090 + i++)
55091 + {
55092 + /* case for using sw parser as the initial NIA address, before
55093 + * HW parsing
55094 + */
55095 + if ((p_PcdParams->p_PrsParams->additionalParams[i].hdr == HEADER_TYPE_NONE) &&
55096 + p_PcdParams->p_PrsParams->additionalParams[i].swPrsEnable)
55097 + {
55098 + initialSwPrs = FmPcdGetSwPrsOffset(p_FmPort->h_FmPcd, HEADER_TYPE_NONE,
55099 + p_PcdParams->p_PrsParams->additionalParams[i].indexPerHdr);
55100 + if (initialSwPrs == ILLEGAL_BASE)
55101 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
55102 +
55103 + /* clear parser first HXS */
55104 + p_FmPort->savedBmiNia &= ~BMI_RFNE_HXS_MASK; /* 0x000000FF */
55105 + /* rewrite with soft parser start */
55106 + p_FmPort->savedBmiNia |= initialSwPrs;
55107 + continue;
55108 + }
55109 +
55110 + hdrNum =
55111 + GetPrsHdrNum(p_PcdParams->p_PrsParams->additionalParams[i].hdr);
55112 + if (hdrNum == ILLEGAL_HDR_NUM)
55113 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
55114 + if (hdrNum == NO_HDR_NUM)
55115 + RETURN_ERROR(
55116 + MAJOR, E_INVALID_VALUE,
55117 + ("Private headers may not use additional parameters"));
55118 +
55119 + err = AdditionalPrsParams(
55120 + p_FmPort, &p_PcdParams->p_PrsParams->additionalParams[i],
55121 + &tmpHxs[hdrNum]);
55122 + if (err)
55123 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
55124 + }
55125 +
55126 + /* Check if ip-reassembly port - need to link sw-parser code */
55127 + if (p_FmPort->h_IpReassemblyManip)
55128 + {
55129 + /* link to sw parser code for IP Frag - only if no other code is applied. */
55130 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv4);
55131 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
55132 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv4_IPR_LABEL);
55133 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
55134 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
55135 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPR_LABEL);
55136 + } else {
55137 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId, HEADER_TYPE_UDP_LITE))
55138 + {
55139 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
55140 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
55141 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
55142 + } else if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
55143 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)))
55144 + {
55145 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
55146 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
55147 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL);
55148 + }
55149 + }
55150 +
55151 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
55152 + if (FmPcdNetEnvIsHdrExist(p_FmPort->h_FmPcd, p_FmPort->netEnvId,
55153 + HEADER_TYPE_UDP_LITE))
55154 + {
55155 + /* link to sw parser code for udp lite - only if no other code is applied. */
55156 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
55157 + if (!(tmpHxs[hdrNum] & PRS_HDR_SW_PRS_EN))
55158 + tmpHxs[hdrNum] |= (PRS_HDR_SW_PRS_EN | UDP_LITE_SW_PATCH_LABEL);
55159 + }
55160 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
55161 + for (i = 0; i < FM_PCD_PRS_NUM_OF_HDRS; i++)
55162 + {
55163 + /* For all header set LCV as taken from netEnv*/
55164 + WRITE_UINT32(
55165 + p_FmPort->p_FmPortPrsRegs->hdrs[i].lcv,
55166 + FmPcdGetLcv(p_FmPort->h_FmPcd, p_FmPort->netEnvId, (uint8_t)i));
55167 + /* set HXS register according to default+Additional params+protocol options */
55168 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[i].softSeqAttach,
55169 + tmpHxs[i]);
55170 + }
55171 +
55172 + /* set tpid. */
55173 + tmpReg = PRS_TPID_DFLT;
55174 + if (p_PcdParams->p_PrsParams->setVlanTpid1)
55175 + {
55176 + tmpReg &= PRS_TPID2_MASK;
55177 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid1
55178 + << PRS_PCTPID_SHIFT;
55179 + }
55180 + if (p_PcdParams->p_PrsParams->setVlanTpid2)
55181 + {
55182 + tmpReg &= PRS_TPID1_MASK;
55183 + tmpReg |= (uint32_t)p_PcdParams->p_PrsParams->vlanTpid2;
55184 + }WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pctpid, tmpReg);
55185 +
55186 + /* enable parser */
55187 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, 0);
55188 +
55189 + if (p_PcdParams->p_PrsParams->prsResultPrivateInfo)
55190 + p_FmPort->privateInfo =
55191 + p_PcdParams->p_PrsParams->prsResultPrivateInfo;
55192 +
55193 + } /* end parser */
55194 + else {
55195 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)
55196 + && (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
55197 + {
55198 + hdrNum = GetPrsHdrNum(HEADER_TYPE_IPv6);
55199 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->hdrs[hdrNum].softSeqAttach,
55200 + (PRS_HDR_SW_PRS_EN | OFFLOAD_SW_PATCH_IPv6_IPF_LABEL));
55201 + }
55202 +
55203 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
55204 +
55205 + p_FmPort->privateInfo = 0;
55206 + }
55207 +
55208 + FmPortCheckNApplyMacsec(p_FmPort);
55209 +
55210 + WRITE_UINT32(
55211 + *p_BmiPrsStartOffset,
55212 + GET_UINT32(*p_BmiPrsStartOffset) + p_FmPort->internalBufferOffset);
55213 +
55214 + /* set initial parser result - used for all engines */
55215 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; i++)
55216 + {
55217 + if (!i)
55218 + WRITE_UINT32(
55219 + *(p_BmiInitPrsResult),
55220 + (uint32_t)(((uint32_t)p_FmPort->privateInfo << BMI_PR_PORTID_SHIFT) | BMI_PRS_RESULT_HIGH));
55221 + else
55222 + {
55223 + if (i < FM_PORT_PRS_RESULT_NUM_OF_WORDS / 2)
55224 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_HIGH);
55225 + else
55226 + WRITE_UINT32(*(p_BmiInitPrsResult+i), BMI_PRS_RESULT_LOW);
55227 + }
55228 + }
55229 +
55230 + return E_OK;
55231 +}
55232 +
55233 +static t_Error DeletePcd(t_FmPort *p_FmPort)
55234 +{
55235 + t_Error err = E_OK;
55236 + volatile uint32_t *p_BmiNia = NULL;
55237 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
55238 +
55239 + ASSERT_COND(p_FmPort);
55240 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55241 +
55242 + if (p_FmPort->imEn)
55243 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55244 + ("available for non-independant mode ports only"));
55245 +
55246 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
55247 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
55248 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
55249 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55250 + ("available for Rx and offline parsing ports only"));
55251 +
55252 + if (!p_FmPort->pcdEngines)
55253 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("called for non PCD port"));
55254 +
55255 + /* get PCD registers pointers */
55256 + switch (p_FmPort->portType)
55257 + {
55258 + case (e_FM_PORT_TYPE_RX_10G):
55259 + case (e_FM_PORT_TYPE_RX):
55260 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
55261 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
55262 + break;
55263 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55264 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
55265 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
55266 + break;
55267 + default:
55268 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55269 + }
55270 +
55271 + if ((GET_UINT32(*p_BmiNia) & GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
55272 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
55273 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
55274 + ("port has to be detached previousely"));
55275 +
55276 + WRITE_UINT32(*p_BmiPrsStartOffset, 0);
55277 +
55278 + /* "cut" PCD out of the port's flow - go to BMI */
55279 + /* WRITE_UINT32(*p_BmiNia, (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)); */
55280 +
55281 + if (p_FmPort->pcdEngines & FM_PCD_PRS)
55282 + {
55283 + /* stop parser */
55284 + WRITE_UINT32(p_FmPort->p_FmPortPrsRegs->pcac, PRS_CAC_STOP);
55285 + /* wait for parser to be in idle state */
55286 + while (GET_UINT32(p_FmPort->p_FmPortPrsRegs->pcac) & PRS_CAC_ACTIVE)
55287 + ;
55288 + }
55289 +
55290 + if (p_FmPort->pcdEngines & FM_PCD_KG)
55291 + {
55292 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
55293 +
55294 + /* unbind all schemes */
55295 + p_FmPort->schemesPerPortVector = GetPortSchemeBindParams(p_FmPort,
55296 + &schemeBind);
55297 +
55298 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
55299 + if (err)
55300 + RETURN_ERROR(MAJOR, err, NO_MSG);
55301 +
55302 + err = FmPcdKgDeleteOrUnbindPortToClsPlanGrp(p_FmPort->h_FmPcd,
55303 + p_FmPort->hardwarePortId,
55304 + p_FmPort->clsPlanGrpId);
55305 + if (err)
55306 + RETURN_ERROR(MAJOR, err, NO_MSG);
55307 + p_FmPort->useClsPlan = FALSE;
55308 + }
55309 +
55310 + if (p_FmPort->pcdEngines & FM_PCD_CC)
55311 + {
55312 + /* unbind - we need to get the treeId too */
55313 + err = FmPcdCcUnbindTree(p_FmPort->h_FmPcd, p_FmPort->ccTreeId);
55314 + if (err)
55315 + RETURN_ERROR(MAJOR, err, NO_MSG);
55316 + }
55317 +
55318 + p_FmPort->pcdEngines = 0;
55319 +
55320 + return E_OK;
55321 +}
55322 +
55323 +static t_Error AttachPCD(t_FmPort *p_FmPort)
55324 +{
55325 + volatile uint32_t *p_BmiNia = NULL;
55326 +
55327 + ASSERT_COND(p_FmPort);
55328 +
55329 + /* get PCD registers pointers */
55330 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55331 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
55332 + else
55333 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
55334 +
55335 + /* check that current NIA is BMI to BMI */
55336 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
55337 + != GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME())
55338 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
55339 + ("may be called only for ports in BMI-to-BMI state."));
55340 +
55341 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
55342 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 1,
55343 + p_FmPort->orFmanCtrl) != E_OK)
55344 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55345 +
55346 + if (p_FmPort->requiredAction & UPDATE_NIA_CMNE)
55347 + {
55348 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55349 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ocmne,
55350 + p_FmPort->savedBmiCmne);
55351 + else
55352 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcmne,
55353 + p_FmPort->savedBmiCmne);
55354 + }
55355 +
55356 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
55357 + WRITE_UINT32(p_FmPort->p_FmPortQmiRegs->fmqm_pnen,
55358 + p_FmPort->savedQmiPnen);
55359 +
55360 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
55361 + {
55362 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55363 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
55364 + p_FmPort->savedBmiFene);
55365 + else
55366 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
55367 + p_FmPort->savedBmiFene);
55368 + }
55369 +
55370 + if (p_FmPort->requiredAction & UPDATE_NIA_FPNE)
55371 + {
55372 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55373 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne,
55374 + p_FmPort->savedBmiFpne);
55375 + else
55376 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne,
55377 + p_FmPort->savedBmiFpne);
55378 + }
55379 +
55380 + if (p_FmPort->requiredAction & UPDATE_OFP_DPTE)
55381 + {
55382 + ASSERT_COND(p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING);
55383 +
55384 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp,
55385 + p_FmPort->savedBmiOfp);
55386 + }
55387 +
55388 + WRITE_UINT32(*p_BmiNia, p_FmPort->savedBmiNia);
55389 +
55390 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
55391 + {
55392 + p_FmPort->origNonRxQmiRegsPndn =
55393 + GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn);
55394 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
55395 + p_FmPort->savedNonRxQmiRegsPndn);
55396 + }
55397 +
55398 + return E_OK;
55399 +}
55400 +
55401 +static t_Error DetachPCD(t_FmPort *p_FmPort)
55402 +{
55403 + volatile uint32_t *p_BmiNia = NULL;
55404 +
55405 + ASSERT_COND(p_FmPort);
55406 +
55407 + /* get PCD registers pointers */
55408 + if (p_FmPort->requiredAction & UPDATE_NIA_PNDN)
55409 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pndn,
55410 + p_FmPort->origNonRxQmiRegsPndn);
55411 +
55412 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55413 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
55414 + else
55415 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
55416 +
55417 + WRITE_UINT32(
55418 + *p_BmiNia,
55419 + (p_FmPort->savedBmiNia & BMI_RFNE_FDCS_MASK) | GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME());
55420 +
55421 + if (FmPcdGetHcHandle(p_FmPort->h_FmPcd))
55422 + FmPcdHcSync(p_FmPort->h_FmPcd);
55423 +
55424 + if (p_FmPort->requiredAction & UPDATE_NIA_FENE)
55425 + {
55426 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55427 + WRITE_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofene,
55428 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
55429 + else
55430 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfene,
55431 + NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR);
55432 + }
55433 +
55434 + if (p_FmPort->requiredAction & UPDATE_NIA_PNEN)
55435 + WRITE_UINT32(p_FmPort->port.qmi_regs->fmqm_pnen,
55436 + NIA_ENG_BMI | NIA_BMI_AC_RELEASE);
55437 +
55438 + if (p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
55439 + if (FmSetNumOfRiscsPerPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId, 2,
55440 + p_FmPort->orFmanCtrl) != E_OK)
55441 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
55442 +
55443 + p_FmPort->requiredAction = 0;
55444 +
55445 + return E_OK;
55446 +}
55447 +
55448 +/*****************************************************************************/
55449 +/* Inter-module API routines */
55450 +/*****************************************************************************/
55451 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci)
55452 +{
55453 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55454 + volatile uint32_t *p_BmiCfgReg = NULL;
55455 + uint32_t tmpReg;
55456 +
55457 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
55458 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
55459 +
55460 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
55461 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
55462 + {
55463 + REPORT_ERROR(MAJOR, E_INVALID_OPERATION, ("The routine is relevant for Tx ports only"));
55464 + return;
55465 + }
55466 +
55467 + p_BmiCfgReg = &p_FmPort->port.bmi_regs->tx.fmbm_tfca;
55468 + tmpReg = GET_UINT32(*p_BmiCfgReg) & ~BMI_CMD_ATTR_MACCMD_MASK;
55469 + tmpReg |= BMI_CMD_ATTR_MACCMD_SECURED;
55470 + tmpReg |= (((uint32_t)dfltSci << BMI_CMD_ATTR_MACCMD_SC_SHIFT)
55471 + & BMI_CMD_ATTR_MACCMD_SC_MASK);
55472 +
55473 + WRITE_UINT32(*p_BmiCfgReg, tmpReg);
55474 +}
55475 +
55476 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort)
55477 +{
55478 + return ((t_FmPort*)h_FmPort)->netEnvId;
55479 +}
55480 +
55481 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort)
55482 +{
55483 + return ((t_FmPort*)h_FmPort)->hardwarePortId;
55484 +}
55485 +
55486 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort)
55487 +{
55488 + return ((t_FmPort*)h_FmPort)->pcdEngines;
55489 +}
55490 +
55491 +#if (DPAA_VERSION >= 11)
55492 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc,
55493 + void **p_Value)
55494 +{
55495 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55496 + uint32_t muramPageOffset;
55497 +
55498 + ASSERT_COND(p_FmPort);
55499 + ASSERT_COND(p_Value);
55500 +
55501 + if (p_FmPort->gprFunc != e_FM_PORT_GPR_EMPTY)
55502 + {
55503 + if (p_FmPort->gprFunc != gprFunc)
55504 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55505 + ("gpr was assigned with different func"));
55506 + }
55507 + else
55508 + {
55509 + switch (gprFunc)
55510 + {
55511 + case (e_FM_PORT_GPR_MURAM_PAGE):
55512 + p_FmPort->p_ParamsPage = FM_MURAM_AllocMem(p_FmPort->h_FmMuram,
55513 + 256, 8);
55514 + if (!p_FmPort->p_ParamsPage)
55515 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for page"));
55516 +
55517 + IOMemSet32(p_FmPort->p_ParamsPage, 0, 256);
55518 + muramPageOffset =
55519 + (uint32_t)(XX_VirtToPhys(p_FmPort->p_ParamsPage)
55520 + - p_FmPort->fmMuramPhysBaseAddr);
55521 + switch (p_FmPort->portType)
55522 + {
55523 + case (e_FM_PORT_TYPE_RX_10G):
55524 + case (e_FM_PORT_TYPE_RX):
55525 + WRITE_UINT32(
55526 + p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr,
55527 + muramPageOffset);
55528 + break;
55529 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55530 + WRITE_UINT32(
55531 + p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ogpr,
55532 + muramPageOffset);
55533 + break;
55534 + default:
55535 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55536 + ("Invalid port type"));
55537 + }
55538 + break;
55539 + default:
55540 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
55541 + }
55542 + p_FmPort->gprFunc = gprFunc;
55543 + }
55544 +
55545 + switch (p_FmPort->gprFunc)
55546 + {
55547 + case (e_FM_PORT_GPR_MURAM_PAGE):
55548 + *p_Value = p_FmPort->p_ParamsPage;
55549 + break;
55550 + default:
55551 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, NO_MSG);
55552 + }
55553 +
55554 + return E_OK;
55555 +}
55556 +#endif /* (DPAA_VERSION >= 11) */
55557 +
55558 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort,
55559 + t_FmPortGetSetCcParams *p_CcParams)
55560 +{
55561 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
55562 + int tmpInt;
55563 + volatile uint32_t *p_BmiPrsStartOffset = NULL;
55564 +
55565 + /* this function called from Cc for pass and receive parameters port params between CC and PORT*/
55566 +
55567 + if ((p_CcParams->getCcParams.type & OFFSET_OF_PR)
55568 + && (p_FmPort->bufferOffsets.prsResultOffset != ILLEGAL_BASE))
55569 + {
55570 + p_CcParams->getCcParams.prOffset =
55571 + (uint8_t)p_FmPort->bufferOffsets.prsResultOffset;
55572 + p_CcParams->getCcParams.type &= ~OFFSET_OF_PR;
55573 + }
55574 + if (p_CcParams->getCcParams.type & HW_PORT_ID)
55575 + {
55576 + p_CcParams->getCcParams.hardwarePortId =
55577 + (uint8_t)p_FmPort->hardwarePortId;
55578 + p_CcParams->getCcParams.type &= ~HW_PORT_ID;
55579 + }
55580 + if ((p_CcParams->getCcParams.type & OFFSET_OF_DATA)
55581 + && (p_FmPort->bufferOffsets.dataOffset != ILLEGAL_BASE))
55582 + {
55583 + p_CcParams->getCcParams.dataOffset =
55584 + (uint16_t)p_FmPort->bufferOffsets.dataOffset;
55585 + p_CcParams->getCcParams.type &= ~OFFSET_OF_DATA;
55586 + }
55587 + if (p_CcParams->getCcParams.type & NUM_OF_TASKS)
55588 + {
55589 + p_CcParams->getCcParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
55590 + p_CcParams->getCcParams.type &= ~NUM_OF_TASKS;
55591 + }
55592 + if (p_CcParams->getCcParams.type & NUM_OF_EXTRA_TASKS)
55593 + {
55594 + p_CcParams->getCcParams.numOfExtraTasks =
55595 + (uint8_t)p_FmPort->tasks.extra;
55596 + p_CcParams->getCcParams.type &= ~NUM_OF_EXTRA_TASKS;
55597 + }
55598 + if (p_CcParams->getCcParams.type & FM_REV)
55599 + {
55600 + p_CcParams->getCcParams.revInfo.majorRev = p_FmPort->fmRevInfo.majorRev;
55601 + p_CcParams->getCcParams.revInfo.minorRev = p_FmPort->fmRevInfo.minorRev;
55602 + p_CcParams->getCcParams.type &= ~FM_REV;
55603 + }
55604 + if (p_CcParams->getCcParams.type & DISCARD_MASK)
55605 + {
55606 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55607 + p_CcParams->getCcParams.discardMask =
55608 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm);
55609 + else
55610 + p_CcParams->getCcParams.discardMask =
55611 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm);
55612 + p_CcParams->getCcParams.type &= ~DISCARD_MASK;
55613 + }
55614 + if (p_CcParams->getCcParams.type & MANIP_EXTRA_SPACE)
55615 + {
55616 + p_CcParams->getCcParams.internalBufferOffset =
55617 + p_FmPort->internalBufferOffset;
55618 + p_CcParams->getCcParams.type &= ~MANIP_EXTRA_SPACE;
55619 + }
55620 + if (p_CcParams->getCcParams.type & GET_NIA_FPNE)
55621 + {
55622 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55623 + p_CcParams->getCcParams.nia =
55624 + GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofpne);
55625 + else
55626 + p_CcParams->getCcParams.nia =
55627 + GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rfpne);
55628 + p_CcParams->getCcParams.type &= ~GET_NIA_FPNE;
55629 + }
55630 + if (p_CcParams->getCcParams.type & GET_NIA_PNDN)
55631 + {
55632 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55633 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55634 + p_CcParams->getCcParams.nia =
55635 + GET_UINT32(p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn);
55636 + p_CcParams->getCcParams.type &= ~GET_NIA_PNDN;
55637 + }
55638 +
55639 + if ((p_CcParams->setCcParams.type & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY)
55640 + && !(p_FmPort->requiredAction & UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY))
55641 + {
55642 + p_FmPort->requiredAction |= UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY;
55643 + p_FmPort->orFmanCtrl = p_CcParams->setCcParams.orFmanCtrl;
55644 + }
55645 +
55646 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
55647 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNEN))
55648 + {
55649 + p_FmPort->savedQmiPnen = p_CcParams->setCcParams.nia;
55650 + p_FmPort->requiredAction |= UPDATE_NIA_PNEN;
55651 + }
55652 + else
55653 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNEN)
55654 + {
55655 + if (p_FmPort->savedQmiPnen != p_CcParams->setCcParams.nia)
55656 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55657 + ("PNEN was defined previously different"));
55658 + }
55659 +
55660 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
55661 + && !(p_FmPort->requiredAction & UPDATE_NIA_PNDN))
55662 + {
55663 + p_FmPort->savedNonRxQmiRegsPndn = p_CcParams->setCcParams.nia;
55664 + p_FmPort->requiredAction |= UPDATE_NIA_PNDN;
55665 + }
55666 + else
55667 + if (p_CcParams->setCcParams.type & UPDATE_NIA_PNDN)
55668 + {
55669 + if (p_FmPort->savedNonRxQmiRegsPndn != p_CcParams->setCcParams.nia)
55670 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
55671 + ("PNDN was defined previously different"));
55672 + }
55673 +
55674 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
55675 + && (p_CcParams->setCcParams.overwrite
55676 + || !(p_FmPort->requiredAction & UPDATE_NIA_FENE)))
55677 + {
55678 + p_FmPort->savedBmiFene = p_CcParams->setCcParams.nia;
55679 + p_FmPort->requiredAction |= UPDATE_NIA_FENE;
55680 + }
55681 + else
55682 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FENE)
55683 + {
55684 + if (p_FmPort->savedBmiFene != p_CcParams->setCcParams.nia)
55685 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
55686 + ("xFENE was defined previously different"));
55687 + }
55688 +
55689 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
55690 + && !(p_FmPort->requiredAction & UPDATE_NIA_FPNE))
55691 + {
55692 + p_FmPort->savedBmiFpne = p_CcParams->setCcParams.nia;
55693 + p_FmPort->requiredAction |= UPDATE_NIA_FPNE;
55694 + }
55695 + else
55696 + if (p_CcParams->setCcParams.type & UPDATE_NIA_FPNE)
55697 + {
55698 + if (p_FmPort->savedBmiFpne != p_CcParams->setCcParams.nia)
55699 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
55700 + ("xFPNE was defined previously different"));
55701 + }
55702 +
55703 + if ((p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
55704 + && !(p_FmPort->requiredAction & UPDATE_NIA_CMNE))
55705 + {
55706 + p_FmPort->savedBmiCmne = p_CcParams->setCcParams.nia;
55707 + p_FmPort->requiredAction |= UPDATE_NIA_CMNE;
55708 + }
55709 + else
55710 + if (p_CcParams->setCcParams.type & UPDATE_NIA_CMNE)
55711 + {
55712 + if (p_FmPort->savedBmiCmne != p_CcParams->setCcParams.nia)
55713 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
55714 + ("xCMNE was defined previously different"));
55715 + }
55716 +
55717 + if ((p_CcParams->setCcParams.type & UPDATE_PSO)
55718 + && !(p_FmPort->requiredAction & UPDATE_PSO))
55719 + {
55720 + /* get PCD registers pointers */
55721 + switch (p_FmPort->portType)
55722 + {
55723 + case (e_FM_PORT_TYPE_RX_10G):
55724 + case (e_FM_PORT_TYPE_RX):
55725 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->rx.fmbm_rpso;
55726 + break;
55727 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55728 + p_BmiPrsStartOffset = &p_FmPort->port.bmi_regs->oh.fmbm_opso;
55729 + break;
55730 + default:
55731 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55732 + }
55733 +
55734 + /* set start parsing offset */
55735 + tmpInt = (int)GET_UINT32(*p_BmiPrsStartOffset)
55736 + + p_CcParams->setCcParams.psoSize;
55737 + if (tmpInt > 0)
55738 + WRITE_UINT32(*p_BmiPrsStartOffset, (uint32_t)tmpInt);
55739 +
55740 + p_FmPort->requiredAction |= UPDATE_PSO;
55741 + p_FmPort->savedPrsStartOffset = p_CcParams->setCcParams.psoSize;
55742 + }
55743 + else
55744 + if (p_CcParams->setCcParams.type & UPDATE_PSO)
55745 + {
55746 + if (p_FmPort->savedPrsStartOffset
55747 + != p_CcParams->setCcParams.psoSize)
55748 + RETURN_ERROR(
55749 + MAJOR,
55750 + E_INVALID_STATE,
55751 + ("parser start offset was defoned previousley different"));
55752 + }
55753 +
55754 + if ((p_CcParams->setCcParams.type & UPDATE_OFP_DPTE)
55755 + && !(p_FmPort->requiredAction & UPDATE_OFP_DPTE))
55756 + {
55757 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55758 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
55759 + p_FmPort->savedBmiOfp = GET_UINT32(p_FmPort->port.bmi_regs->oh.fmbm_ofp);
55760 + p_FmPort->savedBmiOfp &= ~BMI_FIFO_PIPELINE_DEPTH_MASK;
55761 + p_FmPort->savedBmiOfp |= p_CcParams->setCcParams.ofpDpde
55762 + << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
55763 + p_FmPort->requiredAction |= UPDATE_OFP_DPTE;
55764 + }
55765 +
55766 + return E_OK;
55767 +}
55768 +/*********************** End of inter-module routines ************************/
55769 +
55770 +/****************************************/
55771 +/* API Init unit functions */
55772 +/****************************************/
55773 +
55774 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams)
55775 +{
55776 + t_FmPort *p_FmPort;
55777 + uintptr_t baseAddr = p_FmPortParams->baseAddr;
55778 + uint32_t tmpReg;
55779 +
55780 + /* Allocate FM structure */
55781 + p_FmPort = (t_FmPort *)XX_Malloc(sizeof(t_FmPort));
55782 + if (!p_FmPort)
55783 + {
55784 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver structure"));
55785 + return NULL;
55786 + }
55787 + memset(p_FmPort, 0, sizeof(t_FmPort));
55788 +
55789 + /* Allocate the FM driver's parameters structure */
55790 + p_FmPort->p_FmPortDriverParam = (t_FmPortDriverParam *)XX_Malloc(
55791 + sizeof(t_FmPortDriverParam));
55792 + if (!p_FmPort->p_FmPortDriverParam)
55793 + {
55794 + XX_Free(p_FmPort);
55795 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Port driver parameters"));
55796 + return NULL;
55797 + }
55798 + memset(p_FmPort->p_FmPortDriverParam, 0, sizeof(t_FmPortDriverParam));
55799 +
55800 + /* Initialize FM port parameters which will be kept by the driver */
55801 + p_FmPort->portType = p_FmPortParams->portType;
55802 + p_FmPort->portId = p_FmPortParams->portId;
55803 + p_FmPort->pcdEngines = FM_PCD_NONE;
55804 + p_FmPort->f_Exception = p_FmPortParams->f_Exception;
55805 + p_FmPort->h_App = p_FmPortParams->h_App;
55806 + p_FmPort->h_Fm = p_FmPortParams->h_Fm;
55807 +
55808 + /* get FM revision */
55809 + FM_GetRevision(p_FmPort->h_Fm, &p_FmPort->fmRevInfo);
55810 +
55811 + /* calculate global portId number */
55812 + p_FmPort->hardwarePortId = SwPortIdToHwPortId(p_FmPort->portType,
55813 + p_FmPortParams->portId,
55814 + p_FmPort->fmRevInfo.majorRev,
55815 + p_FmPort->fmRevInfo.minorRev);
55816 +
55817 + if (p_FmPort->fmRevInfo.majorRev >= 6)
55818 + {
55819 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
55820 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
55821 + DBG(WARNING,
55822 + ("Port ID %d is recommended for HC port. Overwriting HW defaults to be suitable for HC.",
55823 + FM_OH_PORT_ID));
55824 +
55825 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55826 + && (p_FmPortParams->portId == FM_OH_PORT_ID))
55827 + DBG(WARNING, ("Use non-zero portId for OP port due to insufficient resources on portId 0."));
55828 + }
55829 +
55830 + /* Set up FM port parameters for initialization phase only */
55831 +
55832 + /* First, fill in flibs struct */
55833 + fman_port_defconfig(&p_FmPort->p_FmPortDriverParam->dfltCfg,
55834 + (enum fman_port_type)p_FmPort->portType);
55835 + /* Overwrite some integration specific parameters */
55836 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation =
55837 + DEFAULT_PORT_rxFifoPriElevationLevel;
55838 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr =
55839 + DEFAULT_PORT_rxFifoThreshold;
55840 +
55841 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
55842 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = TRUE;
55843 +#else
55844 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006675 = FALSE;
55845 +#endif
55846 + if ((p_FmPort->fmRevInfo.majorRev == 6)
55847 + && (p_FmPort->fmRevInfo.minorRev == 0))
55848 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = TRUE;
55849 + else
55850 + p_FmPort->p_FmPortDriverParam->dfltCfg.errata_A006320 = FALSE;
55851 +
55852 + /* Excessive Threshold register - exists for pre-FMv3 chips only */
55853 + if (p_FmPort->fmRevInfo.majorRev < 6)
55854 + {
55855 +#ifdef FM_NO_RESTRICT_ON_ACCESS_RSRC
55856 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
55857 + TRUE;
55858 +#endif
55859 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = FALSE;
55860 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = FALSE;
55861 + }
55862 + else
55863 + {
55864 + p_FmPort->p_FmPortDriverParam->dfltCfg.excessive_threshold_register =
55865 + FALSE;
55866 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_rebm_has_sgd = TRUE;
55867 + p_FmPort->p_FmPortDriverParam->dfltCfg.fmbm_tfne_has_features = TRUE;
55868 + }
55869 + if (p_FmPort->fmRevInfo.majorRev == 4)
55870 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = FALSE;
55871 + else
55872 + p_FmPort->p_FmPortDriverParam->dfltCfg.qmi_deq_options_support = TRUE;
55873 +
55874 + /* Continue with other parameters */
55875 + p_FmPort->p_FmPortDriverParam->baseAddr = baseAddr;
55876 + /* set memory map pointers */
55877 + p_FmPort->p_FmPortQmiRegs =
55878 + (t_FmPortQmiRegs *)UINT_TO_PTR(baseAddr + QMI_PORT_REGS_OFFSET);
55879 + p_FmPort->p_FmPortBmiRegs =
55880 + (u_FmPortBmiRegs *)UINT_TO_PTR(baseAddr + BMI_PORT_REGS_OFFSET);
55881 + p_FmPort->p_FmPortPrsRegs =
55882 + (t_FmPortPrsRegs *)UINT_TO_PTR(baseAddr + PRS_PORT_REGS_OFFSET);
55883 +
55884 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.privDataSize =
55885 + DEFAULT_PORT_bufferPrefixContent_privDataSize;
55886 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passPrsResult =
55887 + DEFAULT_PORT_bufferPrefixContent_passPrsResult;
55888 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passTimeStamp =
55889 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
55890 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.passAllOtherPCDInfo =
55891 + DEFAULT_PORT_bufferPrefixContent_passTimeStamp;
55892 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
55893 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
55894 + /* p_FmPort->p_FmPortDriverParam->dmaSwapData = (e_FmDmaSwapOption)DEFAULT_PORT_dmaSwapData;
55895 + p_FmPort->p_FmPortDriverParam->dmaIntContextCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaIntContextCacheAttr;
55896 + p_FmPort->p_FmPortDriverParam->dmaHeaderCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaHeaderCacheAttr;
55897 + p_FmPort->p_FmPortDriverParam->dmaScatterGatherCacheAttr = (e_FmDmaCacheOption)DEFAULT_PORT_dmaScatterGatherCacheAttr;
55898 + p_FmPort->p_FmPortDriverParam->dmaWriteOptimize = DEFAULT_PORT_dmaWriteOptimize;
55899 + */
55900 + p_FmPort->p_FmPortDriverParam->liodnBase = p_FmPortParams->liodnBase;
55901 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore =
55902 + DEFAULT_PORT_cheksumLastBytesIgnore;
55903 +
55904 + p_FmPort->maxFrameLength = DEFAULT_PORT_maxFrameLength;
55905 + /* resource distribution. */
55906 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)
55907 + * BMI_FIFO_UNITS;
55908 + p_FmPort->fifoBufs.extra = DEFAULT_PORT_extraNumOfFifoBufs
55909 + * BMI_FIFO_UNITS;
55910 + p_FmPort->openDmas.num = DEFAULT_PORT_numOfOpenDmas(p_FmPort->portType);
55911 + p_FmPort->openDmas.extra =
55912 + DEFAULT_PORT_extraNumOfOpenDmas(p_FmPort->portType);
55913 + p_FmPort->tasks.num = DEFAULT_PORT_numOfTasks(p_FmPort->portType);
55914 + p_FmPort->tasks.extra = DEFAULT_PORT_extraNumOfTasks(p_FmPort->portType);
55915 +
55916 +
55917 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
55918 + if ((p_FmPort->fmRevInfo.majorRev == 6)
55919 + && (p_FmPort->fmRevInfo.minorRev == 0)
55920 + && ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
55921 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX)))
55922 + {
55923 + p_FmPort->openDmas.num = 16;
55924 + p_FmPort->openDmas.extra = 0;
55925 + }
55926 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
55927 +
55928 + /* Port type specific initialization: */
55929 + switch (p_FmPort->portType)
55930 + {
55931 + case (e_FM_PORT_TYPE_RX):
55932 + case (e_FM_PORT_TYPE_RX_10G):
55933 + /* Initialize FM port parameters for initialization phase only */
55934 + p_FmPort->p_FmPortDriverParam->cutBytesFromEnd =
55935 + DEFAULT_PORT_cutBytesFromEnd;
55936 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = FALSE;
55937 + p_FmPort->p_FmPortDriverParam->frmDiscardOverride =
55938 + DEFAULT_PORT_frmDiscardOverride;
55939 +
55940 + tmpReg =
55941 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfp);
55942 + p_FmPort->p_FmPortDriverParam->rxFifoPriElevationLevel =
55943 + (((tmpReg & BMI_RX_FIFO_PRI_ELEVATION_MASK)
55944 + >> BMI_RX_FIFO_PRI_ELEVATION_SHIFT) + 1)
55945 + * BMI_FIFO_UNITS;
55946 + p_FmPort->p_FmPortDriverParam->rxFifoThreshold = (((tmpReg
55947 + & BMI_RX_FIFO_THRESHOLD_MASK)
55948 + >> BMI_RX_FIFO_THRESHOLD_SHIFT) + 1) * BMI_FIFO_UNITS;
55949 +
55950 + p_FmPort->p_FmPortDriverParam->bufMargins.endMargins =
55951 + DEFAULT_PORT_BufMargins_endMargins;
55952 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
55953 + DEFAULT_PORT_errorsToDiscard;
55954 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext =
55955 + DEFAULT_PORT_forwardIntContextReuse;
55956 +#if (DPAA_VERSION >= 11)
55957 + p_FmPort->p_FmPortDriverParam->noScatherGather =
55958 + DEFAULT_PORT_noScatherGather;
55959 +#endif /* (DPAA_VERSION >= 11) */
55960 + break;
55961 +
55962 + case (e_FM_PORT_TYPE_TX):
55963 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = FALSE;
55964 +#ifdef FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
55965 + tmpReg = 0x00001013;
55966 + WRITE_UINT32( p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp,
55967 + tmpReg);
55968 +#endif /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 */
55969 + case (e_FM_PORT_TYPE_TX_10G):
55970 + tmpReg =
55971 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfp);
55972 + p_FmPort->p_FmPortDriverParam->txFifoMinFillLevel = ((tmpReg
55973 + & BMI_TX_FIFO_MIN_FILL_MASK)
55974 + >> BMI_TX_FIFO_MIN_FILL_SHIFT) * BMI_FIFO_UNITS;
55975 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
55976 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
55977 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
55978 + p_FmPort->p_FmPortDriverParam->txFifoLowComfLevel = (((tmpReg
55979 + & BMI_TX_LOW_COMF_MASK) >> BMI_TX_LOW_COMF_SHIFT) + 1)
55980 + * BMI_FIFO_UNITS;
55981 +
55982 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
55983 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
55984 + DEFAULT_PORT_deqPrefetchOption;
55985 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
55986 + (bool)((p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqHighPriority_1G :
55987 + DEFAULT_PORT_deqHighPriority_10G);
55988 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
55989 + (uint16_t)(
55990 + (p_FmPort->portType == e_FM_PORT_TYPE_TX) ? DEFAULT_PORT_deqByteCnt_1G :
55991 + DEFAULT_PORT_deqByteCnt_10G);
55992 + break;
55993 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
55994 + p_FmPort->p_FmPortDriverParam->errorsToDiscard =
55995 + DEFAULT_PORT_errorsToDiscard;
55996 +#if (DPAA_VERSION >= 11)
55997 + p_FmPort->p_FmPortDriverParam->noScatherGather =
55998 + DEFAULT_PORT_noScatherGather;
55999 +#endif /* (DPAA_VERSION >= 11) */
56000 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
56001 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption =
56002 + DEFAULT_PORT_deqPrefetchOption_HC;
56003 + p_FmPort->p_FmPortDriverParam->deqHighPriority =
56004 + DEFAULT_PORT_deqHighPriority_1G;
56005 + p_FmPort->p_FmPortDriverParam->deqType = DEFAULT_PORT_deqType;
56006 + p_FmPort->p_FmPortDriverParam->deqByteCnt =
56007 + DEFAULT_PORT_deqByteCnt_1G;
56008 +
56009 + tmpReg =
56010 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofp);
56011 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
56012 + (uint8_t)(((tmpReg & BMI_FIFO_PIPELINE_DEPTH_MASK)
56013 + >> BMI_FIFO_PIPELINE_DEPTH_SHIFT) + 1);
56014 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
56015 + && (p_FmPortParams->portId != FM_OH_PORT_ID))
56016 + {
56017 + /* Overwrite HC defaults */
56018 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
56019 + DEFAULT_PORT_fifoDeqPipelineDepth_OH;
56020 + }
56021 +
56022 +#ifndef FM_FRAME_END_PARAMS_FOR_OP
56023 + if (p_FmPort->fmRevInfo.majorRev < 6)
56024 + p_FmPort->p_FmPortDriverParam->cheksumLastBytesIgnore = DEFAULT_notSupported;
56025 +#endif /* !FM_FRAME_END_PARAMS_FOR_OP */
56026 +
56027 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
56028 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
56029 + (p_FmPort->fmRevInfo.majorRev >= 6)))
56030 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth = DEFAULT_notSupported;
56031 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
56032 + break;
56033 +
56034 + default:
56035 + XX_Free(p_FmPort->p_FmPortDriverParam);
56036 + XX_Free(p_FmPort);
56037 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
56038 + return NULL;
56039 + }
56040 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
56041 + if (p_FmPort->fmRevInfo.majorRev == 4)
56042 + p_FmPort->p_FmPortDriverParam->deqPrefetchOption = (e_FmPortDeqPrefetchOption)DEFAULT_notSupported;
56043 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
56044 +
56045 + p_FmPort->imEn = p_FmPortParams->independentModeEnable;
56046 +
56047 + if (p_FmPort->imEn)
56048 + {
56049 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
56050 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G))
56051 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
56052 + DEFAULT_PORT_fifoDeqPipelineDepth_IM;
56053 + FmPortConfigIM(p_FmPort, p_FmPortParams);
56054 + }
56055 + else
56056 + {
56057 + switch (p_FmPort->portType)
56058 + {
56059 + case (e_FM_PORT_TYPE_RX):
56060 + case (e_FM_PORT_TYPE_RX_10G):
56061 + /* Initialize FM port parameters for initialization phase only */
56062 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
56063 + &p_FmPortParams->specificParams.rxParams.extBufPools,
56064 + sizeof(t_FmExtPools));
56065 + p_FmPort->p_FmPortDriverParam->errFqid =
56066 + p_FmPortParams->specificParams.rxParams.errFqid;
56067 + p_FmPort->p_FmPortDriverParam->dfltFqid =
56068 + p_FmPortParams->specificParams.rxParams.dfltFqid;
56069 + p_FmPort->p_FmPortDriverParam->liodnOffset =
56070 + p_FmPortParams->specificParams.rxParams.liodnOffset;
56071 + break;
56072 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
56073 + case (e_FM_PORT_TYPE_TX):
56074 + case (e_FM_PORT_TYPE_TX_10G):
56075 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
56076 + p_FmPort->p_FmPortDriverParam->errFqid =
56077 + p_FmPortParams->specificParams.nonRxParams.errFqid;
56078 + p_FmPort->p_FmPortDriverParam->deqSubPortal =
56079 + (uint8_t)(p_FmPortParams->specificParams.nonRxParams.qmChannel
56080 + & QMI_DEQ_CFG_SUBPORTAL_MASK);
56081 + p_FmPort->p_FmPortDriverParam->dfltFqid =
56082 + p_FmPortParams->specificParams.nonRxParams.dfltFqid;
56083 + break;
56084 + default:
56085 + XX_Free(p_FmPort->p_FmPortDriverParam);
56086 + XX_Free(p_FmPort);
56087 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
56088 + return NULL;
56089 + }
56090 + }
56091 +
56092 + memset(p_FmPort->name, 0, (sizeof(char)) * MODULE_NAME_SIZE);
56093 + if (Sprint(
56094 + p_FmPort->name,
56095 + "FM-%d-port-%s-%d",
56096 + FmGetId(p_FmPort->h_Fm),
56097 + ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING
56098 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)) ? "OH" :
56099 + (p_FmPort->portType == e_FM_PORT_TYPE_RX ? "1g-RX" :
56100 + (p_FmPort->portType == e_FM_PORT_TYPE_TX ? "1g-TX" :
56101 + (p_FmPort->portType
56102 + == e_FM_PORT_TYPE_RX_10G ? "10g-RX" :
56103 + "10g-TX")))),
56104 + p_FmPort->portId) == 0)
56105 + {
56106 + XX_Free(p_FmPort->p_FmPortDriverParam);
56107 + XX_Free(p_FmPort);
56108 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
56109 + return NULL;
56110 + }
56111 +
56112 + p_FmPort->h_Spinlock = XX_InitSpinlock();
56113 + if (!p_FmPort->h_Spinlock)
56114 + {
56115 + XX_Free(p_FmPort->p_FmPortDriverParam);
56116 + XX_Free(p_FmPort);
56117 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
56118 + return NULL;
56119 + }
56120 +
56121 + return p_FmPort;
56122 +}
56123 +
56124 +t_FmPort *rx_port = 0;
56125 +t_FmPort *tx_port = 0;
56126 +
56127 +/**************************************************************************//**
56128 + @Function FM_PORT_Init
56129 +
56130 + @Description Initializes the FM module
56131 +
56132 + @Param[in] h_FmPort - FM module descriptor
56133 +
56134 + @Return E_OK on success; Error code otherwise.
56135 + *//***************************************************************************/
56136 +t_Error FM_PORT_Init(t_Handle h_FmPort)
56137 +{
56138 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56139 + t_FmPortDriverParam *p_DriverParams;
56140 + t_Error errCode;
56141 + t_FmInterModulePortInitParams fmParams;
56142 + t_FmRevisionInfo revInfo;
56143 +
56144 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
56145 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56146 +
56147 + errCode = FmSpBuildBufferStructure(
56148 + &p_FmPort->p_FmPortDriverParam->intContext,
56149 + &p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
56150 + &p_FmPort->p_FmPortDriverParam->bufMargins,
56151 + &p_FmPort->bufferOffsets, &p_FmPort->internalBufferOffset);
56152 + if (errCode != E_OK)
56153 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
56154 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
56155 + if ((p_FmPort->p_FmPortDriverParam->bcbWorkaround) &&
56156 + (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56157 + {
56158 + p_FmPort->p_FmPortDriverParam->errorsToDiscard |= FM_PORT_FRM_ERR_PHYSICAL;
56159 + if (!p_FmPort->fifoBufs.num)
56160 + p_FmPort->fifoBufs.num = DEFAULT_PORT_numOfFifoBufs(p_FmPort->portType)*BMI_FIFO_UNITS;
56161 + p_FmPort->fifoBufs.num += 4*KILOBYTE;
56162 + }
56163 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
56164 +
56165 + CHECK_INIT_PARAMETERS(p_FmPort, CheckInitParameters);
56166 +
56167 + p_DriverParams = p_FmPort->p_FmPortDriverParam;
56168 +
56169 + /* Set up flibs port structure */
56170 + memset(&p_FmPort->port, 0, sizeof(struct fman_port));
56171 + p_FmPort->port.type = (enum fman_port_type)p_FmPort->portType;
56172 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
56173 + p_FmPort->port.fm_rev_maj = revInfo.majorRev;
56174 + p_FmPort->port.fm_rev_min = revInfo.minorRev;
56175 + p_FmPort->port.bmi_regs =
56176 + (union fman_port_bmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + BMI_PORT_REGS_OFFSET);
56177 + p_FmPort->port.qmi_regs =
56178 + (struct fman_port_qmi_regs *)UINT_TO_PTR(p_DriverParams->baseAddr + QMI_PORT_REGS_OFFSET);
56179 + p_FmPort->port.ext_pools_num = (uint8_t)((revInfo.majorRev == 4) ? 4 : 8);
56180 + p_FmPort->port.im_en = p_FmPort->imEn;
56181 + p_FmPort->p_FmPortPrsRegs =
56182 + (t_FmPortPrsRegs *)UINT_TO_PTR(p_DriverParams->baseAddr + PRS_PORT_REGS_OFFSET);
56183 +
56184 + if (((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56185 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)) && !p_FmPort->imEn)
56186 + {
56187 + /* Call the external Buffer routine which also checks fifo
56188 + size and updates it if necessary */
56189 + /* define external buffer pools and pool depletion*/
56190 + errCode = SetExtBufferPools(p_FmPort);
56191 + if (errCode)
56192 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
56193 + /* check if the largest external buffer pool is large enough */
56194 + if (p_DriverParams->bufMargins.startMargins + MIN_EXT_BUF_SIZE
56195 + + p_DriverParams->bufMargins.endMargins
56196 + > p_FmPort->rxPoolsParams.largestBufSize)
56197 + RETURN_ERROR(
56198 + MAJOR,
56199 + E_INVALID_VALUE,
56200 + ("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));
56201 + }
56202 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56203 + {
56204 + {
56205 +#ifdef FM_NO_OP_OBSERVED_POOLS
56206 + t_FmRevisionInfo revInfo;
56207 +
56208 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
56209 + if ((revInfo.majorRev == 4) && (p_DriverParams->enBufPoolDepletion))
56210 +#endif /* FM_NO_OP_OBSERVED_POOLS */
56211 + {
56212 + /* define external buffer pools */
56213 + errCode = SetExtBufferPools(p_FmPort);
56214 + if (errCode)
56215 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
56216 + }
56217 + }
56218 + }
56219 +
56220 + /************************************************************/
56221 + /* Call FM module routine for communicating parameters */
56222 + /************************************************************/
56223 + memset(&fmParams, 0, sizeof(fmParams));
56224 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
56225 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
56226 + fmParams.numOfTasks = (uint8_t)p_FmPort->tasks.num;
56227 + fmParams.numOfExtraTasks = (uint8_t)p_FmPort->tasks.extra;
56228 + fmParams.numOfOpenDmas = (uint8_t)p_FmPort->openDmas.num;
56229 + fmParams.numOfExtraOpenDmas = (uint8_t)p_FmPort->openDmas.extra;
56230 +
56231 + if (p_FmPort->fifoBufs.num)
56232 + {
56233 + errCode = VerifySizeOfFifo(p_FmPort);
56234 + if (errCode != E_OK)
56235 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
56236 + }
56237 + fmParams.sizeOfFifo = p_FmPort->fifoBufs.num;
56238 + fmParams.extraSizeOfFifo = p_FmPort->fifoBufs.extra;
56239 + fmParams.independentMode = p_FmPort->imEn;
56240 + fmParams.liodnOffset = p_DriverParams->liodnOffset;
56241 + fmParams.liodnBase = p_DriverParams->liodnBase;
56242 + fmParams.deqPipelineDepth =
56243 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
56244 + fmParams.maxFrameLength = p_FmPort->maxFrameLength;
56245 +#ifndef FM_DEQ_PIPELINE_PARAMS_FOR_OP
56246 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ||
56247 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
56248 + {
56249 + if (!((p_FmPort->fmRevInfo.majorRev == 4) ||
56250 + (p_FmPort->fmRevInfo.majorRev >= 6)))
56251 + /* HC ports do not have fifoDeqPipelineDepth, but it is needed only
56252 + * for deq threshold calculation.
56253 + */
56254 + fmParams.deqPipelineDepth = 2;
56255 + }
56256 +#endif /* !FM_DEQ_PIPELINE_PARAMS_FOR_OP */
56257 +
56258 + errCode = FmGetSetPortParams(p_FmPort->h_Fm, &fmParams);
56259 + if (errCode)
56260 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
56261 +
56262 + /* get params for use in init */
56263 + p_FmPort->fmMuramPhysBaseAddr =
56264 + (uint64_t)((uint64_t)(fmParams.fmMuramPhysBaseAddr.low)
56265 + | ((uint64_t)(fmParams.fmMuramPhysBaseAddr.high) << 32));
56266 + p_FmPort->h_FmMuram = FmGetMuramHandle(p_FmPort->h_Fm);
56267 +
56268 + errCode = InitLowLevelDriver(p_FmPort);
56269 + if (errCode != E_OK)
56270 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
56271 +
56272 + FmPortDriverParamFree(p_FmPort);
56273 +
56274 +#if (DPAA_VERSION >= 11)
56275 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56276 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
56277 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56278 + {
56279 + t_FmPcdCtrlParamsPage *p_ParamsPage;
56280 +
56281 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
56282 + (void**)&p_ParamsPage);
56283 + ASSERT_COND(p_ParamsPage);
56284 +
56285 + WRITE_UINT32(p_ParamsPage->misc, FM_CTL_PARAMS_PAGE_ALWAYS_ON);
56286 +#ifdef FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
56287 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56288 + {
56289 + WRITE_UINT32(
56290 + p_ParamsPage->misc,
56291 + (GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OP_FIX_EN));
56292 + WRITE_UINT32(
56293 + p_ParamsPage->discardMask,
56294 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
56295 + }
56296 +#endif /* FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675 */
56297 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
56298 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56299 + WRITE_UINT32(
56300 + p_ParamsPage->errorsDiscardMask,
56301 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsem)));
56302 + else
56303 + WRITE_UINT32(
56304 + p_ParamsPage->errorsDiscardMask,
56305 + (GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm) | GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsem)));
56306 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
56307 + }
56308 +#endif /* (DPAA_VERSION >= 11) */
56309 +
56310 + if (p_FmPort->deepSleepVars.autoResMaxSizes)
56311 + FmPortConfigAutoResForDeepSleepSupport1(p_FmPort);
56312 + return E_OK;
56313 +}
56314 +
56315 +/**************************************************************************//**
56316 + @Function FM_PORT_Free
56317 +
56318 + @Description Frees all resources that were assigned to FM module.
56319 +
56320 + Calling this routine invalidates the descriptor.
56321 +
56322 + @Param[in] h_FmPort - FM module descriptor
56323 +
56324 + @Return E_OK on success; Error code otherwise.
56325 + *//***************************************************************************/
56326 +t_Error FM_PORT_Free(t_Handle h_FmPort)
56327 +{
56328 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56329 + t_FmInterModulePortFreeParams fmParams;
56330 +
56331 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56332 +
56333 + if (p_FmPort->pcdEngines)
56334 + RETURN_ERROR(
56335 + MAJOR,
56336 + E_INVALID_STATE,
56337 + ("Trying to free a port with PCD. FM_PORT_DeletePCD must be called first."));
56338 +
56339 + if (p_FmPort->enabled)
56340 + {
56341 + if (FM_PORT_Disable(p_FmPort) != E_OK)
56342 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM_PORT_Disable FAILED"));
56343 + }
56344 +
56345 + if (p_FmPort->imEn)
56346 + FmPortImFree(p_FmPort);
56347 +
56348 + FmPortDriverParamFree(p_FmPort);
56349 +
56350 + memset(&fmParams, 0, sizeof(fmParams));
56351 + fmParams.hardwarePortId = p_FmPort->hardwarePortId;
56352 + fmParams.portType = (e_FmPortType)p_FmPort->portType;
56353 + fmParams.deqPipelineDepth =
56354 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth;
56355 +
56356 + FmFreePortParams(p_FmPort->h_Fm, &fmParams);
56357 +
56358 +#if (DPAA_VERSION >= 11)
56359 + if (FmVSPFreeForPort(p_FmPort->h_Fm, p_FmPort->portType, p_FmPort->portId)
56360 + != E_OK)
56361 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("VSP free of port FAILED"));
56362 +
56363 + if (p_FmPort->p_ParamsPage)
56364 + FM_MURAM_FreeMem(p_FmPort->h_FmMuram, p_FmPort->p_ParamsPage);
56365 +#endif /* (DPAA_VERSION >= 11) */
56366 +
56367 + if (p_FmPort->h_Spinlock)
56368 + XX_FreeSpinlock(p_FmPort->h_Spinlock);
56369 +
56370 + XX_Free(p_FmPort);
56371 +
56372 + return E_OK;
56373 +}
56374 +
56375 +/*************************************************/
56376 +/* API Advanced Init unit functions */
56377 +/*************************************************/
56378 +
56379 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas)
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 + p_FmPort->p_FmPortDriverParam->setNumOfOpenDmas = TRUE;
56387 + memcpy(&p_FmPort->openDmas, p_OpenDmas, sizeof(t_FmPortRsrc));
56388 +
56389 + return E_OK;
56390 +}
56391 +
56392 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
56393 +{
56394 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56395 +
56396 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56397 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56398 +
56399 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
56400 + p_FmPort->p_FmPortDriverParam->setNumOfTasks = TRUE;
56401 + return E_OK;
56402 +}
56403 +
56404 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
56405 +{
56406 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56407 +
56408 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56409 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56410 +
56411 + p_FmPort->p_FmPortDriverParam->setSizeOfFifo = TRUE;
56412 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
56413 +
56414 + return E_OK;
56415 +}
56416 +
56417 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri)
56418 +{
56419 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56420 +
56421 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56422 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56423 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56424 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56425 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("not available for Rx ports"));
56426 +
56427 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_high_pri = highPri;
56428 +
56429 + return E_OK;
56430 +}
56431 +
56432 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType)
56433 +{
56434 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56435 +
56436 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56437 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56438 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56439 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56440 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56441 + ("not available for Rx ports"));
56442 +
56443 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_type =
56444 + (enum fman_port_deq_type)deqType;
56445 +
56446 + return E_OK;
56447 +}
56448 +
56449 +t_Error FM_PORT_ConfigDeqPrefetchOption(
56450 + t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption)
56451 +{
56452 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56453 +
56454 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56455 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56456 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56457 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56458 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56459 + ("not available for Rx ports"));
56460 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_prefetch_opt =
56461 + (enum fman_port_deq_prefetch)deqPrefetchOption;
56462 +
56463 + return E_OK;
56464 +}
56465 +
56466 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort,
56467 + t_FmBackupBmPools *p_BackupBmPools)
56468 +{
56469 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56470 +
56471 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56472 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56473 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56474 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56475 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56476 + ("available for Rx ports only"));
56477 +
56478 + p_FmPort->p_FmPortDriverParam->p_BackupBmPools =
56479 + (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
56480 + if (!p_FmPort->p_FmPortDriverParam->p_BackupBmPools)
56481 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
56482 + memcpy(p_FmPort->p_FmPortDriverParam->p_BackupBmPools, p_BackupBmPools,
56483 + sizeof(t_FmBackupBmPools));
56484 +
56485 + return E_OK;
56486 +}
56487 +
56488 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt)
56489 +{
56490 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56491 +
56492 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56493 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56494 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56495 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56496 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56497 + ("not available for Rx ports"));
56498 +
56499 + p_FmPort->p_FmPortDriverParam->dfltCfg.deq_byte_cnt = deqByteCnt;
56500 +
56501 + return E_OK;
56502 +}
56503 +
56504 +t_Error FM_PORT_ConfigBufferPrefixContent(
56505 + t_Handle h_FmPort, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
56506 +{
56507 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56508 +
56509 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56510 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56511 +
56512 + memcpy(&p_FmPort->p_FmPortDriverParam->bufferPrefixContent,
56513 + p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
56514 + /* if dataAlign was not initialized by user, we return to driver's default */
56515 + if (!p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign)
56516 + p_FmPort->p_FmPortDriverParam->bufferPrefixContent.dataAlign =
56517 + DEFAULT_PORT_bufferPrefixContent_dataAlign;
56518 +
56519 + return E_OK;
56520 +}
56521 +
56522 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort,
56523 + uint8_t checksumLastBytesIgnore)
56524 +{
56525 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56526 +
56527 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56528 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56529 +
56530 + p_FmPort->p_FmPortDriverParam->dfltCfg.checksum_bytes_ignore =
56531 + checksumLastBytesIgnore;
56532 +
56533 + return E_OK;
56534 +}
56535 +
56536 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort,
56537 + uint8_t cutBytesFromEnd)
56538 +{
56539 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56540 +
56541 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56542 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56543 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56544 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56545 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56546 + ("available for Rx ports only"));
56547 +
56548 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_cut_end_bytes = cutBytesFromEnd;
56549 +
56550 + return E_OK;
56551 +}
56552 +
56553 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort,
56554 + t_FmBufPoolDepletion *p_BufPoolDepletion)
56555 +{
56556 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56557 +
56558 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56559 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56560 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56561 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56562 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56563 + ("available for Rx ports only"));
56564 +
56565 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
56566 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion, p_BufPoolDepletion,
56567 + sizeof(t_FmBufPoolDepletion));
56568 +
56569 + return E_OK;
56570 +}
56571 +
56572 +t_Error FM_PORT_ConfigObservedPoolDepletion(
56573 + t_Handle h_FmPort,
56574 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion)
56575 +{
56576 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56577 +
56578 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56579 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56580 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56581 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56582 + ("available for OP ports only"));
56583 +
56584 + p_FmPort->p_FmPortDriverParam->enBufPoolDepletion = TRUE;
56585 + memcpy(&p_FmPort->p_FmPortDriverParam->bufPoolDepletion,
56586 + &p_FmPortObservedBufPoolDepletion->poolDepletionParams,
56587 + sizeof(t_FmBufPoolDepletion));
56588 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools,
56589 + &p_FmPortObservedBufPoolDepletion->poolsParams,
56590 + sizeof(t_FmExtPools));
56591 +
56592 + return E_OK;
56593 +}
56594 +
56595 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools)
56596 +{
56597 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56598 +
56599 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56600 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56601 +
56602 + if (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
56603 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56604 + ("available for OP ports only"));
56605 +
56606 + memcpy(&p_FmPort->p_FmPortDriverParam->extBufPools, p_FmExtPools,
56607 + sizeof(t_FmExtPools));
56608 +
56609 + return E_OK;
56610 +}
56611 +
56612 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort)
56613 +{
56614 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56615 +
56616 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56617 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56618 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
56619 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
56620 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56621 + ("available for Tx ports only"));
56622 +
56623 + p_FmPort->p_FmPortDriverParam->dontReleaseBuf = TRUE;
56624 +
56625 + return E_OK;
56626 +}
56627 +
56628 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color)
56629 +{
56630 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56631 +
56632 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56633 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56634 + p_FmPort->p_FmPortDriverParam->dfltCfg.color = (enum fman_port_color)color;
56635 +
56636 + return E_OK;
56637 +}
56638 +
56639 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq)
56640 +{
56641 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56642 +
56643 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56644 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56645 +
56646 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
56647 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
56648 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56649 + ("Not available for Tx ports"));
56650 +
56651 + p_FmPort->p_FmPortDriverParam->dfltCfg.sync_req = syncReq;
56652 +
56653 + return E_OK;
56654 +}
56655 +
56656 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override)
56657 +{
56658 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56659 +
56660 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56661 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56662 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
56663 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
56664 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56665 + ("Not available for Tx ports"));
56666 +
56667 + p_FmPort->p_FmPortDriverParam->dfltCfg.discard_override = override;
56668 +
56669 + return E_OK;
56670 +}
56671 +
56672 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort,
56673 + fmPortFrameErrSelect_t errs)
56674 +{
56675 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56676 +
56677 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56678 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56679 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56680 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
56681 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
56682 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
56683 + ("available for Rx and offline parsing ports only"));
56684 +
56685 + p_FmPort->p_FmPortDriverParam->errorsToDiscard = errs;
56686 +
56687 + return E_OK;
56688 +}
56689 +
56690 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData)
56691 +{
56692 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56693 +
56694 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56695 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56696 +
56697 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_swap_data =
56698 + (enum fman_port_dma_swap)swapData;
56699 +
56700 + return E_OK;
56701 +}
56702 +
56703 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort,
56704 + e_FmDmaCacheOption intContextCacheAttr)
56705 +{
56706 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56707 +
56708 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56709 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56710 +
56711 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_ic_stash_on =
56712 + (bool)(intContextCacheAttr == e_FM_DMA_STASH);
56713 +
56714 + return E_OK;
56715 +}
56716 +
56717 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort,
56718 + e_FmDmaCacheOption headerCacheAttr)
56719 +{
56720 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56721 +
56722 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56723 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56724 +
56725 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_header_stash_on =
56726 + (bool)(headerCacheAttr == e_FM_DMA_STASH);
56727 +
56728 + return E_OK;
56729 +}
56730 +
56731 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(
56732 + t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr)
56733 +{
56734 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56735 +
56736 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56737 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56738 +
56739 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_sg_stash_on =
56740 + (bool)(scatterGatherCacheAttr == e_FM_DMA_STASH);
56741 +
56742 + return E_OK;
56743 +}
56744 +
56745 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize)
56746 +{
56747 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56748 +
56749 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56750 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56751 +
56752 + if ((p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)
56753 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX))
56754 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56755 + ("Not available for Tx ports"));
56756 +
56757 + p_FmPort->p_FmPortDriverParam->dfltCfg.dma_write_optimize = optimize;
56758 +
56759 + return E_OK;
56760 +}
56761 +
56762 +#if (DPAA_VERSION >= 11)
56763 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather)
56764 +{
56765 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56766 +
56767 + UNUSED(noScatherGather);
56768 + UNUSED(p_FmPort);
56769 +
56770 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56771 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56772 +
56773 + p_FmPort->p_FmPortDriverParam->noScatherGather = noScatherGather;
56774 +
56775 + return E_OK;
56776 +}
56777 +#endif /* (DPAA_VERSION >= 11) */
56778 +
56779 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort,
56780 + bool forwardReuse)
56781 +{
56782 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56783 +
56784 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56785 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56786 +
56787 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56788 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56789 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56790 + ("available for Rx ports only"));
56791 +
56792 + p_FmPort->p_FmPortDriverParam->forwardReuseIntContext = forwardReuse;
56793 +
56794 + return E_OK;
56795 +}
56796 +
56797 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length)
56798 +{
56799 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56800 +
56801 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56802 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56803 +
56804 + p_FmPort->maxFrameLength = length;
56805 +
56806 + return E_OK;
56807 +}
56808 +
56809 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
56810 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort)
56811 +{
56812 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56813 +
56814 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56815 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56816 +
56817 + p_FmPort->p_FmPortDriverParam->bcbWorkaround = TRUE;
56818 +
56819 + return E_OK;
56820 +}
56821 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
56822 +
56823 +/****************************************************/
56824 +/* Hidden-DEBUG Only API */
56825 +/****************************************************/
56826 +
56827 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort,
56828 + uint32_t minFillLevel)
56829 +{
56830 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56831 +
56832 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56833 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56834 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
56835 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
56836 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56837 + ("available for Tx ports only"));
56838 +
56839 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_min_level = minFillLevel;
56840 +
56841 + return E_OK;
56842 +}
56843 +
56844 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort,
56845 + uint8_t deqPipelineDepth)
56846 +{
56847 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56848 +
56849 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56850 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56851 +
56852 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
56853 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX))
56854 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56855 + ("Not available for Rx ports"));
56856 +
56857 + if (p_FmPort->imEn)
56858 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56859 + ("Not available for IM ports!"));
56860 +
56861 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_deq_pipeline_depth =
56862 + deqPipelineDepth;
56863 +
56864 + return E_OK;
56865 +}
56866 +
56867 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort,
56868 + uint32_t fifoLowComfLevel)
56869 +{
56870 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56871 +
56872 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56873 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56874 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX_10G)
56875 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX))
56876 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56877 + ("available for Tx ports only"));
56878 +
56879 + p_FmPort->p_FmPortDriverParam->dfltCfg.tx_fifo_low_comf_level =
56880 + fifoLowComfLevel;
56881 +
56882 + return E_OK;
56883 +}
56884 +
56885 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold)
56886 +{
56887 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56888 +
56889 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56890 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56891 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56892 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56893 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56894 + ("available for Rx ports only"));
56895 +
56896 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_fifo_thr = fifoThreshold;
56897 +
56898 + return E_OK;
56899 +}
56900 +
56901 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort,
56902 + uint32_t priElevationLevel)
56903 +{
56904 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56905 +
56906 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56907 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56908 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
56909 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
56910 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
56911 + ("available for Rx ports only"));
56912 +
56913 + p_FmPort->p_FmPortDriverParam->dfltCfg.rx_pri_elevation = priElevationLevel;
56914 +
56915 + return E_OK;
56916 +}
56917 +/****************************************************/
56918 +/* API Run-time Control unit functions */
56919 +/****************************************************/
56920 +
56921 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort,
56922 + t_FmPortRsrc *p_NumOfOpenDmas)
56923 +{
56924 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56925 + t_Error err;
56926 +
56927 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56928 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56929 +
56930 + if ((!p_NumOfOpenDmas->num) || (p_NumOfOpenDmas->num > MAX_NUM_OF_DMAS))
56931 + RETURN_ERROR( MAJOR, E_INVALID_VALUE,
56932 + ("openDmas-num can't be larger than %d", MAX_NUM_OF_DMAS));
56933 + if (p_NumOfOpenDmas->extra > MAX_NUM_OF_EXTRA_DMAS)
56934 + RETURN_ERROR(
56935 + MAJOR,
56936 + E_INVALID_VALUE,
56937 + ("openDmas-extra can't be larger than %d", MAX_NUM_OF_EXTRA_DMAS));
56938 + err = FmSetNumOfOpenDmas(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
56939 + (uint8_t*)&p_NumOfOpenDmas->num,
56940 + (uint8_t*)&p_NumOfOpenDmas->extra, FALSE);
56941 + if (err)
56942 + RETURN_ERROR(MAJOR, err, NO_MSG);
56943 +
56944 + memcpy(&p_FmPort->openDmas, p_NumOfOpenDmas, sizeof(t_FmPortRsrc));
56945 +
56946 + return E_OK;
56947 +}
56948 +
56949 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks)
56950 +{
56951 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56952 + t_Error err;
56953 +
56954 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56955 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56956 +
56957 + /* only driver uses host command port, so ASSERT rather than RETURN_ERROR */
56958 + ASSERT_COND(p_FmPort->portType != e_FM_PORT_TYPE_OH_HOST_COMMAND);
56959 +
56960 + if ((!p_NumOfTasks->num) || (p_NumOfTasks->num > MAX_NUM_OF_TASKS))
56961 + RETURN_ERROR(
56962 + MAJOR, E_INVALID_VALUE,
56963 + ("NumOfTasks-num can't be larger than %d", MAX_NUM_OF_TASKS));
56964 + if (p_NumOfTasks->extra > MAX_NUM_OF_EXTRA_TASKS)
56965 + RETURN_ERROR(
56966 + MAJOR,
56967 + E_INVALID_VALUE,
56968 + ("NumOfTasks-extra can't be larger than %d", MAX_NUM_OF_EXTRA_TASKS));
56969 +
56970 + err = FmSetNumOfTasks(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
56971 + (uint8_t*)&p_NumOfTasks->num,
56972 + (uint8_t*)&p_NumOfTasks->extra, FALSE);
56973 + if (err)
56974 + RETURN_ERROR(MAJOR, err, NO_MSG);
56975 +
56976 + /* update driver's struct */
56977 + memcpy(&p_FmPort->tasks, p_NumOfTasks, sizeof(t_FmPortRsrc));
56978 + return E_OK;
56979 +}
56980 +
56981 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo)
56982 +{
56983 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
56984 + t_Error err;
56985 +
56986 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
56987 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
56988 +
56989 + if (!p_SizeOfFifo->num || (p_SizeOfFifo->num > MAX_PORT_FIFO_SIZE))
56990 + RETURN_ERROR(
56991 + MAJOR,
56992 + E_INVALID_VALUE,
56993 + ("SizeOfFifo-num has to be in the range of 256 - %d", MAX_PORT_FIFO_SIZE));
56994 + if (p_SizeOfFifo->num % BMI_FIFO_UNITS)
56995 + RETURN_ERROR(
56996 + MAJOR, E_INVALID_VALUE,
56997 + ("SizeOfFifo-num has to be divisible by %d", BMI_FIFO_UNITS));
56998 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
56999 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57000 + {
57001 + /* extra FIFO size (allowed only to Rx ports) */
57002 + if (p_SizeOfFifo->extra % BMI_FIFO_UNITS)
57003 + RETURN_ERROR(
57004 + MAJOR,
57005 + E_INVALID_VALUE,
57006 + ("SizeOfFifo-extra has to be divisible by %d", BMI_FIFO_UNITS));
57007 + }
57008 + else
57009 + if (p_SizeOfFifo->extra)
57010 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
57011 + (" No SizeOfFifo-extra for non Rx ports"));
57012 +
57013 + memcpy(&p_FmPort->fifoBufs, p_SizeOfFifo, sizeof(t_FmPortRsrc));
57014 +
57015 + /* we do not change user's parameter */
57016 + err = VerifySizeOfFifo(p_FmPort);
57017 + if (err)
57018 + RETURN_ERROR(MAJOR, err, NO_MSG);
57019 +
57020 + err = FmSetSizeOfFifo(p_FmPort->h_Fm, p_FmPort->hardwarePortId,
57021 + &p_SizeOfFifo->num, &p_SizeOfFifo->extra, FALSE);
57022 + if (err)
57023 + RETURN_ERROR(MAJOR, err, NO_MSG);
57024 +
57025 + return E_OK;
57026 +}
57027 +
57028 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort)
57029 +{
57030 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57031 +
57032 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
57033 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
57034 + 0);
57035 +
57036 + return p_FmPort->bufferOffsets.dataOffset;
57037 +}
57038 +
57039 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data)
57040 +{
57041 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57042 +
57043 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
57044 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
57045 + NULL);
57046 +
57047 + if (p_FmPort->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
57048 + return NULL;
57049 +
57050 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.pcdInfoOffset);
57051 +}
57052 +
57053 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data)
57054 +{
57055 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57056 +
57057 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
57058 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
57059 + NULL);
57060 +
57061 + if (p_FmPort->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
57062 + return NULL;
57063 +
57064 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.prsResultOffset);
57065 +}
57066 +
57067 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data)
57068 +{
57069 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57070 +
57071 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
57072 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
57073 + NULL);
57074 +
57075 + if (p_FmPort->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
57076 + return NULL;
57077 +
57078 + return (uint64_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.timeStampOffset);
57079 +}
57080 +
57081 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data)
57082 +{
57083 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57084 +
57085 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, NULL);
57086 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
57087 + NULL);
57088 +
57089 + if (p_FmPort->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
57090 + return NULL;
57091 +
57092 + return (uint8_t *)PTR_MOVE(p_Data, p_FmPort->bufferOffsets.hashResultOffset);
57093 +}
57094 +
57095 +t_Error FM_PORT_Disable(t_Handle h_FmPort)
57096 +{
57097 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57098 + int err;
57099 +
57100 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57101 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57102 +
57103 + if (p_FmPort->imEn)
57104 + FmPortImDisable(p_FmPort);
57105 +
57106 + err = fman_port_disable(&p_FmPort->port);
57107 + if (err == -EBUSY)
57108 + {
57109 + DBG(WARNING, ("%s: BMI or QMI is Busy. Port forced down",
57110 + p_FmPort->name));
57111 + }
57112 + else
57113 + if (err != 0)
57114 + {
57115 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_disable"));
57116 + }
57117 +
57118 + p_FmPort->enabled = FALSE;
57119 +
57120 + return E_OK;
57121 +}
57122 +
57123 +t_Error FM_PORT_Enable(t_Handle h_FmPort)
57124 +{
57125 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57126 + int err;
57127 +
57128 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57129 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57130 +
57131 + /* Used by FM_PORT_Free routine as indication
57132 + if to disable port. Thus set it to TRUE prior
57133 + to enabling itself. This way if part of enable
57134 + process fails there will be still things
57135 + to disable during Free. For example, if BMI
57136 + enable succeeded but QMI failed, still BMI
57137 + needs to be disabled by Free. */
57138 + p_FmPort->enabled = TRUE;
57139 +
57140 + if (p_FmPort->imEn)
57141 + FmPortImEnable(p_FmPort);
57142 +
57143 + err = fman_port_enable(&p_FmPort->port);
57144 + if (err != 0)
57145 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_enable"));
57146 +
57147 + return E_OK;
57148 +}
57149 +
57150 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit)
57151 +{
57152 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57153 + uint8_t factor, countUnitBit;
57154 + uint16_t baseGran;
57155 + struct fman_port_rate_limiter params;
57156 + int err;
57157 +
57158 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57159 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
57160 +
57161 + switch (p_FmPort->portType)
57162 + {
57163 + case (e_FM_PORT_TYPE_TX_10G):
57164 + case (e_FM_PORT_TYPE_TX):
57165 + baseGran = BMI_RATE_LIMIT_GRAN_TX;
57166 + break;
57167 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57168 + baseGran = BMI_RATE_LIMIT_GRAN_OP;
57169 + break;
57170 + default:
57171 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57172 + ("available for Tx and Offline parsing ports only"));
57173 + }
57174 +
57175 + countUnitBit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm); /* TimeStamp per nano seconds units */
57176 + /* normally, we use 1 usec as the reference count */
57177 + factor = 1;
57178 + /* if ratelimit is too small for a 1usec factor, multiply the factor */
57179 + while (p_RateLimit->rateLimit < baseGran / factor)
57180 + {
57181 + if (countUnitBit == 31)
57182 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too small"));
57183 +
57184 + countUnitBit++;
57185 + factor <<= 1;
57186 + }
57187 + /* if ratelimit is too large for a 1usec factor, it is also larger than max rate*/
57188 + if (p_RateLimit->rateLimit
57189 + > ((uint32_t)baseGran * (1 << 10) * (uint32_t)factor))
57190 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Rate limit is too large"));
57191 +
57192 + if (!p_RateLimit->maxBurstSize
57193 + || (p_RateLimit->maxBurstSize > BMI_RATE_LIMIT_MAX_BURST_SIZE))
57194 + RETURN_ERROR(
57195 + MAJOR,
57196 + E_INVALID_VALUE,
57197 + ("maxBurstSize must be between 1K and %dk", BMI_RATE_LIMIT_MAX_BURST_SIZE));
57198 +
57199 + params.count_1micro_bit = (uint8_t)FmGetTimeStampScale(p_FmPort->h_Fm);
57200 + params.high_burst_size_gran = FALSE;
57201 + params.burst_size = p_RateLimit->maxBurstSize;
57202 + params.rate = p_RateLimit->rateLimit;
57203 + params.rate_factor = E_FMAN_PORT_RATE_DOWN_NONE;
57204 +
57205 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
57206 + {
57207 +#ifndef FM_NO_ADVANCED_RATE_LIMITER
57208 +
57209 + if ((p_FmPort->fmRevInfo.majorRev == 4)
57210 + || (p_FmPort->fmRevInfo.majorRev >= 6))
57211 + {
57212 + params.high_burst_size_gran = TRUE;
57213 + }
57214 + else
57215 +#endif /* ! FM_NO_ADVANCED_RATE_LIMITER */
57216 + {
57217 + if (p_RateLimit->rateLimitDivider
57218 + != e_FM_PORT_DUAL_RATE_LIMITER_NONE)
57219 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
57220 + ("FM_PORT_ConfigDualRateLimitScaleDown"));
57221 +
57222 + if (p_RateLimit->maxBurstSize % 1000)
57223 + {
57224 + p_RateLimit->maxBurstSize =
57225 + (uint16_t)((p_RateLimit->maxBurstSize / 1000) + 1);
57226 + DBG(WARNING, ("rateLimit.maxBurstSize rounded up to %d", (p_RateLimit->maxBurstSize/1000+1)*1000));
57227 + }
57228 + else
57229 + p_RateLimit->maxBurstSize = (uint16_t)(p_RateLimit->maxBurstSize
57230 + / 1000);
57231 + }
57232 + params.rate_factor =
57233 + (enum fman_port_rate_limiter_scale_down)p_RateLimit->rateLimitDivider;
57234 + params.burst_size = p_RateLimit->maxBurstSize;
57235 + }
57236 +
57237 + err = fman_port_set_rate_limiter(&p_FmPort->port, &params);
57238 + if (err != 0)
57239 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
57240 +
57241 + return E_OK;
57242 +}
57243 +
57244 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort)
57245 +{
57246 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57247 + int err;
57248 +
57249 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57250 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
57251 +
57252 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)
57253 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX)
57254 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
57255 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
57256 + ("available for Tx and Offline parsing ports only"));
57257 +
57258 + err = fman_port_delete_rate_limiter(&p_FmPort->port);
57259 + if (err != 0)
57260 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_rate_limiter"));
57261 + return E_OK;
57262 +}
57263 +
57264 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio,
57265 + uint8_t wq)
57266 +{
57267 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57268 + uint32_t tmpReg;
57269 + uint32_t wqTmpReg;
57270 +
57271 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57272 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57273 +
57274 + if ((p_FmPort->portType != e_FM_PORT_TYPE_TX)
57275 + && (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
57276 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57277 + ("PFC mapping is available for Tx ports only"));
57278 +
57279 + if (prio > 7)
57280 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
57281 + ("PFC priority (%d) is out of range (0-7)", prio));
57282 + if (wq > 7)
57283 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
57284 + ("WQ (%d) is out of range (0-7)", wq));
57285 +
57286 + tmpReg = GET_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0]);
57287 + tmpReg &= ~(0xf << ((7 - prio) * 4));
57288 + wqTmpReg = ((uint32_t)wq << ((7 - prio) * 4));
57289 + tmpReg |= wqTmpReg;
57290 +
57291 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tpfcm[0],
57292 + tmpReg);
57293 +
57294 + return E_OK;
57295 +}
57296 +
57297 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable)
57298 +{
57299 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57300 +
57301 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57302 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57303 +
57304 + fman_port_set_queue_cnt_mode(&p_FmPort->port, enable);
57305 +
57306 + return E_OK;
57307 +}
57308 +
57309 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable)
57310 +{
57311 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57312 + int err;
57313 +
57314 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57315 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57316 +
57317 + err = fman_port_set_perf_cnt_mode(&p_FmPort->port, enable);
57318 + if (err != 0)
57319 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_mode"));
57320 + return E_OK;
57321 +}
57322 +
57323 +t_Error FM_PORT_SetPerformanceCountersParams(
57324 + t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt)
57325 +{
57326 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57327 + struct fman_port_perf_cnt_params params;
57328 + int err;
57329 +
57330 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57331 +
57332 + /* check parameters */
57333 + if (!p_FmPortPerformanceCnt->taskCompVal
57334 + || (p_FmPortPerformanceCnt->taskCompVal > p_FmPort->tasks.num))
57335 + RETURN_ERROR(
57336 + MAJOR,
57337 + E_INVALID_VALUE,
57338 + ("taskCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->taskCompVal, p_FmPort->tasks.num));
57339 + if (!p_FmPortPerformanceCnt->dmaCompVal
57340 + || (p_FmPortPerformanceCnt->dmaCompVal > p_FmPort->openDmas.num))
57341 + RETURN_ERROR(
57342 + MAJOR,
57343 + E_INVALID_VALUE,
57344 + ("dmaCompVal (%d) has to be in the range of 1 - %d (current value)!", p_FmPortPerformanceCnt->dmaCompVal, p_FmPort->openDmas.num));
57345 + if (!p_FmPortPerformanceCnt->fifoCompVal
57346 + || (p_FmPortPerformanceCnt->fifoCompVal > p_FmPort->fifoBufs.num))
57347 + RETURN_ERROR(
57348 + MAJOR,
57349 + E_INVALID_VALUE,
57350 + ("fifoCompVal (%d) has to be in the range of 256 - %d (current value)!", p_FmPortPerformanceCnt->fifoCompVal, p_FmPort->fifoBufs.num));
57351 + if (p_FmPortPerformanceCnt->fifoCompVal % BMI_FIFO_UNITS)
57352 + RETURN_ERROR(
57353 + MAJOR,
57354 + E_INVALID_VALUE,
57355 + ("fifoCompVal (%d) has to be divisible by %d", p_FmPortPerformanceCnt->fifoCompVal, BMI_FIFO_UNITS));
57356 +
57357 + switch (p_FmPort->portType)
57358 + {
57359 + case (e_FM_PORT_TYPE_RX_10G):
57360 + case (e_FM_PORT_TYPE_RX):
57361 + if (!p_FmPortPerformanceCnt->queueCompVal
57362 + || (p_FmPortPerformanceCnt->queueCompVal
57363 + > MAX_PERFORMANCE_RX_QUEUE_COMP))
57364 + RETURN_ERROR(
57365 + MAJOR,
57366 + E_INVALID_VALUE,
57367 + ("performanceCnt.queueCompVal for Rx has to be in the range of 1 - %d", MAX_PERFORMANCE_RX_QUEUE_COMP));
57368 + break;
57369 + case (e_FM_PORT_TYPE_TX_10G):
57370 + case (e_FM_PORT_TYPE_TX):
57371 + if (!p_FmPortPerformanceCnt->queueCompVal
57372 + || (p_FmPortPerformanceCnt->queueCompVal
57373 + > MAX_PERFORMANCE_TX_QUEUE_COMP))
57374 + RETURN_ERROR(
57375 + MAJOR,
57376 + E_INVALID_VALUE,
57377 + ("performanceCnt.queueCompVal for Tx has to be in the range of 1 - %d", MAX_PERFORMANCE_TX_QUEUE_COMP));
57378 + break;
57379 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57380 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
57381 + if (p_FmPortPerformanceCnt->queueCompVal)
57382 + RETURN_ERROR(
57383 + MAJOR,
57384 + E_INVALID_VALUE,
57385 + ("performanceCnt.queueCompVal is not relevant for H/O ports."));
57386 + break;
57387 + default:
57388 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
57389 + }
57390 +
57391 + params.task_val = p_FmPortPerformanceCnt->taskCompVal;
57392 + params.queue_val = p_FmPortPerformanceCnt->queueCompVal;
57393 + params.dma_val = p_FmPortPerformanceCnt->dmaCompVal;
57394 + params.fifo_val = p_FmPortPerformanceCnt->fifoCompVal;
57395 +
57396 + err = fman_port_set_perf_cnt_params(&p_FmPort->port, &params);
57397 + if (err != 0)
57398 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_perf_cnt_params"));
57399 +
57400 + return E_OK;
57401 +}
57402 +
57403 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort)
57404 +{
57405 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57406 + t_FmPortPerformanceCnt currParams, savedParams;
57407 + t_Error err;
57408 + bool underTest, failed = FALSE;
57409 +
57410 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57411 +
57412 + XX_Print("Analyzing Performance parameters for port (type %d, id%d)\n",
57413 + p_FmPort->portType, p_FmPort->portId);
57414 +
57415 + currParams.taskCompVal = (uint8_t)p_FmPort->tasks.num;
57416 + if ((p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
57417 + || (p_FmPort->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND))
57418 + currParams.queueCompVal = 0;
57419 + else
57420 + currParams.queueCompVal = 1;
57421 + currParams.dmaCompVal = (uint8_t)p_FmPort->openDmas.num;
57422 + currParams.fifoCompVal = p_FmPort->fifoBufs.num;
57423 +
57424 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
57425 + ClearPerfCnts(p_FmPort);
57426 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
57427 + != E_OK)
57428 + RETURN_ERROR(MAJOR, err, NO_MSG);
57429 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
57430 + XX_UDelay(1000000);
57431 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
57432 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
57433 + {
57434 + XX_Print(
57435 + "Max num of defined port tasks (%d) utilized - Please enlarge\n",
57436 + p_FmPort->tasks.num);
57437 + failed = TRUE;
57438 + }
57439 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
57440 + {
57441 + XX_Print(
57442 + "Max num of defined port openDmas (%d) utilized - Please enlarge\n",
57443 + p_FmPort->openDmas.num);
57444 + failed = TRUE;
57445 + }
57446 + if (FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
57447 + {
57448 + XX_Print(
57449 + "Max size of defined port fifo (%d) utilized - Please enlarge\n",
57450 + p_FmPort->fifoBufs.num);
57451 + failed = TRUE;
57452 + }
57453 + if (failed)
57454 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
57455 +
57456 + memset(&savedParams, 0, sizeof(savedParams));
57457 + while (TRUE)
57458 + {
57459 + underTest = FALSE;
57460 + if ((currParams.taskCompVal != 1) && !savedParams.taskCompVal)
57461 + {
57462 + currParams.taskCompVal--;
57463 + underTest = TRUE;
57464 + }
57465 + if ((currParams.dmaCompVal != 1) && !savedParams.dmaCompVal)
57466 + {
57467 + currParams.dmaCompVal--;
57468 + underTest = TRUE;
57469 + }
57470 + if ((currParams.fifoCompVal != BMI_FIFO_UNITS)
57471 + && !savedParams.fifoCompVal)
57472 + {
57473 + currParams.fifoCompVal -= BMI_FIFO_UNITS;
57474 + underTest = TRUE;
57475 + }
57476 + if (!underTest)
57477 + break;
57478 +
57479 + ClearPerfCnts(p_FmPort);
57480 + if ((err = FM_PORT_SetPerformanceCountersParams(p_FmPort, &currParams))
57481 + != E_OK)
57482 + RETURN_ERROR(MAJOR, err, NO_MSG);
57483 + FM_PORT_SetPerformanceCounters(p_FmPort, TRUE);
57484 + XX_UDelay(1000000);
57485 + FM_PORT_SetPerformanceCounters(p_FmPort, FALSE);
57486 +
57487 + if (!savedParams.taskCompVal
57488 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL))
57489 + savedParams.taskCompVal = (uint8_t)(currParams.taskCompVal + 2);
57490 + if (!savedParams.dmaCompVal
57491 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL))
57492 + savedParams.dmaCompVal = (uint8_t)(currParams.dmaCompVal + 2);
57493 + if (!savedParams.fifoCompVal
57494 + && FM_PORT_GetCounter(p_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL))
57495 + savedParams.fifoCompVal = currParams.fifoCompVal
57496 + + (2 * BMI_FIFO_UNITS);
57497 + }
57498 +
57499 + XX_Print("best vals: tasks %d, dmas %d, fifos %d\n",
57500 + savedParams.taskCompVal, savedParams.dmaCompVal,
57501 + savedParams.fifoCompVal);
57502 + return E_OK;
57503 +}
57504 +
57505 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable)
57506 +{
57507 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57508 + int err;
57509 +
57510 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57511 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57512 +
57513 + err = fman_port_set_stats_cnt_mode(&p_FmPort->port, enable);
57514 + if (err != 0)
57515 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_stats_cnt_mode"));
57516 + return E_OK;
57517 +}
57518 +
57519 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs)
57520 +{
57521 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57522 + volatile uint32_t *p_ErrDiscard = NULL;
57523 + int err;
57524 +
57525 + UNUSED(p_ErrDiscard);
57526 + err = fman_port_set_err_mask(&p_FmPort->port, (uint32_t)errs);
57527 + if (err != 0)
57528 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_err_mask"));
57529 +
57530 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
57531 + if (p_FmPort->fmRevInfo.majorRev >= 6)
57532 + {
57533 + t_FmPcdCtrlParamsPage *p_ParamsPage;
57534 +
57535 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
57536 + (void**)&p_ParamsPage);
57537 + ASSERT_COND(p_ParamsPage);
57538 + switch (p_FmPort->portType)
57539 + {
57540 + case (e_FM_PORT_TYPE_RX_10G):
57541 + case (e_FM_PORT_TYPE_RX):
57542 + p_ErrDiscard =
57543 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm;
57544 + break;
57545 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
57546 + p_ErrDiscard =
57547 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm;
57548 + break;
57549 + default:
57550 + RETURN_ERROR(
57551 + MAJOR, E_INVALID_OPERATION,
57552 + ("available for Rx and offline parsing ports only"));
57553 + }
57554 + WRITE_UINT32(p_ParamsPage->errorsDiscardMask,
57555 + GET_UINT32(*p_ErrDiscard) | errs);
57556 + }
57557 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
57558 +
57559 + return E_OK;
57560 +}
57561 +
57562 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
57563 + bool enable)
57564 +{
57565 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57566 + int err;
57567 +
57568 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57569 + SANITY_CHECK_RETURN_ERROR(poolId<BM_MAX_NUM_OF_POOLS, E_INVALID_HANDLE);
57570 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57571 +
57572 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57573 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57574 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57575 + ("available for Rx ports only"));
57576 +
57577 + err = fman_port_set_bpool_cnt_mode(&p_FmPort->port, poolId, enable);
57578 + if (err != 0)
57579 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_set_bpool_cnt_mode"));
57580 + return E_OK;
57581 +}
57582 +
57583 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats)
57584 +{
57585 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57586 +
57587 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
57588 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G)){
57589 + p_BmiStats->cntCycle =
57590 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
57591 + /* fmbm_rccn */
57592 + p_BmiStats->cntTaskUtil =
57593 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
57594 + /* fmbm_rtuc */
57595 + p_BmiStats->cntQueueUtil =
57596 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
57597 + /* fmbm_rrquc */
57598 + p_BmiStats->cntDmaUtil =
57599 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
57600 + /* fmbm_rduc */
57601 + p_BmiStats->cntFifoUtil =
57602 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
57603 + /* fmbm_rfuc */
57604 + p_BmiStats->cntRxPauseActivation =
57605 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION);
57606 + /* fmbm_rpac */
57607 + p_BmiStats->cntFrame =
57608 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
57609 + /* fmbm_rfrc */
57610 + p_BmiStats->cntDiscardFrame =
57611 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
57612 + /* fmbm_rfdc */
57613 + p_BmiStats->cntDeallocBuf =
57614 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
57615 + /* fmbm_rbdc */
57616 + p_BmiStats->cntRxBadFrame =
57617 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_BAD_FRAME);
57618 + /* fmbm_rfbc */
57619 + p_BmiStats->cntRxLargeFrame =
57620 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LARGE_FRAME);
57621 + /* fmbm_rlfc */
57622 + p_BmiStats->cntRxFilterFrame =
57623 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
57624 + /* fmbm_rffc */
57625 + p_BmiStats->cntRxListDmaErr =
57626 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
57627 + /* fmbm_rfldec */
57628 + p_BmiStats->cntRxOutOfBuffersDiscard =
57629 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
57630 + /* fmbm_rodc */
57631 + p_BmiStats->cntWredDiscard = 0;
57632 + p_BmiStats->cntLengthErr = 0;
57633 + p_BmiStats->cntUnsupportedFormat = 0;
57634 + }
57635 + else if ((p_FmPort->portType == e_FM_PORT_TYPE_TX)
57636 + || (p_FmPort->portType == e_FM_PORT_TYPE_TX_10G)){
57637 + p_BmiStats->cntCycle =
57638 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
57639 + /* fmbm_tccn */
57640 + p_BmiStats->cntTaskUtil =
57641 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
57642 + /* fmbm_ttuc */
57643 + p_BmiStats->cntQueueUtil =
57644 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_QUEUE_UTIL);
57645 + /* fmbm_ttcquc */
57646 + p_BmiStats->cntDmaUtil =
57647 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
57648 + /* fmbm_tduc */
57649 + p_BmiStats->cntFifoUtil =
57650 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
57651 + /* fmbm_tfuc */
57652 + p_BmiStats->cntRxPauseActivation = 0;
57653 + p_BmiStats->cntFrame =
57654 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
57655 + /* fmbm_tfrc */
57656 + p_BmiStats->cntDiscardFrame =
57657 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
57658 + /* fmbm_tfdc */
57659 + p_BmiStats->cntDeallocBuf =
57660 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
57661 + /* fmbm_tbdc */
57662 + p_BmiStats->cntRxBadFrame = 0;
57663 + p_BmiStats->cntRxLargeFrame = 0;
57664 + p_BmiStats->cntRxFilterFrame = 0;
57665 + p_BmiStats->cntRxListDmaErr = 0;
57666 + p_BmiStats->cntRxOutOfBuffersDiscard = 0;
57667 + p_BmiStats->cntWredDiscard = 0;
57668 + p_BmiStats->cntLengthErr =
57669 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
57670 + /* fmbm_tfledc */
57671 + p_BmiStats->cntUnsupportedFormat =
57672 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
57673 + /* fmbm_tfufdc */
57674 + }
57675 + else if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
57676 + p_BmiStats->cntCycle =
57677 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_CYCLE);
57678 + /* fmbm_occn */
57679 + p_BmiStats->cntTaskUtil =
57680 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_TASK_UTIL);
57681 + /* fmbm_otuc */
57682 + p_BmiStats->cntQueueUtil = 0;
57683 + p_BmiStats->cntDmaUtil =
57684 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DMA_UTIL);
57685 + /* fmbm_oduc */
57686 + p_BmiStats->cntFifoUtil =
57687 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FIFO_UTIL);
57688 + /* fmbm_ofuc*/
57689 + p_BmiStats->cntRxPauseActivation = 0;
57690 + p_BmiStats->cntFrame =
57691 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_FRAME);
57692 + /* fmbm_ofrc */
57693 + p_BmiStats->cntDiscardFrame =
57694 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DISCARD_FRAME);
57695 + /* fmbm_ofdc */
57696 + p_BmiStats->cntDeallocBuf =
57697 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_DEALLOC_BUF);
57698 + /* fmbm_obdc*/
57699 + p_BmiStats->cntRxBadFrame = 0;
57700 + p_BmiStats->cntRxLargeFrame = 0;
57701 + p_BmiStats->cntRxFilterFrame =
57702 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_FILTER_FRAME);
57703 + /* fmbm_offc */
57704 + p_BmiStats->cntRxListDmaErr =
57705 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR);
57706 + /* fmbm_ofldec */
57707 + p_BmiStats->cntRxOutOfBuffersDiscard =
57708 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD);
57709 + /* fmbm_rodc */
57710 + p_BmiStats->cntWredDiscard =
57711 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_WRED_DISCARD);
57712 + /* fmbm_ofwdc */
57713 + p_BmiStats->cntLengthErr =
57714 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_LENGTH_ERR);
57715 + /* fmbm_ofledc */
57716 + p_BmiStats->cntUnsupportedFormat =
57717 + FM_PORT_GetCounter(h_FmPort, e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT);
57718 + /* fmbm_ofufdc */
57719 + }
57720 + return E_OK;
57721 +}
57722 +
57723 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters counter)
57724 +{
57725 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57726 + bool bmiCounter = FALSE;
57727 + enum fman_port_stats_counters statsType;
57728 + enum fman_port_perf_counters perfType;
57729 + enum fman_port_qmi_counters queueType;
57730 + bool isStats;
57731 + t_Error errCode;
57732 +
57733 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
57734 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57735 +
57736 + switch (counter)
57737 + {
57738 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
57739 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
57740 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
57741 + /* check that counter is available for the port type */
57742 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
57743 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57744 + {
57745 + REPORT_ERROR(MINOR, E_INVALID_STATE,
57746 + ("Requested counter is not available for Rx ports"));
57747 + return 0;
57748 + }
57749 + bmiCounter = FALSE;
57750 + break;
57751 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
57752 + bmiCounter = FALSE;
57753 + break;
57754 + default: /* BMI counters (or error - will be checked in BMI routine )*/
57755 + bmiCounter = TRUE;
57756 + break;
57757 + }
57758 +
57759 + if (bmiCounter)
57760 + {
57761 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
57762 + &perfType, &isStats);
57763 + if (errCode != E_OK)
57764 + {
57765 + REPORT_ERROR(MINOR, errCode, NO_MSG);
57766 + return 0;
57767 + }
57768 + if (isStats)
57769 + return fman_port_get_stats_counter(&p_FmPort->port, statsType);
57770 + else
57771 + return fman_port_get_perf_counter(&p_FmPort->port, perfType);
57772 + }
57773 + else /* QMI counter */
57774 + {
57775 + /* check that counters are enabled */
57776 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
57777 + & QMI_PORT_CFG_EN_COUNTERS))
57778 +
57779 + {
57780 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter was not enabled"));
57781 + return 0;
57782 + }
57783 +
57784 + /* Set counter */
57785 + switch (counter)
57786 + {
57787 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
57788 + queueType = E_FMAN_PORT_ENQ_TOTAL;
57789 + break;
57790 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
57791 + queueType = E_FMAN_PORT_DEQ_TOTAL;
57792 + break;
57793 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
57794 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
57795 + break;
57796 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
57797 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
57798 + break;
57799 + default:
57800 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available"));
57801 + return 0;
57802 + }
57803 +
57804 + return fman_port_get_qmi_counter(&p_FmPort->port, queueType);
57805 + }
57806 +
57807 + return 0;
57808 +}
57809 +
57810 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters counter,
57811 + uint32_t value)
57812 +{
57813 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57814 + bool bmiCounter = FALSE;
57815 + enum fman_port_stats_counters statsType;
57816 + enum fman_port_perf_counters perfType;
57817 + enum fman_port_qmi_counters queueType;
57818 + bool isStats;
57819 + t_Error errCode;
57820 +
57821 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57822 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57823 +
57824 + switch (counter)
57825 + {
57826 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
57827 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
57828 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
57829 + /* check that counter is available for the port type */
57830 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX)
57831 + || (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57832 + RETURN_ERROR(
57833 + MINOR, E_INVALID_STATE,
57834 + ("Requested counter is not available for Rx ports"));
57835 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
57836 + bmiCounter = FALSE;
57837 + break;
57838 + default: /* BMI counters (or error - will be checked in BMI routine )*/
57839 + bmiCounter = TRUE;
57840 + break;
57841 + }
57842 +
57843 + if (bmiCounter)
57844 + {
57845 + errCode = BmiPortCheckAndGetCounterType(p_FmPort, counter, &statsType,
57846 + &perfType, &isStats);
57847 + if (errCode != E_OK)
57848 + {
57849 + RETURN_ERROR(MINOR, errCode, NO_MSG);
57850 + }
57851 + if (isStats)
57852 + fman_port_set_stats_counter(&p_FmPort->port, statsType, value);
57853 + else
57854 + fman_port_set_perf_counter(&p_FmPort->port, perfType, value);
57855 + }
57856 + else /* QMI counter */
57857 + {
57858 + /* check that counters are enabled */
57859 + if (!(GET_UINT32(p_FmPort->port.qmi_regs->fmqm_pnc)
57860 + & QMI_PORT_CFG_EN_COUNTERS))
57861 + {
57862 + RETURN_ERROR(MINOR, E_INVALID_STATE,
57863 + ("Requested counter was not enabled"));
57864 + }
57865 +
57866 + /* Set counter */
57867 + switch (counter)
57868 + {
57869 + case (e_FM_PORT_COUNTERS_ENQ_TOTAL):
57870 + queueType = E_FMAN_PORT_ENQ_TOTAL;
57871 + break;
57872 + case (e_FM_PORT_COUNTERS_DEQ_TOTAL):
57873 + queueType = E_FMAN_PORT_DEQ_TOTAL;
57874 + break;
57875 + case (e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT):
57876 + queueType = E_FMAN_PORT_DEQ_FROM_DFLT;
57877 + break;
57878 + case (e_FM_PORT_COUNTERS_DEQ_CONFIRM):
57879 + queueType = E_FMAN_PORT_DEQ_CONFIRM;
57880 + break;
57881 + default:
57882 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
57883 + ("Requested counter is not available"));
57884 + }
57885 +
57886 + fman_port_set_qmi_counter(&p_FmPort->port, queueType, value);
57887 + }
57888 +
57889 + return E_OK;
57890 +}
57891 +
57892 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId)
57893 +{
57894 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57895 +
57896 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, 0);
57897 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57898 +
57899 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
57900 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57901 + {
57902 + REPORT_ERROR(MINOR, E_INVALID_STATE, ("Requested counter is not available for non-Rx ports"));
57903 + return 0;
57904 + }
57905 + return fman_port_get_bpool_counter(&p_FmPort->port, poolId);
57906 +}
57907 +
57908 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId,
57909 + uint32_t value)
57910 +{
57911 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
57912 +
57913 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57914 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57915 +
57916 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX)
57917 + && (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
57918 + RETURN_ERROR( MINOR, E_INVALID_STATE,
57919 + ("Requested counter is not available for non-Rx ports"));
57920 +
57921 + fman_port_set_bpool_counter(&p_FmPort->port, poolId, value);
57922 + return E_OK;
57923 +}
57924 +bool FM_PORT_IsStalled(t_Handle h_FmPort)
57925 +{
57926 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57927 + t_Error err;
57928 + bool isStalled;
57929 +
57930 + SANITY_CHECK_RETURN_VALUE(p_FmPort, E_INVALID_HANDLE, FALSE);
57931 + SANITY_CHECK_RETURN_VALUE(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE,
57932 + FALSE);
57933 +
57934 + err = FmIsPortStalled(p_FmPort->h_Fm, p_FmPort->hardwarePortId, &isStalled);
57935 + if (err != E_OK)
57936 + {
57937 + REPORT_ERROR(MAJOR, err, NO_MSG);
57938 + return TRUE;
57939 + }
57940 + return isStalled;
57941 +}
57942 +
57943 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort)
57944 +{
57945 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57946 +
57947 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57948 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57949 +
57950 + return FmResumeStalledPort(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
57951 +}
57952 +
57953 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum)
57954 +{
57955 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57956 + int err;
57957 +
57958 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57959 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
57960 +
57961 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
57962 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
57963 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
57964 + ("available for Rx ports only"));
57965 +
57966 + if (l4Checksum)
57967 + err = fman_port_modify_rx_fd_bits(
57968 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
57969 + TRUE);
57970 + else
57971 + err = fman_port_modify_rx_fd_bits(
57972 + &p_FmPort->port, (uint8_t)(BMI_PORT_RFNE_FRWD_DCL4C >> 24),
57973 + FALSE);
57974 + if (err != 0)
57975 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_modify_rx_fd_bits"));
57976 +
57977 + return E_OK;
57978 +}
57979 +
57980 +/*****************************************************************************/
57981 +/* API Run-time PCD Control unit functions */
57982 +/*****************************************************************************/
57983 +
57984 +#if (DPAA_VERSION >= 11)
57985 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_VSPParams)
57986 +{
57987 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
57988 + t_Error err = E_OK;
57989 + volatile uint32_t *p_BmiStorageProfileId = NULL, *p_BmiVspe = NULL;
57990 + uint32_t tmpReg = 0, tmp = 0;
57991 + uint16_t hwStoragePrflId;
57992 +
57993 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
57994 + SANITY_CHECK_RETURN_ERROR(p_FmPort->h_Fm, E_INVALID_HANDLE);
57995 + /*for numOfProfiles = 0 don't call this function*/
57996 + SANITY_CHECK_RETURN_ERROR(p_VSPParams->numOfProfiles, E_INVALID_VALUE);
57997 + /*dfltRelativeId should be in the range of numOfProfiles*/
57998 + SANITY_CHECK_RETURN_ERROR(
57999 + p_VSPParams->dfltRelativeId < p_VSPParams->numOfProfiles,
58000 + E_INVALID_VALUE);
58001 + /*p_FmPort should be from Rx type or OP*/
58002 + SANITY_CHECK_RETURN_ERROR(
58003 + ((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)),
58004 + E_INVALID_VALUE);
58005 + /*port should be disabled*/
58006 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->enabled, E_INVALID_STATE);
58007 + /*if its called for Rx port relevant Tx Port should be passed (initialized) too and it should be disabled*/
58008 + SANITY_CHECK_RETURN_ERROR(
58009 + ((p_VSPParams->h_FmTxPort && !((t_FmPort *)(p_VSPParams->h_FmTxPort))->enabled) || (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)),
58010 + E_INVALID_VALUE);
58011 + /*should be called before SetPCD - this port should be without PCD*/
58012 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->pcdEngines, E_INVALID_STATE);
58013 +
58014 + /*alloc window of VSPs for this port*/
58015 + err = FmVSPAllocForPort(p_FmPort->h_Fm, p_FmPort->portType,
58016 + p_FmPort->portId, p_VSPParams->numOfProfiles);
58017 + if (err != E_OK)
58018 + RETURN_ERROR(MAJOR, err, NO_MSG);
58019 +
58020 + /*get absolute VSP ID for dfltRelative*/
58021 + err = FmVSPGetAbsoluteProfileId(p_FmPort->h_Fm, p_FmPort->portType,
58022 + p_FmPort->portId,
58023 + p_VSPParams->dfltRelativeId,
58024 + &hwStoragePrflId);
58025 + if (err != E_OK)
58026 + RETURN_ERROR(MAJOR, err, NO_MSG);
58027 +
58028 + /*fill relevant registers for p_FmPort and relative TxPort in the case p_FmPort from Rx type*/
58029 + switch (p_FmPort->portType)
58030 + {
58031 + case (e_FM_PORT_TYPE_RX_10G):
58032 + case (e_FM_PORT_TYPE_RX):
58033 + p_BmiStorageProfileId =
58034 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid);
58035 + p_BmiVspe =
58036 + &(((t_FmPort *)(p_VSPParams->h_FmTxPort))->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tfne);
58037 +
58038 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
58039 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
58040 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
58041 +
58042 + tmpReg = GET_UINT32(*p_BmiVspe);
58043 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN);
58044 +
58045 + p_BmiStorageProfileId =
58046 + &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid;
58047 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rpp;
58048 + hwStoragePrflId = p_VSPParams->dfltRelativeId;
58049 + break;
58050 +
58051 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
58052 + tmpReg = NIA_ENG_BMI | NIA_BMI_AC_FETCH_ALL_FRAME;
58053 + WRITE_UINT32( p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs.fmqm_pndn,
58054 + tmpReg);
58055 +
58056 + p_BmiStorageProfileId =
58057 + &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofqid;
58058 + p_BmiVspe = &p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_opp;
58059 + tmp |= BMI_EBD_EN;
58060 + break;
58061 +
58062 + default:
58063 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58064 + ("available for Rx and offline parsing ports only"));
58065 + }
58066 +
58067 + p_FmPort->vspe = TRUE;
58068 + p_FmPort->dfltRelativeId = p_VSPParams->dfltRelativeId;
58069 +
58070 + tmpReg = GET_UINT32(*p_BmiStorageProfileId) & ~BMI_SP_ID_MASK;
58071 + tmpReg |= (uint32_t)hwStoragePrflId << BMI_SP_ID_SHIFT;
58072 + WRITE_UINT32(*p_BmiStorageProfileId, tmpReg);
58073 +
58074 + tmpReg = GET_UINT32(*p_BmiVspe);
58075 + WRITE_UINT32(*p_BmiVspe, tmpReg | BMI_SP_EN | tmp);
58076 + return E_OK;
58077 +}
58078 +#endif /* (DPAA_VERSION >= 11) */
58079 +
58080 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles)
58081 +{
58082 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58083 + t_Error err = E_OK;
58084 +
58085 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
58086 + ASSERT_COND(p_FmPort->h_FmPcd);
58087 +
58088 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58089 + {
58090 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58091 + return ERROR_CODE(E_BUSY);
58092 + }
58093 +
58094 + if (numOfProfiles)
58095 + {
58096 + err = FmPcdPlcrAllocProfiles(p_FmPort->h_FmPcd,
58097 + p_FmPort->hardwarePortId, numOfProfiles);
58098 + if (err)
58099 + RETURN_ERROR(MAJOR, err, NO_MSG);
58100 + }
58101 + /* set the port handle within the PCD policer, even if no profiles defined */
58102 + FmPcdPortRegister(p_FmPort->h_FmPcd, h_FmPort, p_FmPort->hardwarePortId);
58103 +
58104 + RELEASE_LOCK(p_FmPort->lock);
58105 +
58106 + return E_OK;
58107 +}
58108 +
58109 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort)
58110 +{
58111 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58112 + t_Error err = E_OK;
58113 +
58114 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58115 + {
58116 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58117 + return ERROR_CODE(E_BUSY);
58118 + }
58119 +
58120 + err = FmPcdPlcrFreeProfiles(p_FmPort->h_FmPcd, p_FmPort->hardwarePortId);
58121 +
58122 + RELEASE_LOCK(p_FmPort->lock);
58123 +
58124 + if (err)
58125 + RETURN_ERROR(MAJOR, err, NO_MSG);
58126 +
58127 + return E_OK;
58128 +}
58129 +
58130 +t_Error FM_PORT_PcdKgModifyInitialScheme(t_Handle h_FmPort,
58131 + t_FmPcdKgSchemeSelect *p_FmPcdKgScheme)
58132 +{
58133 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58134 + volatile uint32_t *p_BmiHpnia = NULL;
58135 + uint32_t tmpReg;
58136 + uint8_t relativeSchemeId;
58137 + uint8_t physicalSchemeId;
58138 +
58139 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58140 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58141 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
58142 + E_INVALID_STATE);
58143 +
58144 + tmpReg = (uint32_t)((p_FmPort->pcdEngines & FM_PCD_CC) ? NIA_KG_CC_EN : 0);
58145 + switch (p_FmPort->portType)
58146 + {
58147 + case (e_FM_PORT_TYPE_RX_10G):
58148 + case (e_FM_PORT_TYPE_RX):
58149 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
58150 + break;
58151 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
58152 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
58153 + break;
58154 + default:
58155 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58156 + ("available for Rx and offline parsing ports only"));
58157 + }
58158 +
58159 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58160 + {
58161 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58162 + return ERROR_CODE(E_BUSY);
58163 + }
58164 +
58165 + /* if we want to change to direct scheme, we need to check that this scheme is valid */
58166 + if (p_FmPcdKgScheme->direct)
58167 + {
58168 + physicalSchemeId = FmPcdKgGetSchemeId(p_FmPcdKgScheme->h_DirectScheme);
58169 + /* check that this scheme is bound to this port */
58170 + if (!(p_FmPort->schemesPerPortVector
58171 + & (uint32_t)(1 << (31 - (uint32_t)physicalSchemeId))))
58172 + {
58173 + RELEASE_LOCK(p_FmPort->lock);
58174 + RETURN_ERROR(
58175 + MAJOR, E_INVALID_STATE,
58176 + ("called with a scheme that is not bound to this port"));
58177 + }
58178 +
58179 + relativeSchemeId = FmPcdKgGetRelativeSchemeId(p_FmPort->h_FmPcd,
58180 + physicalSchemeId);
58181 + if (relativeSchemeId >= FM_PCD_KG_NUM_OF_SCHEMES)
58182 + {
58183 + RELEASE_LOCK(p_FmPort->lock);
58184 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE,
58185 + ("called with invalid Scheme "));
58186 + }
58187 +
58188 + if (!FmPcdKgIsSchemeValidSw(p_FmPcdKgScheme->h_DirectScheme))
58189 + {
58190 + RELEASE_LOCK(p_FmPort->lock);
58191 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
58192 + ("called with uninitialized Scheme "));
58193 + }
58194 +
58195 + WRITE_UINT32(
58196 + *p_BmiHpnia,
58197 + NIA_ENG_KG | tmpReg | NIA_KG_DIRECT | (uint32_t)physicalSchemeId);
58198 + }
58199 + else
58200 + /* change to indirect scheme */
58201 + WRITE_UINT32(*p_BmiHpnia, NIA_ENG_KG | tmpReg);
58202 + RELEASE_LOCK(p_FmPort->lock);
58203 +
58204 + return E_OK;
58205 +}
58206 +
58207 +t_Error FM_PORT_PcdPlcrModifyInitialProfile(t_Handle h_FmPort,
58208 + t_Handle h_Profile)
58209 +{
58210 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58211 + volatile uint32_t *p_BmiNia;
58212 + volatile uint32_t *p_BmiHpnia;
58213 + uint32_t tmpReg;
58214 + uint16_t absoluteProfileId = FmPcdPlcrProfileGetAbsoluteId(h_Profile);
58215 +
58216 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58217 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58218 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_PLCR,
58219 + E_INVALID_STATE);
58220 +
58221 + /* check relevance of this routine - only when policer is used
58222 + directly after BMI or Parser */
58223 + if ((p_FmPort->pcdEngines & FM_PCD_KG)
58224 + || (p_FmPort->pcdEngines & FM_PCD_CC))
58225 + RETURN_ERROR(
58226 + MAJOR,
58227 + E_INVALID_STATE,
58228 + ("relevant only when PCD support mode is e_FM_PCD_SUPPORT_PLCR_ONLY or e_FM_PCD_SUPPORT_PRS_AND_PLCR"));
58229 +
58230 + switch (p_FmPort->portType)
58231 + {
58232 + case (e_FM_PORT_TYPE_RX_10G):
58233 + case (e_FM_PORT_TYPE_RX):
58234 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
58235 + p_BmiHpnia = &p_FmPort->port.bmi_regs->rx.fmbm_rfpne;
58236 + tmpReg = GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK;
58237 + break;
58238 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
58239 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
58240 + p_BmiHpnia = &p_FmPort->port.bmi_regs->oh.fmbm_ofpne;
58241 + tmpReg = 0;
58242 + break;
58243 + default:
58244 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58245 + ("available for Rx and offline parsing ports only"));
58246 + }
58247 +
58248 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58249 + {
58250 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58251 + return ERROR_CODE(E_BUSY);
58252 + }
58253 +
58254 + if (!FmPcdPlcrIsProfileValid(p_FmPort->h_FmPcd, absoluteProfileId))
58255 + {
58256 + RELEASE_LOCK(p_FmPort->lock);
58257 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Invalid profile"));
58258 + }
58259 +
58260 + tmpReg |= (uint32_t)(NIA_ENG_PLCR | NIA_PLCR_ABSOLUTE | absoluteProfileId);
58261 +
58262 + if (p_FmPort->pcdEngines & FM_PCD_PRS) /* e_FM_PCD_SUPPORT_PRS_AND_PLCR */
58263 + {
58264 + /* update BMI HPNIA */
58265 + WRITE_UINT32(*p_BmiHpnia, tmpReg);
58266 + }
58267 + else /* e_FM_PCD_SUPPORT_PLCR_ONLY */
58268 + {
58269 + /* rfne may contain FDCS bits, so first we read them. */
58270 + tmpReg |= (GET_UINT32(*p_BmiNia) & BMI_RFNE_FDCS_MASK);
58271 + /* update BMI NIA */
58272 + WRITE_UINT32(*p_BmiNia, tmpReg);
58273 + }RELEASE_LOCK(p_FmPort->lock);
58274 +
58275 + return E_OK;
58276 +}
58277 +
58278 +t_Error FM_PORT_PcdCcModifyTree(t_Handle h_FmPort, t_Handle h_CcTree)
58279 +{
58280 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58281 + t_Error err = E_OK;
58282 + volatile uint32_t *p_BmiCcBase = NULL;
58283 + volatile uint32_t *p_BmiNia = NULL;
58284 + uint32_t ccTreePhysOffset;
58285 +
58286 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58287 + SANITY_CHECK_RETURN_ERROR(h_CcTree, E_INVALID_HANDLE);
58288 +
58289 + if (p_FmPort->imEn)
58290 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58291 + ("available for non-independent mode ports only"));
58292 +
58293 + /* get PCD registers pointers */
58294 + switch (p_FmPort->portType)
58295 + {
58296 + case (e_FM_PORT_TYPE_RX_10G):
58297 + case (e_FM_PORT_TYPE_RX):
58298 + p_BmiNia = &p_FmPort->port.bmi_regs->rx.fmbm_rfne;
58299 + break;
58300 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
58301 + p_BmiNia = &p_FmPort->port.bmi_regs->oh.fmbm_ofne;
58302 + break;
58303 + default:
58304 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58305 + ("available for Rx and offline parsing ports only"));
58306 + }
58307 +
58308 + /* check that current NIA is BMI to BMI */
58309 + if ((GET_UINT32(*p_BmiNia) & ~BMI_RFNE_FDCS_MASK)
58310 + != GET_NIA_BMI_AC_ENQ_FRAME(p_FmPort->h_FmPcd))
58311 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58312 + ("may be called only for ports in BMI-to-BMI state."));
58313 +
58314 + if (p_FmPort->pcdEngines & FM_PCD_CC)
58315 + {
58316 + if (p_FmPort->h_IpReassemblyManip)
58317 + {
58318 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
58319 + p_FmPort->h_IpReassemblyManip, FALSE);
58320 + if (err != E_OK)
58321 + {
58322 + RETURN_ERROR(MAJOR, err, NO_MSG);
58323 + }
58324 + }
58325 + else
58326 + if (p_FmPort->h_CapwapReassemblyManip)
58327 + {
58328 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd, h_CcTree, NULL,
58329 + p_FmPort->h_CapwapReassemblyManip,
58330 + FALSE);
58331 + if (err != E_OK)
58332 + {
58333 + RETURN_ERROR(MAJOR, err, NO_MSG);
58334 + }
58335 + }
58336 + switch (p_FmPort->portType)
58337 + {
58338 + case (e_FM_PORT_TYPE_RX_10G):
58339 + case (e_FM_PORT_TYPE_RX):
58340 + p_BmiCcBase = &p_FmPort->port.bmi_regs->rx.fmbm_rccb;
58341 + break;
58342 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
58343 + p_BmiCcBase = &p_FmPort->port.bmi_regs->oh.fmbm_occb;
58344 + break;
58345 + default:
58346 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Invalid port type"));
58347 + }
58348 +
58349 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58350 + {
58351 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58352 + return ERROR_CODE(E_BUSY);
58353 + }
58354 + err = FmPcdCcBindTree(p_FmPort->h_FmPcd, NULL, h_CcTree,
58355 + &ccTreePhysOffset, h_FmPort);
58356 + if (err)
58357 + {
58358 + RELEASE_LOCK(p_FmPort->lock);
58359 + RETURN_ERROR(MAJOR, err, NO_MSG);
58360 + }WRITE_UINT32(*p_BmiCcBase, ccTreePhysOffset);
58361 +
58362 + p_FmPort->ccTreeId = h_CcTree;
58363 + RELEASE_LOCK(p_FmPort->lock);
58364 + }
58365 + else
58366 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
58367 + ("Coarse Classification not defined for this port."));
58368 +
58369 + return E_OK;
58370 +}
58371 +
58372 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort)
58373 +{
58374 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58375 + t_Error err = E_OK;
58376 +
58377 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58378 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58379 +
58380 + if (p_FmPort->imEn)
58381 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58382 + ("available for non-independent mode ports only"));
58383 +
58384 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58385 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58386 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58387 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58388 + ("available for Rx and offline parsing ports only"));
58389 +
58390 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58391 + {
58392 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58393 + return ERROR_CODE(E_BUSY);
58394 + }
58395 +
58396 + if (p_FmPort->h_ReassemblyTree)
58397 + p_FmPort->pcdEngines |= FM_PCD_CC;
58398 +
58399 + err = AttachPCD(h_FmPort);
58400 + RELEASE_LOCK(p_FmPort->lock);
58401 +
58402 + return err;
58403 +}
58404 +
58405 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort)
58406 +{
58407 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58408 + t_Error err = E_OK;
58409 +
58410 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58411 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58412 +
58413 + if (p_FmPort->imEn)
58414 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58415 + ("available for non-independent mode ports only"));
58416 +
58417 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58418 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58419 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58420 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58421 + ("available for Rx and offline parsing ports only"));
58422 +
58423 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58424 + {
58425 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58426 + return ERROR_CODE(E_BUSY);
58427 + }
58428 +
58429 + err = DetachPCD(h_FmPort);
58430 + if (err != E_OK)
58431 + {
58432 + RELEASE_LOCK(p_FmPort->lock);
58433 + RETURN_ERROR(MAJOR, err, NO_MSG);
58434 + }
58435 +
58436 + if (p_FmPort->h_ReassemblyTree)
58437 + p_FmPort->pcdEngines &= ~FM_PCD_CC;
58438 + RELEASE_LOCK(p_FmPort->lock);
58439 +
58440 + return E_OK;
58441 +}
58442 +
58443 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_PcdParam)
58444 +{
58445 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58446 + t_Error err = E_OK;
58447 + t_FmPortPcdParams modifiedPcdParams, *p_PcdParams;
58448 + t_FmPcdCcTreeParams *p_FmPcdCcTreeParams;
58449 + t_FmPortPcdCcParams fmPortPcdCcParams;
58450 + t_FmPortGetSetCcParams fmPortGetSetCcParams;
58451 +
58452 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58453 + SANITY_CHECK_RETURN_ERROR(p_PcdParam, E_NULL_POINTER);
58454 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58455 +
58456 + if (p_FmPort->imEn)
58457 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58458 + ("available for non-independent mode ports only"));
58459 +
58460 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58461 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58462 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58463 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58464 + ("available for Rx and offline parsing ports only"));
58465 +
58466 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58467 + {
58468 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58469 + return ERROR_CODE(E_BUSY);
58470 + }
58471 +
58472 + p_FmPort->h_FmPcd = FmGetPcdHandle(p_FmPort->h_Fm);
58473 + ASSERT_COND(p_FmPort->h_FmPcd);
58474 +
58475 + if (p_PcdParam->p_CcParams && !p_PcdParam->p_CcParams->h_CcTree)
58476 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE,
58477 + ("Tree handle must be given if CC is required"));
58478 +
58479 + memcpy(&modifiedPcdParams, p_PcdParam, sizeof(t_FmPortPcdParams));
58480 + p_PcdParams = &modifiedPcdParams;
58481 + if ((p_PcdParams->h_IpReassemblyManip)
58482 +#if (DPAA_VERSION >= 11)
58483 + || (p_PcdParams->h_CapwapReassemblyManip)
58484 +#endif /* (DPAA_VERSION >= 11) */
58485 + )
58486 + {
58487 + if ((p_PcdParams->pcdSupport != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
58488 + && (p_PcdParams->pcdSupport
58489 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC)
58490 + && (p_PcdParams->pcdSupport
58491 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR)
58492 + && (p_PcdParams->pcdSupport
58493 + != e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR))
58494 + {
58495 + RELEASE_LOCK(p_FmPort->lock);
58496 + RETURN_ERROR( MAJOR, E_INVALID_STATE,
58497 + ("pcdSupport must have KG for supporting Reassembly"));
58498 + }
58499 + p_FmPort->h_IpReassemblyManip = p_PcdParams->h_IpReassemblyManip;
58500 +#if (DPAA_VERSION >= 11)
58501 + if ((p_PcdParams->h_IpReassemblyManip)
58502 + && (p_PcdParams->h_CapwapReassemblyManip))
58503 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
58504 + ("Either IP-R or CAPWAP-R is allowed"));
58505 + if ((p_PcdParams->h_CapwapReassemblyManip)
58506 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58507 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
58508 + ("CAPWAP-R is allowed only on offline-port"));
58509 + if (p_PcdParams->h_CapwapReassemblyManip)
58510 + p_FmPort->h_CapwapReassemblyManip =
58511 + p_PcdParams->h_CapwapReassemblyManip;
58512 +#endif /* (DPAA_VERSION >= 11) */
58513 +
58514 + if (!p_PcdParams->p_CcParams)
58515 + {
58516 + if (!((p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
58517 + || (p_PcdParams->pcdSupport
58518 + == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR)))
58519 + {
58520 + RELEASE_LOCK(p_FmPort->lock);
58521 + RETURN_ERROR(
58522 + MAJOR,
58523 + E_INVALID_STATE,
58524 + ("PCD initialization structure is not consistent with pcdSupport"));
58525 + }
58526 +
58527 + /* No user-tree, need to build internal tree */
58528 + p_FmPcdCcTreeParams = (t_FmPcdCcTreeParams*)XX_Malloc(
58529 + sizeof(t_FmPcdCcTreeParams));
58530 + if (!p_FmPcdCcTreeParams)
58531 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_FmPcdCcTreeParams"));
58532 + memset(p_FmPcdCcTreeParams, 0, sizeof(t_FmPcdCcTreeParams));
58533 + p_FmPcdCcTreeParams->h_NetEnv = p_PcdParams->h_NetEnv;
58534 + p_FmPort->h_ReassemblyTree = FM_PCD_CcRootBuild(
58535 + p_FmPort->h_FmPcd, p_FmPcdCcTreeParams);
58536 +
58537 + if (!p_FmPort->h_ReassemblyTree)
58538 + {
58539 + RELEASE_LOCK(p_FmPort->lock);
58540 + XX_Free(p_FmPcdCcTreeParams);
58541 + RETURN_ERROR( MAJOR, E_INVALID_HANDLE,
58542 + ("FM_PCD_CcBuildTree for Reassembly failed"));
58543 + }
58544 + if (p_PcdParams->pcdSupport == e_FM_PORT_PCD_SUPPORT_PRS_AND_KG)
58545 + p_PcdParams->pcdSupport =
58546 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC;
58547 + else
58548 + p_PcdParams->pcdSupport =
58549 + e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR;
58550 +
58551 + memset(&fmPortPcdCcParams, 0, sizeof(t_FmPortPcdCcParams));
58552 + fmPortPcdCcParams.h_CcTree = p_FmPort->h_ReassemblyTree;
58553 + p_PcdParams->p_CcParams = &fmPortPcdCcParams;
58554 + XX_Free(p_FmPcdCcTreeParams);
58555 + }
58556 +
58557 + if (p_FmPort->h_IpReassemblyManip)
58558 + err = FmPcdCcTreeAddIPR(p_FmPort->h_FmPcd,
58559 + p_PcdParams->p_CcParams->h_CcTree,
58560 + p_PcdParams->h_NetEnv,
58561 + p_FmPort->h_IpReassemblyManip, TRUE);
58562 +#if (DPAA_VERSION >= 11)
58563 + else
58564 + if (p_FmPort->h_CapwapReassemblyManip)
58565 + err = FmPcdCcTreeAddCPR(p_FmPort->h_FmPcd,
58566 + p_PcdParams->p_CcParams->h_CcTree,
58567 + p_PcdParams->h_NetEnv,
58568 + p_FmPort->h_CapwapReassemblyManip,
58569 + TRUE);
58570 +#endif /* (DPAA_VERSION >= 11) */
58571 +
58572 + if (err != E_OK)
58573 + {
58574 + if (p_FmPort->h_ReassemblyTree)
58575 + {
58576 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58577 + p_FmPort->h_ReassemblyTree = NULL;
58578 + }RELEASE_LOCK(p_FmPort->lock);
58579 + RETURN_ERROR(MAJOR, err, NO_MSG);
58580 + }
58581 + }
58582 +
58583 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
58584 + {
58585 + if (p_FmPort->h_ReassemblyTree)
58586 + {
58587 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58588 + p_FmPort->h_ReassemblyTree = NULL;
58589 + }RELEASE_LOCK(p_FmPort->lock);
58590 + DBG(TRACE, ("Try LockAll - BUSY"));
58591 + return ERROR_CODE(E_BUSY);
58592 + }
58593 +
58594 + err = SetPcd(h_FmPort, p_PcdParams);
58595 + if (err)
58596 + {
58597 + if (p_FmPort->h_ReassemblyTree)
58598 + {
58599 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58600 + p_FmPort->h_ReassemblyTree = NULL;
58601 + }
58602 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58603 + RELEASE_LOCK(p_FmPort->lock);
58604 + RETURN_ERROR(MAJOR, err, NO_MSG);
58605 + }
58606 +
58607 + if ((p_FmPort->pcdEngines & FM_PCD_PRS)
58608 + && (p_PcdParams->p_PrsParams->includeInPrsStatistics))
58609 + {
58610 + err = FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
58611 + p_FmPort->hardwarePortId, TRUE);
58612 + if (err)
58613 + {
58614 + DeletePcd(p_FmPort);
58615 + if (p_FmPort->h_ReassemblyTree)
58616 + {
58617 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58618 + p_FmPort->h_ReassemblyTree = NULL;
58619 + }
58620 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58621 + RELEASE_LOCK(p_FmPort->lock);
58622 + RETURN_ERROR(MAJOR, err, NO_MSG);
58623 + }
58624 + p_FmPort->includeInPrsStatistics = TRUE;
58625 + }
58626 +
58627 + FmPcdIncNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
58628 +
58629 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
58630 + {
58631 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
58632 +
58633 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
58634 + {
58635 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
58636 + if ((p_FmPort->fmRevInfo.majorRev < 6) &&
58637 + (p_FmPort->pcdEngines & FM_PCD_KG))
58638 + {
58639 + int i;
58640 + for (i = 0; i<p_PcdParams->p_KgParams->numOfSchemes; i++)
58641 + /* The following function must be locked */
58642 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd,
58643 + p_PcdParams->p_KgParams->h_Schemes[i],
58644 + UPDATE_KG_NIA_CC_WA,
58645 + 0);
58646 + }
58647 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
58648 +
58649 +#if (DPAA_VERSION >= 11)
58650 + {
58651 + t_FmPcdCtrlParamsPage *p_ParamsPage;
58652 +
58653 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
58654 + (void**)&p_ParamsPage);
58655 + ASSERT_COND(p_ParamsPage);
58656 + WRITE_UINT32(p_ParamsPage->postBmiFetchNia,
58657 + p_FmPort->savedBmiNia);
58658 + }
58659 +#endif /* (DPAA_VERSION >= 11) */
58660 +
58661 + /* Set post-bmi-fetch nia */
58662 + p_FmPort->savedBmiNia &= BMI_RFNE_FDCS_MASK;
58663 + p_FmPort->savedBmiNia |= (NIA_FM_CTL_AC_POST_BMI_FETCH
58664 + | NIA_ENG_FM_CTL);
58665 +
58666 + /* Set pre-bmi-fetch nia */
58667 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNDN;
58668 +#if (DPAA_VERSION >= 11)
58669 + fmPortGetSetCcParams.setCcParams.nia =
58670 + (NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME | NIA_ENG_FM_CTL);
58671 +#else
58672 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER | NIA_ENG_FM_CTL);
58673 +#endif /* (DPAA_VERSION >= 11) */
58674 + if ((err = FmPortGetSetCcParams(p_FmPort, &fmPortGetSetCcParams))
58675 + != E_OK)
58676 + {
58677 + DeletePcd(p_FmPort);
58678 + if (p_FmPort->h_ReassemblyTree)
58679 + {
58680 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58681 + p_FmPort->h_ReassemblyTree = NULL;
58682 + }
58683 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58684 + RELEASE_LOCK(p_FmPort->lock);
58685 + RETURN_ERROR(MAJOR, err, NO_MSG);
58686 + }
58687 + }
58688 +
58689 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58690 +
58691 + /* Set pop-to-next-step nia */
58692 +#if (DPAA_VERSION == 10)
58693 + if (p_FmPort->fmRevInfo.majorRev < 6)
58694 + {
58695 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_PNEN;
58696 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
58697 + }
58698 + else
58699 + {
58700 +#endif /* (DPAA_VERSION == 10) */
58701 + fmPortGetSetCcParams.getCcParams.type = GET_NIA_FPNE;
58702 +#if (DPAA_VERSION == 10)
58703 + }
58704 +#endif /* (DPAA_VERSION == 10) */
58705 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
58706 + != E_OK)
58707 + {
58708 + DeletePcd(p_FmPort);
58709 + if (p_FmPort->h_ReassemblyTree)
58710 + {
58711 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58712 + p_FmPort->h_ReassemblyTree = NULL;
58713 + }RELEASE_LOCK(p_FmPort->lock);
58714 + RETURN_ERROR(MAJOR, err, NO_MSG);
58715 + }
58716 +
58717 + /* Set post-bmi-prepare-to-enq nia */
58718 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
58719 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ
58720 + | NIA_ENG_FM_CTL);
58721 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
58722 + != E_OK)
58723 + {
58724 + DeletePcd(p_FmPort);
58725 + if (p_FmPort->h_ReassemblyTree)
58726 + {
58727 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58728 + p_FmPort->h_ReassemblyTree = NULL;
58729 + }RELEASE_LOCK(p_FmPort->lock);
58730 + RETURN_ERROR(MAJOR, err, NO_MSG);
58731 + }
58732 +
58733 + if ((p_FmPort->h_IpReassemblyManip)
58734 + || (p_FmPort->h_CapwapReassemblyManip))
58735 + {
58736 +#if (DPAA_VERSION == 10)
58737 + if (p_FmPort->fmRevInfo.majorRev < 6)
58738 + {
58739 + /* Overwrite post-bmi-prepare-to-enq nia */
58740 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FENE;
58741 + fmPortGetSetCcParams.setCcParams.nia = (NIA_FM_CTL_AC_POST_BMI_ENQ_ORR | NIA_ENG_FM_CTL | NIA_ORDER_RESTOR);
58742 + fmPortGetSetCcParams.setCcParams.overwrite = TRUE;
58743 + }
58744 + else
58745 + {
58746 +#endif /* (DPAA_VERSION == 10) */
58747 + /* Set the ORR bit (for order-restoration) */
58748 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_FPNE;
58749 + fmPortGetSetCcParams.setCcParams.nia =
58750 + fmPortGetSetCcParams.getCcParams.nia | NIA_ORDER_RESTOR;
58751 +#if (DPAA_VERSION == 10)
58752 + }
58753 +#endif /* (DPAA_VERSION == 10) */
58754 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
58755 + != E_OK)
58756 + {
58757 + DeletePcd(p_FmPort);
58758 + if (p_FmPort->h_ReassemblyTree)
58759 + {
58760 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58761 + p_FmPort->h_ReassemblyTree = NULL;
58762 + }RELEASE_LOCK(p_FmPort->lock);
58763 + RETURN_ERROR(MAJOR, err, NO_MSG);
58764 + }
58765 + }
58766 + }
58767 + else
58768 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58769 +
58770 +#if (DPAA_VERSION >= 11)
58771 + {
58772 + t_FmPcdCtrlParamsPage *p_ParamsPage;
58773 +
58774 + memset(&fmPortGetSetCcParams, 0, sizeof(t_FmPortGetSetCcParams));
58775 +
58776 + fmPortGetSetCcParams.setCcParams.type = UPDATE_NIA_CMNE;
58777 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
58778 + fmPortGetSetCcParams.setCcParams.nia = NIA_FM_CTL_AC_POP_TO_N_STEP
58779 + | NIA_ENG_FM_CTL;
58780 + else
58781 + fmPortGetSetCcParams.setCcParams.nia =
58782 + NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP | NIA_ENG_FM_CTL;
58783 + if ((err = FmPortGetSetCcParams(h_FmPort, &fmPortGetSetCcParams))
58784 + != E_OK)
58785 + {
58786 + DeletePcd(p_FmPort);
58787 + if (p_FmPort->h_ReassemblyTree)
58788 + {
58789 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58790 + p_FmPort->h_ReassemblyTree = NULL;
58791 + }RELEASE_LOCK(p_FmPort->lock);
58792 + RETURN_ERROR(MAJOR, err, NO_MSG);
58793 + }
58794 +
58795 + FmPortSetGprFunc(p_FmPort, e_FM_PORT_GPR_MURAM_PAGE,
58796 + (void**)&p_ParamsPage);
58797 + ASSERT_COND(p_ParamsPage);
58798 +
58799 + if (FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd))
58800 + WRITE_UINT32(
58801 + p_ParamsPage->misc,
58802 + GET_UINT32(p_ParamsPage->misc) | FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN);
58803 +
58804 + if ((p_FmPort->h_IpReassemblyManip)
58805 + || (p_FmPort->h_CapwapReassemblyManip))
58806 + {
58807 + if (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
58808 + WRITE_UINT32(
58809 + p_ParamsPage->discardMask,
58810 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->ohPortBmiRegs.fmbm_ofsdm));
58811 + else
58812 + WRITE_UINT32(
58813 + p_ParamsPage->discardMask,
58814 + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfsdm));
58815 + }
58816 +#ifdef FM_ERROR_VSP_NO_MATCH_SW006
58817 + if (p_FmPort->vspe)
58818 + WRITE_UINT32(
58819 + p_ParamsPage->misc,
58820 + GET_UINT32(p_ParamsPage->misc) | (p_FmPort->dfltRelativeId & FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK));
58821 +#endif /* FM_ERROR_VSP_NO_MATCH_SW006 */
58822 + }
58823 +#endif /* (DPAA_VERSION >= 11) */
58824 +
58825 + err = AttachPCD(h_FmPort);
58826 + if (err)
58827 + {
58828 + DeletePcd(p_FmPort);
58829 + if (p_FmPort->h_ReassemblyTree)
58830 + {
58831 + FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58832 + p_FmPort->h_ReassemblyTree = NULL;
58833 + }RELEASE_LOCK(p_FmPort->lock);
58834 + RETURN_ERROR(MAJOR, err, NO_MSG);
58835 + }
58836 +
58837 + RELEASE_LOCK(p_FmPort->lock);
58838 +
58839 + return err;
58840 +}
58841 +
58842 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort)
58843 +{
58844 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58845 + t_Error err = E_OK;
58846 +
58847 + SANITY_CHECK_RETURN_ERROR(h_FmPort, E_INVALID_HANDLE);
58848 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58849 +
58850 + if (p_FmPort->imEn)
58851 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION,
58852 + ("available for non-independant mode ports only"));
58853 +
58854 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
58855 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
58856 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
58857 + RETURN_ERROR( MAJOR, E_INVALID_OPERATION,
58858 + ("available for Rx and offline parsing ports only"));
58859 +
58860 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58861 + {
58862 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58863 + return ERROR_CODE(E_BUSY);
58864 + }
58865 +
58866 + err = DetachPCD(h_FmPort);
58867 + if (err)
58868 + {
58869 + RELEASE_LOCK(p_FmPort->lock);
58870 + RETURN_ERROR(MAJOR, err, NO_MSG);
58871 + }
58872 +
58873 + FmPcdDecNetEnvOwners(p_FmPort->h_FmPcd, p_FmPort->netEnvId);
58874 +
58875 + /* we do it anyway, instead of checking if included */
58876 + if ((p_FmPort->pcdEngines & FM_PCD_PRS) && p_FmPort->includeInPrsStatistics)
58877 + {
58878 + FmPcdPrsIncludePortInStatistics(p_FmPort->h_FmPcd,
58879 + p_FmPort->hardwarePortId, FALSE);
58880 + p_FmPort->includeInPrsStatistics = FALSE;
58881 + }
58882 +
58883 + if (!FmPcdLockTryLockAll(p_FmPort->h_FmPcd))
58884 + {
58885 + RELEASE_LOCK(p_FmPort->lock);
58886 + DBG(TRACE, ("Try LockAll - BUSY"));
58887 + return ERROR_CODE(E_BUSY);
58888 + }
58889 +
58890 + err = DeletePcd(h_FmPort);
58891 + FmPcdLockUnlockAll(p_FmPort->h_FmPcd);
58892 + if (err)
58893 + {
58894 + RELEASE_LOCK(p_FmPort->lock);
58895 + RETURN_ERROR(MAJOR, err, NO_MSG);
58896 + }
58897 +
58898 + if (p_FmPort->h_ReassemblyTree)
58899 + {
58900 + err = FM_PCD_CcRootDelete(p_FmPort->h_ReassemblyTree);
58901 + if (err)
58902 + {
58903 + RELEASE_LOCK(p_FmPort->lock);
58904 + RETURN_ERROR(MAJOR, err, NO_MSG);
58905 + }
58906 + p_FmPort->h_ReassemblyTree = NULL;
58907 + }RELEASE_LOCK(p_FmPort->lock);
58908 +
58909 + return err;
58910 +}
58911 +
58912 +t_Error FM_PORT_PcdKgBindSchemes(t_Handle h_FmPort,
58913 + t_FmPcdPortSchemesParams *p_PortScheme)
58914 +{
58915 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58916 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
58917 + t_Error err = E_OK;
58918 + uint32_t tmpScmVec = 0;
58919 + int i;
58920 +
58921 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58922 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58923 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
58924 + E_INVALID_STATE);
58925 +
58926 + schemeBind.netEnvId = p_FmPort->netEnvId;
58927 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
58928 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
58929 + schemeBind.useClsPlan = p_FmPort->useClsPlan;
58930 + for (i = 0; i < schemeBind.numOfSchemes; i++)
58931 + {
58932 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
58933 + p_PortScheme->h_Schemes[i]);
58934 + /* build vector */
58935 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
58936 + }
58937 +
58938 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58939 + {
58940 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58941 + return ERROR_CODE(E_BUSY);
58942 + }
58943 +
58944 + err = FmPcdKgBindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
58945 + if (err == E_OK)
58946 + p_FmPort->schemesPerPortVector |= tmpScmVec;
58947 +
58948 +#ifdef FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
58949 + if ((FmPcdIsAdvancedOffloadSupported(p_FmPort->h_FmPcd)) &&
58950 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
58951 + (p_FmPort->fmRevInfo.majorRev < 6))
58952 + {
58953 + for (i=0; i<p_PortScheme->numOfSchemes; i++)
58954 + FmPcdKgCcGetSetParams(p_FmPort->h_FmPcd, p_PortScheme->h_Schemes[i], UPDATE_KG_NIA_CC_WA, 0);
58955 + }
58956 +#endif /* FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004 */
58957 +
58958 + RELEASE_LOCK(p_FmPort->lock);
58959 +
58960 + return err;
58961 +}
58962 +
58963 +t_Error FM_PORT_PcdKgUnbindSchemes(t_Handle h_FmPort,
58964 + t_FmPcdPortSchemesParams *p_PortScheme)
58965 +{
58966 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
58967 + t_FmPcdKgInterModuleBindPortToSchemes schemeBind;
58968 + t_Error err = E_OK;
58969 + uint32_t tmpScmVec = 0;
58970 + int i;
58971 +
58972 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
58973 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_STATE);
58974 + SANITY_CHECK_RETURN_ERROR(p_FmPort->pcdEngines & FM_PCD_KG,
58975 + E_INVALID_STATE);
58976 +
58977 + schemeBind.netEnvId = p_FmPort->netEnvId;
58978 + schemeBind.hardwarePortId = p_FmPort->hardwarePortId;
58979 + schemeBind.numOfSchemes = p_PortScheme->numOfSchemes;
58980 + for (i = 0; i < schemeBind.numOfSchemes; i++)
58981 + {
58982 + schemeBind.schemesIds[i] = FmPcdKgGetSchemeId(
58983 + p_PortScheme->h_Schemes[i]);
58984 + /* build vector */
58985 + tmpScmVec |= 1 << (31 - (uint32_t)schemeBind.schemesIds[i]);
58986 + }
58987 +
58988 + if (!TRY_LOCK(p_FmPort->h_Spinlock, &p_FmPort->lock))
58989 + {
58990 + DBG(TRACE, ("FM Port Try Lock - BUSY"));
58991 + return ERROR_CODE(E_BUSY);
58992 + }
58993 +
58994 + err = FmPcdKgUnbindPortToSchemes(p_FmPort->h_FmPcd, &schemeBind);
58995 + if (err == E_OK)
58996 + p_FmPort->schemesPerPortVector &= ~tmpScmVec;
58997 + RELEASE_LOCK(p_FmPort->lock);
58998 +
58999 + return err;
59000 +}
59001 +
59002 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort,
59003 + t_FmPortCongestionGrps *p_CongestionGrps)
59004 +{
59005 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59006 + uint8_t priorityTmpArray[FM_PORT_NUM_OF_CONGESTION_GRPS];
59007 + uint8_t mod, index;
59008 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
59009 + int err;
59010 +#if (DPAA_VERSION >= 11)
59011 + int j;
59012 +#endif /* (DPAA_VERSION >= 11) */
59013 +
59014 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
59015 +
59016 + /* un-necessary check of the indexes; probably will be needed in the future when there
59017 + will be more CGs available ....
59018 + for (i=0; i<p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
59019 + if (p_CongestionGrps->congestionGrpsToConsider[i] >= FM_PORT_NUM_OF_CONGESTION_GRPS)
59020 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("CG id!"));
59021 + */
59022 +
59023 +#ifdef FM_NO_OP_OBSERVED_CGS
59024 + if ((p_FmPort->fmRevInfo.majorRev != 4) &&
59025 + (p_FmPort->fmRevInfo.majorRev < 6))
59026 + {
59027 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
59028 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
59029 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
59030 + }
59031 + else
59032 +#endif /* FM_NO_OP_OBSERVED_CGS */
59033 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
59034 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
59035 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
59036 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
59037 + ("Available for Rx & OP ports only"));
59038 +
59039 + /* Prepare groups map array */
59040 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
59041 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
59042 + {
59043 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
59044 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
59045 + if (p_FmPort->fmRevInfo.majorRev != 4)
59046 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
59047 + else
59048 + grpsMap[0] |= (uint32_t)(1 << mod);
59049 + }
59050 +
59051 + memset(&priorityTmpArray, 0,
59052 + FM_PORT_NUM_OF_CONGESTION_GRPS * sizeof(uint8_t));
59053 +
59054 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
59055 + {
59056 +#if (DPAA_VERSION >= 11)
59057 + for (j = 0; j < FM_MAX_NUM_OF_PFC_PRIORITIES; j++)
59058 + if (p_CongestionGrps->pfcPrioritiesEn[i][j])
59059 + priorityTmpArray[p_CongestionGrps->congestionGrpsToConsider[i]] |=
59060 + (0x01 << (FM_MAX_NUM_OF_PFC_PRIORITIES - j - 1));
59061 +#endif /* (DPAA_VERSION >= 11) */
59062 + }
59063 +
59064 +#if (DPAA_VERSION >= 11)
59065 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS; i++)
59066 + {
59067 + err = FmSetCongestionGroupPFCpriority(p_FmPort->h_Fm, i,
59068 + priorityTmpArray[i]);
59069 + if (err)
59070 + return err;
59071 + }
59072 +#endif /* (DPAA_VERSION >= 11) */
59073 +
59074 + err = fman_port_add_congestion_grps(&p_FmPort->port, grpsMap);
59075 + if (err != 0)
59076 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fman_port_add_congestion_grps"));
59077 +
59078 + return E_OK;
59079 +}
59080 +
59081 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort,
59082 + t_FmPortCongestionGrps *p_CongestionGrps)
59083 +{
59084 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59085 + uint8_t mod, index;
59086 + uint32_t i, grpsMap[FMAN_PORT_CG_MAP_NUM];
59087 + int err;
59088 +
59089 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
59090 +
59091 + {
59092 +#ifdef FM_NO_OP_OBSERVED_CGS
59093 + t_FmRevisionInfo revInfo;
59094 +
59095 + FM_GetRevision(p_FmPort->h_Fm, &revInfo);
59096 + if (revInfo.majorRev != 4)
59097 + {
59098 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
59099 + (p_FmPort->portType != e_FM_PORT_TYPE_RX))
59100 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Available for Rx ports only"));
59101 + }
59102 + else
59103 +#endif /* FM_NO_OP_OBSERVED_CGS */
59104 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G)
59105 + && (p_FmPort->portType != e_FM_PORT_TYPE_RX)
59106 + && (p_FmPort->portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING))
59107 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
59108 + ("Available for Rx & OP ports only"));
59109 + }
59110 +
59111 + /* Prepare groups map array */
59112 + memset(grpsMap, 0, FMAN_PORT_CG_MAP_NUM * sizeof(uint32_t));
59113 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
59114 + {
59115 + index = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] / 32);
59116 + mod = (uint8_t)(p_CongestionGrps->congestionGrpsToConsider[i] % 32);
59117 + if (p_FmPort->fmRevInfo.majorRev != 4)
59118 + grpsMap[7 - index] |= (uint32_t)(1 << mod);
59119 + else
59120 + grpsMap[0] |= (uint32_t)(1 << mod);
59121 + }
59122 +
59123 +#if (DPAA_VERSION >= 11)
59124 + for (i = 0; i < p_CongestionGrps->numOfCongestionGrpsToConsider; i++)
59125 + {
59126 + t_Error err = FmSetCongestionGroupPFCpriority(
59127 + p_FmPort->h_Fm, p_CongestionGrps->congestionGrpsToConsider[i],
59128 + 0);
59129 + if (err)
59130 + return err;
59131 + }
59132 +#endif /* (DPAA_VERSION >= 11) */
59133 +
59134 + err = fman_port_remove_congestion_grps(&p_FmPort->port, grpsMap);
59135 + if (err != 0)
59136 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
59137 + ("fman_port_remove_congestion_grps"));
59138 + return E_OK;
59139 +}
59140 +
59141 +#if (DPAA_VERSION >= 11)
59142 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort,
59143 + uint32_t *p_Ipv4OptionsCount)
59144 +{
59145 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
59146 +
59147 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
59148 + SANITY_CHECK_RETURN_ERROR(
59149 + (p_FmPort->portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING),
59150 + E_INVALID_VALUE);
59151 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_ParamsPage, E_INVALID_STATE);
59152 + SANITY_CHECK_RETURN_ERROR(p_Ipv4OptionsCount, E_NULL_POINTER);
59153 +
59154 + *p_Ipv4OptionsCount = GET_UINT32(p_FmPort->p_ParamsPage->ipfOptionsCounter);
59155 +
59156 + return E_OK;
59157 +}
59158 +#endif /* (DPAA_VERSION >= 11) */
59159 +
59160 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx,
59161 + t_FmPortDsarTablesSizes *params)
59162 +{
59163 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
59164 + p_FmPort->deepSleepVars.autoResMaxSizes = XX_Malloc(
59165 + sizeof(struct t_FmPortDsarTablesSizes));
59166 + memcpy(p_FmPort->deepSleepVars.autoResMaxSizes, params,
59167 + sizeof(struct t_FmPortDsarTablesSizes));
59168 + return E_OK;
59169 +}
59170 +
59171 +static t_Error FmPortConfigAutoResForDeepSleepSupport1(t_FmPort *p_FmPort)
59172 +{
59173 + uint32_t *param_page;
59174 + t_FmPortDsarTablesSizes *params = p_FmPort->deepSleepVars.autoResMaxSizes;
59175 + t_ArCommonDesc *ArCommonDescPtr;
59176 + uint32_t size = sizeof(t_ArCommonDesc);
59177 + // ARP
59178 + // should put here if (params->max_num_of_arp_entries)?
59179 + size = ROUND_UP(size,4);
59180 + size += sizeof(t_DsarArpDescriptor);
59181 + size += sizeof(t_DsarArpBindingEntry) * params->maxNumOfArpEntries;
59182 + size += sizeof(t_DsarArpStatistics);
59183 + //ICMPV4
59184 + size = ROUND_UP(size,4);
59185 + size += sizeof(t_DsarIcmpV4Descriptor);
59186 + size += sizeof(t_DsarIcmpV4BindingEntry) * params->maxNumOfEchoIpv4Entries;
59187 + size += sizeof(t_DsarIcmpV4Statistics);
59188 + //ICMPV6
59189 + size = ROUND_UP(size,4);
59190 + size += sizeof(t_DsarIcmpV6Descriptor);
59191 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfEchoIpv6Entries;
59192 + size += sizeof(t_DsarIcmpV6Statistics);
59193 + //ND
59194 + size = ROUND_UP(size,4);
59195 + size += sizeof(t_DsarNdDescriptor);
59196 + size += sizeof(t_DsarIcmpV6BindingEntry) * params->maxNumOfNdpEntries;
59197 + size += sizeof(t_DsarIcmpV6Statistics);
59198 + //SNMP
59199 + size = ROUND_UP(size,4);
59200 + size += sizeof(t_DsarSnmpDescriptor);
59201 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
59202 + * params->maxNumOfSnmpIPV4Entries;
59203 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
59204 + * params->maxNumOfSnmpIPV6Entries;
59205 + size += sizeof(t_OidsTblEntry) * params->maxNumOfSnmpOidEntries;
59206 + size += params->maxNumOfSnmpOidChar;
59207 + size += sizeof(t_DsarIcmpV6Statistics);
59208 + //filters
59209 + size = ROUND_UP(size,4);
59210 + size += params->maxNumOfIpProtFiltering;
59211 + size = ROUND_UP(size,4);
59212 + size += params->maxNumOfUdpPortFiltering * sizeof(t_PortTblEntry);
59213 + size = ROUND_UP(size,4);
59214 + size += params->maxNumOfTcpPortFiltering * sizeof(t_PortTblEntry);
59215 +
59216 + // add here for more protocols
59217 +
59218 + // statistics
59219 + size = ROUND_UP(size,4);
59220 + size += sizeof(t_ArStatistics);
59221 +
59222 + ArCommonDescPtr = FM_MURAM_AllocMem(p_FmPort->h_FmMuram, size, 0x10);
59223 +
59224 + param_page =
59225 + XX_PhysToVirt(
59226 + p_FmPort->fmMuramPhysBaseAddr
59227 + + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
59228 + WRITE_UINT32(
59229 + *param_page,
59230 + (uint32_t)(XX_VirtToPhys(ArCommonDescPtr) - p_FmPort->fmMuramPhysBaseAddr));
59231 + return E_OK;
59232 +}
59233 +
59234 +t_FmPortDsarTablesSizes* FM_PORT_GetDsarTablesMaxSizes(t_Handle h_FmPortRx)
59235 +{
59236 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
59237 + return p_FmPort->deepSleepVars.autoResMaxSizes;
59238 +}
59239 +
59240 +struct arOffsets
59241 +{
59242 + uint32_t arp;
59243 + uint32_t nd;
59244 + uint32_t icmpv4;
59245 + uint32_t icmpv6;
59246 + uint32_t snmp;
59247 + uint32_t stats;
59248 + uint32_t filtIp;
59249 + uint32_t filtUdp;
59250 + uint32_t filtTcp;
59251 +};
59252 +
59253 +static uint32_t AR_ComputeOffsets(struct arOffsets* of,
59254 + struct t_FmPortDsarParams *params,
59255 + t_FmPort *p_FmPort)
59256 +{
59257 + uint32_t size = sizeof(t_ArCommonDesc);
59258 + // ARP
59259 + if (params->p_AutoResArpInfo)
59260 + {
59261 + size = ROUND_UP(size,4);
59262 + of->arp = size;
59263 + size += sizeof(t_DsarArpDescriptor);
59264 + size += sizeof(t_DsarArpBindingEntry)
59265 + * params->p_AutoResArpInfo->tableSize;
59266 + size += sizeof(t_DsarArpStatistics);
59267 + }
59268 + // ICMPV4
59269 + if (params->p_AutoResEchoIpv4Info)
59270 + {
59271 + size = ROUND_UP(size,4);
59272 + of->icmpv4 = size;
59273 + size += sizeof(t_DsarIcmpV4Descriptor);
59274 + size += sizeof(t_DsarIcmpV4BindingEntry)
59275 + * params->p_AutoResEchoIpv4Info->tableSize;
59276 + size += sizeof(t_DsarIcmpV4Statistics);
59277 + }
59278 + // ICMPV6
59279 + if (params->p_AutoResEchoIpv6Info)
59280 + {
59281 + size = ROUND_UP(size,4);
59282 + of->icmpv6 = size;
59283 + size += sizeof(t_DsarIcmpV6Descriptor);
59284 + size += sizeof(t_DsarIcmpV6BindingEntry)
59285 + * params->p_AutoResEchoIpv6Info->tableSize;
59286 + size += sizeof(t_DsarIcmpV6Statistics);
59287 + }
59288 + // ND
59289 + if (params->p_AutoResNdpInfo)
59290 + {
59291 + size = ROUND_UP(size,4);
59292 + of->nd = size;
59293 + size += sizeof(t_DsarNdDescriptor);
59294 + size += sizeof(t_DsarIcmpV6BindingEntry)
59295 + * (params->p_AutoResNdpInfo->tableSizeAssigned
59296 + + params->p_AutoResNdpInfo->tableSizeTmp);
59297 + size += sizeof(t_DsarIcmpV6Statistics);
59298 + }
59299 + // SNMP
59300 + if (params->p_AutoResSnmpInfo)
59301 + {
59302 + size = ROUND_UP(size,4);
59303 + of->snmp = size;
59304 + size += sizeof(t_DsarSnmpDescriptor);
59305 + size += sizeof(t_DsarSnmpIpv4AddrTblEntry)
59306 + * params->p_AutoResSnmpInfo->numOfIpv4Addresses;
59307 + size += sizeof(t_DsarSnmpIpv6AddrTblEntry)
59308 + * params->p_AutoResSnmpInfo->numOfIpv6Addresses;
59309 + size += sizeof(t_OidsTblEntry) * params->p_AutoResSnmpInfo->oidsTblSize;
59310 + size += p_FmPort->deepSleepVars.autoResMaxSizes->maxNumOfSnmpOidChar;
59311 + size += sizeof(t_DsarIcmpV6Statistics);
59312 + }
59313 + //filters
59314 + size = ROUND_UP(size,4);
59315 + if (params->p_AutoResFilteringInfo)
59316 + {
59317 + of->filtIp = size;
59318 + size += params->p_AutoResFilteringInfo->ipProtTableSize;
59319 + size = ROUND_UP(size,4);
59320 + of->filtUdp = size;
59321 + size += params->p_AutoResFilteringInfo->udpPortsTableSize
59322 + * sizeof(t_PortTblEntry);
59323 + size = ROUND_UP(size,4);
59324 + of->filtTcp = size;
59325 + size += params->p_AutoResFilteringInfo->tcpPortsTableSize
59326 + * sizeof(t_PortTblEntry);
59327 + }
59328 + // add here for more protocols
59329 + // statistics
59330 + size = ROUND_UP(size,4);
59331 + of->stats = size;
59332 + size += sizeof(t_ArStatistics);
59333 + return size;
59334 +}
59335 +
59336 +uint32_t* ARDesc;
59337 +void PrsEnable(t_Handle p_FmPcd);
59338 +void PrsDisable(t_Handle p_FmPcd);
59339 +int PrsIsEnabled(t_Handle p_FmPcd);
59340 +t_Handle FM_PCD_GetHcPort(t_Handle h_FmPcd);
59341 +
59342 +static t_Error DsarCheckParams(t_FmPortDsarParams *params,
59343 + t_FmPortDsarTablesSizes *sizes)
59344 +{
59345 + bool macInit = FALSE;
59346 + uint8_t mac[6];
59347 + int i = 0;
59348 +
59349 + // check table sizes
59350 + if (params->p_AutoResArpInfo
59351 + && sizes->maxNumOfArpEntries < params->p_AutoResArpInfo->tableSize)
59352 + RETURN_ERROR(
59353 + MAJOR, E_INVALID_VALUE,
59354 + ("DSAR: Arp table size exceeds the configured maximum size."));
59355 + if (params->p_AutoResEchoIpv4Info
59356 + && sizes->maxNumOfEchoIpv4Entries
59357 + < params->p_AutoResEchoIpv4Info->tableSize)
59358 + RETURN_ERROR(
59359 + MAJOR,
59360 + E_INVALID_VALUE,
59361 + ("DSAR: EchoIpv4 table size exceeds the configured maximum size."));
59362 + if (params->p_AutoResNdpInfo
59363 + && sizes->maxNumOfNdpEntries
59364 + < params->p_AutoResNdpInfo->tableSizeAssigned
59365 + + params->p_AutoResNdpInfo->tableSizeTmp)
59366 + RETURN_ERROR(
59367 + MAJOR, E_INVALID_VALUE,
59368 + ("DSAR: NDP table size exceeds the configured maximum size."));
59369 + if (params->p_AutoResEchoIpv6Info
59370 + && sizes->maxNumOfEchoIpv6Entries
59371 + < params->p_AutoResEchoIpv6Info->tableSize)
59372 + RETURN_ERROR(
59373 + MAJOR,
59374 + E_INVALID_VALUE,
59375 + ("DSAR: EchoIpv6 table size exceeds the configured maximum size."));
59376 + if (params->p_AutoResSnmpInfo
59377 + && sizes->maxNumOfSnmpOidEntries
59378 + < params->p_AutoResSnmpInfo->oidsTblSize)
59379 + RETURN_ERROR(
59380 + MAJOR,
59381 + E_INVALID_VALUE,
59382 + ("DSAR: Snmp Oid table size exceeds the configured maximum size."));
59383 + if (params->p_AutoResSnmpInfo
59384 + && sizes->maxNumOfSnmpIPV4Entries
59385 + < params->p_AutoResSnmpInfo->numOfIpv4Addresses)
59386 + RETURN_ERROR(
59387 + MAJOR,
59388 + E_INVALID_VALUE,
59389 + ("DSAR: Snmp ipv4 table size exceeds the configured maximum size."));
59390 + if (params->p_AutoResSnmpInfo
59391 + && sizes->maxNumOfSnmpIPV6Entries
59392 + < params->p_AutoResSnmpInfo->numOfIpv6Addresses)
59393 + RETURN_ERROR(
59394 + MAJOR,
59395 + E_INVALID_VALUE,
59396 + ("DSAR: Snmp ipv6 table size exceeds the configured maximum size."));
59397 + if (params->p_AutoResFilteringInfo)
59398 + {
59399 + if (sizes->maxNumOfIpProtFiltering
59400 + < params->p_AutoResFilteringInfo->ipProtTableSize)
59401 + RETURN_ERROR(
59402 + MAJOR,
59403 + E_INVALID_VALUE,
59404 + ("DSAR: ip filter table size exceeds the configured maximum size."));
59405 + if (sizes->maxNumOfTcpPortFiltering
59406 + < params->p_AutoResFilteringInfo->udpPortsTableSize)
59407 + RETURN_ERROR(
59408 + MAJOR,
59409 + E_INVALID_VALUE,
59410 + ("DSAR: udp filter table size exceeds the configured maximum size."));
59411 + if (sizes->maxNumOfUdpPortFiltering
59412 + < params->p_AutoResFilteringInfo->tcpPortsTableSize)
59413 + RETURN_ERROR(
59414 + MAJOR,
59415 + E_INVALID_VALUE,
59416 + ("DSAR: tcp filter table size exceeds the configured maximum size."));
59417 + }
59418 + /* check only 1 MAC address is configured (this is what ucode currently supports) */
59419 + if (params->p_AutoResArpInfo && params->p_AutoResArpInfo->tableSize)
59420 + {
59421 + memcpy(mac, params->p_AutoResArpInfo->p_AutoResTable[0].mac, 6);
59422 + i = 1;
59423 + macInit = TRUE;
59424 +
59425 + for (; i < params->p_AutoResArpInfo->tableSize; i++)
59426 + if (memcmp(mac, params->p_AutoResArpInfo->p_AutoResTable[i].mac, 6))
59427 + RETURN_ERROR(
59428 + MAJOR, E_INVALID_VALUE,
59429 + ("DSAR: Only 1 mac address is currently supported."));
59430 + }
59431 + if (params->p_AutoResEchoIpv4Info
59432 + && params->p_AutoResEchoIpv4Info->tableSize)
59433 + {
59434 + i = 0;
59435 + if (!macInit)
59436 + {
59437 + memcpy(mac, params->p_AutoResEchoIpv4Info->p_AutoResTable[0].mac,
59438 + 6);
59439 + i = 1;
59440 + macInit = TRUE;
59441 + }
59442 + for (; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
59443 + if (memcmp(mac,
59444 + params->p_AutoResEchoIpv4Info->p_AutoResTable[i].mac, 6))
59445 + RETURN_ERROR(
59446 + MAJOR, E_INVALID_VALUE,
59447 + ("DSAR: Only 1 mac address is currently supported."));
59448 + }
59449 + if (params->p_AutoResEchoIpv6Info
59450 + && params->p_AutoResEchoIpv6Info->tableSize)
59451 + {
59452 + i = 0;
59453 + if (!macInit)
59454 + {
59455 + memcpy(mac, params->p_AutoResEchoIpv6Info->p_AutoResTable[0].mac,
59456 + 6);
59457 + i = 1;
59458 + macInit = TRUE;
59459 + }
59460 + for (; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
59461 + if (memcmp(mac,
59462 + params->p_AutoResEchoIpv6Info->p_AutoResTable[i].mac, 6))
59463 + RETURN_ERROR(
59464 + MAJOR, E_INVALID_VALUE,
59465 + ("DSAR: Only 1 mac address is currently supported."));
59466 + }
59467 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeAssigned)
59468 + {
59469 + i = 0;
59470 + if (!macInit)
59471 + {
59472 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableAssigned[0].mac,
59473 + 6);
59474 + i = 1;
59475 + macInit = TRUE;
59476 + }
59477 + for (; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
59478 + if (memcmp(mac,
59479 + params->p_AutoResNdpInfo->p_AutoResTableAssigned[i].mac,
59480 + 6))
59481 + RETURN_ERROR(
59482 + MAJOR, E_INVALID_VALUE,
59483 + ("DSAR: Only 1 mac address is currently supported."));
59484 + }
59485 + if (params->p_AutoResNdpInfo && params->p_AutoResNdpInfo->tableSizeTmp)
59486 + {
59487 + i = 0;
59488 + if (!macInit)
59489 + {
59490 + memcpy(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[0].mac, 6);
59491 + i = 1;
59492 + }
59493 + for (; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
59494 + if (memcmp(mac, params->p_AutoResNdpInfo->p_AutoResTableTmp[i].mac,
59495 + 6))
59496 + RETURN_ERROR(
59497 + MAJOR, E_INVALID_VALUE,
59498 + ("DSAR: Only 1 mac address is currently supported."));
59499 + }
59500 + return E_OK;
59501 +}
59502 +
59503 +static int GetBERLen(uint8_t* buf)
59504 +{
59505 + if (*buf & 0x80)
59506 + {
59507 + if ((*buf & 0x7F) == 1)
59508 + return buf[1];
59509 + else
59510 + return *(uint16_t*)&buf[1]; // assuming max len is 2
59511 + }
59512 + else
59513 + return buf[0];
59514 +}
59515 +#define TOTAL_BER_LEN(len) (len < 128) ? len + 2 : len + 3
59516 +
59517 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
59518 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x08402000
59519 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
59520 +static int fm_soc_suspend(void)
59521 +{
59522 + uint32_t *fmclk, tmp32;
59523 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
59524 + tmp32 = GET_UINT32(*fmclk);
59525 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
59526 + tmp32 = GET_UINT32(*fmclk);
59527 + iounmap(fmclk);
59528 + return 0;
59529 +}
59530 +
59531 +void fm_clk_down(void)
59532 +{
59533 + uint32_t *fmclk, tmp32;
59534 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
59535 + tmp32 = GET_UINT32(*fmclk);
59536 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL | 0x40000000);
59537 + tmp32 = GET_UINT32(*fmclk);
59538 + iounmap(fmclk);
59539 +}
59540 +
59541 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params)
59542 +{
59543 + int i, j;
59544 + t_Error err;
59545 + uint32_t nia;
59546 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
59547 + t_FmPort *p_FmPortTx = (t_FmPort *)params->h_FmPortTx;
59548 + t_DsarArpDescriptor *ArpDescriptor;
59549 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor;
59550 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor;
59551 + t_DsarNdDescriptor* NDDescriptor;
59552 +
59553 + uint64_t fmMuramVirtBaseAddr = (uint64_t)PTR_TO_UINT(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr));
59554 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
59555 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
59556 + struct arOffsets* of;
59557 + uint8_t tmp = 0;
59558 + t_FmGetSetParams fmGetSetParams;
59559 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59560 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
59561 + fmGetSetParams.setParams.sleep = 1;
59562 +
59563 + err = DsarCheckParams(params, p_FmPort->deepSleepVars.autoResMaxSizes);
59564 + if (err != E_OK)
59565 + return err;
59566 +
59567 + p_FmPort->deepSleepVars.autoResOffsets = XX_Malloc(sizeof(struct arOffsets));
59568 + of = (struct arOffsets *)p_FmPort->deepSleepVars.autoResOffsets;
59569 + IOMemSet32(ArCommonDescPtr, 0, AR_ComputeOffsets(of, params, p_FmPort));
59570 +
59571 + // common
59572 + WRITE_UINT8(ArCommonDescPtr->arTxPort, p_FmPortTx->hardwarePortId);
59573 + nia = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne); // bmi nia
59574 + if ((nia & 0x007C0000) == 0x00440000) // bmi nia is parser
59575 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne));
59576 + else
59577 + WRITE_UINT32(ArCommonDescPtr->activeHPNIA, nia);
59578 + WRITE_UINT16(ArCommonDescPtr->snmpPort, 161);
59579 +
59580 + // ARP
59581 + if (params->p_AutoResArpInfo)
59582 + {
59583 + t_DsarArpBindingEntry* arp_bindings;
59584 + ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
59585 + WRITE_UINT32(ArCommonDescPtr->p_ArpDescriptor, PTR_TO_UINT(ArpDescriptor) - fmMuramVirtBaseAddr);
59586 + arp_bindings = (t_DsarArpBindingEntry*)(PTR_TO_UINT(ArpDescriptor) + sizeof(t_DsarArpDescriptor));
59587 + if (params->p_AutoResArpInfo->enableConflictDetection)
59588 + WRITE_UINT16(ArpDescriptor->control, 1);
59589 + else
59590 + WRITE_UINT16(ArpDescriptor->control, 0);
59591 + if (params->p_AutoResArpInfo->tableSize)
59592 + {
59593 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResArpInfo->p_AutoResTable;
59594 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
59595 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
59596 + WRITE_UINT16(ArpDescriptor->numOfBindings, params->p_AutoResArpInfo->tableSize);
59597 +
59598 + for (i = 0; i < params->p_AutoResArpInfo->tableSize; i++)
59599 + {
59600 + WRITE_UINT32(arp_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
59601 + if (arp_entry[i].isVlan)
59602 + WRITE_UINT16(arp_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
59603 + }
59604 + WRITE_UINT32(ArpDescriptor->p_Bindings, PTR_TO_UINT(arp_bindings) - fmMuramVirtBaseAddr);
59605 + }
59606 + WRITE_UINT32(ArpDescriptor->p_Statistics, PTR_TO_UINT(arp_bindings) +
59607 + sizeof(t_DsarArpBindingEntry) * params->p_AutoResArpInfo->tableSize - fmMuramVirtBaseAddr);
59608 + }
59609 +
59610 + // ICMPV4
59611 + if (params->p_AutoResEchoIpv4Info)
59612 + {
59613 + t_DsarIcmpV4BindingEntry* icmpv4_bindings;
59614 + ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
59615 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV4Descriptor, PTR_TO_UINT(ICMPV4Descriptor) - fmMuramVirtBaseAddr);
59616 + icmpv4_bindings = (t_DsarIcmpV4BindingEntry*)(PTR_TO_UINT(ICMPV4Descriptor) + sizeof(t_DsarIcmpV4Descriptor));
59617 + WRITE_UINT16(ICMPV4Descriptor->control, 0);
59618 + if (params->p_AutoResEchoIpv4Info->tableSize)
59619 + {
59620 + t_FmPortDsarArpEntry* arp_entry = params->p_AutoResEchoIpv4Info->p_AutoResTable;
59621 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&arp_entry[0].mac[0]);
59622 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&arp_entry[0].mac[2]);
59623 + WRITE_UINT16(ICMPV4Descriptor->numOfBindings, params->p_AutoResEchoIpv4Info->tableSize);
59624 +
59625 + for (i = 0; i < params->p_AutoResEchoIpv4Info->tableSize; i++)
59626 + {
59627 + WRITE_UINT32(icmpv4_bindings[i].ipv4Addr, arp_entry[i].ipAddress);
59628 + if (arp_entry[i].isVlan)
59629 + WRITE_UINT16(icmpv4_bindings[i].vlanId, arp_entry[i].vid & 0xFFF);
59630 + }
59631 + WRITE_UINT32(ICMPV4Descriptor->p_Bindings, PTR_TO_UINT(icmpv4_bindings) - fmMuramVirtBaseAddr);
59632 + }
59633 + WRITE_UINT32(ICMPV4Descriptor->p_Statistics, PTR_TO_UINT(icmpv4_bindings) +
59634 + sizeof(t_DsarIcmpV4BindingEntry) * params->p_AutoResEchoIpv4Info->tableSize - fmMuramVirtBaseAddr);
59635 + }
59636 +
59637 + // ICMPV6
59638 + if (params->p_AutoResEchoIpv6Info)
59639 + {
59640 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
59641 + ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
59642 + WRITE_UINT32(ArCommonDescPtr->p_IcmpV6Descriptor, PTR_TO_UINT(ICMPV6Descriptor) - fmMuramVirtBaseAddr);
59643 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(ICMPV6Descriptor) + sizeof(t_DsarIcmpV6Descriptor));
59644 + WRITE_UINT16(ICMPV6Descriptor->control, 0);
59645 + if (params->p_AutoResEchoIpv6Info->tableSize)
59646 + {
59647 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResEchoIpv6Info->p_AutoResTable;
59648 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
59649 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
59650 + WRITE_UINT16(ICMPV6Descriptor->numOfBindings, params->p_AutoResEchoIpv6Info->tableSize);
59651 +
59652 + for (i = 0; i < params->p_AutoResEchoIpv6Info->tableSize; i++)
59653 + {
59654 + for (j = 0; j < 4; j++)
59655 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
59656 + if (ndp_entry[i].isVlan)
59657 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
59658 + }
59659 + WRITE_UINT32(ICMPV6Descriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
59660 + }
59661 + WRITE_UINT32(ICMPV6Descriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) +
59662 + sizeof(t_DsarIcmpV6BindingEntry) * params->p_AutoResEchoIpv6Info->tableSize - fmMuramVirtBaseAddr);
59663 + }
59664 +
59665 + // ND
59666 + if (params->p_AutoResNdpInfo)
59667 + {
59668 + t_DsarIcmpV6BindingEntry* icmpv6_bindings;
59669 + NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
59670 + WRITE_UINT32(ArCommonDescPtr->p_NdDescriptor, PTR_TO_UINT(NDDescriptor) - fmMuramVirtBaseAddr);
59671 + icmpv6_bindings = (t_DsarIcmpV6BindingEntry*)(PTR_TO_UINT(NDDescriptor) + sizeof(t_DsarNdDescriptor));
59672 + if (params->p_AutoResNdpInfo->enableConflictDetection)
59673 + WRITE_UINT16(NDDescriptor->control, 1);
59674 + else
59675 + WRITE_UINT16(NDDescriptor->control, 0);
59676 + if (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
59677 + {
59678 + t_FmPortDsarNdpEntry* ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableAssigned;
59679 + WRITE_UINT16(*(uint16_t*)&ArCommonDescPtr->macStationAddr[0], *(uint16_t*)&ndp_entry[0].mac[0]);
59680 + WRITE_UINT32(*(uint32_t*)&ArCommonDescPtr->macStationAddr[2], *(uint32_t*)&ndp_entry[0].mac[2]);
59681 + WRITE_UINT16(NDDescriptor->numOfBindings, params->p_AutoResNdpInfo->tableSizeAssigned
59682 + + params->p_AutoResNdpInfo->tableSizeTmp);
59683 +
59684 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeAssigned; i++)
59685 + {
59686 + for (j = 0; j < 4; j++)
59687 + WRITE_UINT32(icmpv6_bindings[i].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
59688 + if (ndp_entry[i].isVlan)
59689 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
59690 + }
59691 + ndp_entry = params->p_AutoResNdpInfo->p_AutoResTableTmp;
59692 + for (i = 0; i < params->p_AutoResNdpInfo->tableSizeTmp; i++)
59693 + {
59694 + for (j = 0; j < 4; j++)
59695 + WRITE_UINT32(icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[j], ndp_entry[i].ipAddress[j]);
59696 + if (ndp_entry[i].isVlan)
59697 + WRITE_UINT16(*(uint16_t*)&icmpv6_bindings[i + params->p_AutoResNdpInfo->tableSizeAssigned].ipv6Addr[4], ndp_entry[i].vid & 0xFFF); // writing vlan
59698 + }
59699 + WRITE_UINT32(NDDescriptor->p_Bindings, PTR_TO_UINT(icmpv6_bindings) - fmMuramVirtBaseAddr);
59700 + }
59701 + WRITE_UINT32(NDDescriptor->p_Statistics, PTR_TO_UINT(icmpv6_bindings) + sizeof(t_DsarIcmpV6BindingEntry)
59702 + * (params->p_AutoResNdpInfo->tableSizeAssigned + params->p_AutoResNdpInfo->tableSizeTmp)
59703 + - fmMuramVirtBaseAddr);
59704 + WRITE_UINT32(NDDescriptor->solicitedAddr, 0xFFFFFFFF);
59705 + }
59706 +
59707 + // SNMP
59708 + if (params->p_AutoResSnmpInfo)
59709 + {
59710 + t_FmPortDsarSnmpInfo *snmpSrc = params->p_AutoResSnmpInfo;
59711 + t_DsarSnmpIpv4AddrTblEntry* snmpIpv4Addr;
59712 + t_DsarSnmpIpv6AddrTblEntry* snmpIpv6Addr;
59713 + t_OidsTblEntry* snmpOid;
59714 + uint8_t *charPointer;
59715 + int len;
59716 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
59717 + WRITE_UINT32(ArCommonDescPtr->p_SnmpDescriptor, PTR_TO_UINT(SnmpDescriptor) - fmMuramVirtBaseAddr);
59718 + WRITE_UINT16(SnmpDescriptor->control, snmpSrc->control);
59719 + WRITE_UINT16(SnmpDescriptor->maxSnmpMsgLength, snmpSrc->maxSnmpMsgLength);
59720 + snmpIpv4Addr = (t_DsarSnmpIpv4AddrTblEntry*)(PTR_TO_UINT(SnmpDescriptor) + sizeof(t_DsarSnmpDescriptor));
59721 + if (snmpSrc->numOfIpv4Addresses)
59722 + {
59723 + t_FmPortDsarSnmpIpv4AddrTblEntry* snmpIpv4AddrSrc = snmpSrc->p_Ipv4AddrTbl;
59724 + WRITE_UINT16(SnmpDescriptor->numOfIpv4Addresses, snmpSrc->numOfIpv4Addresses);
59725 + for (i = 0; i < snmpSrc->numOfIpv4Addresses; i++)
59726 + {
59727 + WRITE_UINT32(snmpIpv4Addr[i].ipv4Addr, snmpIpv4AddrSrc[i].ipv4Addr);
59728 + if (snmpIpv4AddrSrc[i].isVlan)
59729 + WRITE_UINT16(snmpIpv4Addr[i].vlanId, snmpIpv4AddrSrc[i].vid & 0xFFF);
59730 + }
59731 + WRITE_UINT32(SnmpDescriptor->p_Ipv4AddrTbl, PTR_TO_UINT(snmpIpv4Addr) - fmMuramVirtBaseAddr);
59732 + }
59733 + snmpIpv6Addr = (t_DsarSnmpIpv6AddrTblEntry*)(PTR_TO_UINT(snmpIpv4Addr)
59734 + + sizeof(t_DsarSnmpIpv4AddrTblEntry) * snmpSrc->numOfIpv4Addresses);
59735 + if (snmpSrc->numOfIpv6Addresses)
59736 + {
59737 + t_FmPortDsarSnmpIpv6AddrTblEntry* snmpIpv6AddrSrc = snmpSrc->p_Ipv6AddrTbl;
59738 + WRITE_UINT16(SnmpDescriptor->numOfIpv6Addresses, snmpSrc->numOfIpv6Addresses);
59739 + for (i = 0; i < snmpSrc->numOfIpv6Addresses; i++)
59740 + {
59741 + for (j = 0; j < 4; j++)
59742 + WRITE_UINT32(snmpIpv6Addr[i].ipv6Addr[j], snmpIpv6AddrSrc[i].ipv6Addr[j]);
59743 + if (snmpIpv6AddrSrc[i].isVlan)
59744 + WRITE_UINT16(snmpIpv6Addr[i].vlanId, snmpIpv6AddrSrc[i].vid & 0xFFF);
59745 + }
59746 + WRITE_UINT32(SnmpDescriptor->p_Ipv6AddrTbl, PTR_TO_UINT(snmpIpv6Addr) - fmMuramVirtBaseAddr);
59747 + }
59748 + snmpOid = (t_OidsTblEntry*)(PTR_TO_UINT(snmpIpv6Addr)
59749 + + sizeof(t_DsarSnmpIpv6AddrTblEntry) * snmpSrc->numOfIpv6Addresses);
59750 + charPointer = (uint8_t*)(PTR_TO_UINT(snmpOid)
59751 + + sizeof(t_OidsTblEntry) * snmpSrc->oidsTblSize);
59752 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdOnlyCommunityStr[1]));
59753 + Mem2IOCpy32(charPointer, snmpSrc->p_RdOnlyCommunityStr, len);
59754 + WRITE_UINT32(SnmpDescriptor->p_RdOnlyCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59755 + charPointer += len;
59756 + len = TOTAL_BER_LEN(GetBERLen(&snmpSrc->p_RdWrCommunityStr[1]));
59757 + Mem2IOCpy32(charPointer, snmpSrc->p_RdWrCommunityStr, len);
59758 + WRITE_UINT32(SnmpDescriptor->p_RdWrCommunityStr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59759 + charPointer += len;
59760 + WRITE_UINT32(SnmpDescriptor->oidsTblSize, snmpSrc->oidsTblSize);
59761 + WRITE_UINT32(SnmpDescriptor->p_OidsTbl, PTR_TO_UINT(snmpOid) - fmMuramVirtBaseAddr);
59762 + for (i = 0; i < snmpSrc->oidsTblSize; i++)
59763 + {
59764 + WRITE_UINT16(snmpOid->oidSize, snmpSrc->p_OidsTbl[i].oidSize);
59765 + WRITE_UINT16(snmpOid->resSize, snmpSrc->p_OidsTbl[i].resSize);
59766 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].oidVal, snmpSrc->p_OidsTbl[i].oidSize);
59767 + WRITE_UINT32(snmpOid->p_Oid, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59768 + charPointer += snmpSrc->p_OidsTbl[i].oidSize;
59769 + if (snmpSrc->p_OidsTbl[i].resSize <= 4)
59770 + WRITE_UINT32(snmpOid->resValOrPtr, *snmpSrc->p_OidsTbl[i].resVal);
59771 + else
59772 + {
59773 + Mem2IOCpy32(charPointer, snmpSrc->p_OidsTbl[i].resVal, snmpSrc->p_OidsTbl[i].resSize);
59774 + WRITE_UINT32(snmpOid->resValOrPtr, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59775 + charPointer += snmpSrc->p_OidsTbl[i].resSize;
59776 + }
59777 + snmpOid++;
59778 + }
59779 + charPointer = UINT_TO_PTR(ROUND_UP(PTR_TO_UINT(charPointer),4));
59780 + WRITE_UINT32(SnmpDescriptor->p_Statistics, PTR_TO_UINT(charPointer) - fmMuramVirtBaseAddr);
59781 + }
59782 +
59783 + // filtering
59784 + if (params->p_AutoResFilteringInfo)
59785 + {
59786 + if (params->p_AutoResFilteringInfo->ipProtPassOnHit)
59787 + tmp |= IP_PROT_TBL_PASS_MASK;
59788 + if (params->p_AutoResFilteringInfo->udpPortPassOnHit)
59789 + tmp |= UDP_PORT_TBL_PASS_MASK;
59790 + if (params->p_AutoResFilteringInfo->tcpPortPassOnHit)
59791 + tmp |= TCP_PORT_TBL_PASS_MASK;
59792 + WRITE_UINT8(ArCommonDescPtr->filterControl, tmp);
59793 + WRITE_UINT16(ArCommonDescPtr->tcpControlPass, params->p_AutoResFilteringInfo->tcpFlagsMask);
59794 +
59795 + // ip filtering
59796 + if (params->p_AutoResFilteringInfo->ipProtTableSize)
59797 + {
59798 + uint8_t* ip_tbl = (uint8_t*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtIp);
59799 + WRITE_UINT8(ArCommonDescPtr->ipProtocolTblSize, params->p_AutoResFilteringInfo->ipProtTableSize);
59800 + for (i = 0; i < params->p_AutoResFilteringInfo->ipProtTableSize; i++)
59801 + WRITE_UINT8(ip_tbl[i], params->p_AutoResFilteringInfo->p_IpProtTablePtr[i]);
59802 + WRITE_UINT32(ArCommonDescPtr->p_IpProtocolFiltTbl, PTR_TO_UINT(ip_tbl) - fmMuramVirtBaseAddr);
59803 + }
59804 +
59805 + // udp filtering
59806 + if (params->p_AutoResFilteringInfo->udpPortsTableSize)
59807 + {
59808 + t_PortTblEntry* udp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtUdp);
59809 + WRITE_UINT8(ArCommonDescPtr->udpPortTblSize, params->p_AutoResFilteringInfo->udpPortsTableSize);
59810 + for (i = 0; i < params->p_AutoResFilteringInfo->udpPortsTableSize; i++)
59811 + {
59812 + WRITE_UINT32(udp_tbl[i].Ports,
59813 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPort << 16) +
59814 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPort);
59815 + WRITE_UINT32(udp_tbl[i].PortsMask,
59816 + (params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].srcPortMask << 16) +
59817 + params->p_AutoResFilteringInfo->p_UdpPortsTablePtr[i].dstPortMask);
59818 + }
59819 + WRITE_UINT32(ArCommonDescPtr->p_UdpPortFiltTbl, PTR_TO_UINT(udp_tbl) - fmMuramVirtBaseAddr);
59820 + }
59821 +
59822 + // tcp filtering
59823 + if (params->p_AutoResFilteringInfo->tcpPortsTableSize)
59824 + {
59825 + t_PortTblEntry* tcp_tbl = (t_PortTblEntry*)(PTR_TO_UINT(ArCommonDescPtr) + of->filtTcp);
59826 + WRITE_UINT8(ArCommonDescPtr->tcpPortTblSize, params->p_AutoResFilteringInfo->tcpPortsTableSize);
59827 + for (i = 0; i < params->p_AutoResFilteringInfo->tcpPortsTableSize; i++)
59828 + {
59829 + WRITE_UINT32(tcp_tbl[i].Ports,
59830 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPort << 16) +
59831 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPort);
59832 + WRITE_UINT32(tcp_tbl[i].PortsMask,
59833 + (params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].srcPortMask << 16) +
59834 + params->p_AutoResFilteringInfo->p_TcpPortsTablePtr[i].dstPortMask);
59835 + }
59836 + WRITE_UINT32(ArCommonDescPtr->p_TcpPortFiltTbl, PTR_TO_UINT(tcp_tbl) - fmMuramVirtBaseAddr);
59837 + }
59838 + }
59839 + // common stats
59840 + WRITE_UINT32(ArCommonDescPtr->p_ArStats, PTR_TO_UINT(ArCommonDescPtr) + of->stats - fmMuramVirtBaseAddr);
59841 +
59842 + // get into Deep Sleep sequence:
59843 +
59844 + // Ensures that FMan do not enter the idle state. This is done by programing
59845 + // FMDPSLPCR[FM_STOP] to one.
59846 + fm_soc_suspend();
59847 +
59848 + ARDesc = UINT_TO_PTR(XX_VirtToPhys(ArCommonDescPtr));
59849 + return E_OK;
59850 +
59851 +}
59852 +
59853 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId);
59854 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort)
59855 +{
59856 + t_FmGetSetParams fmGetSetParams;
59857 + t_FmPort *p_FmPort = (t_FmPort *)h_DsarRxPort;
59858 + t_FmPort *p_FmPortTx = (t_FmPort *)h_DsarTxPort;
59859 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
59860 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
59861 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59862 + fmGetSetParams.setParams.type = UPDATE_FM_CLD;
59863 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59864 +
59865 + /* Issue graceful stop to HC port */
59866 + FM_PORT_Disable(p_FmPortHc);
59867 +
59868 + // config tx port
59869 + p_FmPort->deepSleepVars.fmbm_tcfg = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg);
59870 + 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);
59871 + // ????
59872 + p_FmPort->deepSleepVars.fmbm_tcmne = GET_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne);
59873 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, 0xE);
59874 + // Stage 7:echo
59875 + p_FmPort->deepSleepVars.fmbm_rfpne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne);
59876 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, 0x2E);
59877 + if (!PrsIsEnabled(h_FmPcd))
59878 + {
59879 + p_FmPort->deepSleepVars.dsarEnabledParser = TRUE;
59880 + PrsEnable(h_FmPcd);
59881 + }
59882 + else
59883 + p_FmPort->deepSleepVars.dsarEnabledParser = FALSE;
59884 +
59885 + p_FmPort->deepSleepVars.fmbm_rfne = GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne);
59886 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, 0x440000);
59887 +
59888 + // save rcfg for restoring: accumulate mode is changed by ucode
59889 + p_FmPort->deepSleepVars.fmbm_rcfg = GET_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg);
59890 + WRITE_UINT32(p_FmPort->port.bmi_regs->rx.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg | BMI_PORT_CFG_AM);
59891 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59892 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
59893 + fmGetSetParams.setParams.sleep = 1;
59894 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59895 +
59896 +// ***** issue external request sync command
59897 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59898 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC;
59899 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59900 + // get
59901 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59902 + fmGetSetParams.getParams.type = GET_FMFP_EXTC;
59903 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59904 + if (fmGetSetParams.getParams.fmfp_extc != 0)
59905 + {
59906 + // clear
59907 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59908 + fmGetSetParams.setParams.type = UPDATE_FPM_EXTC_CLEAR;
59909 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59910 +}
59911 +
59912 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59913 + fmGetSetParams.getParams.type = GET_FMFP_EXTC | GET_FM_NPI;
59914 + do
59915 + {
59916 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59917 + } while (fmGetSetParams.getParams.fmfp_extc != 0 && fmGetSetParams.getParams.fm_npi == 0);
59918 + if (fmGetSetParams.getParams.fm_npi != 0)
59919 + XX_Print("FM: Sync did not finish\n");
59920 +
59921 + // check that all stoped
59922 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59923 + fmGetSetParams.getParams.type = GET_FMQM_GS | GET_FM_NPI;
59924 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59925 + while (fmGetSetParams.getParams.fmqm_gs & 0xF0000000)
59926 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59927 + if (fmGetSetParams.getParams.fmqm_gs == 0 && fmGetSetParams.getParams.fm_npi == 0)
59928 + XX_Print("FM: Sleeping\n");
59929 +// FM_ChangeClock(p_FmPort->h_Fm, p_FmPort->hardwarePortId);
59930 +
59931 + return E_OK;
59932 +}
59933 +
59934 +EXPORT_SYMBOL(FM_PORT_EnterDsarFinal);
59935 +
59936 +void FM_PORT_Dsar_DumpRegs()
59937 +{
59938 + uint32_t* hh = XX_PhysToVirt(PTR_TO_UINT(ARDesc));
59939 + DUMP_MEMORY(hh, 0x220);
59940 +}
59941 +
59942 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx)
59943 +{
59944 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
59945 + t_FmPort *p_FmPortTx = (t_FmPort *)h_FmPortTx;
59946 + t_Handle *h_FmPcd = FmGetPcd(p_FmPort->h_Fm);
59947 + t_FmPort *p_FmPortHc = FM_PCD_GetHcPort(h_FmPcd);
59948 + t_FmGetSetParams fmGetSetParams;
59949 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
59950 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
59951 + fmGetSetParams.setParams.sleep = 0;
59952 + if (p_FmPort->deepSleepVars.autoResOffsets)
59953 + {
59954 + XX_Free(p_FmPort->deepSleepVars.autoResOffsets);
59955 + p_FmPort->deepSleepVars.autoResOffsets = 0;
59956 + }
59957 +
59958 + if (p_FmPort->deepSleepVars.dsarEnabledParser)
59959 + PrsDisable(FmGetPcd(p_FmPort->h_Fm));
59960 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfpne, p_FmPort->deepSleepVars.fmbm_rfpne);
59961 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfne, p_FmPort->deepSleepVars.fmbm_rfne);
59962 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rcfg, p_FmPort->deepSleepVars.fmbm_rcfg);
59963 + FmGetSetParams(p_FmPort->h_Fm, &fmGetSetParams);
59964 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcmne, p_FmPort->deepSleepVars.fmbm_tcmne);
59965 + WRITE_UINT32(p_FmPortTx->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfg, p_FmPort->deepSleepVars.fmbm_tcfg);
59966 + FM_PORT_Enable(p_FmPortHc);
59967 +}
59968 +
59969 +bool FM_PORT_IsInDsar(t_Handle h_FmPort)
59970 +{
59971 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPort;
59972 + return PTR_TO_UINT(p_FmPort->deepSleepVars.autoResOffsets);
59973 +}
59974 +
59975 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats)
59976 +{
59977 + t_FmPort *p_FmPort = (t_FmPort *)h_FmPortRx;
59978 + struct arOffsets *of = (struct arOffsets*)p_FmPort->deepSleepVars.autoResOffsets;
59979 + uint8_t* fmMuramVirtBaseAddr = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr);
59980 + uint32_t *param_page = XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr));
59981 + t_ArCommonDesc *ArCommonDescPtr = (t_ArCommonDesc*)(XX_PhysToVirt(p_FmPort->fmMuramPhysBaseAddr + GET_UINT32(*param_page)));
59982 + t_DsarArpDescriptor *ArpDescriptor = (t_DsarArpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->arp);
59983 + t_DsarArpStatistics* arp_stats = (t_DsarArpStatistics*)(PTR_TO_UINT(ArpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
59984 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor = (t_DsarIcmpV4Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv4);
59985 + t_DsarIcmpV4Statistics* icmpv4_stats = (t_DsarIcmpV4Statistics*)(PTR_TO_UINT(ICMPV4Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
59986 + t_DsarNdDescriptor* NDDescriptor = (t_DsarNdDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->nd);
59987 + t_NdStatistics* nd_stats = (t_NdStatistics*)(PTR_TO_UINT(NDDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
59988 + t_DsarIcmpV6Descriptor* ICMPV6Descriptor = (t_DsarIcmpV6Descriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->icmpv6);
59989 + t_DsarIcmpV6Statistics* icmpv6_stats = (t_DsarIcmpV6Statistics*)(PTR_TO_UINT(ICMPV6Descriptor->p_Statistics) + fmMuramVirtBaseAddr);
59990 + t_DsarSnmpDescriptor* SnmpDescriptor = (t_DsarSnmpDescriptor*)(PTR_TO_UINT(ArCommonDescPtr) + of->snmp);
59991 + t_DsarSnmpStatistics* snmp_stats = (t_DsarSnmpStatistics*)(PTR_TO_UINT(SnmpDescriptor->p_Statistics) + fmMuramVirtBaseAddr);
59992 + stats->arpArCnt = arp_stats->arCnt;
59993 + stats->echoIcmpv4ArCnt = icmpv4_stats->arCnt;
59994 + stats->ndpArCnt = nd_stats->arCnt;
59995 + stats->echoIcmpv6ArCnt = icmpv6_stats->arCnt;
59996 + stats->snmpGetCnt = snmp_stats->snmpGetReqCnt;
59997 + stats->snmpGetNextCnt = snmp_stats->snmpGetNextReqCnt;
59998 + return E_OK;
59999 +}
60000 --- /dev/null
60001 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port.h
60002 @@ -0,0 +1,999 @@
60003 +/*
60004 + * Copyright 2008-2012 Freescale Semiconductor Inc.
60005 + *
60006 + * Redistribution and use in source and binary forms, with or without
60007 + * modification, are permitted provided that the following conditions are met:
60008 + * * Redistributions of source code must retain the above copyright
60009 + * notice, this list of conditions and the following disclaimer.
60010 + * * Redistributions in binary form must reproduce the above copyright
60011 + * notice, this list of conditions and the following disclaimer in the
60012 + * documentation and/or other materials provided with the distribution.
60013 + * * Neither the name of Freescale Semiconductor nor the
60014 + * names of its contributors may be used to endorse or promote products
60015 + * derived from this software without specific prior written permission.
60016 + *
60017 + *
60018 + * ALTERNATIVELY, this software may be distributed under the terms of the
60019 + * GNU General Public License ("GPL") as published by the Free Software
60020 + * Foundation, either version 2 of that License or (at your option) any
60021 + * later version.
60022 + *
60023 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
60024 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
60025 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
60026 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
60027 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60028 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
60029 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
60030 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60031 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60032 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
60033 + */
60034 +
60035 +
60036 +/******************************************************************************
60037 + @File fm_port.h
60038 +
60039 + @Description FM Port internal structures and definitions.
60040 +*//***************************************************************************/
60041 +#ifndef __FM_PORT_H
60042 +#define __FM_PORT_H
60043 +
60044 +#include "error_ext.h"
60045 +#include "std_ext.h"
60046 +#include "fm_port_ext.h"
60047 +
60048 +#include "fm_common.h"
60049 +#include "fm_sp_common.h"
60050 +#include "fsl_fman_sp.h"
60051 +#include "fm_port_ext.h"
60052 +#include "fsl_fman_port.h"
60053 +
60054 +#define __ERR_MODULE__ MODULE_FM_PORT
60055 +
60056 +
60057 +#define MIN_EXT_BUF_SIZE 64
60058 +#define DATA_ALIGNMENT 64
60059 +#define MAX_LIODN_OFFSET 64
60060 +#define MAX_PORT_FIFO_SIZE MIN(BMI_MAX_FIFO_SIZE, 1024*BMI_FIFO_UNITS)
60061 +
60062 +/**************************************************************************//**
60063 + @Description Memory Map defines
60064 +*//***************************************************************************/
60065 +#define BMI_PORT_REGS_OFFSET 0
60066 +#define QMI_PORT_REGS_OFFSET 0x400
60067 +#define PRS_PORT_REGS_OFFSET 0x800
60068 +
60069 +/**************************************************************************//**
60070 + @Description defaults
60071 +*//***************************************************************************/
60072 +#define DEFAULT_PORT_deqHighPriority_1G FALSE
60073 +#define DEFAULT_PORT_deqHighPriority_10G TRUE
60074 +#define DEFAULT_PORT_deqType e_FM_PORT_DEQ_TYPE1
60075 +#define DEFAULT_PORT_deqPrefetchOption e_FM_PORT_DEQ_FULL_PREFETCH
60076 +#define DEFAULT_PORT_deqPrefetchOption_HC e_FM_PORT_DEQ_NO_PREFETCH
60077 +#define DEFAULT_PORT_deqByteCnt_10G 0x1400
60078 +#define DEFAULT_PORT_deqByteCnt_1G 0x400
60079 +#define DEFAULT_PORT_bufferPrefixContent_privDataSize DEFAULT_FM_SP_bufferPrefixContent_privDataSize
60080 +#define DEFAULT_PORT_bufferPrefixContent_passPrsResult DEFAULT_FM_SP_bufferPrefixContent_passPrsResult
60081 +#define DEFAULT_PORT_bufferPrefixContent_passTimeStamp DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp
60082 +#define DEFAULT_PORT_bufferPrefixContent_allOtherPCDInfo DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo
60083 +#define DEFAULT_PORT_bufferPrefixContent_dataAlign DEFAULT_FM_SP_bufferPrefixContent_dataAlign
60084 +#define DEFAULT_PORT_cheksumLastBytesIgnore 0
60085 +#define DEFAULT_PORT_cutBytesFromEnd 4
60086 +#define DEFAULT_PORT_fifoDeqPipelineDepth_IM 2
60087 +
60088 +#define DEFAULT_PORT_frmDiscardOverride FALSE
60089 +
60090 +#define DEFAULT_PORT_dmaSwapData (e_FmDmaSwapOption)DEFAULT_FMAN_SP_DMA_SWAP_DATA
60091 +#define DEFAULT_PORT_dmaIntContextCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR
60092 +#define DEFAULT_PORT_dmaHeaderCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR
60093 +#define DEFAULT_PORT_dmaScatterGatherCacheAttr (e_FmDmaCacheOption)DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR
60094 +#define DEFAULT_PORT_dmaWriteOptimize DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE
60095 +
60096 +#define DEFAULT_PORT_noScatherGather DEFAULT_FMAN_SP_NO_SCATTER_GATHER
60097 +#define DEFAULT_PORT_forwardIntContextReuse FALSE
60098 +#define DEFAULT_PORT_BufMargins_startMargins 32
60099 +#define DEFAULT_PORT_BufMargins_endMargins 0
60100 +#define DEFAULT_PORT_syncReq TRUE
60101 +#define DEFAULT_PORT_syncReqForHc FALSE
60102 +#define DEFAULT_PORT_color e_FM_PORT_COLOR_GREEN
60103 +#define DEFAULT_PORT_errorsToDiscard FM_PORT_FRM_ERR_CLS_DISCARD
60104 +/* #define DEFAULT_PORT_dualRateLimitScaleDown e_FM_PORT_DUAL_RATE_LIMITER_NONE */
60105 +/* #define DEFAULT_PORT_rateLimitBurstSizeHighGranularity FALSE */
60106 +#define DEFAULT_PORT_exception IM_EV_BSY
60107 +#define DEFAULT_PORT_maxFrameLength 9600
60108 +
60109 +#define DEFAULT_notSupported 0xff
60110 +
60111 +#if (DPAA_VERSION < 11)
60112 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
60113 +#define DEFAULT_PORT_rxFifoThreshold (MAX_PORT_FIFO_SIZE*3/4)
60114 +
60115 +#define DEFAULT_PORT_txFifoMinFillLevel 0
60116 +#define DEFAULT_PORT_txFifoLowComfLevel (5*KILOBYTE)
60117 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 1
60118 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
60119 +
60120 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
60121 +
60122 +/* Host command port MUST NOT be changed to more than 1 !!! */
60123 +#define DEFAULT_PORT_numOfTasks(type) \
60124 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
60125 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 16 : \
60126 + ((((type) == e_FM_PORT_TYPE_RX) || \
60127 + ((type) == e_FM_PORT_TYPE_TX) || \
60128 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING)) ? 3 : 1))
60129 +
60130 +#define DEFAULT_PORT_extraNumOfTasks(type) \
60131 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
60132 + (((type) == e_FM_PORT_TYPE_RX) ? 2 : 0))
60133 +
60134 +#define DEFAULT_PORT_numOfOpenDmas(type) \
60135 + (uint32_t)((((type) == e_FM_PORT_TYPE_TX_10G) || \
60136 + ((type) == e_FM_PORT_TYPE_RX_10G)) ? 8 : 1 )
60137 +
60138 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) \
60139 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
60140 + (((type) == e_FM_PORT_TYPE_RX) ? 1 : 0))
60141 +
60142 +#define DEFAULT_PORT_numOfFifoBufs(type) \
60143 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
60144 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 48 : \
60145 + ((type) == e_FM_PORT_TYPE_RX) ? 45 : \
60146 + ((type) == e_FM_PORT_TYPE_TX) ? 44 : 8)
60147 +
60148 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
60149 +
60150 +#else /* (DPAA_VERSION < 11) */
60151 +/* Defaults are registers' reset values */
60152 +#define DEFAULT_PORT_rxFifoPriElevationLevel MAX_PORT_FIFO_SIZE
60153 +#define DEFAULT_PORT_rxFifoThreshold MAX_PORT_FIFO_SIZE
60154 +
60155 +#define DEFAULT_PORT_txFifoMinFillLevel 0
60156 +#define DEFAULT_PORT_txFifoLowComfLevel (5 * KILOBYTE)
60157 +#define DEFAULT_PORT_fifoDeqPipelineDepth_1G 2
60158 +#define DEFAULT_PORT_fifoDeqPipelineDepth_10G 4
60159 +
60160 +#define DEFAULT_PORT_fifoDeqPipelineDepth_OH 2
60161 +
60162 +#define DEFAULT_PORT_numOfTasks(type) \
60163 + (uint32_t)((((type) == e_FM_PORT_TYPE_RX_10G) || \
60164 + ((type) == e_FM_PORT_TYPE_TX_10G)) ? 14 : \
60165 + (((type) == e_FM_PORT_TYPE_RX) || \
60166 + ((type) == e_FM_PORT_TYPE_TX)) ? 4 : \
60167 + ((type) == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) ? 6 : 1)
60168 +
60169 +#define DEFAULT_PORT_extraNumOfTasks(type) 0
60170 +
60171 +#define DEFAULT_PORT_numOfOpenDmas(type) \
60172 + (uint32_t)(((type) == e_FM_PORT_TYPE_RX_10G) ? 8 : \
60173 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 12 : \
60174 + ((type) == e_FM_PORT_TYPE_RX) ? 2 : \
60175 + ((type) == e_FM_PORT_TYPE_TX) ? 3 : \
60176 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 2 : 4)
60177 +
60178 +#define DEFAULT_PORT_extraNumOfOpenDmas(type) 0
60179 +
60180 +#define DEFAULT_PORT_numOfFifoBufs(type) \
60181 + (uint32_t) (((type) == e_FM_PORT_TYPE_RX_10G) ? 96 : \
60182 + ((type) == e_FM_PORT_TYPE_TX_10G) ? 64 : \
60183 + ((type) == e_FM_PORT_TYPE_OH_HOST_COMMAND) ? 10 : 50)
60184 +
60185 +#define DEFAULT_PORT_extraNumOfFifoBufs 0
60186 +
60187 +#endif /* (DPAA_VERSION < 11) */
60188 +
60189 +#define DEFAULT_PORT_txBdRingLength 16
60190 +#define DEFAULT_PORT_rxBdRingLength 128
60191 +#define DEFAULT_PORT_ImfwExtStructsMemId 0
60192 +#define DEFAULT_PORT_ImfwExtStructsMemAttr MEMORY_ATTR_CACHEABLE
60193 +
60194 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
60195 +
60196 +/**************************************************************************//**
60197 + @Collection PCD Engines
60198 +*//***************************************************************************/
60199 +typedef uint32_t fmPcdEngines_t; /**< options as defined below: */
60200 +
60201 +#define FM_PCD_NONE 0 /**< No PCD Engine indicated */
60202 +#define FM_PCD_PRS 0x80000000 /**< Parser indicated */
60203 +#define FM_PCD_KG 0x40000000 /**< Keygen indicated */
60204 +#define FM_PCD_CC 0x20000000 /**< Coarse classification indicated */
60205 +#define FM_PCD_PLCR 0x10000000 /**< Policer indicated */
60206 +#define FM_PCD_MANIP 0x08000000 /**< Manipulation indicated */
60207 +/* @} */
60208 +
60209 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS 8
60210 +#define FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS 256
60211 +#define FM_PORT_CG_REG_NUM(_cgId) (((FM_PORT_NUM_OF_CONGESTION_GRPS/32)-1)-_cgId/32)
60212 +
60213 +#define FM_OH_PORT_ID 0
60214 +
60215 +/***********************************************************************/
60216 +/* SW parser OFFLOAD labels (offsets) */
60217 +/***********************************************************************/
60218 +#if (DPAA_VERSION == 10)
60219 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x300
60220 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x325
60221 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x325
60222 +#else
60223 +#define OFFLOAD_SW_PATCH_IPv4_IPR_LABEL 0x100
60224 +/* Will be used for:
60225 + * 1. identify fragments
60226 + * 2. udp-lite
60227 + */
60228 +#define OFFLOAD_SW_PATCH_IPv6_IPR_LABEL 0x146
60229 +/* Will be used for:
60230 + * 1. will identify the fragmentable area
60231 + * 2. udp-lite
60232 + */
60233 +#define OFFLOAD_SW_PATCH_IPv6_IPF_LABEL 0x261
60234 +#define OFFLOAD_SW_PATCH_CAPWAP_LABEL 0x38d
60235 +#endif /* (DPAA_VERSION == 10) */
60236 +
60237 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
60238 +#define UDP_LITE_SW_PATCH_LABEL 0x2E0
60239 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
60240 +
60241 +
60242 +/**************************************************************************//**
60243 + @Description Memory Mapped Registers
60244 +*//***************************************************************************/
60245 +
60246 +#if defined(__MWERKS__) && !defined(__GNUC__)
60247 +#pragma pack(push,1)
60248 +#endif /* defined(__MWERKS__) && ... */
60249 +
60250 +typedef struct
60251 +{
60252 + volatile uint32_t fmbm_rcfg; /**< Rx Configuration */
60253 + volatile uint32_t fmbm_rst; /**< Rx Status */
60254 + volatile uint32_t fmbm_rda; /**< Rx DMA attributes*/
60255 + volatile uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
60256 + volatile uint32_t fmbm_rfed; /**< Rx Frame End Data*/
60257 + volatile uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
60258 + volatile uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
60259 + volatile uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
60260 + volatile uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
60261 + volatile uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
60262 + volatile uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
60263 + volatile uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
60264 + volatile uint32_t fmbm_rpp; /**< Rx Policer Profile */
60265 + volatile uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
60266 + volatile uint32_t fmbm_reth; /**< Rx Excessive Threshold */
60267 + volatile uint32_t reserved1[0x01];/**< (0x03C) */
60268 + volatile uint32_t fmbm_rprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
60269 + /**< Rx Parse Results Array Initialization*/
60270 + volatile uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
60271 + volatile uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
60272 + volatile uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
60273 + volatile uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
60274 + volatile uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
60275 + volatile uint32_t reserved2[0x02];/**< (0x074-0x078) */
60276 + volatile uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
60277 + volatile uint32_t reserved3[0x20];/**< (0x080 0x0FF) */
60278 + volatile uint32_t fmbm_ebmpi[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
60279 + /**< Buffer Manager pool Information-*/
60280 + volatile uint32_t fmbm_acnt[FM_PORT_MAX_NUM_OF_EXT_POOLS_ALL_INTEGRATIONS];
60281 + /**< Allocate Counter-*/
60282 + volatile uint32_t reserved4[0x08];
60283 + /**< 0x130/0x140 - 0x15F reserved -*/
60284 + volatile uint32_t fmbm_rcgm[FM_PORT_MAX_NUM_OF_CONGESTION_GRPS_ALL_INTEGRATIONS/32];
60285 + /**< Congestion Group Map*/
60286 + volatile uint32_t fmbm_rmpd; /**< BM Pool Depletion */
60287 + volatile uint32_t reserved5[0x1F];/**< (0x184 0x1FF) */
60288 + volatile uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
60289 + volatile uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
60290 + volatile uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
60291 + volatile uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
60292 + volatile uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
60293 + volatile uint32_t fmbm_rfcd; /**< Rx Frame Discard Counter*/
60294 + volatile uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
60295 + volatile uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard Counter-*/
60296 + volatile uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter-*/
60297 + volatile uint32_t fmbm_rpec; /**< Rx RX Prepare to enqueue Counter-*/
60298 + volatile uint32_t reserved6[0x16];/**< (0x228 0x27F) */
60299 + volatile uint32_t fmbm_rpc; /**< Rx Performance Counters*/
60300 + volatile uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
60301 + volatile uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
60302 + volatile uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
60303 + volatile uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization Counter*/
60304 + volatile uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
60305 + volatile uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
60306 + volatile uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
60307 + volatile uint32_t reserved7[0x18];/**< (0x2A0-0x2FF) */
60308 + volatile uint32_t fmbm_rdcfg[0x3];/**< Rx Debug-*/
60309 + volatile uint32_t fmbm_rgpr; /**< Rx General Purpose Register. */
60310 + volatile uint32_t reserved8[0x3a];/**< (0x310-0x3FF) */
60311 +} t_FmPortRxBmiRegs;
60312 +
60313 +typedef struct
60314 +{
60315 + volatile uint32_t fmbm_tcfg; /**< Tx Configuration */
60316 + volatile uint32_t fmbm_tst; /**< Tx Status */
60317 + volatile uint32_t fmbm_tda; /**< Tx DMA attributes */
60318 + volatile uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
60319 + volatile uint32_t fmbm_tfed; /**< Tx Frame End Data */
60320 + volatile uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
60321 + volatile uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
60322 + volatile uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
60323 + volatile uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
60324 + volatile uint32_t fmbm_tfeqid; /**< Tx Frame Error Queue ID */
60325 + volatile uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
60326 + volatile uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
60327 + volatile uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
60328 + volatile uint32_t fmbm_tccb; /**< Tx Coarse Classification Base */
60329 + volatile uint32_t reserved0[0x0e];/**< (0x038-0x070) */
60330 + volatile uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
60331 + volatile uint32_t fmbm_tpfcm[0x02];/**< Tx Priority based Flow Control (PFC) Mapping */
60332 + volatile uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
60333 + volatile uint32_t reserved2[0x60];/**< (0x080-0x200) */
60334 + volatile uint32_t fmbm_tstc; /**< Tx Statistics Counters */
60335 + volatile uint32_t fmbm_tfrc; /**< Tx Frame Counter */
60336 + volatile uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
60337 + volatile uint32_t fmbm_tfledc; /**< Tx Frame Length error discard counter */
60338 + volatile uint32_t fmbm_tfufdc; /**< Tx Frame unsupported format discard Counter */
60339 + volatile uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
60340 + volatile uint32_t reserved3[0x1A];/**< (0x218-0x280) */
60341 + volatile uint32_t fmbm_tpc; /**< Tx Performance Counters*/
60342 + volatile uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
60343 + volatile uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
60344 + volatile uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
60345 + volatile uint32_t fmbm_ttcquc; /**< Tx Transmit Confirm Queue Utilization Counter*/
60346 + volatile uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
60347 + volatile uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
60348 + volatile uint32_t reserved4[16]; /**< (0x29C-0x2FF) */
60349 + volatile uint32_t fmbm_tdcfg[0x3];/**< Tx Debug-*/
60350 + volatile uint32_t fmbm_tgpr; /**< O/H General Purpose Register */
60351 + volatile uint32_t reserved5[0x3a];/**< (0x310-0x3FF) */
60352 +} t_FmPortTxBmiRegs;
60353 +
60354 +typedef struct
60355 +{
60356 + volatile uint32_t fmbm_ocfg; /**< O/H Configuration */
60357 + volatile uint32_t fmbm_ost; /**< O/H Status */
60358 + volatile uint32_t fmbm_oda; /**< O/H DMA attributes */
60359 + volatile uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
60360 + volatile uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
60361 + volatile uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
60362 + volatile uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
60363 + volatile uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
60364 + volatile uint32_t fmbm_opso; /**< O/H Parse Start Offset */
60365 + volatile uint32_t fmbm_opp; /**< O/H Policer Profile */
60366 + volatile uint32_t fmbm_occb; /**< O/H Coarse Classification base */
60367 + volatile uint32_t fmbm_oim; /**< O/H Internal margins*/
60368 + volatile uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
60369 + volatile uint32_t fmbm_ofed; /**< O/H Frame End Data*/
60370 + volatile uint32_t reserved0[2]; /**< (0x038 - 0x03F) */
60371 + volatile uint32_t fmbm_oprai[FM_PORT_PRS_RESULT_NUM_OF_WORDS];
60372 + /**< O/H Parse Results Array Initialization */
60373 + volatile uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
60374 + volatile uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
60375 + volatile uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
60376 + volatile uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
60377 + volatile uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
60378 + volatile uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
60379 + volatile uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
60380 + volatile uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
60381 + volatile uint32_t reserved1[0x20];/**< (0x080 - 0x0FF) */
60382 + volatile uint32_t fmbm_oebmpi[2]; /**< Buffer Manager Observed Pool Information */
60383 + volatile uint32_t reserved2[0x16];/**< (0x108 - 0x15F) */
60384 + volatile uint32_t fmbm_ocgm; /**< Observed Congestion Group Map */
60385 + volatile uint32_t reserved3[0x7]; /**< (0x164 - 0x17F) */
60386 + volatile uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
60387 + volatile uint32_t reserved4[0x1F];/**< (0x184 - 0x1FF) */
60388 + volatile uint32_t fmbm_ostc; /**< O/H Statistics Counters */
60389 + volatile uint32_t fmbm_ofrc; /**< O/H Frame Counter */
60390 + volatile uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
60391 + volatile uint32_t fmbm_ofledc; /**< O/H Frames Length Error Discard Counter */
60392 + volatile uint32_t fmbm_ofufdc; /**< O/H Frames Unsupported Format Discard Counter */
60393 + volatile uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
60394 + volatile uint32_t fmbm_ofwdc; /**< - Rx Frames WRED Discard Counter */
60395 + volatile uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Counter */
60396 + volatile uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
60397 + volatile uint32_t fmbm_oodc; /**< O/H Out of Buffers Discard Counter */
60398 + volatile uint32_t fmbm_opec; /**< O/H Prepare to enqueue Counter */
60399 + volatile uint32_t reserved5[0x15];/**< ( - 0x27F) */
60400 + volatile uint32_t fmbm_opc; /**< O/H Performance Counters */
60401 + volatile uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
60402 + volatile uint32_t fmbm_occn; /**< O/H Cycle Counter */
60403 + volatile uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
60404 + volatile uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
60405 + volatile uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
60406 + volatile uint32_t reserved6[26]; /**< (0x298-0x2FF) */
60407 + volatile uint32_t fmbm_odcfg[0x3];/**< O/H Debug (only 1 in P1023) */
60408 + volatile uint32_t fmbm_ogpr; /**< O/H General Purpose Register. */
60409 + volatile uint32_t reserved7[0x3a];/**< (0x310 0x3FF) */
60410 +} t_FmPortOhBmiRegs;
60411 +
60412 +typedef union
60413 +{
60414 + t_FmPortRxBmiRegs rxPortBmiRegs;
60415 + t_FmPortTxBmiRegs txPortBmiRegs;
60416 + t_FmPortOhBmiRegs ohPortBmiRegs;
60417 +} u_FmPortBmiRegs;
60418 +
60419 +typedef struct
60420 +{
60421 + volatile uint32_t reserved1[2]; /**< 0xn024 - 0x02B */
60422 + volatile uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
60423 + volatile uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
60424 + volatile uint32_t fmqm_pndtfc; /**< PortID n Dequeue Total Frame Counter */
60425 + volatile uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID from Default Counter */
60426 + volatile uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
60427 +} t_FmPortNonRxQmiRegs;
60428 +
60429 +typedef struct
60430 +{
60431 + volatile uint32_t fmqm_pnc; /**< PortID n Configuration Register */
60432 + volatile uint32_t fmqm_pns; /**< PortID n Status Register */
60433 + volatile uint32_t fmqm_pnts; /**< PortID n Task Status Register */
60434 + volatile uint32_t reserved0[4]; /**< 0xn00C - 0xn01B */
60435 + volatile uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
60436 + volatile uint32_t fmqm_pnetfc; /**< PortID n Enqueue Total Frame Counter */
60437 + t_FmPortNonRxQmiRegs nonRxQmiRegs; /**< Registers for Tx Hc & Op ports */
60438 +} t_FmPortQmiRegs;
60439 +
60440 +typedef struct
60441 +{
60442 + struct
60443 + {
60444 + volatile uint32_t softSeqAttach; /**< Soft Sequence Attachment */
60445 + volatile uint32_t lcv; /**< Line-up Enable Confirmation Mask */
60446 + } hdrs[FM_PCD_PRS_NUM_OF_HDRS];
60447 + volatile uint32_t reserved0[0xde];
60448 + volatile uint32_t pcac; /**< Parse Internal Memory Configuration Access Control Register */
60449 + volatile uint32_t pctpid; /**< Parse Internal Memory Configured TPID Register */
60450 +} t_FmPortPrsRegs;
60451 +
60452 +/**************************************************************************//*
60453 + @Description Basic buffer descriptor (BD) structure
60454 +*//***************************************************************************/
60455 +typedef _Packed struct
60456 +{
60457 + volatile uint16_t status;
60458 + volatile uint16_t length;
60459 + volatile uint8_t reserved0[0x6];
60460 + volatile uint8_t reserved1[0x1];
60461 + volatile t_FmPhysAddr buff;
60462 +} _PackedType t_FmImBd;
60463 +
60464 +typedef _Packed struct
60465 +{
60466 + volatile uint16_t gen; /**< tbd */
60467 + volatile uint8_t reserved0[0x1];
60468 + volatile t_FmPhysAddr bdRingBase; /**< tbd */
60469 + volatile uint16_t bdRingSize; /**< tbd */
60470 + volatile uint16_t offsetIn; /**< tbd */
60471 + volatile uint16_t offsetOut; /**< tbd */
60472 + volatile uint8_t reserved1[0x12]; /**< 0x0e - 0x1f */
60473 +} _PackedType t_FmPortImQd;
60474 +
60475 +typedef _Packed struct
60476 +{
60477 + volatile uint32_t mode; /**< Mode register */
60478 + volatile uint32_t rxQdPtr; /**< tbd */
60479 + volatile uint32_t txQdPtr; /**< tbd */
60480 + volatile uint16_t mrblr; /**< tbd */
60481 + volatile uint16_t rxQdBsyCnt; /**< tbd */
60482 + volatile uint8_t reserved0[0x10]; /**< 0x10 - 0x1f */
60483 + t_FmPortImQd rxQd;
60484 + t_FmPortImQd txQd;
60485 + volatile uint8_t reserved1[0xa0]; /**< 0x60 - 0xff */
60486 +} _PackedType t_FmPortImPram;
60487 +
60488 +#if defined(__MWERKS__) && !defined(__GNUC__)
60489 +#pragma pack(pop)
60490 +#endif /* defined(__MWERKS__) && ... */
60491 +
60492 +
60493 +/**************************************************************************//**
60494 + @Description Registers bit fields
60495 +*//***************************************************************************/
60496 +
60497 +/**************************************************************************//**
60498 + @Description BMI defines
60499 +*//***************************************************************************/
60500 +#if (DPAA_VERSION >= 11)
60501 +#define BMI_SP_ID_MASK 0xff000000
60502 +#define BMI_SP_ID_SHIFT 24
60503 +#define BMI_SP_EN 0x01000000
60504 +#endif /* (DPAA_VERSION >= 11) */
60505 +
60506 +#define BMI_PORT_CFG_EN 0x80000000
60507 +#define BMI_PORT_CFG_EN_MACSEC 0x00800000
60508 +#define BMI_PORT_CFG_FDOVR 0x02000000
60509 +#define BMI_PORT_CFG_IM 0x01000000
60510 +#define BMI_PORT_CFG_AM 0x00000040
60511 +#define BMI_PORT_STATUS_BSY 0x80000000
60512 +#define BMI_COUNTERS_EN 0x80000000
60513 +
60514 +#define BMI_PORT_RFNE_FRWD_DCL4C 0x10000000
60515 +#define BMI_PORT_RFNE_FRWD_RPD 0x40000000
60516 +#define BMI_RFNE_FDCS_MASK 0xFF000000
60517 +#define BMI_RFNE_HXS_MASK 0x000000FF
60518 +
60519 +#define BMI_CMD_MR_LEAC 0x00200000
60520 +#define BMI_CMD_MR_SLEAC 0x00100000
60521 +#define BMI_CMD_MR_MA 0x00080000
60522 +#define BMI_CMD_MR_DEAS 0x00040000
60523 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
60524 + BMI_CMD_MR_SLEAC | \
60525 + BMI_CMD_MR_MA | \
60526 + BMI_CMD_MR_DEAS)
60527 +#define BMI_CMD_ATTR_ORDER 0x80000000
60528 +#define BMI_CMD_ATTR_SYNC 0x02000000
60529 +#define BMI_CMD_ATTR_MODE_MISS_ALLIGN_ADDR_EN 0x00080000
60530 +#define BMI_CMD_ATTR_MACCMD_MASK 0x0000ff00
60531 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE 0x00008000
60532 +#define BMI_CMD_ATTR_MACCMD_SECURED 0x00001000
60533 +#define BMI_CMD_ATTR_MACCMD_SC_MASK 0x00000f00
60534 +
60535 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
60536 +#define BMI_STATUS_RX_MASK_UNUSED (uint32_t)(~(FM_PORT_FRM_ERR_DMA | \
60537 + FM_PORT_FRM_ERR_PHYSICAL | \
60538 + FM_PORT_FRM_ERR_SIZE | \
60539 + FM_PORT_FRM_ERR_CLS_DISCARD | \
60540 + FM_PORT_FRM_ERR_EXTRACTION | \
60541 + FM_PORT_FRM_ERR_NO_SCHEME | \
60542 + FM_PORT_FRM_ERR_COLOR_RED | \
60543 + FM_PORT_FRM_ERR_COLOR_YELLOW | \
60544 + FM_PORT_FRM_ERR_ILL_PLCR | \
60545 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
60546 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
60547 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
60548 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
60549 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
60550 + FM_PORT_FRM_ERR_IPRE | \
60551 + FM_PORT_FRM_ERR_IPR_NCSP | \
60552 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW))
60553 +
60554 +#define BMI_STATUS_OP_MASK_UNUSED (uint32_t)(BMI_STATUS_RX_MASK_UNUSED & \
60555 + ~(FM_PORT_FRM_ERR_LENGTH | \
60556 + FM_PORT_FRM_ERR_NON_FM | \
60557 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT))
60558 +
60559 +#define BMI_RATE_LIMIT_EN 0x80000000
60560 +#define BMI_RATE_LIMIT_BURST_SIZE_GRAN 0x80000000
60561 +#define BMI_RATE_LIMIT_SCALE_BY_2 0x00000001
60562 +#define BMI_RATE_LIMIT_SCALE_BY_4 0x00000002
60563 +#define BMI_RATE_LIMIT_SCALE_BY_8 0x00000003
60564 +
60565 +#define BMI_RX_FIFO_THRESHOLD_BC 0x80000000
60566 +
60567 +#define BMI_PRS_RESULT_HIGH 0x00000000
60568 +#define BMI_PRS_RESULT_LOW 0xFFFFFFFF
60569 +
60570 +
60571 +#define RX_ERRS_TO_ENQ (FM_PORT_FRM_ERR_DMA | \
60572 + FM_PORT_FRM_ERR_PHYSICAL | \
60573 + FM_PORT_FRM_ERR_SIZE | \
60574 + FM_PORT_FRM_ERR_EXTRACTION | \
60575 + FM_PORT_FRM_ERR_NO_SCHEME | \
60576 + FM_PORT_FRM_ERR_ILL_PLCR | \
60577 + FM_PORT_FRM_ERR_PLCR_FRAME_LEN | \
60578 + FM_PORT_FRM_ERR_PRS_TIMEOUT | \
60579 + FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT | \
60580 + FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED | \
60581 + FM_PORT_FRM_ERR_PRS_HDR_ERR | \
60582 + FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW | \
60583 + FM_PORT_FRM_ERR_IPRE)
60584 +
60585 +#define OP_ERRS_TO_ENQ (RX_ERRS_TO_ENQ | \
60586 + FM_PORT_FRM_ERR_LENGTH | \
60587 + FM_PORT_FRM_ERR_NON_FM | \
60588 + FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT)
60589 +
60590 +
60591 +#define BMI_RX_FIFO_PRI_ELEVATION_MASK 0x03FF0000
60592 +#define BMI_RX_FIFO_THRESHOLD_MASK 0x000003FF
60593 +#define BMI_TX_FIFO_MIN_FILL_MASK 0x03FF0000
60594 +#define BMI_FIFO_PIPELINE_DEPTH_MASK 0x0000F000
60595 +#define BMI_TX_LOW_COMF_MASK 0x000003FF
60596 +
60597 +/* shifts */
60598 +#define BMI_PORT_CFG_MS_SEL_SHIFT 16
60599 +#define BMI_DMA_ATTR_IC_CACHE_SHIFT FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT
60600 +#define BMI_DMA_ATTR_HDR_CACHE_SHIFT FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT
60601 +#define BMI_DMA_ATTR_SG_CACHE_SHIFT FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT
60602 +
60603 +#define BMI_IM_FOF_SHIFT 28
60604 +#define BMI_PR_PORTID_SHIFT 24
60605 +
60606 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
60607 +#define BMI_RX_FIFO_THRESHOLD_SHIFT 0
60608 +
60609 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
60610 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
60611 +
60612 +#define BMI_IC_SIZE_SHIFT FMAN_SP_IC_SIZE_SHIFT
60613 +
60614 +#define BMI_INT_BUF_MARG_SHIFT 28
60615 +
60616 +#define BMI_EXT_BUF_MARG_END_SHIFT FMAN_SP_EXT_BUF_MARG_END_SHIFT
60617 +
60618 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
60619 +#define BMI_CMD_ATTR_COM_MODE_SHIFT 16
60620 +#define BMI_CMD_ATTR_MACCMD_SHIFT 8
60621 +#define BMI_CMD_ATTR_MACCMD_OVERRIDE_SHIFT 15
60622 +#define BMI_CMD_ATTR_MACCMD_SECURED_SHIFT 12
60623 +#define BMI_CMD_ATTR_MACCMD_SC_SHIFT 8
60624 +
60625 +#define BMI_POOL_DEP_NUM_OF_POOLS_VECTOR_SHIFT 24
60626 +
60627 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
60628 +#define BMI_TX_LOW_COMF_SHIFT 0
60629 +
60630 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
60631 +#define BMI_PERFORMANCE_PORT_COMP_SHIFT 16
60632 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
60633 +#define BMI_PERFORMANCE_FIFO_COMP_SHIFT 0
60634 +
60635 +#define BMI_MAX_BURST_SHIFT 16
60636 +#define BMI_COUNT_RATE_UNIT_SHIFT 16
60637 +
60638 +/* sizes */
60639 +#define FRAME_END_DATA_SIZE 16
60640 +#define FRAME_OFFSET_UNITS 16
60641 +#define MIN_TX_INT_OFFSET 16
60642 +#define MAX_FRAME_OFFSET 64
60643 +#define MAX_FIFO_PIPELINE_DEPTH 8
60644 +#define MAX_PERFORMANCE_TASK_COMP 64
60645 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
60646 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
60647 +#define MAX_PERFORMANCE_DMA_COMP 16
60648 +#define MAX_NUM_OF_TASKS 64
60649 +#define MAX_NUM_OF_EXTRA_TASKS 8
60650 +#define MAX_NUM_OF_DMAS 16
60651 +#define MAX_NUM_OF_EXTRA_DMAS 8
60652 +#define MAX_BURST_SIZE 1024
60653 +#define MIN_NUM_OF_OP_DMAS 2
60654 +
60655 +
60656 +/**************************************************************************//**
60657 + @Description QMI defines
60658 +*//***************************************************************************/
60659 +/* masks */
60660 +#define QMI_PORT_CFG_EN 0x80000000
60661 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
60662 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
60663 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
60664 +
60665 +#define QMI_DEQ_CFG_PREFETCH_NO_TNUM 0x02000000
60666 +#define QMI_DEQ_CFG_PREFETCH_WAITING_TNUM 0
60667 +#define QMI_DEQ_CFG_PREFETCH_1_FRAME 0
60668 +#define QMI_DEQ_CFG_PREFETCH_3_FRAMES 0x01000000
60669 +
60670 +#define QMI_DEQ_CFG_PRI 0x80000000
60671 +#define QMI_DEQ_CFG_TYPE1 0x10000000
60672 +#define QMI_DEQ_CFG_TYPE2 0x20000000
60673 +#define QMI_DEQ_CFG_TYPE3 0x30000000
60674 +
60675 +#define QMI_DEQ_CFG_SUBPORTAL_MASK 0x1f
60676 +#define QMI_DEQ_CFG_SUBPORTAL_SHIFT 20
60677 +
60678 +/**************************************************************************//**
60679 + @Description PARSER defines
60680 +*//***************************************************************************/
60681 +/* masks */
60682 +#define PRS_HDR_ERROR_DIS 0x00000800
60683 +#define PRS_HDR_SW_PRS_EN 0x00000400
60684 +#define PRS_CP_OFFSET_MASK 0x0000000F
60685 +#define PRS_TPID1_MASK 0xFFFF0000
60686 +#define PRS_TPID2_MASK 0x0000FFFF
60687 +#define PRS_TPID_DFLT 0x91009100
60688 +
60689 +#define PRS_HDR_MPLS_LBL_INTER_EN 0x00200000
60690 +#define PRS_HDR_IPV6_ROUTE_HDR_EN 0x00008000
60691 +#define PRS_HDR_PPPOE_MTU_CHECK_EN 0x80000000
60692 +#define PRS_HDR_UDP_PAD_REMOVAL 0x80000000
60693 +#define PRS_HDR_TCP_PAD_REMOVAL 0x80000000
60694 +#define PRS_CAC_STOP 0x00000001
60695 +#define PRS_CAC_ACTIVE 0x00000100
60696 +
60697 +/* shifts */
60698 +#define PRS_PCTPID_SHIFT 16
60699 +#define PRS_HDR_MPLS_NEXT_HDR_SHIFT 22
60700 +#define PRS_HDR_ETH_BC_SHIFT 28
60701 +#define PRS_HDR_ETH_MC_SHIFT 24
60702 +#define PRS_HDR_VLAN_STACKED_SHIFT 16
60703 +#define PRS_HDR_MPLS_STACKED_SHIFT 16
60704 +#define PRS_HDR_IPV4_1_BC_SHIFT 28
60705 +#define PRS_HDR_IPV4_1_MC_SHIFT 24
60706 +#define PRS_HDR_IPV4_2_UC_SHIFT 20
60707 +#define PRS_HDR_IPV4_2_MC_BC_SHIFT 16
60708 +#define PRS_HDR_IPV6_1_MC_SHIFT 24
60709 +#define PRS_HDR_IPV6_2_UC_SHIFT 20
60710 +#define PRS_HDR_IPV6_2_MC_SHIFT 16
60711 +
60712 +#define PRS_HDR_ETH_BC_MASK 0x0fffffff
60713 +#define PRS_HDR_ETH_MC_MASK 0xf0ffffff
60714 +#define PRS_HDR_VLAN_STACKED_MASK 0xfff0ffff
60715 +#define PRS_HDR_MPLS_STACKED_MASK 0xfff0ffff
60716 +#define PRS_HDR_IPV4_1_BC_MASK 0x0fffffff
60717 +#define PRS_HDR_IPV4_1_MC_MASK 0xf0ffffff
60718 +#define PRS_HDR_IPV4_2_UC_MASK 0xff0fffff
60719 +#define PRS_HDR_IPV4_2_MC_BC_MASK 0xfff0ffff
60720 +#define PRS_HDR_IPV6_1_MC_MASK 0xf0ffffff
60721 +#define PRS_HDR_IPV6_2_UC_MASK 0xff0fffff
60722 +#define PRS_HDR_IPV6_2_MC_MASK 0xfff0ffff
60723 +
60724 +/* others */
60725 +#define PRS_HDR_ENTRY_SIZE 8
60726 +#define DEFAULT_CLS_PLAN_VECTOR 0xFFFFFFFF
60727 +
60728 +#define IPSEC_SW_PATCH_START 0x20
60729 +#define SCTP_SW_PATCH_START 0x4D
60730 +#define DCCP_SW_PATCH_START 0x41
60731 +
60732 +/**************************************************************************//**
60733 + @Description IM defines
60734 +*//***************************************************************************/
60735 +#define BD_R_E 0x80000000
60736 +#define BD_L 0x08000000
60737 +
60738 +#define BD_RX_CRE 0x00080000
60739 +#define BD_RX_FTL 0x00040000
60740 +#define BD_RX_FTS 0x00020000
60741 +#define BD_RX_OV 0x00010000
60742 +
60743 +#define BD_RX_ERRORS (BD_RX_CRE | BD_RX_FTL | BD_RX_FTS | BD_RX_OV)
60744 +
60745 +#define FM_IM_SIZEOF_BD sizeof(t_FmImBd)
60746 +
60747 +#define BD_STATUS_MASK 0xffff0000
60748 +#define BD_LENGTH_MASK 0x0000ffff
60749 +
60750 +#define BD_STATUS_AND_LENGTH_SET(bd, val) WRITE_UINT32(*(volatile uint32_t*)(bd), (val))
60751 +
60752 +#define BD_STATUS_AND_LENGTH(bd) GET_UINT32(*(volatile uint32_t*)(bd))
60753 +
60754 +#define BD_GET(id) &p_FmPort->im.p_BdRing[id]
60755 +
60756 +#define IM_ILEGAL_BD_ID 0xffff
60757 +
60758 +/* others */
60759 +#define IM_PRAM_ALIGN 0x100
60760 +
60761 +/* masks */
60762 +#define IM_MODE_GBL 0x20000000
60763 +#define IM_MODE_BO_MASK 0x18000000
60764 +#define IM_MODE_BO_SHIFT 3
60765 +#define IM_MODE_GRC_STP 0x00800000
60766 +
60767 +#define IM_MODE_SET_BO(val) (uint32_t)((val << (31-IM_MODE_BO_SHIFT)) & IM_MODE_BO_MASK)
60768 +
60769 +#define IM_RXQD_BSYINTM 0x0008
60770 +#define IM_RXQD_RXFINTM 0x0010
60771 +#define IM_RXQD_FPMEVT_SEL_MASK 0x0003
60772 +
60773 +#define IM_EV_BSY 0x40000000
60774 +#define IM_EV_RX 0x80000000
60775 +
60776 +
60777 +/**************************************************************************//**
60778 + @Description Additional defines
60779 +*//***************************************************************************/
60780 +
60781 +typedef struct {
60782 + t_Handle h_FmMuram;
60783 + t_FmPortImPram *p_FmPortImPram;
60784 + uint8_t fwExtStructsMemId;
60785 + uint32_t fwExtStructsMemAttr;
60786 + uint16_t bdRingSize;
60787 + t_FmImBd *p_BdRing;
60788 + t_Handle *p_BdShadow;
60789 + uint16_t currBdId;
60790 + uint16_t firstBdOfFrameId;
60791 +
60792 + /* Rx port parameters */
60793 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
60794 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
60795 + t_BufferPoolInfo rxPool;
60796 + uint16_t mrblr;
60797 + uint16_t rxFrameAccumLength;
60798 + t_FmPortImRxStoreCallback *f_RxStore;
60799 +
60800 + /* Tx port parameters */
60801 + uint32_t txFirstBdStatus;
60802 + t_FmPortImTxConfCallback *f_TxConf;
60803 +} t_FmMacIm;
60804 +
60805 +
60806 +typedef struct {
60807 + struct fman_port_cfg dfltCfg;
60808 + uint32_t dfltFqid;
60809 + uint32_t confFqid;
60810 + uint32_t errFqid;
60811 + uintptr_t baseAddr;
60812 + uint8_t deqSubPortal;
60813 + bool deqHighPriority;
60814 + e_FmPortDeqType deqType;
60815 + e_FmPortDeqPrefetchOption deqPrefetchOption;
60816 + uint16_t deqByteCnt;
60817 + uint8_t cheksumLastBytesIgnore;
60818 + uint8_t cutBytesFromEnd;
60819 + t_FmBufPoolDepletion bufPoolDepletion;
60820 + uint8_t pipelineDepth;
60821 + uint16_t fifoLowComfLevel;
60822 + bool frmDiscardOverride;
60823 + bool enRateLimit;
60824 + t_FmPortRateLimit rateLimit;
60825 + e_FmPortDualRateLimiterScaleDown rateLimitDivider;
60826 + bool enBufPoolDepletion;
60827 + uint16_t liodnOffset;
60828 + uint16_t liodnBase;
60829 + t_FmExtPools extBufPools;
60830 + e_FmDmaSwapOption dmaSwapData;
60831 + e_FmDmaCacheOption dmaIntContextCacheAttr;
60832 + e_FmDmaCacheOption dmaHeaderCacheAttr;
60833 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
60834 + bool dmaReadOptimize;
60835 + bool dmaWriteOptimize;
60836 + uint32_t txFifoMinFillLevel;
60837 + uint32_t txFifoLowComfLevel;
60838 + uint32_t rxFifoPriElevationLevel;
60839 + uint32_t rxFifoThreshold;
60840 + t_FmSpBufMargins bufMargins;
60841 + t_FmSpIntContextDataCopy intContext;
60842 + bool syncReq;
60843 + e_FmPortColor color;
60844 + fmPortFrameErrSelect_t errorsToDiscard;
60845 + fmPortFrameErrSelect_t errorsToEnq;
60846 + bool forwardReuseIntContext;
60847 + t_FmBufferPrefixContent bufferPrefixContent;
60848 + t_FmBackupBmPools *p_BackupBmPools;
60849 + bool dontReleaseBuf;
60850 + bool setNumOfTasks;
60851 + bool setNumOfOpenDmas;
60852 + bool setSizeOfFifo;
60853 +#if (DPAA_VERSION >= 11)
60854 + bool noScatherGather;
60855 +#endif /* (DPAA_VERSION >= 11) */
60856 +
60857 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
60858 + bool bcbWorkaround;
60859 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
60860 +} t_FmPortDriverParam;
60861 +
60862 +
60863 +typedef struct t_FmPortRxPoolsParams
60864 +{
60865 + uint8_t numOfPools;
60866 + uint16_t secondLargestBufSize;
60867 + uint16_t largestBufSize;
60868 +} t_FmPortRxPoolsParams;
60869 +
60870 +typedef struct t_FmPortDsarVars {
60871 + t_Handle *autoResOffsets;
60872 + t_FmPortDsarTablesSizes *autoResMaxSizes;
60873 + uint32_t fmbm_tcfg;
60874 + uint32_t fmbm_tcmne;
60875 + uint32_t fmbm_rfne;
60876 + uint32_t fmbm_rfpne;
60877 + uint32_t fmbm_rcfg;
60878 + bool dsarEnabledParser;
60879 +} t_FmPortDsarVars;
60880 +typedef struct {
60881 + struct fman_port port;
60882 + t_Handle h_Fm;
60883 + t_Handle h_FmPcd;
60884 + t_Handle h_FmMuram;
60885 + t_FmRevisionInfo fmRevInfo;
60886 + uint8_t portId;
60887 + e_FmPortType portType;
60888 + int enabled;
60889 + char name[MODULE_NAME_SIZE];
60890 + uint8_t hardwarePortId;
60891 + uint16_t fmClkFreq;
60892 + t_FmPortQmiRegs *p_FmPortQmiRegs;
60893 + u_FmPortBmiRegs *p_FmPortBmiRegs;
60894 + t_FmPortPrsRegs *p_FmPortPrsRegs;
60895 + fmPcdEngines_t pcdEngines;
60896 + uint32_t savedBmiNia;
60897 + uint8_t netEnvId;
60898 + uint32_t optArray[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
60899 + uint32_t lcvs[FM_PCD_PRS_NUM_OF_HDRS];
60900 + uint8_t privateInfo;
60901 + uint32_t schemesPerPortVector;
60902 + bool useClsPlan;
60903 + uint8_t clsPlanGrpId;
60904 + t_Handle ccTreeId;
60905 + t_Handle completeArg;
60906 + void (*f_Complete)(t_Handle arg);
60907 + t_FmSpBufferOffsets bufferOffsets;
60908 + /* Independent-Mode parameters support */
60909 + bool imEn;
60910 + t_FmMacIm im;
60911 + volatile bool lock;
60912 + t_Handle h_Spinlock;
60913 + t_FmPortExceptionCallback *f_Exception;
60914 + t_Handle h_App;
60915 + uint8_t internalBufferOffset;
60916 + uint8_t fmanCtrlEventId;
60917 + uint32_t exceptions;
60918 + bool polling;
60919 + t_FmExtPools extBufPools;
60920 + uint32_t requiredAction;
60921 + uint32_t savedQmiPnen;
60922 + uint32_t savedBmiFene;
60923 + uint32_t savedBmiFpne;
60924 + uint32_t savedBmiCmne;
60925 + uint32_t savedBmiOfp;
60926 + uint32_t savedNonRxQmiRegsPndn;
60927 + uint32_t origNonRxQmiRegsPndn;
60928 + int savedPrsStartOffset;
60929 + bool includeInPrsStatistics;
60930 + uint16_t maxFrameLength;
60931 + t_FmFmanCtrl orFmanCtrl;
60932 + t_FmPortRsrc openDmas;
60933 + t_FmPortRsrc tasks;
60934 + t_FmPortRsrc fifoBufs;
60935 + t_FmPortRxPoolsParams rxPoolsParams;
60936 +// bool explicitUserSizeOfFifo;
60937 + t_Handle h_IpReassemblyManip;
60938 + t_Handle h_CapwapReassemblyManip;
60939 + t_Handle h_ReassemblyTree;
60940 + uint64_t fmMuramPhysBaseAddr;
60941 +#if (DPAA_VERSION >= 11)
60942 + bool vspe;
60943 + uint8_t dfltRelativeId;
60944 + e_FmPortGprFuncType gprFunc;
60945 + t_FmPcdCtrlParamsPage *p_ParamsPage;
60946 +#endif /* (DPAA_VERSION >= 11) */
60947 + t_FmPortDsarVars deepSleepVars;
60948 + t_FmPortDriverParam *p_FmPortDriverParam;
60949 +} t_FmPort;
60950 +
60951 +
60952 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams);
60953 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort);
60954 +
60955 +t_Error FmPortImInit(t_FmPort *p_FmPort);
60956 +void FmPortImFree(t_FmPort *p_FmPort);
60957 +
60958 +t_Error FmPortImEnable (t_FmPort *p_FmPort);
60959 +t_Error FmPortImDisable (t_FmPort *p_FmPort);
60960 +t_Error FmPortImRx (t_FmPort *p_FmPort);
60961 +
60962 +void FmPortSetMacsecLcv(t_Handle h_FmPort);
60963 +void FmPortSetMacsecCmd(t_Handle h_FmPort, uint8_t dfltSci);
60964 +
60965 +
60966 +t_Error FM_PORT_SetNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfOpenDmas);
60967 +t_Error FM_PORT_SetNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
60968 +t_Error FM_PORT_SetSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
60969 +
60970 +static __inline__ uint8_t * BdBufferGet (t_PhysToVirt *f_PhysToVirt, t_FmImBd *p_Bd)
60971 +{
60972 + uint64_t physAddr = (uint64_t)((uint64_t)GET_UINT8(p_Bd->buff.high) << 32);
60973 + physAddr |= GET_UINT32(p_Bd->buff.low);
60974 +
60975 + return (uint8_t *)f_PhysToVirt((physAddress_t)(physAddr));
60976 +}
60977 +
60978 +static __inline__ void SET_ADDR(volatile t_FmPhysAddr *fmPhysAddr, uint64_t value)
60979 +{
60980 + WRITE_UINT8(fmPhysAddr->high,(uint8_t)((value & 0x000000ff00000000LL) >> 32));
60981 + WRITE_UINT32(fmPhysAddr->low,(uint32_t)value);
60982 +}
60983 +
60984 +static __inline__ void BdBufferSet(t_VirtToPhys *f_VirtToPhys, t_FmImBd *p_Bd, uint8_t *p_Buffer)
60985 +{
60986 + uint64_t physAddr = (uint64_t)(f_VirtToPhys(p_Buffer));
60987 + SET_ADDR(&p_Bd->buff, physAddr);
60988 +}
60989 +
60990 +static __inline__ uint16_t GetNextBdId(t_FmPort *p_FmPort, uint16_t id)
60991 +{
60992 + if (id < p_FmPort->im.bdRingSize-1)
60993 + return (uint16_t)(id+1);
60994 + else
60995 + return 0;
60996 +}
60997 +
60998 +void FM_PORT_Dsar_DumpRegs(void);
60999 +
61000 +
61001 +#endif /* __FM_PORT_H */
61002 --- /dev/null
61003 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_dsar.h
61004 @@ -0,0 +1,494 @@
61005 +/*
61006 + * Copyright 2008-2012 Freescale Semiconductor Inc.
61007 + *
61008 + * Redistribution and use in source and binary forms, with or without
61009 + * modification, are permitted provided that the following conditions are met:
61010 + * * Redistributions of source code must retain the above copyright
61011 + * notice, this list of conditions and the following disclaimer.
61012 + * * Redistributions in binary form must reproduce the above copyright
61013 + * notice, this list of conditions and the following disclaimer in the
61014 + * documentation and/or other materials provided with the distribution.
61015 + * * Neither the name of Freescale Semiconductor nor the
61016 + * names of its contributors may be used to endorse or promote products
61017 + * derived from this software without specific prior written permission.
61018 + *
61019 + *
61020 + * ALTERNATIVELY, this software may be distributed under the terms of the
61021 + * GNU General Public License ("GPL") as published by the Free Software
61022 + * Foundation, either version 2 of that License or (at your option) any
61023 + * later version.
61024 + *
61025 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
61026 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
61027 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
61028 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
61029 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61030 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61031 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61032 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61033 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61034 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61035 + */
61036 +
61037 +/**************************************************************************//**
61038 + @File fm_port_dsar.h
61039 +
61040 + @Description Deep Sleep Auto Response project - common module header file.
61041 +
61042 + Author - Eyal Harari
61043 +
61044 + @Cautions See the FMan Controller spec and design document for more information.
61045 +*//***************************************************************************/
61046 +
61047 +#ifndef __FM_PORT_DSAR_H_
61048 +#define __FM_PORT_DSAR_H_
61049 +
61050 +#define DSAR_GETSER_MASK 0xFF0000FF
61051 +
61052 +#if defined(__MWERKS__) && !defined(__GNUC__)
61053 +#pragma pack(push,1)
61054 +#endif /* defined(__MWERKS__) && ... */
61055 +
61056 +/**************************************************************************//**
61057 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
61058 + Refer to the FMan Controller spec for more details.
61059 +*//***************************************************************************/
61060 +typedef _Packed struct
61061 +{
61062 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
61063 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
61064 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
61065 + uint16_t reserved;
61066 +} _PackedType t_DsarArpBindingEntry;
61067 +
61068 +/**************************************************************************//**
61069 + @Description Deep Sleep Auto Response Address Resolution Protocol Statistics Descriptor
61070 + Refer to the FMan Controller spec for more details.
61071 + 0x00 INVAL_CNT Invalid ARP IPv4-Ethernet counter
61072 + 0x04 ECHO_CNT Echo counter
61073 + 0x08 CD_CNT Conflict Detection counter
61074 + 0x0C AR_CNT Auto-Response counter
61075 + 0x10 RATM_CNT Replies Addressed To Me counter
61076 + 0x14 UKOP_CNT Unknown Operation counter
61077 + 0x18 NMTP_CNT Not my TPA counter
61078 + 0x1C NMVLAN_CNT Not My VLAN counter
61079 +*//***************************************************************************/
61080 +typedef _Packed struct
61081 +{
61082 + uint32_t invalCnt; /**< Invalid ARP IPv4-Ethernet counter. */
61083 + uint32_t echoCnt; /**< Echo counter. */
61084 + uint32_t cdCnt; /**< Conflict Detection counter. */
61085 + uint32_t arCnt; /**< Auto-Response counter. */
61086 + uint32_t ratmCnt; /**< Replies Addressed To Me counter. */
61087 + uint32_t ukopCnt; /**< Unknown Operation counter. */
61088 + uint32_t nmtpCnt; /**< Not my TPA counter. */
61089 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
61090 +} _PackedType t_DsarArpStatistics;
61091 +
61092 +
61093 +/**************************************************************************//**
61094 + @Description Deep Sleep Auto Response Address Resolution Protocol Descriptor
61095 + 0x0 0-15 Control bits [0-15]. Bit 15 = CDEN.
61096 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
61097 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an IPv4-MAC Addresses Bindings list.
61098 + 0x6 0-15
61099 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ARP Descriptors statistics data structure.
61100 + 0xA 0-15
61101 + 0xC 0-15 Reserved Reserved. Must be cleared.
61102 + 0xE 015
61103 +
61104 +*//***************************************************************************/
61105 +typedef _Packed struct
61106 +{
61107 + uint16_t control; /** Control bits [0-15]. Bit 15 = CDEN */
61108 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
61109 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
61110 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
61111 + uint32_t reserved1; /**< Reserved. */
61112 +} _PackedType t_DsarArpDescriptor;
61113 +
61114 +
61115 +/**************************************************************************//**
61116 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
61117 + Refer to the FMan Controller spec for more details.
61118 +*//***************************************************************************/
61119 +typedef _Packed struct
61120 +{
61121 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
61122 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
61123 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
61124 + uint16_t reserved;
61125 +} _PackedType t_DsarIcmpV4BindingEntry;
61126 +
61127 +/**************************************************************************//**
61128 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
61129 + Refer to the FMan Controller spec for more details.
61130 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
61131 + 0x04 NMVLAN_CNT Not My VLAN counter
61132 + 0x08 NMIP_CNT Not My IP counter
61133 + 0x0C AR_CNT Auto-Response counter
61134 + 0x10 CSERR_CNT Checksum Error counter
61135 + 0x14 Reserved Reserved
61136 + 0x18 Reserved Reserved
61137 + 0x1C Reserved Reserved
61138 +
61139 +*//***************************************************************************/
61140 +typedef _Packed struct
61141 +{
61142 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
61143 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
61144 + uint32_t nmIpCnt; /**< Not My IP counter */
61145 + uint32_t arCnt; /**< Auto-Response counter */
61146 + uint32_t cserrCnt; /**< Checksum Error counter */
61147 + uint32_t reserved0; /**< Reserved */
61148 + uint32_t reserved1; /**< Reserved */
61149 + uint32_t reserved2; /**< Reserved */
61150 +} _PackedType t_DsarIcmpV4Statistics;
61151 +
61152 +
61153 +
61154 +/**************************************************************************//**
61155 + @Description Deep Sleep Auto Response ICMPv4 Descriptor
61156 + 0x0 0-15 Control bits [0-15]
61157 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
61158 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
61159 + 0x6 0-15
61160 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
61161 + 0xA 0-15
61162 + 0xC 0-15 Reserved Reserved. Must be cleared.
61163 + 0xE 015
61164 +
61165 +*//***************************************************************************/
61166 +typedef _Packed struct
61167 +{
61168 + uint16_t control; /** Control bits [0-15]. */
61169 + uint16_t numOfBindings; /**< Number of VLAN-IPv4 */
61170 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
61171 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
61172 + uint32_t reserved1; /**< Reserved. */
61173 +} _PackedType t_DsarIcmpV4Descriptor;
61174 +
61175 +/**************************************************************************//**
61176 + @Description Deep Sleep Auto Response VLAN-IPv4 Binding Table (for ARP/ICMPv4)
61177 + The 4 left-most bits (15:12) of the VlanId parameter are control flags.
61178 + Flags[3:1] (VlanId[15:13]): Reserved, should be cleared.
61179 + Flags[0] (VlanId[12]): Temporary address.
61180 + \95 0 - Assigned IP address.
61181 + \95 1- Temporary (tentative) IP address.
61182 + Refer to the FMan Controller spec for more details.
61183 +*//***************************************************************************/
61184 +typedef _Packed struct
61185 +{
61186 + uint32_t ipv6Addr[4]; /*!< 3 * 32 bit IPv4 Address. */
61187 + uint16_t resFlags:4; /*!< reserved flags. should be cleared */
61188 + uint16_t vlanId:12; /*!< 12 bits VLAN ID. */
61189 + /*!< This field should be 0x000 for an entry with no VLAN tag or a null VLAN ID. */
61190 + uint16_t reserved;
61191 +} _PackedType t_DsarIcmpV6BindingEntry;
61192 +
61193 +/**************************************************************************//**
61194 + @Description Deep Sleep Auto Response ICMPv4 Statistics Descriptor
61195 + Refer to the FMan Controller spec for more details.
61196 + 0x00 INVAL_CNT Invalid ICMPv4 header counter
61197 + 0x04 NMVLAN_CNT Not My VLAN counter
61198 + 0x08 NMIP_CNT Not My IP counter
61199 + 0x0C AR_CNT Auto-Response counter
61200 + 0x10 CSERR_CNT Checksum Error counter
61201 + 0x14 MCAST_CNT Multicast counter
61202 + 0x18 Reserved Reserved
61203 + 0x1C Reserved Reserved
61204 +
61205 +*//***************************************************************************/
61206 +typedef _Packed struct
61207 +{
61208 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
61209 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
61210 + uint32_t nmIpCnt; /**< Not My IP counter */
61211 + uint32_t arCnt; /**< Auto-Response counter */
61212 + uint32_t reserved1; /**< Reserved */
61213 + uint32_t reserved2; /**< Reserved */
61214 + uint32_t reserved3; /**< Reserved */
61215 + uint32_t reserved4; /**< Reserved */
61216 +} _PackedType t_DsarIcmpV6Statistics;
61217 +
61218 +/**************************************************************************//**
61219 + @Description Deep Sleep Auto Response Neighbor Discovery Statistics Descriptor
61220 + 0x00 INVAL_CNT Invalid Neighbor Discovery message counter
61221 + 0x04 NMVLAN_CNT Not My VLAN counter
61222 + 0x08 NMIP_CNT Not My IP counter
61223 + 0x0C AR_CNT Auto-Response counter
61224 + 0x10 CSERR_CNT Checksum Error counter
61225 + 0x14 USADVERT_CNT Unsolicited Neighbor Advertisements counter
61226 + 0x18 NMMCAST_CNT Not My Multicast group counter
61227 + 0x1C NSLLA_CNT No Source Link-Layer Address counter. Indicates that there was a match on a Target
61228 + Address of a packet that its source IP address is a unicast address, but the ICMPv6
61229 + Source Link-layer Address option is omitted
61230 +*//***************************************************************************/
61231 +typedef _Packed struct
61232 +{
61233 + uint32_t invalCnt; /**< Invalid ICMPv4 Echo counter. */
61234 + uint32_t nmVlanCnt; /**< Not My VLAN counter */
61235 + uint32_t nmIpCnt; /**< Not My IP counter */
61236 + uint32_t arCnt; /**< Auto-Response counter */
61237 + uint32_t reserved1; /**< Reserved */
61238 + uint32_t usadvertCnt; /**< Unsolicited Neighbor Advertisements counter */
61239 + uint32_t nmmcastCnt; /**< Not My Multicast group counter */
61240 + uint32_t nsllaCnt; /**< No Source Link-Layer Address counter */
61241 +} _PackedType t_NdStatistics;
61242 +
61243 +/**************************************************************************//**
61244 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
61245 + 0x0 0-15 Control bits [0-15]
61246 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
61247 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
61248 + 0x6 0-15
61249 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
61250 + 0xA 0-15
61251 + 0xC 0-15 Reserved Reserved. Must be cleared.
61252 + 0xE 015
61253 +
61254 +*//***************************************************************************/
61255 +typedef _Packed struct
61256 +{
61257 + uint16_t control; /** Control bits [0-15]. */
61258 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
61259 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
61260 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
61261 + uint32_t reserved1; /**< Reserved. */
61262 +} _PackedType t_DsarIcmpV6Descriptor;
61263 +
61264 +
61265 +/**************************************************************************//**
61266 + @Description Internet Control Message Protocol (ICMPv6) Echo message header
61267 + The fields names are taken from RFC 4443.
61268 +*//***************************************************************************/
61269 +/* 0 1 2 3 */
61270 +/* 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 */
61271 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
61272 +/* | Type | Code | Checksum | */
61273 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
61274 +/* | Identifier | Sequence Number | */
61275 +/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */
61276 +/* | Data ... */
61277 +/* +-+-+-+-+- */
61278 +typedef _Packed struct
61279 +{
61280 + uint8_t type;
61281 + uint8_t code;
61282 + uint16_t checksum;
61283 + uint16_t identifier;
61284 + uint16_t sequenceNumber;
61285 +} _PackedType t_IcmpV6EchoHdr;
61286 +
61287 +/**************************************************************************//**
61288 + @Description Internet Control Message Protocol (ICMPv6)
61289 + Neighbor Solicitation/Advertisement header
61290 + The fields names are taken from RFC 4861.
61291 + The R/S/O fields are valid for Neighbor Advertisement only
61292 +*//***************************************************************************/
61293 +/* 0 1 2 3
61294 + * 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
61295 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61296 + * | Type | Code | Checksum |
61297 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61298 + * |R|S|O| Reserved |
61299 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61300 + * | |
61301 + * + +
61302 + * | |
61303 + * + Target Address +
61304 + * | |
61305 + * + +
61306 + * | |
61307 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61308 + * | Options ...
61309 + * +-+-+-+-+-+-+-+-+-+-+-+-
61310 + *
61311 + * Options Format:
61312 + * 0 1 2 3
61313 + * 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
61314 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61315 + * | Type | Length | Link-Layer Address ... |
61316 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61317 + * | Link-Layer Address |
61318 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61319 +*/
61320 +typedef _Packed struct
61321 +{
61322 + uint8_t type;
61323 + uint8_t code;
61324 + uint16_t checksum;
61325 + uint32_t router:1;
61326 + uint32_t solicited:1;
61327 + uint32_t override:1;
61328 + uint32_t reserved:29;
61329 + uint32_t targetAddr[4];
61330 + uint8_t optionType;
61331 + uint8_t optionLength;
61332 + uint8_t linkLayerAddr[6];
61333 +} _PackedType t_IcmpV6NdHdr;
61334 +
61335 +/**************************************************************************//**
61336 + @Description Deep Sleep Auto Response ICMPv6 Descriptor
61337 + 0x0 0-15 Control bits [0-15]
61338 + 0x2 0-15 NumOfBindings Number of entries in the binding list.
61339 + 0x4 0-15 BindingsPointer Bindings Pointer. This points to an VLAN-IPv4 Addresses Bindings list.
61340 + 0x6 0-15
61341 + 0x8 0-15 StatisticsPointer Statistics Pointer. This field points to the ICMPv4 statistics data structure.
61342 + 0xA 0-15
61343 + 0xC 0-15 Reserved Reserved. Must be cleared.
61344 + 0xE 015
61345 +
61346 +*//***************************************************************************/
61347 +typedef _Packed struct
61348 +{
61349 + uint16_t control; /** Control bits [0-15]. */
61350 + uint16_t numOfBindings; /**< Number of VLAN-IPv6 */
61351 + uint32_t p_Bindings; /**< VLAN-IPv4 Bindings table pointer. */
61352 + uint32_t p_Statistics; /**< Statistics Data Structure pointer. */
61353 + uint32_t solicitedAddr; /**< Solicited Node Multicast Group Address */
61354 +} _PackedType t_DsarNdDescriptor;
61355 +
61356 +/**************************************************************************//**
61357 +@Description Deep Sleep Auto Response SNMP OIDs table entry
61358 +
61359 +*//***************************************************************************/
61360 +typedef struct {
61361 + uint16_t oidSize; /**< Size in octets of the OID. */
61362 + uint16_t resSize; /**< Size in octets of the value that is attached to the OID. */
61363 + uint32_t p_Oid; /**< Pointer to the OID. OID is encoded in BER but type and length are excluded. */
61364 + uint32_t resValOrPtr; /**< Value (for up to 4 octets) or pointer to the Value. Encoded in BER. */
61365 + uint32_t reserved;
61366 +} t_OidsTblEntry;
61367 +
61368 +/**************************************************************************//**
61369 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
61370 + Refer to the FMan Controller spec for more details.
61371 +*//***************************************************************************/
61372 +typedef struct
61373 +{
61374 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
61375 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
61376 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
61377 + uint16_t reserved;
61378 +} t_DsarSnmpIpv4AddrTblEntry;
61379 +
61380 +/**************************************************************************//**
61381 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
61382 + Refer to the FMan Controller spec for more details.
61383 +*//***************************************************************************/
61384 +#pragma pack(push,1)
61385 +typedef struct
61386 +{
61387 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
61388 + uint16_t vlanId; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
61389 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
61390 + uint16_t reserved;
61391 +} t_DsarSnmpIpv6AddrTblEntry;
61392 +#pragma pack(pop)
61393 +
61394 +/**************************************************************************//**
61395 +@Description Deep Sleep Auto Response SNMP statistics table
61396 +
61397 +*//***************************************************************************/
61398 +typedef struct {
61399 + uint32_t snmpErrCnt; /**< Counts SNMP errors (wrong version, BER encoding, format). */
61400 + uint32_t snmpCommunityErrCnt; /**< Counts messages that were dropped due to insufficient permission. */
61401 + uint32_t snmpTotalDiscardCnt; /**< Counts any message that was dropped. */
61402 + uint32_t snmpGetReqCnt; /**< Counts the number of get-request messages */
61403 + uint32_t snmpGetNextReqCnt; /**< Counts the number of get-next-request messages */
61404 +} t_DsarSnmpStatistics;
61405 +
61406 +/**************************************************************************//**
61407 + @Description Deep Sleep Auto Response SNMP Descriptor
61408 +
61409 +*//***************************************************************************/
61410 +typedef struct
61411 +{
61412 + uint16_t control; /**< Control bits [0-15]. */
61413 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
61414 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
61415 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
61416 + uint32_t p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
61417 + uint32_t p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
61418 + uint32_t p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
61419 + uint32_t p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
61420 + uint32_t p_OidsTbl; /**< Pointer to OIDs table. */
61421 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
61422 + uint32_t p_Statistics; /**< Pointer to SNMP statistics table. */
61423 +} t_DsarSnmpDescriptor;
61424 +
61425 +/**************************************************************************//**
61426 +@Description Deep Sleep Auto Response (Common) Statistics
61427 +
61428 +*//***************************************************************************/
61429 +typedef _Packed struct {
61430 + uint32_t dsarDiscarded;
61431 + uint32_t dsarErrDiscarded;
61432 + uint32_t dsarFragDiscarded;
61433 + uint32_t dsarTunnelDiscarded;
61434 + uint32_t dsarArpDiscarded;
61435 + uint32_t dsarIpDiscarded;
61436 + uint32_t dsarTcpDiscarded;
61437 + uint32_t dsarUdpDiscarded;
61438 + uint32_t dsarIcmpV6ChecksumErr; /* ICMPv6 Checksum Error counter */
61439 + uint32_t dsarIcmpV6OtherType; /* ICMPv6 'Other' type (not Echo or Neighbor Solicitaion/Advertisement counter */
61440 + uint32_t dsarIcmpV4OtherType; /* ICMPv4 'Other' type (not Echo) counter */
61441 +} _PackedType t_ArStatistics;
61442 +
61443 +
61444 +/**************************************************************************//**
61445 +@Description Deep Sleep Auto Response TCP/UDP port filter table entry
61446 +
61447 +*//***************************************************************************/
61448 +typedef _Packed struct {
61449 + uint32_t Ports;
61450 + uint32_t PortsMask;
61451 +} _PackedType t_PortTblEntry;
61452 +
61453 +
61454 +
61455 +/**************************************************************************//**
61456 +@Description Deep Sleep Auto Response Common Parameters Descriptor
61457 +
61458 +*//***************************************************************************/
61459 +typedef _Packed struct {
61460 + uint8_t arTxPort; /* 0x00 0-7 Auto Response Transmit Port number */
61461 + uint8_t controlBits; /* 0x00 8-15 Auto Response control bits */
61462 + uint16_t res1; /* 0x00 16-31 Reserved */
61463 + uint32_t activeHPNIA; /* 0x04 0-31 Active mode Hardware Parser NIA */
61464 + uint16_t snmpPort; /* 0x08 0-15 SNMP Port. */
61465 + uint8_t macStationAddr[6]; /* 0x08 16-31 and 0x0C 0-31 MAC Station Address */
61466 + uint8_t res2; /* 0x10 0-7 Reserved */
61467 + uint8_t filterControl; /* 0x10 8-15 Filtering Control Bits. */
61468 + uint16_t tcpControlPass; /* 0x10 16-31 TCP control pass flags */
61469 + uint8_t ipProtocolTblSize; /* 0x14 0-7 IP Protocol Table Size. */
61470 + uint8_t udpPortTblSize; /* 0x14 8-15 UDP Port Table Size. */
61471 + uint8_t tcpPortTblSize; /* 0x14 16-23 TCP Port Table Size. */
61472 + uint8_t res3; /* 0x14 24-31 Reserved */
61473 + uint32_t p_IpProtocolFiltTbl; /* 0x18 0-31 Pointer to IP Protocol Filter Table */
61474 + uint32_t p_UdpPortFiltTbl; /* 0x1C 0-31 Pointer to UDP Port Filter Table */
61475 + uint32_t p_TcpPortFiltTbl; /* 0x20 0-31 Pointer to TCP Port Filter Table */
61476 + uint32_t res4; /* 0x24 Reserved */
61477 + uint32_t p_ArpDescriptor; /* 0x28 0-31 ARP Descriptor Pointer. */
61478 + uint32_t p_NdDescriptor; /* 0x2C 0-31 Neighbor Discovery Descriptor. */
61479 + uint32_t p_IcmpV4Descriptor; /* 0x30 0-31 ICMPv4 Descriptor pointer. */
61480 + uint32_t p_IcmpV6Descriptor; /* 0x34 0-31 ICMPv6 Descriptor pointer. */
61481 + uint32_t p_SnmpDescriptor; /* 0x38 0-31 SNMP Descriptor pointer. */
61482 + uint32_t p_ArStats; /* 0x3C 0-31 Pointer to Auto Response Statistics */
61483 +} _PackedType t_ArCommonDesc;
61484 +
61485 +#if defined(__MWERKS__) && !defined(__GNUC__)
61486 +#pragma pack(pop)
61487 +#endif /* defined(__MWERKS__) && ... */
61488 +
61489 +/* t_ArCommonDesc.filterControl bits */
61490 +#define IP_PROT_TBL_PASS_MASK 0x08
61491 +#define UDP_PORT_TBL_PASS_MASK 0x04
61492 +#define TCP_PORT_TBL_PASS_MASK 0x02
61493 +
61494 +/* Offset of TCF flags within TCP packet */
61495 +#define TCP_FLAGS_OFFSET 12
61496 +
61497 +
61498 +#endif /* __FM_PORT_DSAR_H_ */
61499 --- /dev/null
61500 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fm_port_im.c
61501 @@ -0,0 +1,753 @@
61502 +/*
61503 + * Copyright 2008-2012 Freescale Semiconductor Inc.
61504 + *
61505 + * Redistribution and use in source and binary forms, with or without
61506 + * modification, are permitted provided that the following conditions are met:
61507 + * * Redistributions of source code must retain the above copyright
61508 + * notice, this list of conditions and the following disclaimer.
61509 + * * Redistributions in binary form must reproduce the above copyright
61510 + * notice, this list of conditions and the following disclaimer in the
61511 + * documentation and/or other materials provided with the distribution.
61512 + * * Neither the name of Freescale Semiconductor nor the
61513 + * names of its contributors may be used to endorse or promote products
61514 + * derived from this software without specific prior written permission.
61515 + *
61516 + *
61517 + * ALTERNATIVELY, this software may be distributed under the terms of the
61518 + * GNU General Public License ("GPL") as published by the Free Software
61519 + * Foundation, either version 2 of that License or (at your option) any
61520 + * later version.
61521 + *
61522 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
61523 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
61524 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
61525 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
61526 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61527 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61528 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61529 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61530 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61531 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61532 + */
61533 +
61534 +
61535 +/******************************************************************************
61536 + @File fm_port_im.c
61537 +
61538 + @Description FM Port Independent-Mode ...
61539 +*//***************************************************************************/
61540 +#include "std_ext.h"
61541 +#include "string_ext.h"
61542 +#include "error_ext.h"
61543 +#include "memcpy_ext.h"
61544 +#include "fm_muram_ext.h"
61545 +
61546 +#include "fm_port.h"
61547 +
61548 +
61549 +#define TX_CONF_STATUS_UNSENT 0x1
61550 +
61551 +
61552 +typedef enum e_TxConfType
61553 +{
61554 + e_TX_CONF_TYPE_CHECK = 0 /**< check if all the buffers were touched by the muxator, no confirmation callback */
61555 + ,e_TX_CONF_TYPE_CALLBACK = 1 /**< confirm to user all the available sent buffers */
61556 + ,e_TX_CONF_TYPE_FLUSH = 3 /**< confirm all buffers plus the unsent one with an appropriate status */
61557 +} e_TxConfType;
61558 +
61559 +
61560 +static void ImException(t_Handle h_FmPort, uint32_t event)
61561 +{
61562 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
61563 +
61564 + ASSERT_COND(((event & (IM_EV_RX | IM_EV_BSY)) && FmIsMaster(p_FmPort->h_Fm)) ||
61565 + !FmIsMaster(p_FmPort->h_Fm));
61566 +
61567 + if (event & IM_EV_RX)
61568 + FmPortImRx(p_FmPort);
61569 + if ((event & IM_EV_BSY) && p_FmPort->f_Exception)
61570 + p_FmPort->f_Exception(p_FmPort->h_App, e_FM_PORT_EXCEPTION_IM_BUSY);
61571 +}
61572 +
61573 +
61574 +static t_Error TxConf(t_FmPort *p_FmPort, e_TxConfType confType)
61575 +{
61576 + t_Error retVal = E_BUSY;
61577 + uint32_t bdStatus;
61578 + uint16_t savedStartBdId, confBdId;
61579 +
61580 + ASSERT_COND(p_FmPort);
61581 +
61582 + /*
61583 + if (confType==e_TX_CONF_TYPE_CHECK)
61584 + return (WfqEntryIsQueueEmpty(p_FmPort->im.h_WfqEntry) ? E_OK : E_BUSY);
61585 + */
61586 +
61587 + confBdId = savedStartBdId = p_FmPort->im.currBdId;
61588 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
61589 +
61590 + /* If R bit is set, we don't enter, or we break.
61591 + we run till we get to R, or complete the loop */
61592 + while ((!(bdStatus & BD_R_E) || (confType == e_TX_CONF_TYPE_FLUSH)) && (retVal != E_OK))
61593 + {
61594 + if (confType & e_TX_CONF_TYPE_CALLBACK) /* if it is confirmation with user callbacks */
61595 + BD_STATUS_AND_LENGTH_SET(BD_GET(confBdId), 0);
61596 +
61597 + /* case 1: R bit is 0 and Length is set -> confirm! */
61598 + if ((confType & e_TX_CONF_TYPE_CALLBACK) && (bdStatus & BD_LENGTH_MASK))
61599 + {
61600 + if (p_FmPort->im.f_TxConf)
61601 + {
61602 + if ((confType == e_TX_CONF_TYPE_FLUSH) && (bdStatus & BD_R_E))
61603 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
61604 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
61605 + TX_CONF_STATUS_UNSENT,
61606 + p_FmPort->im.p_BdShadow[confBdId]);
61607 + else
61608 + p_FmPort->im.f_TxConf(p_FmPort->h_App,
61609 + BdBufferGet(XX_PhysToVirt, BD_GET(confBdId)),
61610 + 0,
61611 + p_FmPort->im.p_BdShadow[confBdId]);
61612 + }
61613 + }
61614 + /* case 2: R bit is 0 and Length is 0 -> not used yet, nop! */
61615 +
61616 + confBdId = GetNextBdId(p_FmPort, confBdId);
61617 + if (confBdId == savedStartBdId)
61618 + retVal = E_OK;
61619 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(confBdId));
61620 + }
61621 +
61622 + return retVal;
61623 +}
61624 +
61625 +t_Error FmPortImEnable(t_FmPort *p_FmPort)
61626 +{
61627 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
61628 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg & ~IM_MODE_GRC_STP));
61629 + return E_OK;
61630 +}
61631 +
61632 +t_Error FmPortImDisable(t_FmPort *p_FmPort)
61633 +{
61634 + uint32_t tmpReg = GET_UINT32(p_FmPort->im.p_FmPortImPram->mode);
61635 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, (uint32_t)(tmpReg | IM_MODE_GRC_STP));
61636 + return E_OK;
61637 +}
61638 +
61639 +t_Error FmPortImRx(t_FmPort *p_FmPort)
61640 +{
61641 + t_Handle h_CurrUserPriv, h_NewUserPriv;
61642 + uint32_t bdStatus;
61643 + volatile uint8_t buffPos;
61644 + uint16_t length;
61645 + uint16_t errors;
61646 + uint8_t *p_CurData, *p_Data;
61647 + uint32_t flags;
61648 +
61649 + ASSERT_COND(p_FmPort);
61650 +
61651 + flags = XX_LockIntrSpinlock(p_FmPort->h_Spinlock);
61652 + if (p_FmPort->lock)
61653 + {
61654 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
61655 + return E_OK;
61656 + }
61657 + p_FmPort->lock = TRUE;
61658 + XX_UnlockIntrSpinlock(p_FmPort->h_Spinlock, flags);
61659 +
61660 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61661 +
61662 + while (!(bdStatus & BD_R_E)) /* while there is data in the Rx BD */
61663 + {
61664 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_NewUserPriv)) == NULL)
61665 + {
61666 + p_FmPort->lock = FALSE;
61667 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
61668 + }
61669 +
61670 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
61671 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
61672 +
61673 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
61674 + h_CurrUserPriv = p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId];
61675 + length = (uint16_t)((bdStatus & BD_L) ?
61676 + ((bdStatus & BD_LENGTH_MASK) - p_FmPort->im.rxFrameAccumLength):
61677 + (bdStatus & BD_LENGTH_MASK));
61678 + p_FmPort->im.rxFrameAccumLength += length;
61679 +
61680 + /* determine whether buffer is first, last, first and last (single */
61681 + /* buffer frame) or middle (not first and not last) */
61682 + buffPos = (uint8_t)((p_FmPort->im.currBdId == p_FmPort->im.firstBdOfFrameId) ?
61683 + ((bdStatus & BD_L) ? SINGLE_BUF : FIRST_BUF) :
61684 + ((bdStatus & BD_L) ? LAST_BUF : MIDDLE_BUF));
61685 +
61686 + if (bdStatus & BD_L)
61687 + {
61688 + p_FmPort->im.rxFrameAccumLength = 0;
61689 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
61690 + }
61691 +
61692 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
61693 +
61694 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), BD_R_E);
61695 +
61696 + errors = (uint16_t)((bdStatus & BD_RX_ERRORS) >> 16);
61697 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_NewUserPriv;
61698 +
61699 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
61700 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.offsetOut, (uint16_t)(p_FmPort->im.currBdId<<4));
61701 + /* Pass the buffer if one of the conditions is true:
61702 + - There are no errors
61703 + - This is a part of a larger frame ( the application has already received some buffers ) */
61704 + if ((buffPos != SINGLE_BUF) || !errors)
61705 + {
61706 + if (p_FmPort->im.f_RxStore(p_FmPort->h_App,
61707 + p_CurData,
61708 + length,
61709 + errors,
61710 + buffPos,
61711 + h_CurrUserPriv) == e_RX_STORE_RESPONSE_PAUSE)
61712 + break;
61713 + }
61714 + else if (p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
61715 + p_CurData,
61716 + h_CurrUserPriv))
61717 + {
61718 + p_FmPort->lock = FALSE;
61719 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Failed freeing data buffer"));
61720 + }
61721 +
61722 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61723 + }
61724 + p_FmPort->lock = FALSE;
61725 + return E_OK;
61726 +}
61727 +
61728 +void FmPortConfigIM (t_FmPort *p_FmPort, t_FmPortParams *p_FmPortParams)
61729 +{
61730 + ASSERT_COND(p_FmPort);
61731 +
61732 + SANITY_CHECK_RETURN(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
61733 +
61734 + p_FmPort->im.h_FmMuram = p_FmPortParams->specificParams.imRxTxParams.h_FmMuram;
61735 + p_FmPort->p_FmPortDriverParam->liodnOffset = p_FmPortParams->specificParams.imRxTxParams.liodnOffset;
61736 + p_FmPort->im.dataMemId = p_FmPortParams->specificParams.imRxTxParams.dataMemId;
61737 + p_FmPort->im.dataMemAttributes = p_FmPortParams->specificParams.imRxTxParams.dataMemAttributes;
61738 +
61739 + p_FmPort->im.fwExtStructsMemId = DEFAULT_PORT_ImfwExtStructsMemId;
61740 + p_FmPort->im.fwExtStructsMemAttr = DEFAULT_PORT_ImfwExtStructsMemAttr;
61741 +
61742 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
61743 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
61744 + {
61745 + p_FmPort->im.rxPool.h_BufferPool = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.h_BufferPool;
61746 + p_FmPort->im.rxPool.f_GetBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_GetBuf;
61747 + p_FmPort->im.rxPool.f_PutBuf = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PutBuf;
61748 + p_FmPort->im.rxPool.bufferSize = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.bufferSize;
61749 + p_FmPort->im.rxPool.f_PhysToVirt = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_PhysToVirt;
61750 + if (!p_FmPort->im.rxPool.f_PhysToVirt)
61751 + p_FmPort->im.rxPool.f_PhysToVirt = XX_PhysToVirt;
61752 + p_FmPort->im.rxPool.f_VirtToPhys = p_FmPortParams->specificParams.imRxTxParams.rxPoolParams.f_VirtToPhys;
61753 + if (!p_FmPort->im.rxPool.f_VirtToPhys)
61754 + p_FmPort->im.rxPool.f_VirtToPhys = XX_VirtToPhys;
61755 + p_FmPort->im.f_RxStore = p_FmPortParams->specificParams.imRxTxParams.f_RxStore;
61756 +
61757 + p_FmPort->im.mrblr = 0x8000;
61758 + while (p_FmPort->im.mrblr)
61759 + {
61760 + if (p_FmPort->im.rxPool.bufferSize & p_FmPort->im.mrblr)
61761 + break;
61762 + p_FmPort->im.mrblr >>= 1;
61763 + }
61764 + if (p_FmPort->im.mrblr != p_FmPort->im.rxPool.bufferSize)
61765 + DBG(WARNING, ("Max-Rx-Buffer-Length set to %d", p_FmPort->im.mrblr));
61766 + p_FmPort->im.bdRingSize = DEFAULT_PORT_rxBdRingLength;
61767 + p_FmPort->exceptions = DEFAULT_PORT_exception;
61768 + if (FmIsMaster(p_FmPort->h_Fm))
61769 + p_FmPort->polling = FALSE;
61770 + else
61771 + p_FmPort->polling = TRUE;
61772 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
61773 + }
61774 + else
61775 + {
61776 + p_FmPort->im.f_TxConf = p_FmPortParams->specificParams.imRxTxParams.f_TxConf;
61777 +
61778 + p_FmPort->im.bdRingSize = DEFAULT_PORT_txBdRingLength;
61779 + }
61780 +}
61781 +
61782 +t_Error FmPortImCheckInitParameters(t_FmPort *p_FmPort)
61783 +{
61784 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX) &&
61785 + (p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) &&
61786 + (p_FmPort->portType != e_FM_PORT_TYPE_TX) &&
61787 + (p_FmPort->portType != e_FM_PORT_TYPE_TX_10G))
61788 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, NO_MSG);
61789 +
61790 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
61791 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
61792 + {
61793 + if (!POWER_OF_2(p_FmPort->im.mrblr))
61794 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must be power of 2!!!"));
61795 + if (p_FmPort->im.mrblr < 256)
61796 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("max Rx buffer length must at least 256!!!"));
61797 + if (p_FmPort->p_FmPortDriverParam->liodnOffset & ~FM_LIODN_OFFSET_MASK)
61798 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
61799 + }
61800 +
61801 + return E_OK;
61802 +}
61803 +
61804 +t_Error FmPortImInit(t_FmPort *p_FmPort)
61805 +{
61806 + t_FmImBd *p_Bd=NULL;
61807 + t_Handle h_BufContext;
61808 + uint64_t tmpPhysBase;
61809 + uint16_t log2Num;
61810 + uint8_t *p_Data/*, *p_Tmp*/;
61811 + int i;
61812 + t_Error err;
61813 + uint16_t tmpReg16;
61814 + uint32_t tmpReg32;
61815 +
61816 + ASSERT_COND(p_FmPort);
61817 +
61818 + p_FmPort->im.p_FmPortImPram =
61819 + (t_FmPortImPram *)FM_MURAM_AllocMem(p_FmPort->im.h_FmMuram, sizeof(t_FmPortImPram), IM_PRAM_ALIGN);
61820 + if (!p_FmPort->im.p_FmPortImPram)
61821 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Parameter-RAM!!!"));
61822 + WRITE_BLOCK(p_FmPort->im.p_FmPortImPram, 0, sizeof(t_FmPortImPram));
61823 +
61824 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
61825 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
61826 + {
61827 + p_FmPort->im.p_BdRing =
61828 + (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize),
61829 + p_FmPort->im.fwExtStructsMemId,
61830 + 4);
61831 + if (!p_FmPort->im.p_BdRing)
61832 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD ring!!!"));
61833 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
61834 +
61835 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
61836 + if (!p_FmPort->im.p_BdShadow)
61837 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
61838 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
61839 +
61840 + /* Initialize the Rx-BD ring */
61841 + for (i=0; i<p_FmPort->im.bdRingSize; i++)
61842 + {
61843 + p_Bd = BD_GET(i);
61844 + BD_STATUS_AND_LENGTH_SET (p_Bd, BD_R_E);
61845 +
61846 + if ((p_Data = p_FmPort->im.rxPool.f_GetBuf(p_FmPort->im.rxPool.h_BufferPool, &h_BufContext)) == NULL)
61847 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("Data buffer"));
61848 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, p_Bd, p_Data);
61849 + p_FmPort->im.p_BdShadow[i] = h_BufContext;
61850 + }
61851 +
61852 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
61853 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
61854 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
61855 + else
61856 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
61857 +
61858 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->rxQdPtr,
61859 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
61860 + p_FmPort->fmMuramPhysBaseAddr + 0x20));
61861 +
61862 + LOG2((uint64_t)p_FmPort->im.mrblr, log2Num);
61863 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->mrblr, log2Num);
61864 +
61865 + /* Initialize Rx QD */
61866 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
61867 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->rxQd.bdRingBase, tmpPhysBase);
61868 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
61869 +
61870 + /* Update the IM PRAM address in the BMI */
61871 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rfqid,
61872 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
61873 + p_FmPort->fmMuramPhysBaseAddr));
61874 + if (!p_FmPort->polling || p_FmPort->exceptions)
61875 + {
61876 + /* Allocate, configure and register interrupts */
61877 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
61878 + if (err)
61879 + RETURN_ERROR(MAJOR, err, NO_MSG);
61880 +
61881 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
61882 + tmpReg16 = (uint16_t)(p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK);
61883 + tmpReg32 = 0;
61884 +
61885 + if (p_FmPort->exceptions & IM_EV_BSY)
61886 + {
61887 + tmpReg16 |= IM_RXQD_BSYINTM;
61888 + tmpReg32 |= IM_EV_BSY;
61889 + }
61890 + if (!p_FmPort->polling)
61891 + {
61892 + tmpReg16 |= IM_RXQD_RXFINTM;
61893 + tmpReg32 |= IM_EV_RX;
61894 + }
61895 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
61896 +
61897 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException , (t_Handle)p_FmPort);
61898 +
61899 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
61900 + }
61901 + else
61902 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
61903 + }
61904 + else
61905 + {
61906 + p_FmPort->im.p_BdRing = (t_FmImBd *)XX_MallocSmart((uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize), p_FmPort->im.fwExtStructsMemId, 4);
61907 + if (!p_FmPort->im.p_BdRing)
61908 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Tx BD ring!!!"));
61909 + IOMemSet32(p_FmPort->im.p_BdRing, 0, (uint32_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
61910 +
61911 + p_FmPort->im.p_BdShadow = (t_Handle *)XX_Malloc((uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
61912 + if (!p_FmPort->im.p_BdShadow)
61913 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("Independent-Mode Rx BD shadow!!!"));
61914 + memset(p_FmPort->im.p_BdShadow, 0, (uint32_t)(sizeof(t_Handle)*p_FmPort->im.bdRingSize));
61915 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
61916 +
61917 + if ((p_FmPort->im.dataMemAttributes & MEMORY_ATTR_CACHEABLE) ||
61918 + (p_FmPort->im.fwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE))
61919 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_GBL | IM_MODE_SET_BO(2));
61920 + else
61921 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->mode, IM_MODE_SET_BO(2));
61922 +
61923 + WRITE_UINT32(p_FmPort->im.p_FmPortImPram->txQdPtr,
61924 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
61925 + p_FmPort->fmMuramPhysBaseAddr + 0x40));
61926 +
61927 + /* Initialize Tx QD */
61928 + tmpPhysBase = (uint64_t)(XX_VirtToPhys(p_FmPort->im.p_BdRing));
61929 + SET_ADDR(&p_FmPort->im.p_FmPortImPram->txQd.bdRingBase, tmpPhysBase);
61930 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.bdRingSize, (uint16_t)(sizeof(t_FmImBd)*p_FmPort->im.bdRingSize));
61931 +
61932 + /* Update the IM PRAM address in the BMI */
61933 + WRITE_UINT32(p_FmPort->p_FmPortBmiRegs->txPortBmiRegs.fmbm_tcfqid,
61934 + (uint32_t)((uint64_t)(XX_VirtToPhys(p_FmPort->im.p_FmPortImPram)) -
61935 + p_FmPort->fmMuramPhysBaseAddr));
61936 + }
61937 +
61938 +
61939 + return E_OK;
61940 +}
61941 +
61942 +void FmPortImFree(t_FmPort *p_FmPort)
61943 +{
61944 + uint32_t bdStatus;
61945 + uint8_t *p_CurData;
61946 +
61947 + ASSERT_COND(p_FmPort);
61948 + ASSERT_COND(p_FmPort->im.p_FmPortImPram);
61949 +
61950 + if ((p_FmPort->portType == e_FM_PORT_TYPE_RX) ||
61951 + (p_FmPort->portType == e_FM_PORT_TYPE_RX_10G))
61952 + {
61953 + if (!p_FmPort->polling || p_FmPort->exceptions)
61954 + {
61955 + /* Deallocate and unregister interrupts */
61956 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
61957 +
61958 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
61959 +
61960 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
61961 +
61962 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
61963 + }
61964 + /* Try first clean what has received */
61965 + FmPortImRx(p_FmPort);
61966 +
61967 + /* Now, get rid of the the empty buffer! */
61968 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61969 +
61970 + while (bdStatus & BD_R_E) /* while there is data in the Rx BD */
61971 + {
61972 + p_CurData = BdBufferGet(p_FmPort->im.rxPool.f_PhysToVirt, BD_GET(p_FmPort->im.currBdId));
61973 +
61974 + BdBufferSet(p_FmPort->im.rxPool.f_VirtToPhys, BD_GET(p_FmPort->im.currBdId), NULL);
61975 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), 0);
61976 +
61977 + p_FmPort->im.rxPool.f_PutBuf(p_FmPort->im.rxPool.h_BufferPool,
61978 + p_CurData,
61979 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
61980 +
61981 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
61982 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
61983 + }
61984 + }
61985 + else
61986 + TxConf(p_FmPort, e_TX_CONF_TYPE_FLUSH);
61987 +
61988 + FM_MURAM_FreeMem(p_FmPort->im.h_FmMuram, p_FmPort->im.p_FmPortImPram);
61989 +
61990 + if (p_FmPort->im.p_BdShadow)
61991 + XX_Free(p_FmPort->im.p_BdShadow);
61992 +
61993 + if (p_FmPort->im.p_BdRing)
61994 + XX_FreeSmart(p_FmPort->im.p_BdRing);
61995 +}
61996 +
61997 +
61998 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal)
61999 +{
62000 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62001 +
62002 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
62003 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
62004 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62005 +
62006 + p_FmPort->im.mrblr = newVal;
62007 +
62008 + return E_OK;
62009 +}
62010 +
62011 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
62012 +{
62013 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62014 +
62015 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
62016 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
62017 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62018 +
62019 + p_FmPort->im.bdRingSize = newVal;
62020 +
62021 + return E_OK;
62022 +}
62023 +
62024 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal)
62025 +{
62026 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62027 +
62028 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
62029 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
62030 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62031 +
62032 + p_FmPort->im.bdRingSize = newVal;
62033 +
62034 + return E_OK;
62035 +}
62036 +
62037 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
62038 + uint8_t memId,
62039 + uint32_t memAttributes)
62040 +{
62041 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62042 +
62043 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
62044 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
62045 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62046 +
62047 + p_FmPort->im.fwExtStructsMemId = memId;
62048 + p_FmPort->im.fwExtStructsMemAttr = memAttributes;
62049 +
62050 + return E_OK;
62051 +}
62052 +
62053 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort)
62054 +{
62055 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62056 +
62057 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
62058 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
62059 + SANITY_CHECK_RETURN_ERROR(p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62060 +
62061 + if ((p_FmPort->portType != e_FM_PORT_TYPE_RX_10G) && (p_FmPort->portType != e_FM_PORT_TYPE_RX))
62062 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available for Rx ports only"));
62063 +
62064 + if (!FmIsMaster(p_FmPort->h_Fm))
62065 + RETURN_ERROR(MAJOR, E_INVALID_OPERATION, ("Available on master-partition only;"
62066 + "in guest-partitions, IM is always in polling!"));
62067 +
62068 + p_FmPort->polling = TRUE;
62069 +
62070 + return E_OK;
62071 +}
62072 +
62073 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable)
62074 +{
62075 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62076 + t_Error err;
62077 + uint16_t tmpReg16;
62078 + uint32_t tmpReg32;
62079 +
62080 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
62081 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
62082 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62083 +
62084 + if (exception == e_FM_PORT_EXCEPTION_IM_BUSY)
62085 + {
62086 + if (enable)
62087 + {
62088 + p_FmPort->exceptions |= IM_EV_BSY;
62089 + if (p_FmPort->fmanCtrlEventId == (uint8_t)NO_IRQ)
62090 + {
62091 + /* Allocate, configure and register interrupts */
62092 + err = FmAllocFmanCtrlEventReg(p_FmPort->h_Fm, &p_FmPort->fmanCtrlEventId);
62093 + if (err)
62094 + RETURN_ERROR(MAJOR, err, NO_MSG);
62095 + ASSERT_COND(!(p_FmPort->fmanCtrlEventId & ~IM_RXQD_FPMEVT_SEL_MASK));
62096 +
62097 + FmRegisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, ImException, (t_Handle)p_FmPort);
62098 + tmpReg16 = (uint16_t)((p_FmPort->fmanCtrlEventId & IM_RXQD_FPMEVT_SEL_MASK) | IM_RXQD_BSYINTM);
62099 + tmpReg32 = IM_EV_BSY;
62100 + }
62101 + else
62102 + {
62103 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) | IM_RXQD_BSYINTM);
62104 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) | IM_EV_BSY;
62105 + }
62106 +
62107 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
62108 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
62109 + }
62110 + else
62111 + {
62112 + p_FmPort->exceptions &= ~IM_EV_BSY;
62113 + if (!p_FmPort->exceptions && p_FmPort->polling)
62114 + {
62115 + FmFreeFmanCtrlEventReg(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
62116 + FmUnregisterFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId);
62117 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, 0);
62118 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, 0);
62119 + p_FmPort->fmanCtrlEventId = (uint8_t)NO_IRQ;
62120 + }
62121 + else
62122 + {
62123 + tmpReg16 = (uint16_t)(GET_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen) & ~IM_RXQD_BSYINTM);
62124 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->rxQd.gen, tmpReg16);
62125 + tmpReg32 = FmGetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId) & ~IM_EV_BSY;
62126 + FmSetFmanCtrlIntr(p_FmPort->h_Fm, p_FmPort->fmanCtrlEventId, tmpReg32);
62127 + }
62128 + }
62129 + }
62130 + else
62131 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("Invalid exception."));
62132 +
62133 + return E_OK;
62134 +}
62135 +
62136 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
62137 + uint8_t *p_Data,
62138 + uint16_t length,
62139 + bool lastBuffer,
62140 + t_Handle h_BufContext)
62141 +{
62142 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62143 + uint16_t nextBdId;
62144 + uint32_t bdStatus, nextBdStatus;
62145 + bool firstBuffer;
62146 +
62147 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
62148 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
62149 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62150 +
62151 + bdStatus = BD_STATUS_AND_LENGTH(BD_GET(p_FmPort->im.currBdId));
62152 + nextBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
62153 + nextBdStatus = BD_STATUS_AND_LENGTH(BD_GET(nextBdId));
62154 +
62155 + if (!(bdStatus & BD_R_E) && !(nextBdStatus & BD_R_E))
62156 + {
62157 + /* Confirm the current BD - BD is available */
62158 + if ((bdStatus & BD_LENGTH_MASK) && (p_FmPort->im.f_TxConf))
62159 + p_FmPort->im.f_TxConf (p_FmPort->h_App,
62160 + BdBufferGet(XX_PhysToVirt, BD_GET(p_FmPort->im.currBdId)),
62161 + 0,
62162 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId]);
62163 +
62164 + bdStatus = length;
62165 +
62166 + /* if this is the first BD of a frame */
62167 + if (p_FmPort->im.firstBdOfFrameId == IM_ILEGAL_BD_ID)
62168 + {
62169 + firstBuffer = TRUE;
62170 + p_FmPort->im.txFirstBdStatus = (bdStatus | BD_R_E);
62171 +
62172 + if (!lastBuffer)
62173 + p_FmPort->im.firstBdOfFrameId = p_FmPort->im.currBdId;
62174 + }
62175 + else
62176 + firstBuffer = FALSE;
62177 +
62178 + BdBufferSet(XX_VirtToPhys, BD_GET(p_FmPort->im.currBdId), p_Data);
62179 + p_FmPort->im.p_BdShadow[p_FmPort->im.currBdId] = h_BufContext;
62180 +
62181 + /* deal with last */
62182 + if (lastBuffer)
62183 + {
62184 + /* if single buffer frame */
62185 + if (firstBuffer)
62186 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.currBdId), p_FmPort->im.txFirstBdStatus | BD_L);
62187 + else
62188 + {
62189 + /* Set the last BD of the frame */
62190 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), (bdStatus | BD_R_E | BD_L));
62191 + /* Set the first BD of the frame */
62192 + BD_STATUS_AND_LENGTH_SET(BD_GET(p_FmPort->im.firstBdOfFrameId), p_FmPort->im.txFirstBdStatus);
62193 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
62194 + }
62195 + WRITE_UINT16(p_FmPort->im.p_FmPortImPram->txQd.offsetIn, (uint16_t)(GetNextBdId(p_FmPort, p_FmPort->im.currBdId)<<4));
62196 + }
62197 + else if (!firstBuffer) /* mid frame buffer */
62198 + BD_STATUS_AND_LENGTH_SET (BD_GET(p_FmPort->im.currBdId), bdStatus | BD_R_E);
62199 +
62200 + p_FmPort->im.currBdId = GetNextBdId(p_FmPort, p_FmPort->im.currBdId);
62201 + }
62202 + else
62203 + {
62204 + /* Discard current frame. Return error. */
62205 + if (p_FmPort->im.firstBdOfFrameId != IM_ILEGAL_BD_ID)
62206 + {
62207 + /* Error: No free BD */
62208 + /* Response: Discard current frame. Return error. */
62209 + uint16_t cleanBdId = p_FmPort->im.firstBdOfFrameId;
62210 +
62211 + ASSERT_COND(p_FmPort->im.firstBdOfFrameId != p_FmPort->im.currBdId);
62212 +
62213 + /* Since firstInFrame is not NULL, one buffer at least has already been
62214 + inserted into the BD ring. Using do-while covers the situation of a
62215 + frame spanned throughout the whole Tx BD ring (p_CleanBd is incremented
62216 + prior to testing whether or not it's equal to TxBd). */
62217 + do
62218 + {
62219 + BD_STATUS_AND_LENGTH_SET(BD_GET(cleanBdId), 0);
62220 + /* Advance BD pointer */
62221 + cleanBdId = GetNextBdId(p_FmPort, cleanBdId);
62222 + } while (cleanBdId != p_FmPort->im.currBdId);
62223 +
62224 + p_FmPort->im.currBdId = cleanBdId;
62225 + p_FmPort->im.firstBdOfFrameId = IM_ILEGAL_BD_ID;
62226 + }
62227 +
62228 + return ERROR_CODE(E_FULL);
62229 + }
62230 +
62231 + return E_OK;
62232 +}
62233 +
62234 +void FM_PORT_ImTxConf(t_Handle h_FmPort)
62235 +{
62236 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62237 +
62238 + SANITY_CHECK_RETURN(p_FmPort, E_INVALID_HANDLE);
62239 + SANITY_CHECK_RETURN(p_FmPort->imEn, E_INVALID_STATE);
62240 + SANITY_CHECK_RETURN(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62241 +
62242 + TxConf(p_FmPort, e_TX_CONF_TYPE_CALLBACK);
62243 +}
62244 +
62245 +t_Error FM_PORT_ImRx(t_Handle h_FmPort)
62246 +{
62247 + t_FmPort *p_FmPort = (t_FmPort*)h_FmPort;
62248 +
62249 + SANITY_CHECK_RETURN_ERROR(p_FmPort, E_INVALID_HANDLE);
62250 + SANITY_CHECK_RETURN_ERROR(p_FmPort->imEn, E_INVALID_STATE);
62251 + SANITY_CHECK_RETURN_ERROR(!p_FmPort->p_FmPortDriverParam, E_INVALID_HANDLE);
62252 +
62253 + return FmPortImRx(p_FmPort);
62254 +}
62255 --- /dev/null
62256 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Port/fman_port.c
62257 @@ -0,0 +1,1570 @@
62258 +/*
62259 + * Copyright 2008-2012 Freescale Semiconductor Inc.
62260 + *
62261 + * Redistribution and use in source and binary forms, with or without
62262 + * modification, are permitted provided that the following conditions are met:
62263 + * * Redistributions of source code must retain the above copyright
62264 + * notice, this list of conditions and the following disclaimer.
62265 + * * Redistributions in binary form must reproduce the above copyright
62266 + * notice, this list of conditions and the following disclaimer in the
62267 + * documentation and/or other materials provided with the distribution.
62268 + * * Neither the name of Freescale Semiconductor nor the
62269 + * names of its contributors may be used to endorse or promote products
62270 + * derived from this software without specific prior written permission.
62271 + *
62272 + *
62273 + * ALTERNATIVELY, this software may be distributed under the terms of the
62274 + * GNU General Public License ("GPL") as published by the Free Software
62275 + * Foundation, either version 2 of that License or (at your option) any
62276 + * later version.
62277 + *
62278 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
62279 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
62280 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
62281 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
62282 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
62283 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
62284 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62285 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62286 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
62287 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62288 + */
62289 +
62290 +
62291 +#include "std_ext.h"
62292 +#include "error_ext.h"
62293 +#include "common/general.h"
62294 +
62295 +#include "fman_common.h"
62296 +#include "fsl_fman_port.h"
62297 +
62298 +
62299 +/* problem Eyal: the following should not be here*/
62300 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
62301 +
62302 +static uint32_t get_no_pcd_nia_bmi_ac_enc_frame(struct fman_port_cfg *cfg)
62303 +{
62304 + if (cfg->errata_A006675)
62305 + return NIA_ENG_FM_CTL |
62306 + NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME;
62307 + else
62308 + return NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
62309 +}
62310 +
62311 +static int init_bmi_rx(struct fman_port *port,
62312 + struct fman_port_cfg *cfg,
62313 + struct fman_port_params *params)
62314 +{
62315 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
62316 + uint32_t tmp;
62317 +
62318 + /* Rx Configuration register */
62319 + tmp = 0;
62320 + if (port->im_en)
62321 + tmp |= BMI_PORT_CFG_IM;
62322 + else if (cfg->discard_override)
62323 + tmp |= BMI_PORT_CFG_FDOVR;
62324 + iowrite32be(tmp, &regs->fmbm_rcfg);
62325 +
62326 + /* DMA attributes */
62327 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
62328 + if (cfg->dma_ic_stash_on)
62329 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
62330 + if (cfg->dma_header_stash_on)
62331 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
62332 + if (cfg->dma_sg_stash_on)
62333 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
62334 + if (cfg->dma_write_optimize)
62335 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
62336 + iowrite32be(tmp, &regs->fmbm_rda);
62337 +
62338 + /* Rx FIFO parameters */
62339 + tmp = (cfg->rx_pri_elevation / FMAN_PORT_BMI_FIFO_UNITS - 1) <<
62340 + BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
62341 + tmp |= cfg->rx_fifo_thr / FMAN_PORT_BMI_FIFO_UNITS - 1;
62342 + iowrite32be(tmp, &regs->fmbm_rfp);
62343 +
62344 + if (cfg->excessive_threshold_register)
62345 + /* always allow access to the extra resources */
62346 + iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
62347 +
62348 + /* Frame end data */
62349 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
62350 + BMI_RX_FRAME_END_CS_IGNORE_SHIFT;
62351 + tmp |= (uint32_t)cfg->rx_cut_end_bytes <<
62352 + BMI_RX_FRAME_END_CUT_SHIFT;
62353 + if (cfg->errata_A006320)
62354 + tmp &= 0xffe0ffff;
62355 + iowrite32be(tmp, &regs->fmbm_rfed);
62356 +
62357 + /* Internal context parameters */
62358 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62359 + BMI_IC_TO_EXT_SHIFT;
62360 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62361 + BMI_IC_FROM_INT_SHIFT;
62362 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
62363 + iowrite32be(tmp, &regs->fmbm_ricp);
62364 +
62365 + /* Internal buffer offset */
62366 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
62367 + << BMI_INT_BUF_MARG_SHIFT;
62368 + iowrite32be(tmp, &regs->fmbm_rim);
62369 +
62370 + /* External buffer margins */
62371 + if (!port->im_en)
62372 + {
62373 + tmp = (uint32_t)cfg->ext_buf_start_margin <<
62374 + BMI_EXT_BUF_MARG_START_SHIFT;
62375 + tmp |= (uint32_t)cfg->ext_buf_end_margin;
62376 + if (cfg->fmbm_rebm_has_sgd && cfg->no_scatter_gather)
62377 + tmp |= BMI_SG_DISABLE;
62378 + iowrite32be(tmp, &regs->fmbm_rebm);
62379 + }
62380 +
62381 + /* Frame attributes */
62382 + tmp = BMI_CMD_RX_MR_DEF;
62383 + if (!port->im_en)
62384 + {
62385 + tmp |= BMI_CMD_ATTR_ORDER;
62386 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
62387 + if (cfg->sync_req)
62388 + tmp |= BMI_CMD_ATTR_SYNC;
62389 + }
62390 + iowrite32be(tmp, &regs->fmbm_rfca);
62391 +
62392 + /* NIA */
62393 + if (port->im_en)
62394 + tmp = NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_RX;
62395 + else
62396 + {
62397 + tmp = (uint32_t)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
62398 + tmp |= get_no_pcd_nia_bmi_ac_enc_frame(cfg);
62399 + }
62400 + iowrite32be(tmp, &regs->fmbm_rfne);
62401 +
62402 + /* Enqueue NIA */
62403 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
62404 +
62405 + /* Default/error queues */
62406 + if (!port->im_en)
62407 + {
62408 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_rfqid);
62409 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_refqid);
62410 + }
62411 +
62412 + /* Discard/error masks */
62413 + iowrite32be(params->discard_mask, &regs->fmbm_rfsdm);
62414 + iowrite32be(params->err_mask, &regs->fmbm_rfsem);
62415 +
62416 + /* Statistics counters */
62417 + tmp = 0;
62418 + if (cfg->stats_counters_enable)
62419 + tmp = BMI_COUNTERS_EN;
62420 + iowrite32be(tmp, &regs->fmbm_rstc);
62421 +
62422 + /* Performance counters */
62423 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
62424 + tmp = 0;
62425 + if (cfg->perf_counters_enable)
62426 + tmp = BMI_COUNTERS_EN;
62427 + iowrite32be(tmp, &regs->fmbm_rpc);
62428 +
62429 + return 0;
62430 +}
62431 +
62432 +static int init_bmi_tx(struct fman_port *port,
62433 + struct fman_port_cfg *cfg,
62434 + struct fman_port_params *params)
62435 +{
62436 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
62437 + uint32_t tmp;
62438 +
62439 + /* Tx Configuration register */
62440 + tmp = 0;
62441 + if (port->im_en)
62442 + tmp |= BMI_PORT_CFG_IM;
62443 + iowrite32be(tmp, &regs->fmbm_tcfg);
62444 +
62445 + /* DMA attributes */
62446 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
62447 + if (cfg->dma_ic_stash_on)
62448 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
62449 + if (cfg->dma_header_stash_on)
62450 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
62451 + if (cfg->dma_sg_stash_on)
62452 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
62453 + iowrite32be(tmp, &regs->fmbm_tda);
62454 +
62455 + /* Tx FIFO parameters */
62456 + tmp = (cfg->tx_fifo_min_level / FMAN_PORT_BMI_FIFO_UNITS) <<
62457 + BMI_TX_FIFO_MIN_FILL_SHIFT;
62458 + tmp |= ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
62459 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
62460 + tmp |= (uint32_t)(cfg->tx_fifo_low_comf_level /
62461 + FMAN_PORT_BMI_FIFO_UNITS - 1);
62462 + iowrite32be(tmp, &regs->fmbm_tfp);
62463 +
62464 + /* Frame end data */
62465 + tmp = (uint32_t)cfg->checksum_bytes_ignore <<
62466 + BMI_FRAME_END_CS_IGNORE_SHIFT;
62467 + iowrite32be(tmp, &regs->fmbm_tfed);
62468 +
62469 + /* Internal context parameters */
62470 + if (!port->im_en)
62471 + {
62472 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62473 + BMI_IC_TO_EXT_SHIFT;
62474 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62475 + BMI_IC_FROM_INT_SHIFT;
62476 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
62477 + iowrite32be(tmp, &regs->fmbm_ticp);
62478 + }
62479 + /* Frame attributes */
62480 + tmp = BMI_CMD_TX_MR_DEF;
62481 + if (port->im_en)
62482 + tmp |= BMI_CMD_MR_DEAS;
62483 + else
62484 + {
62485 + tmp |= BMI_CMD_ATTR_ORDER;
62486 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
62487 + }
62488 + iowrite32be(tmp, &regs->fmbm_tfca);
62489 +
62490 + /* Dequeue NIA + enqueue NIA */
62491 + if (port->im_en)
62492 + {
62493 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfdne);
62494 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_IND_MODE_TX, &regs->fmbm_tfene);
62495 + }
62496 + else
62497 + {
62498 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
62499 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
62500 + if (cfg->fmbm_tfne_has_features)
62501 + iowrite32be(!params->dflt_fqid ?
62502 + BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
62503 + NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
62504 + if (!params->dflt_fqid && params->dont_release_buf)
62505 + {
62506 + iowrite32be(0x00FFFFFF, &regs->fmbm_tcfqid);
62507 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE, &regs->fmbm_tfene);
62508 + if (cfg->fmbm_tfne_has_features)
62509 + iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN, &regs->fmbm_tfne);
62510 + }
62511 + }
62512 +
62513 + /* Confirmation/error queues */
62514 + if (!port->im_en)
62515 + {
62516 + if (params->dflt_fqid || !params->dont_release_buf)
62517 + iowrite32be(params->dflt_fqid & 0x00FFFFFF, &regs->fmbm_tcfqid);
62518 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_tefqid);
62519 + }
62520 + /* Statistics counters */
62521 + tmp = 0;
62522 + if (cfg->stats_counters_enable)
62523 + tmp = BMI_COUNTERS_EN;
62524 + iowrite32be(tmp, &regs->fmbm_tstc);
62525 +
62526 + /* Performance counters */
62527 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
62528 + tmp = 0;
62529 + if (cfg->perf_counters_enable)
62530 + tmp = BMI_COUNTERS_EN;
62531 + iowrite32be(tmp, &regs->fmbm_tpc);
62532 +
62533 + return 0;
62534 +}
62535 +
62536 +static int init_bmi_oh(struct fman_port *port,
62537 + struct fman_port_cfg *cfg,
62538 + struct fman_port_params *params)
62539 +{
62540 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
62541 + uint32_t tmp;
62542 +
62543 + /* OP Configuration register */
62544 + tmp = 0;
62545 + if (cfg->discard_override)
62546 + tmp |= BMI_PORT_CFG_FDOVR;
62547 + iowrite32be(tmp, &regs->fmbm_ocfg);
62548 +
62549 + /* DMA attributes */
62550 + tmp = (uint32_t)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
62551 + if (cfg->dma_ic_stash_on)
62552 + tmp |= BMI_DMA_ATTR_IC_STASH_ON;
62553 + if (cfg->dma_header_stash_on)
62554 + tmp |= BMI_DMA_ATTR_HDR_STASH_ON;
62555 + if (cfg->dma_sg_stash_on)
62556 + tmp |= BMI_DMA_ATTR_SG_STASH_ON;
62557 + if (cfg->dma_write_optimize)
62558 + tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
62559 + iowrite32be(tmp, &regs->fmbm_oda);
62560 +
62561 + /* Tx FIFO parameters */
62562 + tmp = ((uint32_t)cfg->tx_fifo_deq_pipeline_depth - 1) <<
62563 + BMI_FIFO_PIPELINE_DEPTH_SHIFT;
62564 + iowrite32be(tmp, &regs->fmbm_ofp);
62565 +
62566 + /* Internal context parameters */
62567 + tmp = ((uint32_t)cfg->ic_ext_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62568 + BMI_IC_TO_EXT_SHIFT;
62569 + tmp |= ((uint32_t)cfg->ic_int_offset / FMAN_PORT_IC_OFFSET_UNITS) <<
62570 + BMI_IC_FROM_INT_SHIFT;
62571 + tmp |= cfg->ic_size / FMAN_PORT_IC_OFFSET_UNITS;
62572 + iowrite32be(tmp, &regs->fmbm_oicp);
62573 +
62574 + /* Frame attributes */
62575 + tmp = BMI_CMD_OP_MR_DEF;
62576 + tmp |= (uint32_t)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
62577 + if (cfg->sync_req)
62578 + tmp |= BMI_CMD_ATTR_SYNC;
62579 + if (port->type == E_FMAN_PORT_TYPE_OP)
62580 + tmp |= BMI_CMD_ATTR_ORDER;
62581 + iowrite32be(tmp, &regs->fmbm_ofca);
62582 +
62583 + /* Internal buffer offset */
62584 + tmp = ((uint32_t)cfg->int_buf_start_margin / FMAN_PORT_IC_OFFSET_UNITS)
62585 + << BMI_INT_BUF_MARG_SHIFT;
62586 + iowrite32be(tmp, &regs->fmbm_oim);
62587 +
62588 + /* Dequeue NIA */
62589 + iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_ofdne);
62590 +
62591 + /* NIA and Enqueue NIA */
62592 + if (port->type == E_FMAN_PORT_TYPE_HC) {
62593 + iowrite32be(NIA_ENG_FM_CTL | NIA_FM_CTL_AC_HC,
62594 + &regs->fmbm_ofne);
62595 + iowrite32be(NIA_ENG_QMI_ENQ, &regs->fmbm_ofene);
62596 + } else {
62597 + iowrite32be(get_no_pcd_nia_bmi_ac_enc_frame(cfg),
62598 + &regs->fmbm_ofne);
62599 + iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR,
62600 + &regs->fmbm_ofene);
62601 + }
62602 +
62603 + /* Default/error queues */
62604 + iowrite32be((params->dflt_fqid & 0x00FFFFFF), &regs->fmbm_ofqid);
62605 + iowrite32be((params->err_fqid & 0x00FFFFFF), &regs->fmbm_oefqid);
62606 +
62607 + /* Discard/error masks */
62608 + if (port->type == E_FMAN_PORT_TYPE_OP) {
62609 + iowrite32be(params->discard_mask, &regs->fmbm_ofsdm);
62610 + iowrite32be(params->err_mask, &regs->fmbm_ofsem);
62611 + }
62612 +
62613 + /* Statistics counters */
62614 + tmp = 0;
62615 + if (cfg->stats_counters_enable)
62616 + tmp = BMI_COUNTERS_EN;
62617 + iowrite32be(tmp, &regs->fmbm_ostc);
62618 +
62619 + /* Performance counters */
62620 + fman_port_set_perf_cnt_params(port, &cfg->perf_cnt_params);
62621 + tmp = 0;
62622 + if (cfg->perf_counters_enable)
62623 + tmp = BMI_COUNTERS_EN;
62624 + iowrite32be(tmp, &regs->fmbm_opc);
62625 +
62626 + return 0;
62627 +}
62628 +
62629 +static int init_qmi(struct fman_port *port,
62630 + struct fman_port_cfg *cfg,
62631 + struct fman_port_params *params)
62632 +{
62633 + struct fman_port_qmi_regs *regs = port->qmi_regs;
62634 + uint32_t tmp;
62635 +
62636 + tmp = 0;
62637 + if (cfg->queue_counters_enable)
62638 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
62639 + iowrite32be(tmp, &regs->fmqm_pnc);
62640 +
62641 + /* Rx port configuration */
62642 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
62643 + (port->type == E_FMAN_PORT_TYPE_RX_10G)) {
62644 + /* Enqueue NIA */
62645 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
62646 + return 0;
62647 + }
62648 +
62649 + /* Continue with Tx and O/H port configuration */
62650 + if ((port->type == E_FMAN_PORT_TYPE_TX) ||
62651 + (port->type == E_FMAN_PORT_TYPE_TX_10G)) {
62652 + /* Enqueue NIA */
62653 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
62654 + &regs->fmqm_pnen);
62655 + /* Dequeue NIA */
62656 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
62657 + } else {
62658 + /* Enqueue NIA */
62659 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
62660 + /* Dequeue NIA */
62661 + iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_FETCH, &regs->fmqm_pndn);
62662 + }
62663 +
62664 + /* Dequeue Configuration register */
62665 + tmp = 0;
62666 + if (cfg->deq_high_pri)
62667 + tmp |= QMI_DEQ_CFG_PRI;
62668 +
62669 + switch (cfg->deq_type) {
62670 + case E_FMAN_PORT_DEQ_BY_PRI:
62671 + tmp |= QMI_DEQ_CFG_TYPE1;
62672 + break;
62673 + case E_FMAN_PORT_DEQ_ACTIVE_FQ:
62674 + tmp |= QMI_DEQ_CFG_TYPE2;
62675 + break;
62676 + case E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
62677 + tmp |= QMI_DEQ_CFG_TYPE3;
62678 + break;
62679 + default:
62680 + return -EINVAL;
62681 + }
62682 +
62683 + if (cfg->qmi_deq_options_support) {
62684 + if ((port->type == E_FMAN_PORT_TYPE_HC) &&
62685 + (cfg->deq_prefetch_opt != E_FMAN_PORT_DEQ_NO_PREFETCH))
62686 + return -EINVAL;
62687 +
62688 + switch (cfg->deq_prefetch_opt) {
62689 + case E_FMAN_PORT_DEQ_NO_PREFETCH:
62690 + break;
62691 + case E_FMAN_PORT_DEQ_PART_PREFETCH:
62692 + tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
62693 + break;
62694 + case E_FMAN_PORT_DEQ_FULL_PREFETCH:
62695 + tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
62696 + break;
62697 + default:
62698 + return -EINVAL;
62699 + }
62700 + }
62701 + tmp |= (uint32_t)(params->deq_sp & QMI_DEQ_CFG_SP_MASK) <<
62702 + QMI_DEQ_CFG_SP_SHIFT;
62703 + tmp |= cfg->deq_byte_cnt;
62704 + iowrite32be(tmp, &regs->fmqm_pndc);
62705 +
62706 + return 0;
62707 +}
62708 +
62709 +static void get_rx_stats_reg(struct fman_port *port,
62710 + enum fman_port_stats_counters counter,
62711 + uint32_t **stats_reg)
62712 +{
62713 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
62714 +
62715 + switch (counter) {
62716 + case E_FMAN_PORT_STATS_CNT_FRAME:
62717 + *stats_reg = &regs->fmbm_rfrc;
62718 + break;
62719 + case E_FMAN_PORT_STATS_CNT_DISCARD:
62720 + *stats_reg = &regs->fmbm_rfdc;
62721 + break;
62722 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
62723 + *stats_reg = &regs->fmbm_rbdc;
62724 + break;
62725 + case E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME:
62726 + *stats_reg = &regs->fmbm_rfbc;
62727 + break;
62728 + case E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME:
62729 + *stats_reg = &regs->fmbm_rlfc;
62730 + break;
62731 + case E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF:
62732 + *stats_reg = &regs->fmbm_rodc;
62733 + break;
62734 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
62735 + *stats_reg = &regs->fmbm_rffc;
62736 + break;
62737 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
62738 + *stats_reg = &regs->fmbm_rfldec;
62739 + break;
62740 + default:
62741 + *stats_reg = NULL;
62742 + }
62743 +}
62744 +
62745 +static void get_tx_stats_reg(struct fman_port *port,
62746 + enum fman_port_stats_counters counter,
62747 + uint32_t **stats_reg)
62748 +{
62749 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
62750 +
62751 + switch (counter) {
62752 + case E_FMAN_PORT_STATS_CNT_FRAME:
62753 + *stats_reg = &regs->fmbm_tfrc;
62754 + break;
62755 + case E_FMAN_PORT_STATS_CNT_DISCARD:
62756 + *stats_reg = &regs->fmbm_tfdc;
62757 + break;
62758 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
62759 + *stats_reg = &regs->fmbm_tbdc;
62760 + break;
62761 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
62762 + *stats_reg = &regs->fmbm_tfledc;
62763 + break;
62764 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
62765 + *stats_reg = &regs->fmbm_tfufdc;
62766 + break;
62767 + default:
62768 + *stats_reg = NULL;
62769 + }
62770 +}
62771 +
62772 +static void get_oh_stats_reg(struct fman_port *port,
62773 + enum fman_port_stats_counters counter,
62774 + uint32_t **stats_reg)
62775 +{
62776 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
62777 +
62778 + switch (counter) {
62779 + case E_FMAN_PORT_STATS_CNT_FRAME:
62780 + *stats_reg = &regs->fmbm_ofrc;
62781 + break;
62782 + case E_FMAN_PORT_STATS_CNT_DISCARD:
62783 + *stats_reg = &regs->fmbm_ofdc;
62784 + break;
62785 + case E_FMAN_PORT_STATS_CNT_DEALLOC_BUF:
62786 + *stats_reg = &regs->fmbm_obdc;
62787 + break;
62788 + case E_FMAN_PORT_STATS_CNT_FILTERED_FRAME:
62789 + *stats_reg = &regs->fmbm_offc;
62790 + break;
62791 + case E_FMAN_PORT_STATS_CNT_DMA_ERR:
62792 + *stats_reg = &regs->fmbm_ofldec;
62793 + break;
62794 + case E_FMAN_PORT_STATS_CNT_LEN_ERR:
62795 + *stats_reg = &regs->fmbm_ofledc;
62796 + break;
62797 + case E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT:
62798 + *stats_reg = &regs->fmbm_ofufdc;
62799 + break;
62800 + case E_FMAN_PORT_STATS_CNT_WRED_DISCARD:
62801 + *stats_reg = &regs->fmbm_ofwdc;
62802 + break;
62803 + default:
62804 + *stats_reg = NULL;
62805 + }
62806 +}
62807 +
62808 +static void get_rx_perf_reg(struct fman_port *port,
62809 + enum fman_port_perf_counters counter,
62810 + uint32_t **perf_reg)
62811 +{
62812 + struct fman_port_rx_bmi_regs *regs = &port->bmi_regs->rx;
62813 +
62814 + switch (counter) {
62815 + case E_FMAN_PORT_PERF_CNT_CYCLE:
62816 + *perf_reg = &regs->fmbm_rccn;
62817 + break;
62818 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
62819 + *perf_reg = &regs->fmbm_rtuc;
62820 + break;
62821 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
62822 + *perf_reg = &regs->fmbm_rrquc;
62823 + break;
62824 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
62825 + *perf_reg = &regs->fmbm_rduc;
62826 + break;
62827 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
62828 + *perf_reg = &regs->fmbm_rfuc;
62829 + break;
62830 + case E_FMAN_PORT_PERF_CNT_RX_PAUSE:
62831 + *perf_reg = &regs->fmbm_rpac;
62832 + break;
62833 + default:
62834 + *perf_reg = NULL;
62835 + }
62836 +}
62837 +
62838 +static void get_tx_perf_reg(struct fman_port *port,
62839 + enum fman_port_perf_counters counter,
62840 + uint32_t **perf_reg)
62841 +{
62842 + struct fman_port_tx_bmi_regs *regs = &port->bmi_regs->tx;
62843 +
62844 + switch (counter) {
62845 + case E_FMAN_PORT_PERF_CNT_CYCLE:
62846 + *perf_reg = &regs->fmbm_tccn;
62847 + break;
62848 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
62849 + *perf_reg = &regs->fmbm_ttuc;
62850 + break;
62851 + case E_FMAN_PORT_PERF_CNT_QUEUE_UTIL:
62852 + *perf_reg = &regs->fmbm_ttcquc;
62853 + break;
62854 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
62855 + *perf_reg = &regs->fmbm_tduc;
62856 + break;
62857 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
62858 + *perf_reg = &regs->fmbm_tfuc;
62859 + break;
62860 + default:
62861 + *perf_reg = NULL;
62862 + }
62863 +}
62864 +
62865 +static void get_oh_perf_reg(struct fman_port *port,
62866 + enum fman_port_perf_counters counter,
62867 + uint32_t **perf_reg)
62868 +{
62869 + struct fman_port_oh_bmi_regs *regs = &port->bmi_regs->oh;
62870 +
62871 + switch (counter) {
62872 + case E_FMAN_PORT_PERF_CNT_CYCLE:
62873 + *perf_reg = &regs->fmbm_occn;
62874 + break;
62875 + case E_FMAN_PORT_PERF_CNT_TASK_UTIL:
62876 + *perf_reg = &regs->fmbm_otuc;
62877 + break;
62878 + case E_FMAN_PORT_PERF_CNT_DMA_UTIL:
62879 + *perf_reg = &regs->fmbm_oduc;
62880 + break;
62881 + case E_FMAN_PORT_PERF_CNT_FIFO_UTIL:
62882 + *perf_reg = &regs->fmbm_ofuc;
62883 + break;
62884 + default:
62885 + *perf_reg = NULL;
62886 + }
62887 +}
62888 +
62889 +static void get_qmi_counter_reg(struct fman_port *port,
62890 + enum fman_port_qmi_counters counter,
62891 + uint32_t **queue_reg)
62892 +{
62893 + struct fman_port_qmi_regs *regs = port->qmi_regs;
62894 +
62895 + switch (counter) {
62896 + case E_FMAN_PORT_ENQ_TOTAL:
62897 + *queue_reg = &regs->fmqm_pnetfc;
62898 + break;
62899 + case E_FMAN_PORT_DEQ_TOTAL:
62900 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
62901 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
62902 + /* Counter not available for Rx ports */
62903 + *queue_reg = NULL;
62904 + else
62905 + *queue_reg = &regs->fmqm_pndtfc;
62906 + break;
62907 + case E_FMAN_PORT_DEQ_FROM_DFLT:
62908 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
62909 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
62910 + /* Counter not available for Rx ports */
62911 + *queue_reg = NULL;
62912 + else
62913 + *queue_reg = &regs->fmqm_pndfdc;
62914 + break;
62915 + case E_FMAN_PORT_DEQ_CONFIRM:
62916 + if ((port->type == E_FMAN_PORT_TYPE_RX) ||
62917 + (port->type == E_FMAN_PORT_TYPE_RX_10G))
62918 + /* Counter not available for Rx ports */
62919 + *queue_reg = NULL;
62920 + else
62921 + *queue_reg = &regs->fmqm_pndcc;
62922 + break;
62923 + default:
62924 + *queue_reg = NULL;
62925 + }
62926 +}
62927 +
62928 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type)
62929 +{
62930 + cfg->dma_swap_data = E_FMAN_PORT_DMA_NO_SWAP;
62931 + cfg->dma_ic_stash_on = FALSE;
62932 + cfg->dma_header_stash_on = FALSE;
62933 + cfg->dma_sg_stash_on = FALSE;
62934 + cfg->dma_write_optimize = TRUE;
62935 + cfg->color = E_FMAN_PORT_COLOR_GREEN;
62936 + cfg->discard_override = FALSE;
62937 + cfg->checksum_bytes_ignore = 0;
62938 + cfg->rx_cut_end_bytes = 4;
62939 + cfg->rx_pri_elevation = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
62940 + cfg->rx_fifo_thr = ((0x3FF + 1) * FMAN_PORT_BMI_FIFO_UNITS);
62941 + cfg->rx_fd_bits = 0;
62942 + cfg->ic_ext_offset = 0;
62943 + cfg->ic_int_offset = 0;
62944 + cfg->ic_size = 0;
62945 + cfg->int_buf_start_margin = 0;
62946 + cfg->ext_buf_start_margin = 0;
62947 + cfg->ext_buf_end_margin = 0;
62948 + cfg->tx_fifo_min_level = 0;
62949 + cfg->tx_fifo_low_comf_level = (5 * KILOBYTE);
62950 + cfg->stats_counters_enable = TRUE;
62951 + cfg->perf_counters_enable = TRUE;
62952 + cfg->deq_type = E_FMAN_PORT_DEQ_BY_PRI;
62953 +
62954 + if (type == E_FMAN_PORT_TYPE_HC) {
62955 + cfg->sync_req = FALSE;
62956 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_NO_PREFETCH;
62957 + } else {
62958 + cfg->sync_req = TRUE;
62959 + cfg->deq_prefetch_opt = E_FMAN_PORT_DEQ_FULL_PREFETCH;
62960 + }
62961 +
62962 + if (type == E_FMAN_PORT_TYPE_TX_10G) {
62963 + cfg->tx_fifo_deq_pipeline_depth = 4;
62964 + cfg->deq_high_pri = TRUE;
62965 + cfg->deq_byte_cnt = 0x1400;
62966 + } else {
62967 + if ((type == E_FMAN_PORT_TYPE_HC) ||
62968 + (type == E_FMAN_PORT_TYPE_OP))
62969 + cfg->tx_fifo_deq_pipeline_depth = 2;
62970 + else
62971 + cfg->tx_fifo_deq_pipeline_depth = 1;
62972 +
62973 + cfg->deq_high_pri = FALSE;
62974 + cfg->deq_byte_cnt = 0x400;
62975 + }
62976 + cfg->no_scatter_gather = DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
62977 +}
62978 +
62979 +static uint8_t fman_port_find_bpool(struct fman_port *port, uint8_t bpid)
62980 +{
62981 + uint32_t *bp_reg, tmp;
62982 + uint8_t i, id;
62983 +
62984 + /* Find the pool */
62985 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
62986 + for (i = 0;
62987 + (i < port->ext_pools_num && (i < FMAN_PORT_MAX_EXT_POOLS_NUM));
62988 + i++) {
62989 + tmp = ioread32be(&bp_reg[i]);
62990 + id = (uint8_t)((tmp & BMI_EXT_BUF_POOL_ID_MASK) >>
62991 + BMI_EXT_BUF_POOL_ID_SHIFT);
62992 +
62993 + if (id == bpid)
62994 + break;
62995 + }
62996 +
62997 + return i;
62998 +}
62999 +
63000 +int fman_port_init(struct fman_port *port,
63001 + struct fman_port_cfg *cfg,
63002 + struct fman_port_params *params)
63003 +{
63004 + int err;
63005 +
63006 + /* Init BMI registers */
63007 + switch (port->type) {
63008 + case E_FMAN_PORT_TYPE_RX:
63009 + case E_FMAN_PORT_TYPE_RX_10G:
63010 + err = init_bmi_rx(port, cfg, params);
63011 + break;
63012 + case E_FMAN_PORT_TYPE_TX:
63013 + case E_FMAN_PORT_TYPE_TX_10G:
63014 + err = init_bmi_tx(port, cfg, params);
63015 + break;
63016 + case E_FMAN_PORT_TYPE_OP:
63017 + case E_FMAN_PORT_TYPE_HC:
63018 + err = init_bmi_oh(port, cfg, params);
63019 + break;
63020 + default:
63021 + return -EINVAL;
63022 + }
63023 +
63024 + if (err)
63025 + return err;
63026 +
63027 + /* Init QMI registers */
63028 + if (!port->im_en)
63029 + {
63030 + err = init_qmi(port, cfg, params);
63031 + return err;
63032 + }
63033 + return 0;
63034 +}
63035 +
63036 +int fman_port_enable(struct fman_port *port)
63037 +{
63038 + uint32_t *bmi_cfg_reg, tmp;
63039 + bool rx_port;
63040 +
63041 + switch (port->type) {
63042 + case E_FMAN_PORT_TYPE_RX:
63043 + case E_FMAN_PORT_TYPE_RX_10G:
63044 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
63045 + rx_port = TRUE;
63046 + break;
63047 + case E_FMAN_PORT_TYPE_TX:
63048 + case E_FMAN_PORT_TYPE_TX_10G:
63049 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
63050 + rx_port = FALSE;
63051 + break;
63052 + case E_FMAN_PORT_TYPE_OP:
63053 + case E_FMAN_PORT_TYPE_HC:
63054 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
63055 + rx_port = FALSE;
63056 + break;
63057 + default:
63058 + return -EINVAL;
63059 + }
63060 +
63061 + /* Enable QMI */
63062 + if (!rx_port) {
63063 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
63064 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
63065 + }
63066 +
63067 + /* Enable BMI */
63068 + tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
63069 + iowrite32be(tmp, bmi_cfg_reg);
63070 +
63071 + return 0;
63072 +}
63073 +
63074 +int fman_port_disable(const struct fman_port *port)
63075 +{
63076 + uint32_t *bmi_cfg_reg, *bmi_status_reg, tmp;
63077 + bool rx_port, failure = FALSE;
63078 + int count;
63079 +
63080 + switch (port->type) {
63081 + case E_FMAN_PORT_TYPE_RX:
63082 + case E_FMAN_PORT_TYPE_RX_10G:
63083 + bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
63084 + bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
63085 + rx_port = TRUE;
63086 + break;
63087 + case E_FMAN_PORT_TYPE_TX:
63088 + case E_FMAN_PORT_TYPE_TX_10G:
63089 + bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
63090 + bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
63091 + rx_port = FALSE;
63092 + break;
63093 + case E_FMAN_PORT_TYPE_OP:
63094 + case E_FMAN_PORT_TYPE_HC:
63095 + bmi_cfg_reg = &port->bmi_regs->oh.fmbm_ocfg;
63096 + bmi_status_reg = &port->bmi_regs->oh.fmbm_ost;
63097 + rx_port = FALSE;
63098 + break;
63099 + default:
63100 + return -EINVAL;
63101 + }
63102 +
63103 + /* Disable QMI */
63104 + if (!rx_port) {
63105 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
63106 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
63107 +
63108 + /* Wait for QMI to finish FD handling */
63109 + count = 100;
63110 + do {
63111 + udelay(10);
63112 + tmp = ioread32be(&port->qmi_regs->fmqm_pns);
63113 + } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
63114 +
63115 + if (count == 0)
63116 + {
63117 + /* Timeout */
63118 + failure = TRUE;
63119 + }
63120 + }
63121 +
63122 + /* Disable BMI */
63123 + tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
63124 + iowrite32be(tmp, bmi_cfg_reg);
63125 +
63126 + /* Wait for graceful stop end */
63127 + count = 500;
63128 + do {
63129 + udelay(10);
63130 + tmp = ioread32be(bmi_status_reg);
63131 + } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
63132 +
63133 + if (count == 0)
63134 + {
63135 + /* Timeout */
63136 + failure = TRUE;
63137 + }
63138 +
63139 + if (failure)
63140 + return -EBUSY;
63141 +
63142 + return 0;
63143 +}
63144 +
63145 +int fman_port_set_bpools(const struct fman_port *port,
63146 + const struct fman_port_bpools *bp)
63147 +{
63148 + uint32_t tmp, *bp_reg, *bp_depl_reg;
63149 + uint8_t i, max_bp_num;
63150 + bool grp_depl_used = FALSE, rx_port;
63151 +
63152 + switch (port->type) {
63153 + case E_FMAN_PORT_TYPE_RX:
63154 + case E_FMAN_PORT_TYPE_RX_10G:
63155 + max_bp_num = port->ext_pools_num;
63156 + rx_port = TRUE;
63157 + bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
63158 + bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
63159 + break;
63160 + case E_FMAN_PORT_TYPE_OP:
63161 + if (port->fm_rev_maj != 4)
63162 + return -EINVAL;
63163 + max_bp_num = FMAN_PORT_OBS_EXT_POOLS_NUM;
63164 + rx_port = FALSE;
63165 + bp_reg = port->bmi_regs->oh.fmbm_oebmpi;
63166 + bp_depl_reg = &port->bmi_regs->oh.fmbm_ompd;
63167 + break;
63168 + default:
63169 + return -EINVAL;
63170 + }
63171 +
63172 + if (rx_port) {
63173 + /* Check buffers are provided in ascending order */
63174 + for (i = 0;
63175 + (i < (bp->count-1) && (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1));
63176 + i++) {
63177 + if (bp->bpool[i].size > bp->bpool[i+1].size)
63178 + return -EINVAL;
63179 + }
63180 + }
63181 +
63182 + /* Set up external buffers pools */
63183 + for (i = 0; i < bp->count; i++) {
63184 + tmp = BMI_EXT_BUF_POOL_VALID;
63185 + tmp |= ((uint32_t)bp->bpool[i].bpid <<
63186 + BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
63187 +
63188 + if (rx_port) {
63189 + if (bp->counters_enable)
63190 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
63191 +
63192 + if (bp->bpool[i].is_backup)
63193 + tmp |= BMI_EXT_BUF_POOL_BACKUP;
63194 +
63195 + tmp |= (uint32_t)bp->bpool[i].size;
63196 + }
63197 +
63198 + iowrite32be(tmp, &bp_reg[i]);
63199 + }
63200 +
63201 + /* Clear unused pools */
63202 + for (i = bp->count; i < max_bp_num; i++)
63203 + iowrite32be(0, &bp_reg[i]);
63204 +
63205 + /* Pools depletion */
63206 + tmp = 0;
63207 + for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
63208 + if (bp->bpool[i].grp_bp_depleted) {
63209 + grp_depl_used = TRUE;
63210 + tmp |= 0x80000000 >> i;
63211 + }
63212 +
63213 + if (bp->bpool[i].single_bp_depleted)
63214 + tmp |= 0x80 >> i;
63215 +
63216 + if (bp->bpool[i].pfc_priorities_en)
63217 + tmp |= 0x0100 << i;
63218 + }
63219 +
63220 + if (grp_depl_used)
63221 + tmp |= ((uint32_t)bp->grp_bp_depleted_num - 1) <<
63222 + BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
63223 +
63224 + iowrite32be(tmp, bp_depl_reg);
63225 + return 0;
63226 +}
63227 +
63228 +int fman_port_set_rate_limiter(struct fman_port *port,
63229 + struct fman_port_rate_limiter *rate_limiter)
63230 +{
63231 + uint32_t *rate_limit_reg, *rate_limit_scale_reg;
63232 + uint32_t granularity, tmp;
63233 + uint8_t usec_bit, factor;
63234 +
63235 + switch (port->type) {
63236 + case E_FMAN_PORT_TYPE_TX:
63237 + case E_FMAN_PORT_TYPE_TX_10G:
63238 + rate_limit_reg = &port->bmi_regs->tx.fmbm_trlmt;
63239 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
63240 + granularity = BMI_RATE_LIMIT_GRAN_TX;
63241 + break;
63242 + case E_FMAN_PORT_TYPE_OP:
63243 + rate_limit_reg = &port->bmi_regs->oh.fmbm_orlmt;
63244 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
63245 + granularity = BMI_RATE_LIMIT_GRAN_OP;
63246 + break;
63247 + default:
63248 + return -EINVAL;
63249 + }
63250 +
63251 + /* Factor is per 1 usec count */
63252 + factor = 1;
63253 + usec_bit = rate_limiter->count_1micro_bit;
63254 +
63255 + /* If rate limit is too small for an 1usec factor, adjust timestamp
63256 + * scale and multiply the factor */
63257 + while (rate_limiter->rate < (granularity / factor)) {
63258 + if (usec_bit == 31)
63259 + /* Can't configure rate limiter - rate is too small */
63260 + return -EINVAL;
63261 +
63262 + usec_bit++;
63263 + factor <<= 1;
63264 + }
63265 +
63266 + /* Figure out register value. The "while" above quarantees that
63267 + * (rate_limiter->rate * factor / granularity) >= 1 */
63268 + tmp = (uint32_t)(rate_limiter->rate * factor / granularity - 1);
63269 +
63270 + /* Check rate limit isn't too large */
63271 + if (tmp >= BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS)
63272 + return -EINVAL;
63273 +
63274 + /* Check burst size is in allowed range */
63275 + if ((rate_limiter->burst_size == 0) ||
63276 + (rate_limiter->burst_size >
63277 + BMI_RATE_LIMIT_MAX_BURST_SIZE))
63278 + return -EINVAL;
63279 +
63280 + tmp |= (uint32_t)(rate_limiter->burst_size - 1) <<
63281 + BMI_RATE_LIMIT_MAX_BURST_SHIFT;
63282 +
63283 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
63284 + (port->fm_rev_maj == 4)) {
63285 + if (rate_limiter->high_burst_size_gran)
63286 + tmp |= BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN;
63287 + }
63288 +
63289 + iowrite32be(tmp, rate_limit_reg);
63290 +
63291 + /* Set up rate limiter scale register */
63292 + tmp = BMI_RATE_LIMIT_SCALE_EN;
63293 + tmp |= (31 - (uint32_t)usec_bit) << BMI_RATE_LIMIT_SCALE_TSBS_SHIFT;
63294 +
63295 + if ((port->type == E_FMAN_PORT_TYPE_OP) &&
63296 + (port->fm_rev_maj == 4))
63297 + tmp |= rate_limiter->rate_factor;
63298 +
63299 + iowrite32be(tmp, rate_limit_scale_reg);
63300 +
63301 + return 0;
63302 +}
63303 +
63304 +int fman_port_delete_rate_limiter(struct fman_port *port)
63305 +{
63306 + uint32_t *rate_limit_scale_reg;
63307 +
63308 + switch (port->type) {
63309 + case E_FMAN_PORT_TYPE_TX:
63310 + case E_FMAN_PORT_TYPE_TX_10G:
63311 + rate_limit_scale_reg = &port->bmi_regs->tx.fmbm_trlmts;
63312 + break;
63313 + case E_FMAN_PORT_TYPE_OP:
63314 + rate_limit_scale_reg = &port->bmi_regs->oh.fmbm_orlmts;
63315 + break;
63316 + default:
63317 + return -EINVAL;
63318 + }
63319 +
63320 + iowrite32be(0, rate_limit_scale_reg);
63321 + return 0;
63322 +}
63323 +
63324 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask)
63325 +{
63326 + uint32_t *err_mask_reg;
63327 +
63328 + /* Obtain register address */
63329 + switch (port->type) {
63330 + case E_FMAN_PORT_TYPE_RX:
63331 + case E_FMAN_PORT_TYPE_RX_10G:
63332 + err_mask_reg = &port->bmi_regs->rx.fmbm_rfsem;
63333 + break;
63334 + case E_FMAN_PORT_TYPE_OP:
63335 + err_mask_reg = &port->bmi_regs->oh.fmbm_ofsem;
63336 + break;
63337 + default:
63338 + return -EINVAL;
63339 + }
63340 +
63341 + iowrite32be(err_mask, err_mask_reg);
63342 + return 0;
63343 +}
63344 +
63345 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask)
63346 +{
63347 + uint32_t *discard_mask_reg;
63348 +
63349 + /* Obtain register address */
63350 + switch (port->type) {
63351 + case E_FMAN_PORT_TYPE_RX:
63352 + case E_FMAN_PORT_TYPE_RX_10G:
63353 + discard_mask_reg = &port->bmi_regs->rx.fmbm_rfsdm;
63354 + break;
63355 + case E_FMAN_PORT_TYPE_OP:
63356 + discard_mask_reg = &port->bmi_regs->oh.fmbm_ofsdm;
63357 + break;
63358 + default:
63359 + return -EINVAL;
63360 + }
63361 +
63362 + iowrite32be(discard_mask, discard_mask_reg);
63363 + return 0;
63364 +}
63365 +
63366 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
63367 + uint8_t rx_fd_bits,
63368 + bool add)
63369 +{
63370 + uint32_t tmp;
63371 +
63372 + switch (port->type) {
63373 + case E_FMAN_PORT_TYPE_RX:
63374 + case E_FMAN_PORT_TYPE_RX_10G:
63375 + break;
63376 + default:
63377 + return -EINVAL;
63378 + }
63379 +
63380 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_rfne);
63381 +
63382 + if (add)
63383 + tmp |= (uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
63384 + else
63385 + tmp &= ~((uint32_t)rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT);
63386 +
63387 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_rfne);
63388 + return 0;
63389 +}
63390 +
63391 +int fman_port_set_perf_cnt_params(struct fman_port *port,
63392 + struct fman_port_perf_cnt_params *params)
63393 +{
63394 + uint32_t *pcp_reg, tmp;
63395 +
63396 + /* Obtain register address and check parameters are in range */
63397 + switch (port->type) {
63398 + case E_FMAN_PORT_TYPE_RX:
63399 + case E_FMAN_PORT_TYPE_RX_10G:
63400 + pcp_reg = &port->bmi_regs->rx.fmbm_rpcp;
63401 + if ((params->queue_val == 0) ||
63402 + (params->queue_val > MAX_PERFORMANCE_RX_QUEUE_COMP))
63403 + return -EINVAL;
63404 + break;
63405 + case E_FMAN_PORT_TYPE_TX:
63406 + case E_FMAN_PORT_TYPE_TX_10G:
63407 + pcp_reg = &port->bmi_regs->tx.fmbm_tpcp;
63408 + if ((params->queue_val == 0) ||
63409 + (params->queue_val > MAX_PERFORMANCE_TX_QUEUE_COMP))
63410 + return -EINVAL;
63411 + break;
63412 + case E_FMAN_PORT_TYPE_OP:
63413 + case E_FMAN_PORT_TYPE_HC:
63414 + pcp_reg = &port->bmi_regs->oh.fmbm_opcp;
63415 + if (params->queue_val != 0)
63416 + return -EINVAL;
63417 + break;
63418 + default:
63419 + return -EINVAL;
63420 + }
63421 +
63422 + if ((params->task_val == 0) ||
63423 + (params->task_val > MAX_PERFORMANCE_TASK_COMP))
63424 + return -EINVAL;
63425 + if ((params->dma_val == 0) ||
63426 + (params->dma_val > MAX_PERFORMANCE_DMA_COMP))
63427 + return -EINVAL;
63428 + if ((params->fifo_val == 0) ||
63429 + ((params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS) >
63430 + MAX_PERFORMANCE_FIFO_COMP))
63431 + return -EINVAL;
63432 + tmp = (uint32_t)(params->task_val - 1) <<
63433 + BMI_PERFORMANCE_TASK_COMP_SHIFT;
63434 + tmp |= (uint32_t)(params->dma_val - 1) <<
63435 + BMI_PERFORMANCE_DMA_COMP_SHIFT;
63436 + tmp |= (uint32_t)(params->fifo_val / FMAN_PORT_BMI_FIFO_UNITS - 1);
63437 +
63438 + switch (port->type) {
63439 + case E_FMAN_PORT_TYPE_RX:
63440 + case E_FMAN_PORT_TYPE_RX_10G:
63441 + case E_FMAN_PORT_TYPE_TX:
63442 + case E_FMAN_PORT_TYPE_TX_10G:
63443 + tmp |= (uint32_t)(params->queue_val - 1) <<
63444 + BMI_PERFORMANCE_QUEUE_COMP_SHIFT;
63445 + break;
63446 + default:
63447 + break;
63448 + }
63449 +
63450 +
63451 + iowrite32be(tmp, pcp_reg);
63452 + return 0;
63453 +}
63454 +
63455 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable)
63456 +{
63457 + uint32_t *stats_reg, tmp;
63458 +
63459 + switch (port->type) {
63460 + case E_FMAN_PORT_TYPE_RX:
63461 + case E_FMAN_PORT_TYPE_RX_10G:
63462 + stats_reg = &port->bmi_regs->rx.fmbm_rstc;
63463 + break;
63464 + case E_FMAN_PORT_TYPE_TX:
63465 + case E_FMAN_PORT_TYPE_TX_10G:
63466 + stats_reg = &port->bmi_regs->tx.fmbm_tstc;
63467 + break;
63468 + case E_FMAN_PORT_TYPE_OP:
63469 + case E_FMAN_PORT_TYPE_HC:
63470 + stats_reg = &port->bmi_regs->oh.fmbm_ostc;
63471 + break;
63472 + default:
63473 + return -EINVAL;
63474 + }
63475 +
63476 + tmp = ioread32be(stats_reg);
63477 +
63478 + if (enable)
63479 + tmp |= BMI_COUNTERS_EN;
63480 + else
63481 + tmp &= ~BMI_COUNTERS_EN;
63482 +
63483 + iowrite32be(tmp, stats_reg);
63484 + return 0;
63485 +}
63486 +
63487 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable)
63488 +{
63489 + uint32_t *stats_reg, tmp;
63490 +
63491 + switch (port->type) {
63492 + case E_FMAN_PORT_TYPE_RX:
63493 + case E_FMAN_PORT_TYPE_RX_10G:
63494 + stats_reg = &port->bmi_regs->rx.fmbm_rpc;
63495 + break;
63496 + case E_FMAN_PORT_TYPE_TX:
63497 + case E_FMAN_PORT_TYPE_TX_10G:
63498 + stats_reg = &port->bmi_regs->tx.fmbm_tpc;
63499 + break;
63500 + case E_FMAN_PORT_TYPE_OP:
63501 + case E_FMAN_PORT_TYPE_HC:
63502 + stats_reg = &port->bmi_regs->oh.fmbm_opc;
63503 + break;
63504 + default:
63505 + return -EINVAL;
63506 + }
63507 +
63508 + tmp = ioread32be(stats_reg);
63509 +
63510 + if (enable)
63511 + tmp |= BMI_COUNTERS_EN;
63512 + else
63513 + tmp &= ~BMI_COUNTERS_EN;
63514 +
63515 + iowrite32be(tmp, stats_reg);
63516 + return 0;
63517 +}
63518 +
63519 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable)
63520 +{
63521 + uint32_t tmp;
63522 +
63523 + tmp = ioread32be(&port->qmi_regs->fmqm_pnc);
63524 +
63525 + if (enable)
63526 + tmp |= QMI_PORT_CFG_EN_COUNTERS;
63527 + else
63528 + tmp &= ~QMI_PORT_CFG_EN_COUNTERS;
63529 +
63530 + iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
63531 + return 0;
63532 +}
63533 +
63534 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
63535 + uint8_t bpid,
63536 + bool enable)
63537 +{
63538 + uint8_t index;
63539 + uint32_t tmp;
63540 +
63541 + switch (port->type) {
63542 + case E_FMAN_PORT_TYPE_RX:
63543 + case E_FMAN_PORT_TYPE_RX_10G:
63544 + break;
63545 + default:
63546 + return -EINVAL;
63547 + }
63548 +
63549 + /* Find the pool */
63550 + index = fman_port_find_bpool(port, bpid);
63551 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
63552 + /* Not found */
63553 + return -EINVAL;
63554 +
63555 + tmp = ioread32be(&port->bmi_regs->rx.fmbm_ebmpi[index]);
63556 +
63557 + if (enable)
63558 + tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
63559 + else
63560 + tmp &= ~BMI_EXT_BUF_POOL_EN_COUNTER;
63561 +
63562 + iowrite32be(tmp, &port->bmi_regs->rx.fmbm_ebmpi[index]);
63563 + return 0;
63564 +}
63565 +
63566 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
63567 + enum fman_port_stats_counters counter)
63568 +{
63569 + uint32_t *stats_reg, ret_val;
63570 +
63571 + switch (port->type) {
63572 + case E_FMAN_PORT_TYPE_RX:
63573 + case E_FMAN_PORT_TYPE_RX_10G:
63574 + get_rx_stats_reg(port, counter, &stats_reg);
63575 + break;
63576 + case E_FMAN_PORT_TYPE_TX:
63577 + case E_FMAN_PORT_TYPE_TX_10G:
63578 + get_tx_stats_reg(port, counter, &stats_reg);
63579 + break;
63580 + case E_FMAN_PORT_TYPE_OP:
63581 + case E_FMAN_PORT_TYPE_HC:
63582 + get_oh_stats_reg(port, counter, &stats_reg);
63583 + break;
63584 + default:
63585 + stats_reg = NULL;
63586 + }
63587 +
63588 + if (stats_reg == NULL)
63589 + return 0;
63590 +
63591 + ret_val = ioread32be(stats_reg);
63592 + return ret_val;
63593 +}
63594 +
63595 +void fman_port_set_stats_counter(struct fman_port *port,
63596 + enum fman_port_stats_counters counter,
63597 + uint32_t value)
63598 +{
63599 + uint32_t *stats_reg;
63600 +
63601 + switch (port->type) {
63602 + case E_FMAN_PORT_TYPE_RX:
63603 + case E_FMAN_PORT_TYPE_RX_10G:
63604 + get_rx_stats_reg(port, counter, &stats_reg);
63605 + break;
63606 + case E_FMAN_PORT_TYPE_TX:
63607 + case E_FMAN_PORT_TYPE_TX_10G:
63608 + get_tx_stats_reg(port, counter, &stats_reg);
63609 + break;
63610 + case E_FMAN_PORT_TYPE_OP:
63611 + case E_FMAN_PORT_TYPE_HC:
63612 + get_oh_stats_reg(port, counter, &stats_reg);
63613 + break;
63614 + default:
63615 + stats_reg = NULL;
63616 + }
63617 +
63618 + if (stats_reg == NULL)
63619 + return;
63620 +
63621 + iowrite32be(value, stats_reg);
63622 +}
63623 +
63624 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
63625 + enum fman_port_perf_counters counter)
63626 +{
63627 + uint32_t *perf_reg, ret_val;
63628 +
63629 + switch (port->type) {
63630 + case E_FMAN_PORT_TYPE_RX:
63631 + case E_FMAN_PORT_TYPE_RX_10G:
63632 + get_rx_perf_reg(port, counter, &perf_reg);
63633 + break;
63634 + case E_FMAN_PORT_TYPE_TX:
63635 + case E_FMAN_PORT_TYPE_TX_10G:
63636 + get_tx_perf_reg(port, counter, &perf_reg);
63637 + break;
63638 + case E_FMAN_PORT_TYPE_OP:
63639 + case E_FMAN_PORT_TYPE_HC:
63640 + get_oh_perf_reg(port, counter, &perf_reg);
63641 + break;
63642 + default:
63643 + perf_reg = NULL;
63644 + }
63645 +
63646 + if (perf_reg == NULL)
63647 + return 0;
63648 +
63649 + ret_val = ioread32be(perf_reg);
63650 + return ret_val;
63651 +}
63652 +
63653 +void fman_port_set_perf_counter(struct fman_port *port,
63654 + enum fman_port_perf_counters counter,
63655 + uint32_t value)
63656 +{
63657 + uint32_t *perf_reg;
63658 +
63659 + switch (port->type) {
63660 + case E_FMAN_PORT_TYPE_RX:
63661 + case E_FMAN_PORT_TYPE_RX_10G:
63662 + get_rx_perf_reg(port, counter, &perf_reg);
63663 + break;
63664 + case E_FMAN_PORT_TYPE_TX:
63665 + case E_FMAN_PORT_TYPE_TX_10G:
63666 + get_tx_perf_reg(port, counter, &perf_reg);
63667 + break;
63668 + case E_FMAN_PORT_TYPE_OP:
63669 + case E_FMAN_PORT_TYPE_HC:
63670 + get_oh_perf_reg(port, counter, &perf_reg);
63671 + break;
63672 + default:
63673 + perf_reg = NULL;
63674 + }
63675 +
63676 + if (perf_reg == NULL)
63677 + return;
63678 +
63679 + iowrite32be(value, perf_reg);
63680 +}
63681 +
63682 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
63683 + enum fman_port_qmi_counters counter)
63684 +{
63685 + uint32_t *queue_reg, ret_val;
63686 +
63687 + get_qmi_counter_reg(port, counter, &queue_reg);
63688 +
63689 + if (queue_reg == NULL)
63690 + return 0;
63691 +
63692 + ret_val = ioread32be(queue_reg);
63693 + return ret_val;
63694 +}
63695 +
63696 +void fman_port_set_qmi_counter(struct fman_port *port,
63697 + enum fman_port_qmi_counters counter,
63698 + uint32_t value)
63699 +{
63700 + uint32_t *queue_reg;
63701 +
63702 + get_qmi_counter_reg(port, counter, &queue_reg);
63703 +
63704 + if (queue_reg == NULL)
63705 + return;
63706 +
63707 + iowrite32be(value, queue_reg);
63708 +}
63709 +
63710 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid)
63711 +{
63712 + uint8_t index;
63713 + uint32_t ret_val;
63714 +
63715 + switch (port->type) {
63716 + case E_FMAN_PORT_TYPE_RX:
63717 + case E_FMAN_PORT_TYPE_RX_10G:
63718 + break;
63719 + default:
63720 + return 0;
63721 + }
63722 +
63723 + /* Find the pool */
63724 + index = fman_port_find_bpool(port, bpid);
63725 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
63726 + /* Not found */
63727 + return 0;
63728 +
63729 + ret_val = ioread32be(&port->bmi_regs->rx.fmbm_acnt[index]);
63730 + return ret_val;
63731 +}
63732 +
63733 +void fman_port_set_bpool_counter(struct fman_port *port,
63734 + uint8_t bpid,
63735 + uint32_t value)
63736 +{
63737 + uint8_t index;
63738 +
63739 + switch (port->type) {
63740 + case E_FMAN_PORT_TYPE_RX:
63741 + case E_FMAN_PORT_TYPE_RX_10G:
63742 + break;
63743 + default:
63744 + return;
63745 + }
63746 +
63747 + /* Find the pool */
63748 + index = fman_port_find_bpool(port, bpid);
63749 + if (index == port->ext_pools_num || index == FMAN_PORT_MAX_EXT_POOLS_NUM)
63750 + /* Not found */
63751 + return;
63752 +
63753 + iowrite32be(value, &port->bmi_regs->rx.fmbm_acnt[index]);
63754 +}
63755 +
63756 +int fman_port_add_congestion_grps(struct fman_port *port,
63757 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
63758 +{
63759 + int i;
63760 + uint32_t tmp, *grp_map_reg;
63761 + uint8_t max_grp_map_num;
63762 +
63763 + switch (port->type) {
63764 + case E_FMAN_PORT_TYPE_RX:
63765 + case E_FMAN_PORT_TYPE_RX_10G:
63766 + if (port->fm_rev_maj == 4)
63767 + max_grp_map_num = 1;
63768 + else
63769 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
63770 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
63771 + break;
63772 + case E_FMAN_PORT_TYPE_OP:
63773 + max_grp_map_num = 1;
63774 + if (port->fm_rev_maj != 4)
63775 + return -EINVAL;
63776 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
63777 + break;
63778 + default:
63779 + return -EINVAL;
63780 + }
63781 +
63782 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
63783 + if (grps_map[i] == 0)
63784 + continue;
63785 + tmp = ioread32be(&grp_map_reg[i]);
63786 + tmp |= grps_map[i];
63787 + iowrite32be(tmp, &grp_map_reg[i]);
63788 + }
63789 +
63790 + return 0;
63791 +}
63792 +
63793 +int fman_port_remove_congestion_grps(struct fman_port *port,
63794 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM])
63795 +{
63796 + int i;
63797 + uint32_t tmp, *grp_map_reg;
63798 + uint8_t max_grp_map_num;
63799 +
63800 + switch (port->type) {
63801 + case E_FMAN_PORT_TYPE_RX:
63802 + case E_FMAN_PORT_TYPE_RX_10G:
63803 + if (port->fm_rev_maj == 4)
63804 + max_grp_map_num = 1;
63805 + else
63806 + max_grp_map_num = FMAN_PORT_CG_MAP_NUM;
63807 + grp_map_reg = port->bmi_regs->rx.fmbm_rcgm;
63808 + break;
63809 + case E_FMAN_PORT_TYPE_OP:
63810 + max_grp_map_num = 1;
63811 + if (port->fm_rev_maj != 4)
63812 + return -EINVAL;
63813 + grp_map_reg = port->bmi_regs->oh.fmbm_ocgm;
63814 + break;
63815 + default:
63816 + return -EINVAL;
63817 + }
63818 +
63819 + for (i = (max_grp_map_num - 1); i >= 0; i--) {
63820 + if (grps_map[i] == 0)
63821 + continue;
63822 + tmp = ioread32be(&grp_map_reg[i]);
63823 + tmp &= ~grps_map[i];
63824 + iowrite32be(tmp, &grp_map_reg[i]);
63825 + }
63826 + return 0;
63827 +}
63828 --- /dev/null
63829 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/Makefile
63830 @@ -0,0 +1,15 @@
63831 +#
63832 +# Makefile for the Freescale Ethernet controllers
63833 +#
63834 +ccflags-y += -DVERSION=\"\"
63835 +#
63836 +#Include netcomm SW specific definitions
63837 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
63838 +
63839 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
63840 +
63841 +ccflags-y += -I$(NCSW_FM_INC)
63842 +
63843 +obj-y += fsl-ncsw-RTC.o
63844 +
63845 +fsl-ncsw-RTC-objs := fm_rtc.o fman_rtc.o
63846 --- /dev/null
63847 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.c
63848 @@ -0,0 +1,692 @@
63849 +/*
63850 + * Copyright 2008-2012 Freescale Semiconductor Inc.
63851 + *
63852 + * Redistribution and use in source and binary forms, with or without
63853 + * modification, are permitted provided that the following conditions are met:
63854 + * * Redistributions of source code must retain the above copyright
63855 + * notice, this list of conditions and the following disclaimer.
63856 + * * Redistributions in binary form must reproduce the above copyright
63857 + * notice, this list of conditions and the following disclaimer in the
63858 + * documentation and/or other materials provided with the distribution.
63859 + * * Neither the name of Freescale Semiconductor nor the
63860 + * names of its contributors may be used to endorse or promote products
63861 + * derived from this software without specific prior written permission.
63862 + *
63863 + *
63864 + * ALTERNATIVELY, this software may be distributed under the terms of the
63865 + * GNU General Public License ("GPL") as published by the Free Software
63866 + * Foundation, either version 2 of that License or (at your option) any
63867 + * later version.
63868 + *
63869 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
63870 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63871 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
63872 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
63873 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
63874 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63875 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
63876 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63877 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63878 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63879 + */
63880 +
63881 +
63882 +/******************************************************************************
63883 + @File fm_rtc.c
63884 +
63885 + @Description FM RTC driver implementation.
63886 +
63887 + @Cautions None
63888 +*//***************************************************************************/
63889 +#include <linux/math64.h>
63890 +#include "error_ext.h"
63891 +#include "debug_ext.h"
63892 +#include "string_ext.h"
63893 +#include "part_ext.h"
63894 +#include "xx_ext.h"
63895 +#include "ncsw_ext.h"
63896 +
63897 +#include "fm_rtc.h"
63898 +#include "fm_common.h"
63899 +
63900 +
63901 +
63902 +/*****************************************************************************/
63903 +static t_Error CheckInitParameters(t_FmRtc *p_Rtc)
63904 +{
63905 + struct rtc_cfg *p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
63906 + int i;
63907 +
63908 + if ((p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL) &&
63909 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM) &&
63910 + (p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR))
63911 + RETURN_ERROR(MAJOR, E_INVALID_CLOCK, ("Source clock undefined"));
63912 +
63913 + if (p_Rtc->outputClockDivisor == 0)
63914 + {
63915 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
63916 + ("Divisor for output clock (should be positive)"));
63917 + }
63918 +
63919 + for (i=0; i < FM_RTC_NUM_OF_ALARMS; i++)
63920 + {
63921 + if ((p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW) &&
63922 + (p_RtcDriverParam->alarm_polarity[i] != E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH))
63923 + {
63924 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm %d signal polarity", i));
63925 + }
63926 + }
63927 + for (i=0; i < FM_RTC_NUM_OF_EXT_TRIGGERS; i++)
63928 + {
63929 + if ((p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE) &&
63930 + (p_RtcDriverParam->trigger_polarity[i] != E_FMAN_RTC_TRIGGER_ON_RISING_EDGE))
63931 + {
63932 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Trigger %d signal polarity", i));
63933 + }
63934 + }
63935 +
63936 + return E_OK;
63937 +}
63938 +
63939 +/*****************************************************************************/
63940 +static void RtcExceptions(t_Handle h_FmRtc)
63941 +{
63942 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
63943 + struct rtc_regs *p_MemMap;
63944 + register uint32_t events;
63945 +
63946 + ASSERT_COND(p_Rtc);
63947 + p_MemMap = p_Rtc->p_MemMap;
63948 +
63949 + events = fman_rtc_check_and_clear_event(p_MemMap);
63950 + if (events & FMAN_RTC_TMR_TEVENT_ALM1)
63951 + {
63952 + if (p_Rtc->alarmParams[0].clearOnExpiration)
63953 + {
63954 + fman_rtc_set_timer_alarm_l(p_MemMap, 0, 0);
63955 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM1);
63956 + }
63957 + ASSERT_COND(p_Rtc->alarmParams[0].f_AlarmCallback);
63958 + p_Rtc->alarmParams[0].f_AlarmCallback(p_Rtc->h_App, 0);
63959 + }
63960 + if (events & FMAN_RTC_TMR_TEVENT_ALM2)
63961 + {
63962 + if (p_Rtc->alarmParams[1].clearOnExpiration)
63963 + {
63964 + fman_rtc_set_timer_alarm_l(p_MemMap, 1, 0);
63965 + fman_rtc_disable_interupt(p_MemMap, FMAN_RTC_TMR_TEVENT_ALM2);
63966 + }
63967 + ASSERT_COND(p_Rtc->alarmParams[1].f_AlarmCallback);
63968 + p_Rtc->alarmParams[1].f_AlarmCallback(p_Rtc->h_App, 1);
63969 + }
63970 + if (events & FMAN_RTC_TMR_TEVENT_PP1)
63971 + {
63972 + ASSERT_COND(p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback);
63973 + p_Rtc->periodicPulseParams[0].f_PeriodicPulseCallback(p_Rtc->h_App, 0);
63974 + }
63975 + if (events & FMAN_RTC_TMR_TEVENT_PP2)
63976 + {
63977 + ASSERT_COND(p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback);
63978 + p_Rtc->periodicPulseParams[1].f_PeriodicPulseCallback(p_Rtc->h_App, 1);
63979 + }
63980 + if (events & FMAN_RTC_TMR_TEVENT_ETS1)
63981 + {
63982 + ASSERT_COND(p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback);
63983 + p_Rtc->externalTriggerParams[0].f_ExternalTriggerCallback(p_Rtc->h_App, 0);
63984 + }
63985 + if (events & FMAN_RTC_TMR_TEVENT_ETS2)
63986 + {
63987 + ASSERT_COND(p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback);
63988 + p_Rtc->externalTriggerParams[1].f_ExternalTriggerCallback(p_Rtc->h_App, 1);
63989 + }
63990 +}
63991 +
63992 +
63993 +/*****************************************************************************/
63994 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam)
63995 +{
63996 + t_FmRtc *p_Rtc;
63997 +
63998 + SANITY_CHECK_RETURN_VALUE(p_FmRtcParam, E_NULL_POINTER, NULL);
63999 +
64000 + /* Allocate memory for the FM RTC driver parameters */
64001 + p_Rtc = (t_FmRtc *)XX_Malloc(sizeof(t_FmRtc));
64002 + if (!p_Rtc)
64003 + {
64004 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver structure"));
64005 + return NULL;
64006 + }
64007 +
64008 + memset(p_Rtc, 0, sizeof(t_FmRtc));
64009 +
64010 + /* Allocate memory for the FM RTC driver parameters */
64011 + p_Rtc->p_RtcDriverParam = (struct rtc_cfg *)XX_Malloc(sizeof(struct rtc_cfg));
64012 + if (!p_Rtc->p_RtcDriverParam)
64013 + {
64014 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM RTC driver parameters"));
64015 + XX_Free(p_Rtc);
64016 + return NULL;
64017 + }
64018 +
64019 + memset(p_Rtc->p_RtcDriverParam, 0, sizeof(struct rtc_cfg));
64020 +
64021 + /* Store RTC configuration parameters */
64022 + p_Rtc->h_Fm = p_FmRtcParam->h_Fm;
64023 +
64024 + /* Set default RTC configuration parameters */
64025 + fman_rtc_defconfig(p_Rtc->p_RtcDriverParam);
64026 +
64027 + p_Rtc->outputClockDivisor = DEFAULT_OUTPUT_CLOCK_DIVISOR;
64028 + p_Rtc->p_RtcDriverParam->bypass = DEFAULT_BYPASS;
64029 + p_Rtc->clockPeriodNanoSec = DEFAULT_CLOCK_PERIOD; /* 1 usec */
64030 +
64031 +
64032 + /* Store RTC parameters in the RTC control structure */
64033 + p_Rtc->p_MemMap = (struct rtc_regs *)UINT_TO_PTR(p_FmRtcParam->baseAddress);
64034 + p_Rtc->h_App = p_FmRtcParam->h_App;
64035 +
64036 + return p_Rtc;
64037 +}
64038 +
64039 +/*****************************************************************************/
64040 +t_Error FM_RTC_Init(t_Handle h_FmRtc)
64041 +{
64042 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64043 + struct rtc_cfg *p_RtcDriverParam;
64044 + struct rtc_regs *p_MemMap;
64045 + uint32_t freqCompensation = 0;
64046 + uint64_t tmpDouble;
64047 + bool init_freq_comp = FALSE;
64048 +
64049 + p_RtcDriverParam = p_Rtc->p_RtcDriverParam;
64050 + p_MemMap = p_Rtc->p_MemMap;
64051 +
64052 + if (CheckInitParameters(p_Rtc)!=E_OK)
64053 + RETURN_ERROR(MAJOR, E_CONFLICT,
64054 + ("Init Parameters are not Valid"));
64055 +
64056 + /* TODO check that no timestamping MACs are working in this stage. */
64057 +
64058 + /* find source clock frequency in Mhz */
64059 + if (p_Rtc->p_RtcDriverParam->src_clk != E_FMAN_RTC_SOURCE_CLOCK_SYSTEM)
64060 + p_Rtc->srcClkFreqMhz = p_Rtc->p_RtcDriverParam->ext_src_clk_freq;
64061 + else
64062 + p_Rtc->srcClkFreqMhz = (uint32_t)(FmGetMacClockFreq(p_Rtc->h_Fm));
64063 +
64064 + /* if timer in Master mode Initialize TMR_CTRL */
64065 + /* We want the counter (TMR_CNT) to count in nano-seconds */
64066 + if (!p_RtcDriverParam->timer_slave_mode && p_Rtc->p_RtcDriverParam->bypass)
64067 + p_Rtc->clockPeriodNanoSec = (1000 / p_Rtc->srcClkFreqMhz);
64068 + else
64069 + {
64070 + /* Initialize TMR_ADD with the initial frequency compensation value:
64071 + freqCompensation = (2^32 / frequency ratio) */
64072 + /* frequency ratio = sorce clock/rtc clock =
64073 + * (p_Rtc->srcClkFreqMhz*1000000))/ 1/(p_Rtc->clockPeriodNanoSec * 1000000000) */
64074 + init_freq_comp = TRUE;
64075 + freqCompensation = (uint32_t)DIV_CEIL(ACCUMULATOR_OVERFLOW * 1000,
64076 + p_Rtc->clockPeriodNanoSec * p_Rtc->srcClkFreqMhz);
64077 + }
64078 +
64079 + /* check the legality of the relation between source and destination clocks */
64080 + /* should be larger than 1.0001 */
64081 + tmpDouble = 10000 * (uint64_t)p_Rtc->clockPeriodNanoSec * (uint64_t)p_Rtc->srcClkFreqMhz;
64082 + if ((tmpDouble) <= 10001)
64083 + RETURN_ERROR(MAJOR, E_CONFLICT,
64084 + ("Invalid relation between source and destination clocks. Should be larger than 1.0001"));
64085 +
64086 + fman_rtc_init(p_RtcDriverParam,
64087 + p_MemMap,
64088 + FM_RTC_NUM_OF_ALARMS,
64089 + FM_RTC_NUM_OF_PERIODIC_PULSES,
64090 + FM_RTC_NUM_OF_EXT_TRIGGERS,
64091 + init_freq_comp,
64092 + freqCompensation,
64093 + p_Rtc->outputClockDivisor);
64094 +
64095 + /* Register the FM RTC interrupt */
64096 + FmRegisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL, RtcExceptions , p_Rtc);
64097 +
64098 + /* Free parameters structures */
64099 + XX_Free(p_Rtc->p_RtcDriverParam);
64100 + p_Rtc->p_RtcDriverParam = NULL;
64101 +
64102 + return E_OK;
64103 +}
64104 +
64105 +/*****************************************************************************/
64106 +t_Error FM_RTC_Free(t_Handle h_FmRtc)
64107 +{
64108 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64109 +
64110 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64111 +
64112 + if (p_Rtc->p_RtcDriverParam)
64113 + {
64114 + XX_Free(p_Rtc->p_RtcDriverParam);
64115 + }
64116 + else
64117 + {
64118 + FM_RTC_Disable(h_FmRtc);
64119 + }
64120 +
64121 + /* Unregister FM RTC interrupt */
64122 + FmUnregisterIntr(p_Rtc->h_Fm, e_FM_MOD_TMR, 0, e_FM_INTR_TYPE_NORMAL);
64123 + XX_Free(p_Rtc);
64124 +
64125 + return E_OK;
64126 +}
64127 +
64128 +/*****************************************************************************/
64129 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
64130 + e_FmSrcClk srcClk,
64131 + uint32_t freqInMhz)
64132 +{
64133 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64134 +
64135 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64136 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64137 +
64138 + p_Rtc->p_RtcDriverParam->src_clk = (enum fman_src_clock)srcClk;
64139 + if (srcClk != e_FM_RTC_SOURCE_CLOCK_SYSTEM)
64140 + p_Rtc->p_RtcDriverParam->ext_src_clk_freq = freqInMhz;
64141 +
64142 + return E_OK;
64143 +}
64144 +
64145 +/*****************************************************************************/
64146 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period)
64147 +{
64148 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64149 +
64150 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64151 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64152 +
64153 + p_Rtc->clockPeriodNanoSec = period;
64154 +
64155 + return E_OK;
64156 +}
64157 +
64158 +/*****************************************************************************/
64159 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled)
64160 +{
64161 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64162 +
64163 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64164 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64165 +
64166 + p_Rtc->p_RtcDriverParam->bypass = enabled;
64167 +
64168 + return E_OK;
64169 +}
64170 +
64171 +/*****************************************************************************/
64172 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted)
64173 +{
64174 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64175 +
64176 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64177 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64178 +
64179 + p_Rtc->p_RtcDriverParam->invert_input_clk_phase = inverted;
64180 +
64181 + return E_OK;
64182 +}
64183 +
64184 +/*****************************************************************************/
64185 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted)
64186 +{
64187 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64188 +
64189 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64190 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64191 +
64192 + p_Rtc->p_RtcDriverParam->invert_output_clk_phase = inverted;
64193 +
64194 + return E_OK;
64195 +}
64196 +
64197 +/*****************************************************************************/
64198 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor)
64199 +{
64200 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64201 +
64202 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64203 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64204 +
64205 + p_Rtc->outputClockDivisor = divisor;
64206 +
64207 + return E_OK;
64208 +}
64209 +
64210 +/*****************************************************************************/
64211 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable)
64212 +{
64213 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64214 +
64215 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64216 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64217 +
64218 + p_Rtc->p_RtcDriverParam->pulse_realign = enable;
64219 +
64220 + return E_OK;
64221 +}
64222 +
64223 +/*****************************************************************************/
64224 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
64225 + uint8_t alarmId,
64226 + e_FmRtcAlarmPolarity alarmPolarity)
64227 +{
64228 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64229 +
64230 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64231 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64232 +
64233 + if (alarmId >= FM_RTC_NUM_OF_ALARMS)
64234 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
64235 +
64236 + p_Rtc->p_RtcDriverParam->alarm_polarity[alarmId] =
64237 + (enum fman_rtc_alarm_polarity)alarmPolarity;
64238 +
64239 + return E_OK;
64240 +}
64241 +
64242 +/*****************************************************************************/
64243 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
64244 + uint8_t triggerId,
64245 + e_FmRtcTriggerPolarity triggerPolarity)
64246 +{
64247 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64248 +
64249 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64250 + SANITY_CHECK_RETURN_ERROR(p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64251 +
64252 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
64253 + {
64254 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
64255 + }
64256 +
64257 + p_Rtc->p_RtcDriverParam->trigger_polarity[triggerId] =
64258 + (enum fman_rtc_trigger_polarity)triggerPolarity;
64259 +
64260 + return E_OK;
64261 +}
64262 +
64263 +/*****************************************************************************/
64264 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock)
64265 +{
64266 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64267 +
64268 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64269 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64270 +
64271 + fman_rtc_enable(p_Rtc->p_MemMap, resetClock);
64272 + return E_OK;
64273 +}
64274 +
64275 +/*****************************************************************************/
64276 +t_Error FM_RTC_Disable(t_Handle h_FmRtc)
64277 +{
64278 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64279 +
64280 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64281 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64282 +
64283 + /* TODO A check must be added here, that no timestamping MAC's
64284 + * are working in this stage. */
64285 + fman_rtc_disable(p_Rtc->p_MemMap);
64286 +
64287 + return E_OK;
64288 +}
64289 +
64290 +/*****************************************************************************/
64291 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset)
64292 +{
64293 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64294 +
64295 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64296 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64297 +
64298 + fman_rtc_set_timer_offset(p_Rtc->p_MemMap, offset);
64299 + return E_OK;
64300 +}
64301 +
64302 +/*****************************************************************************/
64303 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams)
64304 +{
64305 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64306 + uint64_t tmpAlarm;
64307 + bool enable = FALSE;
64308 +
64309 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64310 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64311 +
64312 + if (p_FmRtcAlarmParams->alarmId >= FM_RTC_NUM_OF_ALARMS)
64313 + {
64314 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Alarm ID"));
64315 + }
64316 +
64317 + if (p_FmRtcAlarmParams->alarmTime < p_Rtc->clockPeriodNanoSec)
64318 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
64319 + ("Alarm time must be equal or larger than RTC period - %d nanoseconds",
64320 + p_Rtc->clockPeriodNanoSec));
64321 + tmpAlarm = p_FmRtcAlarmParams->alarmTime;
64322 + if (do_div(tmpAlarm, p_Rtc->clockPeriodNanoSec))
64323 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
64324 + ("Alarm time must be a multiple of RTC period - %d nanoseconds",
64325 + p_Rtc->clockPeriodNanoSec));
64326 +
64327 + if (p_FmRtcAlarmParams->f_AlarmCallback)
64328 + {
64329 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].f_AlarmCallback = p_FmRtcAlarmParams->f_AlarmCallback;
64330 + p_Rtc->alarmParams[p_FmRtcAlarmParams->alarmId].clearOnExpiration = p_FmRtcAlarmParams->clearOnExpiration;
64331 + enable = TRUE;
64332 + }
64333 +
64334 + fman_rtc_set_alarm(p_Rtc->p_MemMap, p_FmRtcAlarmParams->alarmId, (unsigned long)tmpAlarm, enable);
64335 +
64336 + return E_OK;
64337 +}
64338 +
64339 +/*****************************************************************************/
64340 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams)
64341 +{
64342 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64343 + bool enable = FALSE;
64344 + uint64_t tmpFiper;
64345 +
64346 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64347 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64348 +
64349 + if (p_FmRtcPeriodicPulseParams->periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
64350 + {
64351 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
64352 + }
64353 + if (fman_rtc_is_enabled(p_Rtc->p_MemMap))
64354 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Can't set Periodic pulse when RTC is enabled."));
64355 + if (p_FmRtcPeriodicPulseParams->periodicPulsePeriod < p_Rtc->clockPeriodNanoSec)
64356 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
64357 + ("Periodic pulse must be equal or larger than RTC period - %d nanoseconds",
64358 + p_Rtc->clockPeriodNanoSec));
64359 + tmpFiper = p_FmRtcPeriodicPulseParams->periodicPulsePeriod;
64360 + if (do_div(tmpFiper, p_Rtc->clockPeriodNanoSec))
64361 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
64362 + ("Periodic pulse must be a multiple of RTC period - %d nanoseconds",
64363 + p_Rtc->clockPeriodNanoSec));
64364 + if (tmpFiper & 0xffffffff00000000LL)
64365 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,
64366 + ("Periodic pulse/RTC Period must be smaller than 4294967296",
64367 + p_Rtc->clockPeriodNanoSec));
64368 +
64369 + if (p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback)
64370 + {
64371 + p_Rtc->periodicPulseParams[p_FmRtcPeriodicPulseParams->periodicPulseId].f_PeriodicPulseCallback =
64372 + p_FmRtcPeriodicPulseParams->f_PeriodicPulseCallback;
64373 + enable = TRUE;
64374 + }
64375 + fman_rtc_set_periodic_pulse(p_Rtc->p_MemMap, p_FmRtcPeriodicPulseParams->periodicPulseId, (uint32_t)tmpFiper, enable);
64376 + return E_OK;
64377 +}
64378 +
64379 +/*****************************************************************************/
64380 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId)
64381 +{
64382 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64383 +
64384 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64385 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64386 +
64387 + if (periodicPulseId >= FM_RTC_NUM_OF_PERIODIC_PULSES)
64388 + {
64389 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("Periodic pulse ID"));
64390 + }
64391 +
64392 + p_Rtc->periodicPulseParams[periodicPulseId].f_PeriodicPulseCallback = NULL;
64393 + fman_rtc_clear_periodic_pulse(p_Rtc->p_MemMap, periodicPulseId);
64394 +
64395 + return E_OK;
64396 +}
64397 +
64398 +/*****************************************************************************/
64399 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams)
64400 +{
64401 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64402 + bool enable = FALSE;
64403 +
64404 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64405 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64406 +
64407 + if (p_FmRtcExternalTriggerParams->externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
64408 + {
64409 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
64410 + }
64411 +
64412 + if (p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback)
64413 + {
64414 + p_Rtc->externalTriggerParams[p_FmRtcExternalTriggerParams->externalTriggerId].f_ExternalTriggerCallback = p_FmRtcExternalTriggerParams->f_ExternalTriggerCallback;
64415 + enable = TRUE;
64416 + }
64417 +
64418 + fman_rtc_set_ext_trigger(p_Rtc->p_MemMap, p_FmRtcExternalTriggerParams->externalTriggerId, enable, p_FmRtcExternalTriggerParams->usePulseAsInput);
64419 + return E_OK;
64420 +}
64421 +
64422 +/*****************************************************************************/
64423 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t externalTriggerId)
64424 +{
64425 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64426 +
64427 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64428 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64429 +
64430 + if (externalTriggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
64431 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External Trigger ID"));
64432 +
64433 + p_Rtc->externalTriggerParams[externalTriggerId].f_ExternalTriggerCallback = NULL;
64434 +
64435 + fman_rtc_clear_external_trigger(p_Rtc->p_MemMap, externalTriggerId);
64436 +
64437 + return E_OK;
64438 +}
64439 +
64440 +/*****************************************************************************/
64441 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
64442 + uint8_t triggerId,
64443 + uint64_t *p_TimeStamp)
64444 +{
64445 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64446 +
64447 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64448 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64449 +
64450 + if (triggerId >= FM_RTC_NUM_OF_EXT_TRIGGERS)
64451 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION, ("External trigger ID"));
64452 +
64453 + *p_TimeStamp = fman_rtc_get_trigger_stamp(p_Rtc->p_MemMap, triggerId)*p_Rtc->clockPeriodNanoSec;
64454 +
64455 + return E_OK;
64456 +}
64457 +
64458 +/*****************************************************************************/
64459 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts)
64460 +{
64461 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64462 +
64463 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64464 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64465 +
64466 + *p_Ts = fman_rtc_get_timer(p_Rtc->p_MemMap)*p_Rtc->clockPeriodNanoSec;
64467 +
64468 + return E_OK;
64469 +}
64470 +
64471 +/*****************************************************************************/
64472 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts)
64473 +{
64474 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64475 +
64476 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64477 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64478 +
64479 + do_div(ts, p_Rtc->clockPeriodNanoSec);
64480 + fman_rtc_set_timer(p_Rtc->p_MemMap, (int64_t)ts);
64481 +
64482 + return E_OK;
64483 +}
64484 +
64485 +/*****************************************************************************/
64486 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation)
64487 +{
64488 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64489 +
64490 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64491 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64492 +
64493 + *p_Compensation = fman_rtc_get_frequency_compensation(p_Rtc->p_MemMap);
64494 +
64495 + return E_OK;
64496 +}
64497 +
64498 +/*****************************************************************************/
64499 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation)
64500 +{
64501 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64502 +
64503 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64504 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64505 +
64506 + /* set the new freqCompensation */
64507 + fman_rtc_set_frequency_compensation(p_Rtc->p_MemMap, freqCompensation);
64508 +
64509 + return E_OK;
64510 +}
64511 +
64512 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
64513 +/*****************************************************************************/
64514 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events)
64515 +{
64516 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64517 +
64518 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64519 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64520 +
64521 + /* enable interrupt */
64522 + fman_rtc_enable_interupt(p_Rtc->p_MemMap, events);
64523 +
64524 + return E_OK;
64525 +}
64526 +
64527 +/*****************************************************************************/
64528 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events)
64529 +{
64530 + t_FmRtc *p_Rtc = (t_FmRtc *)h_FmRtc;
64531 +
64532 + SANITY_CHECK_RETURN_ERROR(p_Rtc, E_INVALID_HANDLE);
64533 + SANITY_CHECK_RETURN_ERROR(!p_Rtc->p_RtcDriverParam, E_INVALID_STATE);
64534 +
64535 + /* disable interrupt */
64536 + fman_rtc_disable_interupt(p_Rtc->p_MemMap, events);
64537 +
64538 + return E_OK;
64539 +}
64540 +#endif
64541 --- /dev/null
64542 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fm_rtc.h
64543 @@ -0,0 +1,96 @@
64544 +/*
64545 + * Copyright 2008-2012 Freescale Semiconductor Inc.
64546 + *
64547 + * Redistribution and use in source and binary forms, with or without
64548 + * modification, are permitted provided that the following conditions are met:
64549 + * * Redistributions of source code must retain the above copyright
64550 + * notice, this list of conditions and the following disclaimer.
64551 + * * Redistributions in binary form must reproduce the above copyright
64552 + * notice, this list of conditions and the following disclaimer in the
64553 + * documentation and/or other materials provided with the distribution.
64554 + * * Neither the name of Freescale Semiconductor nor the
64555 + * names of its contributors may be used to endorse or promote products
64556 + * derived from this software without specific prior written permission.
64557 + *
64558 + *
64559 + * ALTERNATIVELY, this software may be distributed under the terms of the
64560 + * GNU General Public License ("GPL") as published by the Free Software
64561 + * Foundation, either version 2 of that License or (at your option) any
64562 + * later version.
64563 + *
64564 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64565 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64566 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64567 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64568 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64569 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64570 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64571 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64572 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64573 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64574 + */
64575 +
64576 +
64577 +/******************************************************************************
64578 + @File fm_rtc.h
64579 +
64580 + @Description Memory map and internal definitions for FM RTC IEEE1588 Timer driver.
64581 +
64582 + @Cautions None
64583 +*//***************************************************************************/
64584 +
64585 +#ifndef __FM_RTC_H__
64586 +#define __FM_RTC_H__
64587 +
64588 +#include "std_ext.h"
64589 +#include "fm_rtc_ext.h"
64590 +
64591 +
64592 +#define __ERR_MODULE__ MODULE_FM_RTC
64593 +
64594 +/* General definitions */
64595 +
64596 +#define ACCUMULATOR_OVERFLOW ((uint64_t)(1LL << 32))
64597 +#define DEFAULT_OUTPUT_CLOCK_DIVISOR 0x00000002
64598 +#define DEFAULT_BYPASS FALSE
64599 +#define DEFAULT_CLOCK_PERIOD 1000
64600 +
64601 +
64602 +
64603 +typedef struct t_FmRtcAlarm
64604 +{
64605 + t_FmRtcExceptionsCallback *f_AlarmCallback;
64606 + bool clearOnExpiration;
64607 +} t_FmRtcAlarm;
64608 +
64609 +typedef struct t_FmRtcPeriodicPulse
64610 +{
64611 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback;
64612 +} t_FmRtcPeriodicPulse;
64613 +
64614 +typedef struct t_FmRtcExternalTrigger
64615 +{
64616 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback;
64617 +} t_FmRtcExternalTrigger;
64618 +
64619 +
64620 +/**************************************************************************//**
64621 + @Description RTC FM driver control structure.
64622 +*//***************************************************************************/
64623 +typedef struct t_FmRtc
64624 +{
64625 + t_Part *p_Part; /**< Pointer to the integration device */
64626 + t_Handle h_Fm;
64627 + t_Handle h_App; /**< Application handle */
64628 + struct rtc_regs *p_MemMap;
64629 + uint32_t clockPeriodNanoSec; /**< RTC clock period in nano-seconds (for FS mode) */
64630 + uint32_t srcClkFreqMhz;
64631 + uint16_t outputClockDivisor; /**< Output clock divisor (for FS mode) */
64632 + t_FmRtcAlarm alarmParams[FM_RTC_NUM_OF_ALARMS];
64633 + t_FmRtcPeriodicPulse periodicPulseParams[FM_RTC_NUM_OF_PERIODIC_PULSES];
64634 + t_FmRtcExternalTrigger externalTriggerParams[FM_RTC_NUM_OF_EXT_TRIGGERS];
64635 + struct rtc_cfg *p_RtcDriverParam; /**< RTC Driver parameters (for Init phase) */
64636 +} t_FmRtc;
64637 +
64638 +
64639 +#endif /* __FM_RTC_H__ */
64640 --- /dev/null
64641 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/Rtc/fman_rtc.c
64642 @@ -0,0 +1,334 @@
64643 +/*
64644 + * Copyright 2008-2013 Freescale Semiconductor Inc.
64645 + *
64646 + * Redistribution and use in source and binary forms, with or without
64647 + * modification, are permitted provided that the following conditions are met:
64648 + * * Redistributions of source code must retain the above copyright
64649 + * notice, this list of conditions and the following disclaimer.
64650 + * * Redistributions in binary form must reproduce the above copyright
64651 + * notice, this list of conditions and the following disclaimer in the
64652 + * documentation and/or other materials provided with the distribution.
64653 + * * Neither the name of Freescale Semiconductor nor the
64654 + * names of its contributors may be used to endorse or promote products
64655 + * derived from this software without specific prior written permission.
64656 + *
64657 + *
64658 + * ALTERNATIVELY, this software may be distributed under the terms of the
64659 + * GNU General Public License ("GPL") as published by the Free Software
64660 + * Foundation, either version 2 of that License or (at your option) any
64661 + * later version.
64662 + *
64663 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
64664 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
64665 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64666 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
64667 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
64668 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
64669 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
64670 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
64671 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64672 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64673 + */
64674 +
64675 +#include "fsl_fman_rtc.h"
64676 +
64677 +void fman_rtc_defconfig(struct rtc_cfg *cfg)
64678 +{
64679 + int i;
64680 + cfg->src_clk = DEFAULT_SRC_CLOCK;
64681 + cfg->invert_input_clk_phase = DEFAULT_INVERT_INPUT_CLK_PHASE;
64682 + cfg->invert_output_clk_phase = DEFAULT_INVERT_OUTPUT_CLK_PHASE;
64683 + cfg->pulse_realign = DEFAULT_PULSE_REALIGN;
64684 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_ALARMS; i++)
64685 + cfg->alarm_polarity[i] = DEFAULT_ALARM_POLARITY;
64686 + for (i = 0; i < FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS; i++)
64687 + cfg->trigger_polarity[i] = DEFAULT_TRIGGER_POLARITY;
64688 +}
64689 +
64690 +uint32_t fman_rtc_get_events(struct rtc_regs *regs)
64691 +{
64692 + return ioread32be(&regs->tmr_tevent);
64693 +}
64694 +
64695 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask)
64696 +{
64697 + return ioread32be(&regs->tmr_tevent) & ev_mask;
64698 +}
64699 +
64700 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs)
64701 +{
64702 + return ioread32be(&regs->tmr_temask);
64703 +}
64704 +
64705 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask)
64706 +{
64707 + iowrite32be(mask, &regs->tmr_temask);
64708 +}
64709 +
64710 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events)
64711 +{
64712 + iowrite32be(events, &regs->tmr_tevent);
64713 +}
64714 +
64715 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs)
64716 +{
64717 + uint32_t event;
64718 +
64719 + event = ioread32be(&regs->tmr_tevent);
64720 + event &= ioread32be(&regs->tmr_temask);
64721 +
64722 + if (event)
64723 + iowrite32be(event, &regs->tmr_tevent);
64724 + return event;
64725 +}
64726 +
64727 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs)
64728 +{
64729 + return ioread32be(&regs->tmr_add);
64730 +}
64731 +
64732 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val)
64733 +{
64734 + iowrite32be(val, &regs->tmr_add);
64735 +}
64736 +
64737 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t events)
64738 +{
64739 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) | events);
64740 +}
64741 +
64742 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t events)
64743 +{
64744 + fman_rtc_set_interrupt_mask(regs, fman_rtc_get_interrupt_mask(regs) & ~events);
64745 +}
64746 +
64747 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index, uint32_t val)
64748 +{
64749 + iowrite32be(val, &regs->tmr_alarm[index].tmr_alarm_l);
64750 +}
64751 +
64752 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val)
64753 +{
64754 + iowrite32be(val, &regs->tmr_fiper[index]);
64755 +}
64756 +
64757 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val)
64758 +{
64759 + iowrite32be((uint32_t)val, &regs->tmr_alarm[index].tmr_alarm_l);
64760 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_alarm[index].tmr_alarm_h);
64761 +}
64762 +
64763 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val)
64764 +{
64765 + iowrite32be((uint32_t)val, &regs->tmr_off_l);
64766 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_off_h);
64767 +}
64768 +
64769 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id)
64770 +{
64771 + uint64_t time;
64772 + /* TMR_CNT_L must be read first to get an accurate value */
64773 + time = (uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_l);
64774 + time |= ((uint64_t)ioread32be(&regs->tmr_etts[id].tmr_etts_h)
64775 + << 32);
64776 +
64777 + return time;
64778 +}
64779 +
64780 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs)
64781 +{
64782 + return ioread32be(&regs->tmr_ctrl);
64783 +}
64784 +
64785 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val)
64786 +{
64787 + iowrite32be(val, &regs->tmr_ctrl);
64788 +}
64789 +
64790 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs)
64791 +{
64792 + fman_rtc_set_timer_ctrl(regs, FMAN_RTC_TMR_CTRL_TMSR);
64793 + udelay(10);
64794 + fman_rtc_set_timer_ctrl(regs, 0);
64795 +}
64796 +
64797 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
64798 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
64799 + uint32_t freq_compensation, uint32_t output_clock_divisor)
64800 +{
64801 + uint32_t tmr_ctrl;
64802 + int i;
64803 +
64804 + fman_rtc_timers_soft_reset(regs);
64805 +
64806 + /* Set the source clock */
64807 + switch (cfg->src_clk) {
64808 + case E_FMAN_RTC_SOURCE_CLOCK_SYSTEM:
64809 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK;
64810 + break;
64811 + case E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR:
64812 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK;
64813 + break;
64814 + default:
64815 + /* Use a clock from the External TMR reference clock.*/
64816 + tmr_ctrl = FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK;
64817 + break;
64818 + }
64819 +
64820 + /* whatever period the user picked, the timestamp will advance in '1'
64821 + * every time the period passed. */
64822 + tmr_ctrl |= ((1 << FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT) &
64823 + FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK);
64824 +
64825 + if (cfg->invert_input_clk_phase)
64826 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_CIPH;
64827 + if (cfg->invert_output_clk_phase)
64828 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_COPH;
64829 +
64830 + for (i = 0; i < num_alarms; i++) {
64831 + if (cfg->alarm_polarity[i] ==
64832 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW)
64833 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ALMP1 >> i);
64834 + }
64835 +
64836 + for (i = 0; i < num_ext_triggers; i++)
64837 + if (cfg->trigger_polarity[i] ==
64838 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE)
64839 + tmr_ctrl |= (FMAN_RTC_TMR_CTRL_ETEP1 << i);
64840 +
64841 + if (!cfg->timer_slave_mode && cfg->bypass)
64842 + tmr_ctrl |= FMAN_RTC_TMR_CTRL_BYP;
64843 +
64844 + fman_rtc_set_timer_ctrl(regs, tmr_ctrl);
64845 + if (init_freq_comp)
64846 + fman_rtc_set_frequency_compensation(regs, freq_compensation);
64847 +
64848 + /* Clear TMR_ALARM registers */
64849 + for (i = 0; i < num_alarms; i++)
64850 + fman_rtc_set_timer_alarm(regs, i, 0xFFFFFFFFFFFFFFFFLL);
64851 +
64852 + /* Clear TMR_TEVENT */
64853 + fman_rtc_ack_event(regs, FMAN_RTC_TMR_TEVENT_ALL);
64854 +
64855 + /* Initialize TMR_TEMASK */
64856 + fman_rtc_set_interrupt_mask(regs, 0);
64857 +
64858 + /* Clear TMR_FIPER registers */
64859 + for (i = 0; i < num_fipers; i++)
64860 + fman_rtc_set_timer_fiper(regs, i, 0xFFFFFFFF);
64861 +
64862 + /* Initialize TMR_PRSC */
64863 + iowrite32be(output_clock_divisor, &regs->tmr_prsc);
64864 +
64865 + /* Clear TMR_OFF */
64866 + fman_rtc_set_timer_offset(regs, 0);
64867 +}
64868 +
64869 +bool fman_rtc_is_enabled(struct rtc_regs *regs)
64870 +{
64871 + return (bool)(fman_rtc_get_timer_ctrl(regs) & FMAN_RTC_TMR_CTRL_TE);
64872 +}
64873 +
64874 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock)
64875 +{
64876 + uint32_t tmr_ctrl = fman_rtc_get_timer_ctrl(regs);
64877 +
64878 + /* TODO check that no timestamping MACs are working in this stage. */
64879 + if (reset_clock) {
64880 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TMSR));
64881 +
64882 + udelay(10);
64883 + /* Clear TMR_OFF */
64884 + fman_rtc_set_timer_offset(regs, 0);
64885 + }
64886 +
64887 + fman_rtc_set_timer_ctrl(regs, (tmr_ctrl | FMAN_RTC_TMR_CTRL_TE));
64888 +}
64889 +
64890 +void fman_rtc_disable(struct rtc_regs *regs)
64891 +{
64892 + fman_rtc_set_timer_ctrl(regs, (fman_rtc_get_timer_ctrl(regs)
64893 + & ~(FMAN_RTC_TMR_CTRL_TE)));
64894 +}
64895 +
64896 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id)
64897 +{
64898 + uint32_t tmp_reg;
64899 + if (id == 0)
64900 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP1;
64901 + else
64902 + tmp_reg = FMAN_RTC_TMR_TEVENT_PP2;
64903 + fman_rtc_disable_interupt(regs, tmp_reg);
64904 +
64905 + tmp_reg = fman_rtc_get_timer_ctrl(regs);
64906 + if (tmp_reg & FMAN_RTC_TMR_CTRL_FS)
64907 + fman_rtc_set_timer_ctrl(regs, tmp_reg & ~FMAN_RTC_TMR_CTRL_FS);
64908 +
64909 + fman_rtc_set_timer_fiper(regs, id, 0xFFFFFFFF);
64910 +}
64911 +
64912 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id)
64913 +{
64914 + uint32_t tmpReg, tmp_ctrl;
64915 +
64916 + if (id == 0)
64917 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
64918 + else
64919 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
64920 + fman_rtc_disable_interupt(regs, tmpReg);
64921 +
64922 + if (id == 0)
64923 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
64924 + else
64925 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
64926 + tmp_ctrl = fman_rtc_get_timer_ctrl(regs);
64927 + if (tmp_ctrl & tmpReg)
64928 + fman_rtc_set_timer_ctrl(regs, tmp_ctrl & ~tmpReg);
64929 +}
64930 +
64931 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable)
64932 +{
64933 + uint32_t tmpReg;
64934 + fman_rtc_set_timer_alarm(regs, id, val);
64935 + if (enable) {
64936 + if (id == 0)
64937 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM1;
64938 + else
64939 + tmpReg = FMAN_RTC_TMR_TEVENT_ALM2;
64940 + fman_rtc_enable_interupt(regs, tmpReg);
64941 + }
64942 +}
64943 +
64944 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
64945 + bool enable)
64946 +{
64947 + uint32_t tmpReg;
64948 + fman_rtc_set_timer_fiper(regs, id, val);
64949 + if (enable) {
64950 + if (id == 0)
64951 + tmpReg = FMAN_RTC_TMR_TEVENT_PP1;
64952 + else
64953 + tmpReg = FMAN_RTC_TMR_TEVENT_PP2;
64954 + fman_rtc_enable_interupt(regs, tmpReg);
64955 + }
64956 +}
64957 +
64958 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
64959 + bool use_pulse_as_input)
64960 +{
64961 + uint32_t tmpReg;
64962 + if (enable) {
64963 + if (id == 0)
64964 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS1;
64965 + else
64966 + tmpReg = FMAN_RTC_TMR_TEVENT_ETS2;
64967 + fman_rtc_enable_interupt(regs, tmpReg);
64968 + }
64969 + if (use_pulse_as_input) {
64970 + if (id == 0)
64971 + tmpReg = FMAN_RTC_TMR_CTRL_PP1L;
64972 + else
64973 + tmpReg = FMAN_RTC_TMR_CTRL_PP2L;
64974 + fman_rtc_set_timer_ctrl(regs, fman_rtc_get_timer_ctrl(regs) | tmpReg);
64975 + }
64976 +}
64977 --- /dev/null
64978 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/Makefile
64979 @@ -0,0 +1,15 @@
64980 +#
64981 +# Makefile for the Freescale Ethernet controllers
64982 +#
64983 +ccflags-y += -DVERSION=\"\"
64984 +#
64985 +#Include netcomm SW specific definitions
64986 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
64987 +
64988 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
64989 +
64990 +ccflags-y += -I$(NCSW_FM_INC)
64991 +
64992 +obj-y += fsl-ncsw-sp.o
64993 +
64994 +fsl-ncsw-sp-objs := fm_sp.o fman_sp.o
64995 --- /dev/null
64996 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.c
64997 @@ -0,0 +1,757 @@
64998 +/*
64999 + * Copyright 2008-2012 Freescale Semiconductor Inc.
65000 + *
65001 + * Redistribution and use in source and binary forms, with or without
65002 + * modification, are permitted provided that the following conditions are met:
65003 + * * Redistributions of source code must retain the above copyright
65004 + * notice, this list of conditions and the following disclaimer.
65005 + * * Redistributions in binary form must reproduce the above copyright
65006 + * notice, this list of conditions and the following disclaimer in the
65007 + * documentation and/or other materials provided with the distribution.
65008 + * * Neither the name of Freescale Semiconductor nor the
65009 + * names of its contributors may be used to endorse or promote products
65010 + * derived from this software without specific prior written permission.
65011 + *
65012 + *
65013 + * ALTERNATIVELY, this software may be distributed under the terms of the
65014 + * GNU General Public License ("GPL") as published by the Free Software
65015 + * Foundation, either version 2 of that License or (at your option) any
65016 + * later version.
65017 + *
65018 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
65019 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65020 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
65021 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
65022 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65023 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
65024 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
65025 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65026 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
65027 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65028 + */
65029 +
65030 +
65031 +/******************************************************************************
65032 + @File fm_sp.c
65033 +
65034 + @Description FM PCD Storage profile ...
65035 +*//***************************************************************************/
65036 +
65037 +#include "std_ext.h"
65038 +#include "error_ext.h"
65039 +#include "string_ext.h"
65040 +#include "debug_ext.h"
65041 +#include "net_ext.h"
65042 +
65043 +#include "fm_vsp_ext.h"
65044 +#include "fm_sp.h"
65045 +#include "fm_common.h"
65046 +#include "fsl_fman_sp.h"
65047 +
65048 +
65049 +#if (DPAA_VERSION >= 11)
65050 +static t_Error CheckParamsGeneratedInternally(t_FmVspEntry *p_FmVspEntry)
65051 +{
65052 + t_Error err = E_OK;
65053 +
65054 + if ((err = FmSpCheckIntContextParams(&p_FmVspEntry->intContext))!= E_OK)
65055 + RETURN_ERROR(MAJOR, err, NO_MSG);
65056 + if ((err = FmSpCheckBufMargins(&p_FmVspEntry->bufMargins)) != E_OK)
65057 + RETURN_ERROR(MAJOR, err, NO_MSG);
65058 + return err;
65059 +
65060 +}
65061 +
65062 +static t_Error CheckParams(t_FmVspEntry *p_FmVspEntry)
65063 +{
65064 + t_Error err = E_OK;
65065 +
65066 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65067 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65068 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->h_Fm, E_INVALID_HANDLE);
65069 +
65070 + if ((err = FmSpCheckBufPoolsParams(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools,
65071 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools,
65072 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)) != E_OK)
65073 +
65074 + RETURN_ERROR(MAJOR, err, NO_MSG);
65075 +
65076 + if (p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset & ~FM_LIODN_OFFSET_MASK)
65077 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("liodnOffset is larger than %d", FM_LIODN_OFFSET_MASK+1));
65078 +
65079 + err = FmVSPCheckRelativeProfile(p_FmVspEntry->h_Fm,
65080 + p_FmVspEntry->portType,
65081 + p_FmVspEntry->portId,
65082 + p_FmVspEntry->relativeProfileId);
65083 +
65084 + return err;
65085 +}
65086 +#endif /* (DPAA_VERSION >= 11) */
65087 +
65088 +
65089 +/*****************************************************************************/
65090 +/* Inter-module API routines */
65091 +/*****************************************************************************/
65092 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools,
65093 + uint8_t *orderedArray,
65094 + uint16_t *sizesArray)
65095 +{
65096 + uint16_t bufSize = 0;
65097 + int i=0, j=0, k=0;
65098 +
65099 + /* First we copy the external buffers pools information to an ordered local array */
65100 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
65101 + {
65102 + /* get pool size */
65103 + bufSize = p_FmExtPools->extBufPool[i].size;
65104 +
65105 + /* keep sizes in an array according to poolId for direct access */
65106 + sizesArray[p_FmExtPools->extBufPool[i].id] = bufSize;
65107 +
65108 + /* save poolId in an ordered array according to size */
65109 + for (j=0;j<=i;j++)
65110 + {
65111 + /* this is the next free place in the array */
65112 + if (j==i)
65113 + orderedArray[i] = p_FmExtPools->extBufPool[i].id;
65114 + else
65115 + {
65116 + /* find the right place for this poolId */
65117 + if (bufSize < sizesArray[orderedArray[j]])
65118 + {
65119 + /* move the poolIds one place ahead to make room for this poolId */
65120 + for (k=i;k>j;k--)
65121 + orderedArray[k] = orderedArray[k-1];
65122 +
65123 + /* now k==j, this is the place for the new size */
65124 + orderedArray[k] = p_FmExtPools->extBufPool[i].id;
65125 + break;
65126 + }
65127 + }
65128 + }
65129 + }
65130 +}
65131 +
65132 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
65133 + t_FmBackupBmPools *p_FmBackupBmPools,
65134 + t_FmBufPoolDepletion *p_FmBufPoolDepletion)
65135 +{
65136 +
65137 + int i = 0, j = 0;
65138 + bool found;
65139 + uint8_t count = 0;
65140 +
65141 + if (p_FmExtPools)
65142 + {
65143 + if (p_FmExtPools->numOfPoolsUsed > FM_PORT_MAX_NUM_OF_EXT_POOLS)
65144 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numOfPoolsUsed can't be larger than %d", FM_PORT_MAX_NUM_OF_EXT_POOLS));
65145 +
65146 + for (i=0;i<p_FmExtPools->numOfPoolsUsed;i++)
65147 + {
65148 + if (p_FmExtPools->extBufPool[i].id >= BM_MAX_NUM_OF_POOLS)
65149 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].id can't be larger than %d", i, BM_MAX_NUM_OF_POOLS));
65150 + if (!p_FmExtPools->extBufPool[i].size)
65151 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("extBufPools.extBufPool[%d].size is 0", i));
65152 + }
65153 + }
65154 + if (!p_FmExtPools && (p_FmBackupBmPools || p_FmBufPoolDepletion))
65155 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("backupBmPools ot bufPoolDepletion can not be defined without external pools"));
65156 +
65157 + /* backup BM pools indication is valid only for some chip derivatives
65158 + (limited by the config routine) */
65159 + if (p_FmBackupBmPools)
65160 + {
65161 + if (p_FmBackupBmPools->numOfBackupPools >= p_FmExtPools->numOfPoolsUsed)
65162 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("p_BackupBmPools must be smaller than extBufPools.numOfPoolsUsed"));
65163 + found = FALSE;
65164 + for (i = 0;i<p_FmBackupBmPools->numOfBackupPools;i++)
65165 + {
65166 +
65167 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
65168 + {
65169 + if (p_FmBackupBmPools->poolIds[i] == p_FmExtPools->extBufPool[j].id)
65170 + {
65171 + found = TRUE;
65172 + break;
65173 + }
65174 + }
65175 + if (!found)
65176 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("All p_BackupBmPools.poolIds must be included in extBufPools.extBufPool[n].id"));
65177 + else
65178 + found = FALSE;
65179 + }
65180 + }
65181 +
65182 + /* up to extBufPools.numOfPoolsUsed pools may be defined */
65183 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->poolsGrpModeEnable)
65184 + {
65185 + if ((p_FmBufPoolDepletion->numOfPools > p_FmExtPools->numOfPoolsUsed))
65186 + 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));
65187 +
65188 + if (!p_FmBufPoolDepletion->numOfPools)
65189 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPoolsToConsider can not be 0 when poolsGrpModeEnable=TRUE"));
65190 +
65191 + found = FALSE;
65192 + count = 0;
65193 + /* for each pool that is in poolsToConsider, check if it is defined
65194 + in extBufPool */
65195 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
65196 + {
65197 + if (p_FmBufPoolDepletion->poolsToConsider[i])
65198 + {
65199 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
65200 + {
65201 + if (i == p_FmExtPools->extBufPool[j].id)
65202 + {
65203 + found = TRUE;
65204 + count++;
65205 + break;
65206 + }
65207 + }
65208 + if (!found)
65209 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
65210 + else
65211 + found = FALSE;
65212 + }
65213 + }
65214 + /* check that the number of pools that we have checked is equal to the number announced by the user */
65215 + if (count != p_FmBufPoolDepletion->numOfPools)
65216 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufPoolDepletion.numOfPools is larger than the number of pools defined."));
65217 + }
65218 +
65219 + if (p_FmBufPoolDepletion && p_FmBufPoolDepletion->singlePoolModeEnable)
65220 + {
65221 + /* calculate vector for number of pools depletion */
65222 + found = FALSE;
65223 + count = 0;
65224 + for (i=0;i<BM_MAX_NUM_OF_POOLS;i++)
65225 + {
65226 + if (p_FmBufPoolDepletion->poolsToConsiderForSingleMode[i])
65227 + {
65228 + for (j=0;j<p_FmExtPools->numOfPoolsUsed;j++)
65229 + {
65230 + if (i == p_FmExtPools->extBufPool[j].id)
65231 + {
65232 + found = TRUE;
65233 + count++;
65234 + break;
65235 + }
65236 + }
65237 + if (!found)
65238 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Pools selected for depletion are not used."));
65239 + else
65240 + found = FALSE;
65241 + }
65242 + }
65243 + if (!count)
65244 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("No pools defined for single buffer mode pool depletion."));
65245 + }
65246 +
65247 + return E_OK;
65248 +}
65249 +
65250 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy)
65251 +{
65252 + /* Check that divisible by 16 and not larger than 240 */
65253 + if (p_FmSpIntContextDataCopy->intContextOffset >MAX_INT_OFFSET)
65254 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset can't be larger than %d", MAX_INT_OFFSET));
65255 + if (p_FmSpIntContextDataCopy->intContextOffset % OFFSET_UNITS)
65256 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.intContextOffset has to be divisible by %d", OFFSET_UNITS));
65257 +
65258 + /* check that ic size+ic internal offset, does not exceed ic block size */
65259 + if (p_FmSpIntContextDataCopy->size + p_FmSpIntContextDataCopy->intContextOffset > MAX_IC_SIZE)
65260 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size + intContext.intContextOffset has to be smaller than %d", MAX_IC_SIZE));
65261 + /* Check that divisible by 16 and not larger than 256 */
65262 + if (p_FmSpIntContextDataCopy->size % OFFSET_UNITS)
65263 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.size has to be divisible by %d", OFFSET_UNITS));
65264 +
65265 + /* Check that divisible by 16 and not larger than 4K */
65266 + if (p_FmSpIntContextDataCopy->extBufOffset > MAX_EXT_OFFSET)
65267 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset can't be larger than %d", MAX_EXT_OFFSET));
65268 + if (p_FmSpIntContextDataCopy->extBufOffset % OFFSET_UNITS)
65269 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("intContext.extBufOffset has to be divisible by %d", OFFSET_UNITS));
65270 +
65271 + return E_OK;
65272 +}
65273 +
65274 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins)
65275 +{
65276 + /* Check the margin definition */
65277 + if (p_FmSpBufMargins->startMargins > MAX_EXT_BUFFER_OFFSET)
65278 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.startMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
65279 + if (p_FmSpBufMargins->endMargins > MAX_EXT_BUFFER_OFFSET)
65280 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("bufMargins.endMargins can't be larger than %d", MAX_EXT_BUFFER_OFFSET));
65281 +
65282 + return E_OK;
65283 +}
65284 +
65285 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy,
65286 + t_FmBufferPrefixContent *p_BufferPrefixContent,
65287 + t_FmSpBufMargins *p_FmSpBufMargins,
65288 + t_FmSpBufferOffsets *p_FmSpBufferOffsets,
65289 + uint8_t *internalBufferOffset)
65290 +{
65291 + uint32_t tmp;
65292 +
65293 + SANITY_CHECK_RETURN_ERROR(p_FmSpIntContextDataCopy, E_INVALID_VALUE);
65294 + ASSERT_COND(p_FmSpIntContextDataCopy);
65295 + ASSERT_COND(p_BufferPrefixContent);
65296 + ASSERT_COND(p_FmSpBufMargins);
65297 + ASSERT_COND(p_FmSpBufferOffsets);
65298 +
65299 + /* Align start of internal context data to 16 byte */
65300 + p_FmSpIntContextDataCopy->extBufOffset =
65301 + (uint16_t)((p_BufferPrefixContent->privDataSize & (OFFSET_UNITS-1)) ?
65302 + ((p_BufferPrefixContent->privDataSize + OFFSET_UNITS) & ~(uint16_t)(OFFSET_UNITS-1)) :
65303 + p_BufferPrefixContent->privDataSize);
65304 +
65305 + /* Translate margin and intContext params to FM parameters */
65306 + /* Initialize with illegal value. Later we'll set legal values. */
65307 + p_FmSpBufferOffsets->prsResultOffset = (uint32_t)ILLEGAL_BASE;
65308 + p_FmSpBufferOffsets->timeStampOffset = (uint32_t)ILLEGAL_BASE;
65309 + p_FmSpBufferOffsets->hashResultOffset= (uint32_t)ILLEGAL_BASE;
65310 + p_FmSpBufferOffsets->pcdInfoOffset = (uint32_t)ILLEGAL_BASE;
65311 +
65312 + /* Internally the driver supports 4 options
65313 + 1. prsResult/timestamp/hashResult selection (in fact 8 options, but for simplicity we'll
65314 + relate to it as 1).
65315 + 2. All IC context (from AD) not including debug.*/
65316 +
65317 + /* This 'if' covers option 2. We copy from beginning of context. */
65318 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
65319 + {
65320 + p_FmSpIntContextDataCopy->size = 128; /* must be aligned to 16 */
65321 + /* Start copying data after 16 bytes (FD) from the beginning of the internal context */
65322 + p_FmSpIntContextDataCopy->intContextOffset = 16;
65323 +
65324 + if (p_BufferPrefixContent->passAllOtherPCDInfo)
65325 + p_FmSpBufferOffsets->pcdInfoOffset = p_FmSpIntContextDataCopy->extBufOffset;
65326 + if (p_BufferPrefixContent->passPrsResult)
65327 + p_FmSpBufferOffsets->prsResultOffset =
65328 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 16);
65329 + if (p_BufferPrefixContent->passTimeStamp)
65330 + p_FmSpBufferOffsets->timeStampOffset =
65331 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 48);
65332 + if (p_BufferPrefixContent->passHashResult)
65333 + p_FmSpBufferOffsets->hashResultOffset =
65334 + (uint32_t)(p_FmSpIntContextDataCopy->extBufOffset + 56);
65335 + }
65336 + else
65337 + {
65338 + /* This case covers the options under 1 */
65339 + /* Copy size must be in 16-byte granularity. */
65340 + p_FmSpIntContextDataCopy->size =
65341 + (uint16_t)((p_BufferPrefixContent->passPrsResult ? 32 : 0) +
65342 + ((p_BufferPrefixContent->passTimeStamp ||
65343 + p_BufferPrefixContent->passHashResult) ? 16 : 0));
65344 +
65345 + /* Align start of internal context data to 16 byte */
65346 + p_FmSpIntContextDataCopy->intContextOffset =
65347 + (uint8_t)(p_BufferPrefixContent->passPrsResult ? 32 :
65348 + ((p_BufferPrefixContent->passTimeStamp ||
65349 + p_BufferPrefixContent->passHashResult) ? 64 : 0));
65350 +
65351 + if (p_BufferPrefixContent->passPrsResult)
65352 + p_FmSpBufferOffsets->prsResultOffset = p_FmSpIntContextDataCopy->extBufOffset;
65353 + if (p_BufferPrefixContent->passTimeStamp)
65354 + p_FmSpBufferOffsets->timeStampOffset = p_BufferPrefixContent->passPrsResult ?
65355 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult)) :
65356 + p_FmSpIntContextDataCopy->extBufOffset;
65357 + if (p_BufferPrefixContent->passHashResult)
65358 + /* If PR is not requested, whether TS is requested or not, IC will be copied from TS */
65359 + p_FmSpBufferOffsets->hashResultOffset = p_BufferPrefixContent->passPrsResult ?
65360 + (p_FmSpIntContextDataCopy->extBufOffset + sizeof(t_FmPrsResult) + 8) :
65361 + p_FmSpIntContextDataCopy->extBufOffset + 8;
65362 + }
65363 +
65364 + if (p_FmSpIntContextDataCopy->size)
65365 + p_FmSpBufMargins->startMargins =
65366 + (uint16_t)(p_FmSpIntContextDataCopy->extBufOffset +
65367 + p_FmSpIntContextDataCopy->size);
65368 + else
65369 + /* No Internal Context passing, STartMargin is immediately after privateInfo */
65370 + p_FmSpBufMargins->startMargins = p_BufferPrefixContent->privDataSize;
65371 +
65372 + /* save extra space for manip in both external and internal buffers */
65373 + if (p_BufferPrefixContent->manipExtraSpace)
65374 + {
65375 + uint8_t extraSpace;
65376 +#ifdef FM_CAPWAP_SUPPORT
65377 + if ((p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE) >= 256)
65378 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
65379 + ("p_BufferPrefixContent->manipExtraSpace should be less than %d",
65380 + 256-CAPWAP_FRAG_EXTRA_SPACE));
65381 + extraSpace = (uint8_t)(p_BufferPrefixContent->manipExtraSpace + CAPWAP_FRAG_EXTRA_SPACE);
65382 +#else
65383 + extraSpace = p_BufferPrefixContent->manipExtraSpace;
65384 +#endif /* FM_CAPWAP_SUPPORT */
65385 + p_FmSpBufferOffsets->manipOffset = p_FmSpBufMargins->startMargins;
65386 + p_FmSpBufMargins->startMargins += extraSpace;
65387 + *internalBufferOffset = extraSpace;
65388 + }
65389 +
65390 + /* align data start */
65391 + tmp = (uint32_t)(p_FmSpBufMargins->startMargins % p_BufferPrefixContent->dataAlign);
65392 + if (tmp)
65393 + p_FmSpBufMargins->startMargins += (p_BufferPrefixContent->dataAlign-tmp);
65394 + p_FmSpBufferOffsets->dataOffset = p_FmSpBufMargins->startMargins;
65395 +
65396 + return E_OK;
65397 +}
65398 +/*********************** End of inter-module routines ************************/
65399 +
65400 +
65401 +#if (DPAA_VERSION >= 11)
65402 +/*****************************************************************************/
65403 +/* API routines */
65404 +/*****************************************************************************/
65405 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams)
65406 +{
65407 + t_FmVspEntry *p_FmVspEntry = NULL;
65408 + struct fm_storage_profile_params fm_vsp_params;
65409 +
65410 + p_FmVspEntry = (t_FmVspEntry *)XX_Malloc(sizeof(t_FmVspEntry));
65411 + if (!p_FmVspEntry)
65412 + {
65413 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
65414 + return NULL;
65415 + }
65416 + memset(p_FmVspEntry, 0, sizeof(t_FmVspEntry));
65417 +
65418 + p_FmVspEntry->p_FmVspEntryDriverParams = (t_FmVspEntryDriverParams *)XX_Malloc(sizeof(t_FmVspEntryDriverParams));
65419 + if (!p_FmVspEntry->p_FmVspEntryDriverParams)
65420 + {
65421 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("p_StorageProfile allocation failed"));
65422 + XX_Free(p_FmVspEntry);
65423 + return NULL;
65424 + }
65425 + memset(p_FmVspEntry->p_FmVspEntryDriverParams, 0, sizeof(t_FmVspEntryDriverParams));
65426 + fman_vsp_defconfig(&fm_vsp_params);
65427 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = fm_vsp_params.header_cache_attr;
65428 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = fm_vsp_params.int_context_cache_attr;
65429 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = fm_vsp_params.scatter_gather_cache_attr;
65430 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = fm_vsp_params.dma_swap_data;
65431 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = fm_vsp_params.dma_write_optimize;
65432 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = fm_vsp_params.no_scather_gather;
65433 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.privDataSize = DEFAULT_FM_SP_bufferPrefixContent_privDataSize;
65434 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passPrsResult= DEFAULT_FM_SP_bufferPrefixContent_passPrsResult;
65435 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passTimeStamp= DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
65436 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.passAllOtherPCDInfo
65437 + = DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp;
65438 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
65439 + p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset = p_FmVspParams->liodnOffset;
65440 +
65441 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools, &p_FmVspParams->extBufPools, sizeof(t_FmExtPools));
65442 + p_FmVspEntry->h_Fm = p_FmVspParams->h_Fm;
65443 + p_FmVspEntry->portType = p_FmVspParams->portParams.portType;
65444 + p_FmVspEntry->portId = p_FmVspParams->portParams.portId;
65445 +
65446 + p_FmVspEntry->relativeProfileId = p_FmVspParams->relativeProfileId;
65447 +
65448 + return p_FmVspEntry;
65449 +}
65450 +
65451 +t_Error FM_VSP_Init(t_Handle h_FmVsp)
65452 +{
65453 +
65454 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
65455 + struct fm_storage_profile_params fm_vsp_params;
65456 + uint8_t orderedArray[FM_PORT_MAX_NUM_OF_EXT_POOLS];
65457 + uint16_t sizesArray[BM_MAX_NUM_OF_POOLS];
65458 + t_Error err;
65459 + uint16_t absoluteProfileId = 0;
65460 + int i = 0;
65461 +
65462 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65463 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams,E_INVALID_HANDLE);
65464 +
65465 + CHECK_INIT_PARAMETERS(p_FmVspEntry, CheckParams);
65466 +
65467 + memset(&orderedArray, 0, sizeof(uint8_t) * FM_PORT_MAX_NUM_OF_EXT_POOLS);
65468 + memset(&sizesArray, 0, sizeof(uint16_t) * BM_MAX_NUM_OF_POOLS);
65469 +
65470 + err = FmSpBuildBufferStructure(&p_FmVspEntry->intContext,
65471 + &p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent,
65472 + &p_FmVspEntry->bufMargins,
65473 + &p_FmVspEntry->bufferOffsets,
65474 + &p_FmVspEntry->internalBufferOffset);
65475 + if (err != E_OK)
65476 + RETURN_ERROR(MAJOR, err, NO_MSG);
65477 +
65478 +
65479 + err = CheckParamsGeneratedInternally(p_FmVspEntry);
65480 + if (err != E_OK)
65481 + RETURN_ERROR(MAJOR, err, NO_MSG);
65482 +
65483 +
65484 + p_FmVspEntry->p_FmSpRegsBase =
65485 + (struct fm_pcd_storage_profile_regs *)FmGetVSPBaseAddr(p_FmVspEntry->h_Fm);
65486 + if (!p_FmVspEntry->p_FmSpRegsBase)
65487 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("impossible to initialize SpRegsBase"));
65488 +
65489 + /* order external buffer pools in ascending order of buffer pools sizes */
65490 + FmSpSetBufPoolsInAscOrderOfBufSizes(&(p_FmVspEntry->p_FmVspEntryDriverParams)->extBufPools,
65491 + orderedArray,
65492 + sizesArray);
65493 +
65494 + p_FmVspEntry->extBufPools.numOfPoolsUsed =
65495 + p_FmVspEntry->p_FmVspEntryDriverParams->extBufPools.numOfPoolsUsed;
65496 + for (i = 0; i < p_FmVspEntry->extBufPools.numOfPoolsUsed; i++)
65497 + {
65498 + p_FmVspEntry->extBufPools.extBufPool[i].id = orderedArray[i];
65499 + p_FmVspEntry->extBufPools.extBufPool[i].size = sizesArray[orderedArray[i]];
65500 + }
65501 +
65502 + /* on user responsibility to fill it according requirement */
65503 + memset(&fm_vsp_params, 0, sizeof(struct fm_storage_profile_params));
65504 + fm_vsp_params.dma_swap_data = p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData;
65505 + fm_vsp_params.int_context_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr;
65506 + fm_vsp_params.header_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr;
65507 + fm_vsp_params.scatter_gather_cache_attr = p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr;
65508 + fm_vsp_params.dma_write_optimize = p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize;
65509 + fm_vsp_params.liodn_offset = p_FmVspEntry->p_FmVspEntryDriverParams->liodnOffset;
65510 + fm_vsp_params.no_scather_gather = p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather;
65511 +
65512 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
65513 + {
65514 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = TRUE;
65515 + fm_vsp_params.buf_pool_depletion.pools_grp_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsGrpModeEnable;
65516 + fm_vsp_params.buf_pool_depletion.num_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->numOfPools;
65517 + fm_vsp_params.buf_pool_depletion.pools_to_consider = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsider;
65518 + fm_vsp_params.buf_pool_depletion.single_pool_mode_enable = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->singlePoolModeEnable;
65519 + fm_vsp_params.buf_pool_depletion.pools_to_consider_for_single_mode = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->poolsToConsiderForSingleMode;
65520 + fm_vsp_params.buf_pool_depletion.has_pfc_priorities = TRUE;
65521 + fm_vsp_params.buf_pool_depletion.pfc_priorities_en = p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion->pfcPrioritiesEn;
65522 + }
65523 + else
65524 + fm_vsp_params.buf_pool_depletion.buf_pool_depletion_enabled = FALSE;
65525 +
65526 + if (p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
65527 + {
65528 + fm_vsp_params.backup_pools.num_backup_pools = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->numOfBackupPools;
65529 + fm_vsp_params.backup_pools.pool_ids = p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools->poolIds;
65530 + }
65531 + else
65532 + fm_vsp_params.backup_pools.num_backup_pools = 0;
65533 +
65534 + fm_vsp_params.fm_ext_pools.num_pools_used = p_FmVspEntry->extBufPools.numOfPoolsUsed;
65535 + fm_vsp_params.fm_ext_pools.ext_buf_pool = (struct fman_ext_pool_params*)&p_FmVspEntry->extBufPools.extBufPool;
65536 + fm_vsp_params.buf_margins = (struct fman_sp_buf_margins*)&p_FmVspEntry->bufMargins;
65537 + fm_vsp_params.int_context = (struct fman_sp_int_context_data_copy*)&p_FmVspEntry->intContext;
65538 +
65539 + /* no check on err - it was checked earlier */
65540 + FmVSPGetAbsoluteProfileId(p_FmVspEntry->h_Fm,
65541 + p_FmVspEntry->portType,
65542 + p_FmVspEntry->portId,
65543 + p_FmVspEntry->relativeProfileId,
65544 + &absoluteProfileId);
65545 +
65546 + ASSERT_COND(p_FmVspEntry->p_FmSpRegsBase);
65547 + ASSERT_COND(fm_vsp_params.int_context);
65548 + ASSERT_COND(fm_vsp_params.buf_margins);
65549 + ASSERT_COND((absoluteProfileId <= FM_VSP_MAX_NUM_OF_ENTRIES));
65550 +
65551 + /* Set all registers related to VSP */
65552 + 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);
65553 +
65554 + p_FmVspEntry->absoluteSpId = absoluteProfileId;
65555 +
65556 + if (p_FmVspEntry->p_FmVspEntryDriverParams)
65557 + XX_Free(p_FmVspEntry->p_FmVspEntryDriverParams);
65558 + p_FmVspEntry->p_FmVspEntryDriverParams = NULL;
65559 +
65560 + return E_OK;
65561 +}
65562 +
65563 +t_Error FM_VSP_Free(t_Handle h_FmVsp)
65564 +{
65565 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry *)h_FmVsp;
65566 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
65567 + XX_Free(p_FmVspEntry);
65568 + return E_OK;
65569 +}
65570 +
65571 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp, t_FmBufferPrefixContent *p_FmBufferPrefixContent)
65572 +{
65573 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65574 +
65575 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65576 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65577 +
65578 + memcpy(&p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent, p_FmBufferPrefixContent, sizeof(t_FmBufferPrefixContent));
65579 + /* if dataAlign was not initialized by user, we return to driver's default */
65580 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign)
65581 + p_FmVspEntry->p_FmVspEntryDriverParams->bufferPrefixContent.dataAlign = DEFAULT_FM_SP_bufferPrefixContent_dataAlign;
65582 +
65583 + return E_OK;
65584 +}
65585 +
65586 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData)
65587 +{
65588 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65589 +
65590 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65591 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65592 +
65593 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaSwapData = swapData;
65594 +
65595 + return E_OK;
65596 +}
65597 +
65598 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp, e_FmDmaCacheOption intContextCacheAttr)
65599 +{
65600 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65601 +
65602 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65603 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65604 +
65605 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaIntContextCacheAttr = intContextCacheAttr;
65606 +
65607 + return E_OK;
65608 +}
65609 +
65610 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr)
65611 +{
65612 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65613 +
65614 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65615 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65616 +
65617 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaHeaderCacheAttr = headerCacheAttr;
65618 +
65619 + return E_OK;
65620 +}
65621 +
65622 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp, e_FmDmaCacheOption scatterGatherCacheAttr)
65623 +{
65624 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65625 +
65626 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65627 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65628 +
65629 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaScatterGatherCacheAttr = scatterGatherCacheAttr;
65630 +
65631 + return E_OK;
65632 +}
65633 +
65634 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize)
65635 +{
65636 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65637 +
65638 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65639 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65640 +
65641 +
65642 + p_FmVspEntry->p_FmVspEntryDriverParams->dmaWriteOptimize = optimize;
65643 +
65644 + return E_OK;
65645 +}
65646 +
65647 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather)
65648 +{
65649 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65650 +
65651 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry, E_INVALID_HANDLE);
65652 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65653 +
65654 +
65655 + p_FmVspEntry->p_FmVspEntryDriverParams->noScatherGather = noScatherGather;
65656 +
65657 + return E_OK;
65658 +}
65659 +
65660 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion)
65661 +{
65662 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65663 +
65664 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
65665 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65666 + SANITY_CHECK_RETURN_ERROR(p_BufPoolDepletion, E_INVALID_HANDLE);
65667 +
65668 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion = (t_FmBufPoolDepletion *)XX_Malloc(sizeof(t_FmBufPoolDepletion));
65669 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion)
65670 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BufPoolDepletion allocation failed"));
65671 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BufPoolDepletion, p_BufPoolDepletion, sizeof(t_FmBufPoolDepletion));
65672 +
65673 + return E_OK;
65674 +}
65675 +
65676 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools)
65677 +{
65678 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65679 +
65680 + SANITY_CHECK_RETURN_ERROR(h_FmVsp, E_INVALID_HANDLE);
65681 + SANITY_CHECK_RETURN_ERROR(p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_HANDLE);
65682 + SANITY_CHECK_RETURN_ERROR(p_BackupBmPools, E_INVALID_HANDLE);
65683 +
65684 + p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools = (t_FmBackupBmPools *)XX_Malloc(sizeof(t_FmBackupBmPools));
65685 + if (!p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools)
65686 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("p_BackupBmPools allocation failed"));
65687 + memcpy(p_FmVspEntry->p_FmVspEntryDriverParams->p_BackupBmPools, p_BackupBmPools, sizeof(t_FmBackupBmPools));
65688 +
65689 + return E_OK;
65690 +}
65691 +
65692 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp)
65693 +{
65694 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65695 +
65696 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, 0);
65697 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, 0);
65698 +
65699 + return p_FmVspEntry->bufferOffsets.dataOffset;
65700 +}
65701 +
65702 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data)
65703 +{
65704 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65705 +
65706 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
65707 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
65708 +
65709 + if (p_FmVspEntry->bufferOffsets.pcdInfoOffset == ILLEGAL_BASE)
65710 + return NULL;
65711 +
65712 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.pcdInfoOffset);
65713 +}
65714 +
65715 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data)
65716 +{
65717 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65718 +
65719 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
65720 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
65721 +
65722 + if (p_FmVspEntry->bufferOffsets.prsResultOffset == ILLEGAL_BASE)
65723 + return NULL;
65724 +
65725 + return (t_FmPrsResult *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.prsResultOffset);
65726 +}
65727 +
65728 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data)
65729 +{
65730 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65731 +
65732 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
65733 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
65734 +
65735 + if (p_FmVspEntry->bufferOffsets.timeStampOffset == ILLEGAL_BASE)
65736 + return NULL;
65737 +
65738 + return (uint64_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.timeStampOffset);
65739 +}
65740 +
65741 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data)
65742 +{
65743 + t_FmVspEntry *p_FmVspEntry = (t_FmVspEntry*)h_FmVsp;
65744 +
65745 + SANITY_CHECK_RETURN_VALUE(p_FmVspEntry, E_INVALID_HANDLE, NULL);
65746 + SANITY_CHECK_RETURN_VALUE(!p_FmVspEntry->p_FmVspEntryDriverParams, E_INVALID_STATE, NULL);
65747 +
65748 + if (p_FmVspEntry->bufferOffsets.hashResultOffset == ILLEGAL_BASE)
65749 + return NULL;
65750 +
65751 + return (uint8_t *)PTR_MOVE(p_Data, p_FmVspEntry->bufferOffsets.hashResultOffset);
65752 +}
65753 +
65754 +#endif /* (DPAA_VERSION >= 11) */
65755 --- /dev/null
65756 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fm_sp.h
65757 @@ -0,0 +1,85 @@
65758 +/*
65759 + * Copyright 2008-2012 Freescale Semiconductor Inc.
65760 + *
65761 + * Redistribution and use in source and binary forms, with or without
65762 + * modification, are permitted provided that the following conditions are met:
65763 + * * Redistributions of source code must retain the above copyright
65764 + * notice, this list of conditions and the following disclaimer.
65765 + * * Redistributions in binary form must reproduce the above copyright
65766 + * notice, this list of conditions and the following disclaimer in the
65767 + * documentation and/or other materials provided with the distribution.
65768 + * * Neither the name of Freescale Semiconductor nor the
65769 + * names of its contributors may be used to endorse or promote products
65770 + * derived from this software without specific prior written permission.
65771 + *
65772 + *
65773 + * ALTERNATIVELY, this software may be distributed under the terms of the
65774 + * GNU General Public License ("GPL") as published by the Free Software
65775 + * Foundation, either version 2 of that License or (at your option) any
65776 + * later version.
65777 + *
65778 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
65779 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65780 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
65781 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
65782 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65783 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
65784 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
65785 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65786 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
65787 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65788 + */
65789 +
65790 +
65791 +/******************************************************************************
65792 + @File fm_sp.h
65793 +
65794 + @Description FM SP ...
65795 +*//***************************************************************************/
65796 +#ifndef __FM_SP_H
65797 +#define __FM_SP_H
65798 +
65799 +#include "std_ext.h"
65800 +#include "error_ext.h"
65801 +#include "list_ext.h"
65802 +
65803 +#include "fm_sp_common.h"
65804 +#include "fm_common.h"
65805 +
65806 +
65807 +#define __ERR_MODULE__ MODULE_FM_SP
65808 +
65809 +typedef struct {
65810 + t_FmBufferPrefixContent bufferPrefixContent;
65811 + e_FmDmaSwapOption dmaSwapData;
65812 + e_FmDmaCacheOption dmaIntContextCacheAttr;
65813 + e_FmDmaCacheOption dmaHeaderCacheAttr;
65814 + e_FmDmaCacheOption dmaScatterGatherCacheAttr;
65815 + bool dmaWriteOptimize;
65816 + uint16_t liodnOffset;
65817 + bool noScatherGather;
65818 + t_FmBufPoolDepletion *p_BufPoolDepletion;
65819 + t_FmBackupBmPools *p_BackupBmPools;
65820 + t_FmExtPools extBufPools;
65821 +} t_FmVspEntryDriverParams;
65822 +
65823 +typedef struct {
65824 + bool valid;
65825 + volatile bool lock;
65826 + uint8_t pointedOwners;
65827 + uint16_t absoluteSpId;
65828 + uint8_t internalBufferOffset;
65829 + t_FmSpBufMargins bufMargins;
65830 + t_FmSpIntContextDataCopy intContext;
65831 + t_FmSpBufferOffsets bufferOffsets;
65832 + t_Handle h_Fm;
65833 + e_FmPortType portType; /**< Port type */
65834 + uint8_t portId; /**< Port Id - relative to type */
65835 + uint8_t relativeProfileId;
65836 + struct fm_pcd_storage_profile_regs *p_FmSpRegsBase;
65837 + t_FmExtPools extBufPools;
65838 + t_FmVspEntryDriverParams *p_FmVspEntryDriverParams;
65839 +} t_FmVspEntry;
65840 +
65841 +
65842 +#endif /* __FM_SP_H */
65843 --- /dev/null
65844 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/SP/fman_sp.c
65845 @@ -0,0 +1,197 @@
65846 +/*
65847 + * Copyright 2013 Freescale Semiconductor Inc.
65848 + *
65849 + * Redistribution and use in source and binary forms, with or without
65850 + * modification, are permitted provided that the following conditions are met:
65851 + * * Redistributions of source code must retain the above copyright
65852 + * notice, this list of conditions and the following disclaimer.
65853 + * * Redistributions in binary form must reproduce the above copyright
65854 + * notice, this list of conditions and the following disclaimer in the
65855 + * documentation and/or other materials provided with the distribution.
65856 + * * Neither the name of Freescale Semiconductor nor the
65857 + * names of its contributors may be used to endorse or promote products
65858 + * derived from this software without specific prior written permission.
65859 + *
65860 + *
65861 + * ALTERNATIVELY, this software may be distributed under the terms of the
65862 + * GNU General Public License ("GPL") as published by the Free Software
65863 + * Foundation, either version 2 of that License or (at your option) any
65864 + * later version.
65865 + *
65866 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
65867 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
65868 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
65869 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
65870 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65871 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
65872 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
65873 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65874 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
65875 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65876 + */
65877 +
65878 +#include "fsl_fman_sp.h"
65879 +
65880 +
65881 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
65882 + uint16_t index)
65883 +{
65884 + struct fm_pcd_storage_profile_regs *sp_regs;
65885 + sp_regs = &regs[index];
65886 + return ioread32be(&sp_regs->fm_sp_acnt);
65887 +}
65888 +
65889 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
65890 + uint16_t index, uint32_t value)
65891 +{
65892 + struct fm_pcd_storage_profile_regs *sp_regs;
65893 + sp_regs = &regs[index];
65894 + iowrite32be(value, &sp_regs->fm_sp_acnt);
65895 +}
65896 +
65897 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg)
65898 +{
65899 + cfg->dma_swap_data =
65900 + DEFAULT_FMAN_SP_DMA_SWAP_DATA;
65901 + cfg->int_context_cache_attr =
65902 + DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR;
65903 + cfg->header_cache_attr =
65904 + DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR;
65905 + cfg->scatter_gather_cache_attr =
65906 + DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR;
65907 + cfg->dma_write_optimize =
65908 + DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE;
65909 + cfg->no_scather_gather =
65910 + DEFAULT_FMAN_SP_NO_SCATTER_GATHER;
65911 +}
65912 +
65913 +static inline uint32_t calc_vec_dep(int max_pools, bool *pools,
65914 + struct fman_ext_pools *ext_buf_pools, uint32_t mask)
65915 +{
65916 + int i, j;
65917 + uint32_t vector = 0;
65918 + for (i = 0; i < max_pools; i++)
65919 + if (pools[i])
65920 + for (j = 0; j < ext_buf_pools->num_pools_used; j++)
65921 + if (i == ext_buf_pools->ext_buf_pool[j].id) {
65922 + vector |= mask >> j;
65923 + break;
65924 + }
65925 + return vector;
65926 +}
65927 +
65928 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
65929 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
65930 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
65931 + int max_num_of_pfc_priorities)
65932 +{
65933 + int i = 0, j = 0;
65934 + struct fm_pcd_storage_profile_regs *sp_regs;
65935 + uint32_t tmp_reg, vector;
65936 + struct fman_ext_pools *ext_buf_pools = &fm_vsp_params->fm_ext_pools;
65937 + struct fman_buf_pool_depletion *buf_pool_depletion =
65938 + &fm_vsp_params->buf_pool_depletion;
65939 + struct fman_backup_bm_pools *backup_pools =
65940 + &fm_vsp_params->backup_pools;
65941 + struct fman_sp_int_context_data_copy *int_context_data_copy =
65942 + fm_vsp_params->int_context;
65943 + struct fman_sp_buf_margins *external_buffer_margins =
65944 + fm_vsp_params->buf_margins;
65945 + bool no_scather_gather = fm_vsp_params->no_scather_gather;
65946 + uint16_t liodn_offset = fm_vsp_params->liodn_offset;
65947 +
65948 + sp_regs = &regs[index];
65949 +
65950 + /* fill external buffers manager pool information register*/
65951 + for (i = 0; i < ext_buf_pools->num_pools_used; i++) {
65952 + tmp_reg = FMAN_SP_EXT_BUF_POOL_VALID |
65953 + FMAN_SP_EXT_BUF_POOL_EN_COUNTER;
65954 + tmp_reg |= ((uint32_t)ext_buf_pools->ext_buf_pool[i].id <<
65955 + FMAN_SP_EXT_BUF_POOL_ID_SHIFT);
65956 + tmp_reg |= ext_buf_pools->ext_buf_pool[i].size;
65957 + /* functionality available only for some deriviatives
65958 + (limited by config) */
65959 + for (j = 0; j < backup_pools->num_backup_pools; j++)
65960 + if (ext_buf_pools->ext_buf_pool[i].id ==
65961 + backup_pools->pool_ids[j]) {
65962 + tmp_reg |= FMAN_SP_EXT_BUF_POOL_BACKUP;
65963 + break;
65964 + }
65965 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebmpi[i]);
65966 + }
65967 +
65968 + /* clear unused pools */
65969 + for (i = ext_buf_pools->num_pools_used;
65970 + i < port_max_num_of_ext_pools; i++)
65971 + iowrite32be(0, &sp_regs->fm_sp_ebmpi[i]);
65972 +
65973 + /* fill pool depletion register*/
65974 + tmp_reg = 0;
65975 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->pools_grp_mode_enable) {
65976 + /* calculate vector for number of pools depletion */
65977 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
65978 + pools_to_consider, ext_buf_pools, 0x80000000);
65979 +
65980 + /* configure num of pools and vector for number of pools mode */
65981 + tmp_reg |= (((uint32_t)buf_pool_depletion->num_pools - 1) <<
65982 + FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT);
65983 + tmp_reg |= vector;
65984 + }
65985 +
65986 + if (buf_pool_depletion->buf_pool_depletion_enabled && buf_pool_depletion->single_pool_mode_enable) {
65987 + /* calculate vector for number of pools depletion */
65988 + vector = calc_vec_dep(bm_max_num_of_pools, buf_pool_depletion->
65989 + pools_to_consider_for_single_mode,
65990 + ext_buf_pools, 0x00000080);
65991 +
65992 + /* configure num of pools and vector for number of pools mode */
65993 + tmp_reg |= vector;
65994 + }
65995 +
65996 + /* fill QbbPEV */
65997 + if (buf_pool_depletion->buf_pool_depletion_enabled) {
65998 + vector = 0;
65999 + for (i = 0; i < max_num_of_pfc_priorities; i++)
66000 + if (buf_pool_depletion->pfc_priorities_en[i] == TRUE)
66001 + vector |= 0x00000100 << i;
66002 + tmp_reg |= vector;
66003 + }
66004 + iowrite32be(tmp_reg, &sp_regs->fm_sp_mpd);
66005 +
66006 + /* fill dma attributes register */
66007 + tmp_reg = 0;
66008 + tmp_reg |= (uint32_t)fm_vsp_params->dma_swap_data <<
66009 + FMAN_SP_DMA_ATTR_SWP_SHIFT;
66010 + tmp_reg |= (uint32_t)fm_vsp_params->int_context_cache_attr <<
66011 + FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT;
66012 + tmp_reg |= (uint32_t)fm_vsp_params->header_cache_attr <<
66013 + FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT;
66014 + tmp_reg |= (uint32_t)fm_vsp_params->scatter_gather_cache_attr <<
66015 + FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT;
66016 + if (fm_vsp_params->dma_write_optimize)
66017 + tmp_reg |= FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE;
66018 + iowrite32be(tmp_reg, &sp_regs->fm_sp_da);
66019 +
66020 + /* IC parameters - fill internal context parameters register */
66021 + tmp_reg = 0;
66022 + tmp_reg |= (((uint32_t)int_context_data_copy->ext_buf_offset/
66023 + OFFSET_UNITS) << FMAN_SP_IC_TO_EXT_SHIFT);
66024 + tmp_reg |= (((uint32_t)int_context_data_copy->int_context_offset/
66025 + OFFSET_UNITS) << FMAN_SP_IC_FROM_INT_SHIFT);
66026 + tmp_reg |= (((uint32_t)int_context_data_copy->size/OFFSET_UNITS) <<
66027 + FMAN_SP_IC_SIZE_SHIFT);
66028 + iowrite32be(tmp_reg, &sp_regs->fm_sp_icp);
66029 +
66030 + /* buffer margins - fill external buffer margins register */
66031 + tmp_reg = 0;
66032 + tmp_reg |= (((uint32_t)external_buffer_margins->start_margins) <<
66033 + FMAN_SP_EXT_BUF_MARG_START_SHIFT);
66034 + tmp_reg |= (((uint32_t)external_buffer_margins->end_margins) <<
66035 + FMAN_SP_EXT_BUF_MARG_END_SHIFT);
66036 + if (no_scather_gather)
66037 + tmp_reg |= FMAN_SP_SG_DISABLE;
66038 + iowrite32be(tmp_reg, &sp_regs->fm_sp_ebm);
66039 +
66040 + /* buffer margins - fill spliodn register */
66041 + iowrite32be(liodn_offset, &sp_regs->fm_sp_spliodn);
66042 +}
66043 --- /dev/null
66044 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.c
66045 @@ -0,0 +1,5216 @@
66046 +/*
66047 + * Copyright 2008-2012 Freescale Semiconductor Inc.
66048 + *
66049 + * Redistribution and use in source and binary forms, with or without
66050 + * modification, are permitted provided that the following conditions are met:
66051 + * * Redistributions of source code must retain the above copyright
66052 + * notice, this list of conditions and the following disclaimer.
66053 + * * Redistributions in binary form must reproduce the above copyright
66054 + * notice, this list of conditions and the following disclaimer in the
66055 + * documentation and/or other materials provided with the distribution.
66056 + * * Neither the name of Freescale Semiconductor nor the
66057 + * names of its contributors may be used to endorse or promote products
66058 + * derived from this software without specific prior written permission.
66059 + *
66060 + *
66061 + * ALTERNATIVELY, this software may be distributed under the terms of the
66062 + * GNU General Public License ("GPL") as published by the Free Software
66063 + * Foundation, either version 2 of that License or (at your option) any
66064 + * later version.
66065 + *
66066 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
66067 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
66068 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
66069 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
66070 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
66071 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
66072 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
66073 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
66074 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66075 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66076 + */
66077 +
66078 +
66079 +/******************************************************************************
66080 + @File fm.c
66081 +
66082 + @Description FM driver routines implementation.
66083 +*//***************************************************************************/
66084 +#include "std_ext.h"
66085 +#include "error_ext.h"
66086 +#include "xx_ext.h"
66087 +#include "string_ext.h"
66088 +#include "sprint_ext.h"
66089 +#include "debug_ext.h"
66090 +#include "fm_muram_ext.h"
66091 +#include <linux/math64.h>
66092 +
66093 +#include "fm_common.h"
66094 +#include "fm_ipc.h"
66095 +#include "fm.h"
66096 +#ifndef CONFIG_FMAN_ARM
66097 +#include <linux/fsl/svr.h>
66098 +#endif
66099 +#include "fsl_fman.h"
66100 +
66101 +
66102 +/****************************************/
66103 +/* static functions */
66104 +/****************************************/
66105 +
66106 +static volatile bool blockingFlag = FALSE;
66107 +static void IpcMsgCompletionCB(t_Handle h_Fm,
66108 + uint8_t *p_Msg,
66109 + uint8_t *p_Reply,
66110 + uint32_t replyLength,
66111 + t_Error status)
66112 +{
66113 + UNUSED(h_Fm);UNUSED(p_Msg);UNUSED(p_Reply);UNUSED(replyLength);UNUSED(status);
66114 + blockingFlag = FALSE;
66115 +}
66116 +
66117 +static void FreeInitResources(t_Fm *p_Fm)
66118 +{
66119 + if (p_Fm->camBaseAddr)
66120 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
66121 + if (p_Fm->fifoBaseAddr)
66122 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->fifoBaseAddr));
66123 + if (p_Fm->resAddr)
66124 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->resAddr));
66125 +}
66126 +
66127 +static bool IsFmanCtrlCodeLoaded(t_Fm *p_Fm)
66128 +{
66129 + t_FMIramRegs *p_Iram;
66130 +
66131 + ASSERT_COND(p_Fm);
66132 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
66133 +
66134 + return (bool)!!(GET_UINT32(p_Iram->iready) & IRAM_READY);
66135 +}
66136 +
66137 +static t_Error CheckFmParameters(t_Fm *p_Fm)
66138 +{
66139 + if (IsFmanCtrlCodeLoaded(p_Fm) && !p_Fm->resetOnInit)
66140 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Old FMan CTRL code is loaded; FM must be reset!"));
66141 +#if (DPAA_VERSION < 11)
66142 + if (!p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats ||
66143 + (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats > DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS))
66144 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
66145 + ("axiDbgNumOfBeats has to be in the range 1 - %d", DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS));
66146 +#endif /* (DPAA_VERSION < 11) */
66147 + if (p_Fm->p_FmDriverParam->dma_cam_num_of_entries % DMA_CAM_UNITS)
66148 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_cam_num_of_entries has to be divisble by %d", DMA_CAM_UNITS));
66149 +// 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))
66150 +// 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));
66151 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer > DMA_THRESH_MAX_COMMQ)
66152 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
66153 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer > DMA_THRESH_MAX_COMMQ)
66154 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_COMMQ));
66155 + if (p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer >= p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer)
66156 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_comm_qtsh_clr_emer must be smaller than dma_comm_qtsh_asrt_emer"));
66157 +#if (DPAA_VERSION < 11)
66158 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
66159 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
66160 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
66161 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
66162 + if (p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer)
66163 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_read_buf_tsh_clr_emer must be smaller than dma_read_buf_tsh_asrt_emer"));
66164 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer > DMA_THRESH_MAX_BUF)
66165 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_asrt_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
66166 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer > DMA_THRESH_MAX_BUF)
66167 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer can not be larger than %d", DMA_THRESH_MAX_BUF));
66168 + if (p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer >= p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer)
66169 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_write_buf_tsh_clr_emer must be smaller than dma_write_buf_tsh_asrt_emer"));
66170 +#else /* (DPAA_VERSION >= 11) */
66171 + if ((p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_READ_EM)||
66172 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_INT_WRITE_EM) ||
66173 + (p_Fm->p_FmDriverParam->dma_dbg_cnt_mode == E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT))
66174 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_dbg_cnt_mode value not supported by this integration."));
66175 + if ((p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_READ_EMERGENCY)||
66176 + (p_Fm->p_FmDriverParam->dma_emergency_bus_select == FM_DMA_MURAM_WRITE_EMERGENCY))
66177 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("emergencyBusSelect value not supported by this integration."));
66178 + if (p_Fm->p_FmDriverParam->dma_stop_on_bus_error)
66179 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_stop_on_bus_error not supported by this integration."));
66180 +#ifdef FM_AID_MODE_NO_TNUM_SW005
66181 + if (p_Fm->p_FmDriverParam->dma_aid_mode != E_FMAN_DMA_AID_OUT_PORT_ID)
66182 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_aid_mode not supported by this integration."));
66183 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
66184 + if (p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats)
66185 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dma_axi_dbg_num_of_beats not supported by this integration."));
66186 +#endif /* (DPAA_VERSION < 11) */
66187 +
66188 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
66189 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fmClkFreq must be set."));
66190 + if (USEC_TO_CLK(p_Fm->p_FmDriverParam->dma_watchdog, p_Fm->p_FmStateStruct->fmClkFreq) > DMA_MAX_WATCHDOG)
66191 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
66192 + ("dma_watchdog depends on FM clock. dma_watchdog(in microseconds) * clk (in Mhz), may not exceed 0x08x", DMA_MAX_WATCHDOG));
66193 +
66194 +#if (DPAA_VERSION >= 11)
66195 + if ((p_Fm->partVSPBase + p_Fm->partNumOfVSPs) > FM_VSP_MAX_NUM_OF_ENTRIES)
66196 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("partVSPBase+partNumOfVSPs out of range!!!"));
66197 +#endif /* (DPAA_VERSION >= 11) */
66198 +
66199 + if (p_Fm->p_FmStateStruct->totalFifoSize % BMI_FIFO_UNITS)
66200 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalFifoSize number has to be divisible by %d", BMI_FIFO_UNITS));
66201 + if (!p_Fm->p_FmStateStruct->totalFifoSize ||
66202 + (p_Fm->p_FmStateStruct->totalFifoSize > BMI_MAX_FIFO_SIZE))
66203 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
66204 + ("totalFifoSize (currently defined as %d) has to be in the range of 256 to %d",
66205 + p_Fm->p_FmStateStruct->totalFifoSize,
66206 + BMI_MAX_FIFO_SIZE));
66207 + if (!p_Fm->p_FmStateStruct->totalNumOfTasks ||
66208 + (p_Fm->p_FmStateStruct->totalNumOfTasks > BMI_MAX_NUM_OF_TASKS))
66209 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("totalNumOfTasks number has to be in the range 1 - %d", BMI_MAX_NUM_OF_TASKS));
66210 +
66211 +#ifdef FM_HAS_TOTAL_DMAS
66212 + if (!p_Fm->p_FmStateStruct->maxNumOfOpenDmas ||
66213 + (p_Fm->p_FmStateStruct->maxNumOfOpenDmas > BMI_MAX_NUM_OF_DMAS))
66214 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("maxNumOfOpenDmas number has to be in the range 1 - %d", BMI_MAX_NUM_OF_DMAS));
66215 +#endif /* FM_HAS_TOTAL_DMAS */
66216 +
66217 + if (p_Fm->p_FmDriverParam->disp_limit_tsh > FPM_MAX_DISP_LIMIT)
66218 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("disp_limit_tsh can't be greater than %d", FPM_MAX_DISP_LIMIT));
66219 +
66220 + if (!p_Fm->f_Exception)
66221 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
66222 + if (!p_Fm->f_BusError)
66223 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exceptions callback not provided"));
66224 +
66225 +#ifdef FM_NO_WATCHDOG
66226 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 2) &&
66227 + (p_Fm->p_FmDriverParam->dma_watchdog))
66228 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("watchdog!"));
66229 +#endif /* FM_NO_WATCHDOG */
66230 +
66231 +#ifdef FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
66232 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
66233 + (p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err))
66234 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("HaltOnEccError!"));
66235 +#endif /* FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008 */
66236 +
66237 +#ifdef FM_NO_TNUM_AGING
66238 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
66239 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
66240 + if (p_Fm->p_FmDriverParam->tnum_aging_period)
66241 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Tnum aging!"));
66242 +#endif /* FM_NO_TNUM_AGING */
66243 +
66244 + /* check that user did not set revision-dependent exceptions */
66245 +#ifdef FM_NO_DISPATCH_RAM_ECC
66246 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev != 4) &&
66247 + (p_Fm->p_FmStateStruct->revInfo.majorRev < 6))
66248 + if (p_Fm->userSetExceptions & FM_EX_BMI_DISPATCH_RAM_ECC)
66249 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_BMI_DISPATCH_RAM_ECC!"));
66250 +#endif /* FM_NO_DISPATCH_RAM_ECC */
66251 +
66252 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
66253 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 4)
66254 + if (p_Fm->userSetExceptions & (FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC))
66255 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC/e_FM_EX_QMI_DOUBLE_ECC!"));
66256 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
66257 +
66258 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
66259 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
66260 + if (p_Fm->userSetExceptions & FM_EX_QMI_SINGLE_ECC)
66261 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("exception e_FM_EX_QMI_SINGLE_ECC!"));
66262 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
66263 +
66264 + return E_OK;
66265 +}
66266 +
66267 +
66268 +static void SendIpcIsr(t_Fm *p_Fm, uint32_t macEvent, uint32_t pendingReg)
66269 +{
66270 + ASSERT_COND(p_Fm->guestId == NCSW_MASTER_ID);
66271 +
66272 + if (p_Fm->intrMng[macEvent].guestId == NCSW_MASTER_ID)
66273 + p_Fm->intrMng[macEvent].f_Isr(p_Fm->intrMng[macEvent].h_SrcHandle);
66274 +
66275 + /* If the MAC is running on guest-partition and we have IPC session with it,
66276 + we inform him about the event through IPC; otherwise, we ignore the event. */
66277 + else if (p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId])
66278 + {
66279 + t_Error err;
66280 + t_FmIpcIsr fmIpcIsr;
66281 + t_FmIpcMsg msg;
66282 +
66283 + memset(&msg, 0, sizeof(msg));
66284 + msg.msgId = FM_GUEST_ISR;
66285 + fmIpcIsr.pendingReg = pendingReg;
66286 + fmIpcIsr.boolErr = FALSE;
66287 + memcpy(msg.msgBody, &fmIpcIsr, sizeof(fmIpcIsr));
66288 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[p_Fm->intrMng[macEvent].guestId],
66289 + (uint8_t*)&msg,
66290 + sizeof(msg.msgId) + sizeof(fmIpcIsr),
66291 + NULL,
66292 + NULL,
66293 + NULL,
66294 + NULL);
66295 + if (err != E_OK)
66296 + REPORT_ERROR(MINOR, err, NO_MSG);
66297 + }
66298 + else
66299 + DBG(TRACE, ("FM Guest mode, without IPC - can't call ISR!"));
66300 +}
66301 +
66302 +static void BmiErrEvent(t_Fm *p_Fm)
66303 +{
66304 + uint32_t event;
66305 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
66306 +
66307 +
66308 + event = fman_get_bmi_err_event(bmi_rg);
66309 +
66310 + if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
66311 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STORAGE_PROFILE_ECC);
66312 + if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
66313 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_LIST_RAM_ECC);
66314 + if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
66315 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_STATISTICS_RAM_ECC);
66316 + if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
66317 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_BMI_DISPATCH_RAM_ECC);
66318 +}
66319 +
66320 +static void QmiErrEvent(t_Fm *p_Fm)
66321 +{
66322 + uint32_t event;
66323 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66324 +
66325 + event = fman_get_qmi_err_event(qmi_rg);
66326 +
66327 + if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
66328 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DOUBLE_ECC);
66329 + if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
66330 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
66331 +}
66332 +
66333 +static void DmaErrEvent(t_Fm *p_Fm)
66334 +{
66335 + uint32_t status, com_id;
66336 + uint8_t tnum;
66337 + uint8_t hardwarePortId;
66338 + uint8_t relativePortId;
66339 + uint16_t liodn;
66340 + struct fman_dma_regs *dma_rg = p_Fm->p_FmDmaRegs;
66341 +
66342 + status = fman_get_dma_err_event(dma_rg);
66343 +
66344 + if (status & DMA_STATUS_BUS_ERR)
66345 + {
66346 + com_id = fman_get_dma_com_id(dma_rg);
66347 + hardwarePortId = (uint8_t)(((com_id & DMA_TRANSFER_PORTID_MASK) >> DMA_TRANSFER_PORTID_SHIFT));
66348 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66349 + HW_PORT_ID_TO_SW_PORT_ID(relativePortId, hardwarePortId);
66350 + tnum = (uint8_t)((com_id & DMA_TRANSFER_TNUM_MASK) >> DMA_TRANSFER_TNUM_SHIFT);
66351 + liodn = (uint16_t)(com_id & DMA_TRANSFER_LIODN_MASK);
66352 + ASSERT_COND(p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] != e_FM_PORT_TYPE_DUMMY);
66353 + p_Fm->f_BusError(p_Fm->h_App,
66354 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId],
66355 + relativePortId,
66356 + fman_get_dma_addr(dma_rg),
66357 + tnum,
66358 + liodn);
66359 + }
66360 + if (status & DMA_STATUS_FM_SPDAT_ECC)
66361 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SINGLE_PORT_ECC);
66362 + if (status & DMA_STATUS_READ_ECC)
66363 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_READ_ECC);
66364 + if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
66365 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_SYSTEM_WRITE_ECC);
66366 + if (status & DMA_STATUS_FM_WRITE_ECC)
66367 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_DMA_FM_WRITE_ECC);
66368 + }
66369 +
66370 +static void FpmErrEvent(t_Fm *p_Fm)
66371 +{
66372 + uint32_t event;
66373 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66374 +
66375 + event = fman_get_fpm_err_event(fpm_rg);
66376 +
66377 + if ((event & FPM_EV_MASK_DOUBLE_ECC) && (event & FPM_EV_MASK_DOUBLE_ECC_EN))
66378 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_DOUBLE_ECC);
66379 + if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
66380 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_STALL_ON_TASKS);
66381 + if ((event & FPM_EV_MASK_SINGLE_ECC) && (event & FPM_EV_MASK_SINGLE_ECC_EN))
66382 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_FPM_SINGLE_ECC);
66383 +}
66384 +
66385 +static void MuramErrIntr(t_Fm *p_Fm)
66386 +{
66387 + uint32_t event;
66388 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66389 +
66390 + event = fman_get_muram_err_event(fpm_rg);
66391 +
66392 + if (event & FPM_RAM_MURAM_ECC)
66393 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_MURAM_ECC);
66394 +}
66395 +
66396 +static void IramErrIntr(t_Fm *p_Fm)
66397 +{
66398 + uint32_t event;
66399 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66400 +
66401 + event = fman_get_iram_err_event(fpm_rg);
66402 +
66403 + if (event & FPM_RAM_IRAM_ECC)
66404 + p_Fm->f_Exception(p_Fm->h_App, e_FM_EX_IRAM_ECC);
66405 +}
66406 +
66407 +static void QmiEvent(t_Fm *p_Fm)
66408 +{
66409 + uint32_t event;
66410 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
66411 +
66412 + event = fman_get_qmi_event(qmi_rg);
66413 +
66414 + if (event & QMI_INTR_EN_SINGLE_ECC)
66415 + p_Fm->f_Exception(p_Fm->h_App,e_FM_EX_QMI_SINGLE_ECC);
66416 +}
66417 +
66418 +static void UnimplementedIsr(t_Handle h_Arg)
66419 +{
66420 + UNUSED(h_Arg);
66421 +
66422 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented ISR!"));
66423 +}
66424 +
66425 +static void UnimplementedFmanCtrlIsr(t_Handle h_Arg, uint32_t event)
66426 +{
66427 + UNUSED(h_Arg); UNUSED(event);
66428 +
66429 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unimplemented FmCtl ISR!"));
66430 +}
66431 +
66432 +static void EnableTimeStamp(t_Fm *p_Fm)
66433 +{
66434 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
66435 +
66436 + ASSERT_COND(p_Fm->p_FmStateStruct);
66437 + ASSERT_COND(p_Fm->p_FmStateStruct->count1MicroBit);
66438 +
66439 + fman_enable_time_stamp(fpm_rg, p_Fm->p_FmStateStruct->count1MicroBit, p_Fm->p_FmStateStruct->fmClkFreq);
66440 +
66441 + p_Fm->p_FmStateStruct->enabledTimeStamp = TRUE;
66442 +}
66443 +
66444 +static t_Error ClearIRam(t_Fm *p_Fm)
66445 +{
66446 + t_FMIramRegs *p_Iram;
66447 + int i;
66448 + int iram_size;
66449 +
66450 + ASSERT_COND(p_Fm);
66451 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
66452 + iram_size = FM_IRAM_SIZE(p_Fm->p_FmStateStruct->revInfo.majorRev,p_Fm->p_FmStateStruct->revInfo.minorRev);
66453 +
66454 + /* Enable the auto-increment */
66455 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
66456 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
66457 +
66458 + for (i=0; i < (iram_size/4); i++)
66459 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
66460 +
66461 + WRITE_UINT32(p_Iram->iadd, iram_size - 4);
66462 + CORE_MemoryBarrier();
66463 + while (GET_UINT32(p_Iram->idata) != 0xffffffff) ;
66464 +
66465 + return E_OK;
66466 +}
66467 +
66468 +static t_Error LoadFmanCtrlCode(t_Fm *p_Fm)
66469 +{
66470 + t_FMIramRegs *p_Iram;
66471 + int i;
66472 + uint32_t tmp;
66473 + uint8_t compTo16;
66474 +
66475 + ASSERT_COND(p_Fm);
66476 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
66477 +
66478 + /* Enable the auto-increment */
66479 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
66480 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
66481 +
66482 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
66483 + WRITE_UINT32(p_Iram->idata, p_Fm->firmware.p_Code[i]);
66484 +
66485 + compTo16 = (uint8_t)(p_Fm->firmware.size % 16);
66486 + if (compTo16)
66487 + for (i=0; i < ((16-compTo16) / 4); i++)
66488 + WRITE_UINT32(p_Iram->idata, 0xffffffff);
66489 +
66490 + WRITE_UINT32(p_Iram->iadd,p_Fm->firmware.size-4);
66491 + while (GET_UINT32(p_Iram->iadd) != (p_Fm->firmware.size-4)) ;
66492 +
66493 + /* verify that writing has completed */
66494 + while (GET_UINT32(p_Iram->idata) != p_Fm->firmware.p_Code[(p_Fm->firmware.size / 4)-1]) ;
66495 +
66496 + if (p_Fm->fwVerify)
66497 + {
66498 + WRITE_UINT32(p_Iram->iadd, IRAM_IADD_AIE);
66499 + while (GET_UINT32(p_Iram->iadd) != IRAM_IADD_AIE) ;
66500 + for (i=0; i < (p_Fm->firmware.size / 4); i++)
66501 + {
66502 + tmp = GET_UINT32(p_Iram->idata);
66503 + if (tmp != p_Fm->firmware.p_Code[i])
66504 + RETURN_ERROR(MAJOR, E_WRITE_FAILED,
66505 + ("UCode write error : write 0x%x, read 0x%x",
66506 + p_Fm->firmware.p_Code[i],tmp));
66507 + }
66508 + WRITE_UINT32(p_Iram->iadd, 0x0);
66509 + }
66510 +
66511 + /* Enable patch from IRAM */
66512 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
66513 + XX_UDelay(1000);
66514 +
66515 + DBG(INFO, ("FMan-Controller code (ver %d.%d.%d) loaded to IRAM.",
66516 + ((uint16_t *)p_Fm->firmware.p_Code)[2],
66517 + ((uint8_t *)p_Fm->firmware.p_Code)[6],
66518 + ((uint8_t *)p_Fm->firmware.p_Code)[7]));
66519 +
66520 + return E_OK;
66521 +}
66522 +
66523 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
66524 +static t_Error FwNotResetErratumBugzilla6173WA(t_Fm *p_Fm)
66525 +{
66526 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
66527 + uint32_t tmpReg;
66528 + uint32_t savedSpliodn[63];
66529 +
66530 + /* write to IRAM first location the debug instruction */
66531 + WRITE_UINT32(p_Iram->iadd, 0);
66532 + while (GET_UINT32(p_Iram->iadd) != 0) ;
66533 + WRITE_UINT32(p_Iram->idata, FM_FW_DEBUG_INSTRUCTION);
66534 +
66535 + WRITE_UINT32(p_Iram->iadd, 0);
66536 + while (GET_UINT32(p_Iram->iadd) != 0) ;
66537 + while (GET_UINT32(p_Iram->idata) != FM_FW_DEBUG_INSTRUCTION) ;
66538 +
66539 + /* Enable patch from IRAM */
66540 + WRITE_UINT32(p_Iram->iready, IRAM_READY);
66541 + CORE_MemoryBarrier();
66542 + XX_UDelay(100);
66543 + IO2MemCpy32((uint8_t *)savedSpliodn,
66544 + (uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
66545 + 63*sizeof(uint32_t));
66546 +
66547 + /* reset FMAN */
66548 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66549 + CORE_MemoryBarrier();
66550 + XX_UDelay(100);
66551 +
66552 + /* verify breakpoint debug status register */
66553 + tmpReg = GET_UINT32(*(uint32_t *)UINT_TO_PTR(p_Fm->baseAddr + FM_DEBUG_STATUS_REGISTER_OFFSET));
66554 + if (!tmpReg)
66555 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Invalid debug status register value is '0'"));
66556 +
66557 + /*************************************/
66558 + /* Load FMan-Controller code to IRAM */
66559 + /*************************************/
66560 + ClearIRam(p_Fm);
66561 + if (p_Fm->firmware.p_Code &&
66562 + (LoadFmanCtrlCode(p_Fm) != E_OK))
66563 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
66564 + XX_UDelay(100);
66565 +
66566 + /* reset FMAN again to start the microcode */
66567 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
66568 + CORE_MemoryBarrier();
66569 + XX_UDelay(100);
66570 + Mem2IOCpy32((uint8_t *)p_Fm->p_FmBmiRegs->fmbm_spliodn,
66571 + (uint8_t *)savedSpliodn,
66572 + 63*sizeof(uint32_t));
66573 +
66574 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
66575 + {
66576 + fman_resume(p_Fm->p_FmFpmRegs);
66577 + CORE_MemoryBarrier();
66578 + XX_UDelay(100);
66579 + }
66580 +
66581 + return E_OK;
66582 +}
66583 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
66584 +
66585 +static void GuestErrorIsr(t_Fm *p_Fm, uint32_t pending)
66586 +{
66587 +#define FM_G_CALL_1G_MAC_ERR_ISR(_id) \
66588 +do { \
66589 + 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);\
66590 +} while (0)
66591 +#define FM_G_CALL_10G_MAC_ERR_ISR(_id) \
66592 +do { \
66593 + 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);\
66594 +} while (0)
66595 +
66596 + /* error interrupts */
66597 + if (pending & ERR_INTR_EN_1G_MAC0)
66598 + FM_G_CALL_1G_MAC_ERR_ISR(0);
66599 + if (pending & ERR_INTR_EN_1G_MAC1)
66600 + FM_G_CALL_1G_MAC_ERR_ISR(1);
66601 + if (pending & ERR_INTR_EN_1G_MAC2)
66602 + FM_G_CALL_1G_MAC_ERR_ISR(2);
66603 + if (pending & ERR_INTR_EN_1G_MAC3)
66604 + FM_G_CALL_1G_MAC_ERR_ISR(3);
66605 + if (pending & ERR_INTR_EN_1G_MAC4)
66606 + FM_G_CALL_1G_MAC_ERR_ISR(4);
66607 + if (pending & ERR_INTR_EN_1G_MAC5)
66608 + FM_G_CALL_1G_MAC_ERR_ISR(5);
66609 + if (pending & ERR_INTR_EN_1G_MAC6)
66610 + FM_G_CALL_1G_MAC_ERR_ISR(6);
66611 + if (pending & ERR_INTR_EN_1G_MAC7)
66612 + FM_G_CALL_1G_MAC_ERR_ISR(7);
66613 + if (pending & ERR_INTR_EN_10G_MAC0)
66614 + FM_G_CALL_10G_MAC_ERR_ISR(0);
66615 + if (pending & ERR_INTR_EN_10G_MAC1)
66616 + FM_G_CALL_10G_MAC_ERR_ISR(1);
66617 +}
66618 +
66619 +static void GuestEventIsr(t_Fm *p_Fm, uint32_t pending)
66620 +{
66621 +#define FM_G_CALL_1G_MAC_ISR(_id) \
66622 +do { \
66623 + 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);\
66624 +} while (0)
66625 +#define FM_G_CALL_10G_MAC_ISR(_id) \
66626 +do { \
66627 + 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);\
66628 +} while (0)
66629 +
66630 + if (pending & INTR_EN_1G_MAC0)
66631 + FM_G_CALL_1G_MAC_ISR(0);
66632 + if (pending & INTR_EN_1G_MAC1)
66633 + FM_G_CALL_1G_MAC_ISR(1);
66634 + if (pending & INTR_EN_1G_MAC2)
66635 + FM_G_CALL_1G_MAC_ISR(2);
66636 + if (pending & INTR_EN_1G_MAC3)
66637 + FM_G_CALL_1G_MAC_ISR(3);
66638 + if (pending & INTR_EN_1G_MAC4)
66639 + FM_G_CALL_1G_MAC_ISR(4);
66640 + if (pending & INTR_EN_1G_MAC5)
66641 + FM_G_CALL_1G_MAC_ISR(5);
66642 + if (pending & INTR_EN_1G_MAC6)
66643 + FM_G_CALL_1G_MAC_ISR(6);
66644 + if (pending & INTR_EN_1G_MAC7)
66645 + FM_G_CALL_1G_MAC_ISR(7);
66646 + if (pending & INTR_EN_10G_MAC0)
66647 + FM_G_CALL_10G_MAC_ISR(0);
66648 + if (pending & INTR_EN_10G_MAC1)
66649 + FM_G_CALL_10G_MAC_ISR(1);
66650 + if (pending & INTR_EN_TMR)
66651 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
66652 +}
66653 +
66654 +#if (DPAA_VERSION >= 11)
66655 +static t_Error SetVSPWindow(t_Handle h_Fm,
66656 + uint8_t hardwarePortId,
66657 + uint8_t baseStorageProfile,
66658 + uint8_t log2NumOfProfiles)
66659 +{
66660 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66661 +
66662 + ASSERT_COND(h_Fm);
66663 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
66664 +
66665 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
66666 + !p_Fm->p_FmBmiRegs &&
66667 + p_Fm->h_IpcSessions[0])
66668 + {
66669 + t_FmIpcVspSetPortWindow fmIpcVspSetPortWindow;
66670 + t_FmIpcMsg msg;
66671 + t_Error err = E_OK;
66672 +
66673 + memset(&msg, 0, sizeof(msg));
66674 + memset(&fmIpcVspSetPortWindow, 0, sizeof(t_FmIpcVspSetPortWindow));
66675 + fmIpcVspSetPortWindow.hardwarePortId = hardwarePortId;
66676 + fmIpcVspSetPortWindow.baseStorageProfile = baseStorageProfile;
66677 + fmIpcVspSetPortWindow.log2NumOfProfiles = log2NumOfProfiles;
66678 + msg.msgId = FM_VSP_SET_PORT_WINDOW;
66679 + memcpy(msg.msgBody, &fmIpcVspSetPortWindow, sizeof(t_FmIpcVspSetPortWindow));
66680 +
66681 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66682 + (uint8_t*)&msg,
66683 + sizeof(msg.msgId),
66684 + NULL,
66685 + NULL,
66686 + NULL,
66687 + NULL);
66688 + if (err != E_OK)
66689 + RETURN_ERROR(MINOR, err, NO_MSG);
66690 + return E_OK;
66691 + }
66692 + else if (!p_Fm->p_FmBmiRegs)
66693 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
66694 + ("Either IPC or 'baseAddress' is required!"));
66695 +
66696 + fman_set_vsp_window(p_Fm->p_FmBmiRegs,
66697 + hardwarePortId,
66698 + baseStorageProfile,
66699 + log2NumOfProfiles);
66700 +
66701 + return E_OK;
66702 +}
66703 +
66704 +static uint8_t AllocVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
66705 +{
66706 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66707 + uint8_t profilesFound = 0;
66708 + int i = 0;
66709 + uint32_t intFlags;
66710 +
66711 + if (!numOfProfiles)
66712 + return E_OK;
66713 +
66714 + if ((numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES) ||
66715 + (base + numOfProfiles > FM_VSP_MAX_NUM_OF_ENTRIES))
66716 + return (uint8_t)ILLEGAL_BASE;
66717 +
66718 + if (p_Fm->h_IpcSessions[0])
66719 + {
66720 + t_FmIpcResourceAllocParams ipcAllocParams;
66721 + t_FmIpcMsg msg;
66722 + t_FmIpcReply reply;
66723 + t_Error err;
66724 + uint32_t replyLength;
66725 +
66726 + memset(&msg, 0, sizeof(msg));
66727 + memset(&reply, 0, sizeof(reply));
66728 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
66729 + ipcAllocParams.guestId = p_Fm->guestId;
66730 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
66731 + ipcAllocParams.base = p_Fm->partVSPBase;
66732 + msg.msgId = FM_VSP_ALLOC;
66733 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
66734 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66735 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66736 + (uint8_t*)&msg,
66737 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
66738 + (uint8_t*)&reply,
66739 + &replyLength,
66740 + NULL,
66741 + NULL);
66742 + if ((err != E_OK) ||
66743 + (replyLength != (sizeof(uint32_t) + sizeof(uint8_t))))
66744 + RETURN_ERROR(MAJOR, err, NO_MSG);
66745 + else
66746 + memcpy((uint8_t*)&p_Fm->partVSPBase, reply.replyBody, sizeof(uint8_t));
66747 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
66748 + RETURN_ERROR(MAJOR, err, NO_MSG);
66749 + }
66750 + if (p_Fm->guestId != NCSW_MASTER_ID)
66751 + {
66752 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
66753 + return (uint8_t)ILLEGAL_BASE;
66754 + }
66755 +
66756 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
66757 + for (i = base; i < base + numOfProfiles; i++)
66758 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == (uint8_t)ILLEGAL_BASE)
66759 + profilesFound++;
66760 + else
66761 + break;
66762 +
66763 + if (profilesFound == numOfProfiles)
66764 + for (i = base; i<base + numOfProfiles; i++)
66765 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = guestId;
66766 + else
66767 + {
66768 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66769 + return (uint8_t)ILLEGAL_BASE;
66770 + }
66771 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
66772 +
66773 + return base;
66774 +}
66775 +
66776 +static void FreeVSPsForPartition(t_Handle h_Fm, uint8_t base, uint8_t numOfProfiles, uint8_t guestId)
66777 +{
66778 + t_Fm *p_Fm = (t_Fm *)h_Fm;
66779 + int i = 0;
66780 +
66781 + ASSERT_COND(p_Fm);
66782 +
66783 + if (p_Fm->h_IpcSessions[0])
66784 + {
66785 + t_FmIpcResourceAllocParams ipcAllocParams;
66786 + t_FmIpcMsg msg;
66787 + t_FmIpcReply reply;
66788 + uint32_t replyLength;
66789 + t_Error err;
66790 +
66791 + memset(&msg, 0, sizeof(msg));
66792 + memset(&reply, 0, sizeof(reply));
66793 + memset(&ipcAllocParams, 0, sizeof(t_FmIpcResourceAllocParams));
66794 + ipcAllocParams.guestId = p_Fm->guestId;
66795 + ipcAllocParams.num = p_Fm->partNumOfVSPs;
66796 + ipcAllocParams.base = p_Fm->partVSPBase;
66797 + msg.msgId = FM_VSP_FREE;
66798 + memcpy(msg.msgBody, &ipcAllocParams, sizeof(t_FmIpcResourceAllocParams));
66799 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
66800 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
66801 + (uint8_t*)&msg,
66802 + sizeof(msg.msgId) + sizeof(t_FmIpcResourceAllocParams),
66803 + (uint8_t*)&reply,
66804 + &replyLength,
66805 + NULL,
66806 + NULL);
66807 + if (err != E_OK)
66808 + REPORT_ERROR(MAJOR, err, NO_MSG);
66809 + return;
66810 + }
66811 + if (p_Fm->guestId != NCSW_MASTER_ID)
66812 + {
66813 + DBG(WARNING, ("FM Guest mode, without IPC - can't validate VSP range!"));
66814 + return;
66815 + }
66816 +
66817 + ASSERT_COND(p_Fm->p_FmSp);
66818 +
66819 + for (i=base; i<numOfProfiles; i++)
66820 + {
66821 + if (p_Fm->p_FmSp->profiles[i].profilesMng.ownerId == guestId)
66822 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
66823 + else
66824 + DBG(WARNING, ("Request for freeing storage profile window which wasn't allocated to this partition"));
66825 + }
66826 +}
66827 +#endif /* (DPAA_VERSION >= 11) */
66828 +
66829 +static t_Error FmGuestHandleIpcMsgCB(t_Handle h_Fm,
66830 + uint8_t *p_Msg,
66831 + uint32_t msgLength,
66832 + uint8_t *p_Reply,
66833 + uint32_t *p_ReplyLength)
66834 +{
66835 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66836 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
66837 +
66838 + UNUSED(p_Reply);
66839 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66840 + SANITY_CHECK_RETURN_ERROR((msgLength > sizeof(uint32_t)), E_INVALID_VALUE);
66841 +
66842 +#ifdef DISABLE_SANITY_CHECKS
66843 + UNUSED(msgLength);
66844 +#endif /* DISABLE_SANITY_CHECKS */
66845 +
66846 + ASSERT_COND(p_Msg);
66847 +
66848 + *p_ReplyLength = 0;
66849 +
66850 + switch (p_IpcMsg->msgId)
66851 + {
66852 + case (FM_GUEST_ISR):
66853 + {
66854 + t_FmIpcIsr ipcIsr;
66855 +
66856 + memcpy((uint8_t*)&ipcIsr, p_IpcMsg->msgBody, sizeof(t_FmIpcIsr));
66857 + if (ipcIsr.boolErr)
66858 + GuestErrorIsr(p_Fm, ipcIsr.pendingReg);
66859 + else
66860 + GuestEventIsr(p_Fm, ipcIsr.pendingReg);
66861 + break;
66862 + }
66863 + default:
66864 + *p_ReplyLength = 0;
66865 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
66866 + }
66867 + return E_OK;
66868 +}
66869 +
66870 +static t_Error FmHandleIpcMsgCB(t_Handle h_Fm,
66871 + uint8_t *p_Msg,
66872 + uint32_t msgLength,
66873 + uint8_t *p_Reply,
66874 + uint32_t *p_ReplyLength)
66875 +{
66876 + t_Error err;
66877 + t_Fm *p_Fm = (t_Fm*)h_Fm;
66878 + t_FmIpcMsg *p_IpcMsg = (t_FmIpcMsg*)p_Msg;
66879 + t_FmIpcReply *p_IpcReply = (t_FmIpcReply*)p_Reply;
66880 +
66881 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
66882 + SANITY_CHECK_RETURN_ERROR((msgLength >= sizeof(uint32_t)), E_INVALID_VALUE);
66883 +
66884 +#ifdef DISABLE_SANITY_CHECKS
66885 + UNUSED(msgLength);
66886 +#endif /* DISABLE_SANITY_CHECKS */
66887 +
66888 + ASSERT_COND(p_IpcMsg);
66889 +
66890 + memset(p_IpcReply, 0, (sizeof(uint8_t) * FM_IPC_MAX_REPLY_SIZE));
66891 + *p_ReplyLength = 0;
66892 +
66893 + switch (p_IpcMsg->msgId)
66894 + {
66895 + case (FM_GET_SET_PORT_PARAMS):
66896 + {
66897 + t_FmIpcPortInInitParams ipcInitParams;
66898 + t_FmInterModulePortInitParams initParams;
66899 + t_FmIpcPortOutInitParams ipcOutInitParams;
66900 +
66901 + memcpy((uint8_t*)&ipcInitParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortInInitParams));
66902 + initParams.hardwarePortId = ipcInitParams.hardwarePortId;
66903 + initParams.portType = (e_FmPortType)ipcInitParams.enumPortType;
66904 + initParams.independentMode = (bool)(ipcInitParams.boolIndependentMode);
66905 + initParams.liodnOffset = ipcInitParams.liodnOffset;
66906 + initParams.numOfTasks = ipcInitParams.numOfTasks;
66907 + initParams.numOfExtraTasks = ipcInitParams.numOfExtraTasks;
66908 + initParams.numOfOpenDmas = ipcInitParams.numOfOpenDmas;
66909 + initParams.numOfExtraOpenDmas = ipcInitParams.numOfExtraOpenDmas;
66910 + initParams.sizeOfFifo = ipcInitParams.sizeOfFifo;
66911 + initParams.extraSizeOfFifo = ipcInitParams.extraSizeOfFifo;
66912 + initParams.deqPipelineDepth = ipcInitParams.deqPipelineDepth;
66913 + initParams.maxFrameLength = ipcInitParams.maxFrameLength;
66914 + initParams.liodnBase = ipcInitParams.liodnBase;
66915 +
66916 + p_IpcReply->error = (uint32_t)FmGetSetPortParams(h_Fm, &initParams);
66917 +
66918 + ipcOutInitParams.ipcPhysAddr.high = initParams.fmMuramPhysBaseAddr.high;
66919 + ipcOutInitParams.ipcPhysAddr.low = initParams.fmMuramPhysBaseAddr.low;
66920 + ipcOutInitParams.sizeOfFifo = initParams.sizeOfFifo;
66921 + ipcOutInitParams.extraSizeOfFifo = initParams.extraSizeOfFifo;
66922 + ipcOutInitParams.numOfTasks = initParams.numOfTasks;
66923 + ipcOutInitParams.numOfExtraTasks = initParams.numOfExtraTasks;
66924 + ipcOutInitParams.numOfOpenDmas = initParams.numOfOpenDmas;
66925 + ipcOutInitParams.numOfExtraOpenDmas = initParams.numOfExtraOpenDmas;
66926 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcOutInitParams, sizeof(ipcOutInitParams));
66927 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams);
66928 + break;
66929 + }
66930 + case (FM_SET_SIZE_OF_FIFO):
66931 + {
66932 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
66933 +
66934 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
66935 + p_IpcReply->error = (uint32_t)FmSetSizeOfFifo(h_Fm,
66936 + ipcPortRsrcParams.hardwarePortId,
66937 + &ipcPortRsrcParams.val,
66938 + &ipcPortRsrcParams.extra,
66939 + (bool)ipcPortRsrcParams.boolInitialConfig);
66940 + *p_ReplyLength = sizeof(uint32_t);
66941 + break;
66942 + }
66943 + case (FM_SET_NUM_OF_TASKS):
66944 + {
66945 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
66946 +
66947 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
66948 + p_IpcReply->error = (uint32_t)FmSetNumOfTasks(h_Fm, ipcPortRsrcParams.hardwarePortId,
66949 + (uint8_t*)&ipcPortRsrcParams.val,
66950 + (uint8_t*)&ipcPortRsrcParams.extra,
66951 + (bool)ipcPortRsrcParams.boolInitialConfig);
66952 + *p_ReplyLength = sizeof(uint32_t);
66953 + break;
66954 + }
66955 + case (FM_SET_NUM_OF_OPEN_DMAS):
66956 + {
66957 + t_FmIpcPortRsrcParams ipcPortRsrcParams;
66958 +
66959 + memcpy((uint8_t*)&ipcPortRsrcParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortRsrcParams));
66960 + p_IpcReply->error = (uint32_t)FmSetNumOfOpenDmas(h_Fm, ipcPortRsrcParams.hardwarePortId,
66961 + (uint8_t*)&ipcPortRsrcParams.val,
66962 + (uint8_t*)&ipcPortRsrcParams.extra,
66963 + (bool)ipcPortRsrcParams.boolInitialConfig);
66964 + *p_ReplyLength = sizeof(uint32_t);
66965 + break;
66966 + }
66967 + case (FM_RESUME_STALLED_PORT):
66968 + *p_ReplyLength = sizeof(uint32_t);
66969 + p_IpcReply->error = (uint32_t)FmResumeStalledPort(h_Fm, p_IpcMsg->msgBody[0]);
66970 + break;
66971 + case (FM_MASTER_IS_ALIVE):
66972 + {
66973 + uint8_t guestId = p_IpcMsg->msgBody[0];
66974 + /* build the FM master partition IPC address */
66975 + memset(p_Fm->fmIpcHandlerModuleName[guestId], 0, (sizeof(char)) * MODULE_NAME_SIZE);
66976 + if (Sprint (p_Fm->fmIpcHandlerModuleName[guestId], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, guestId) != (guestId<10 ? 6:7))
66977 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
66978 + p_Fm->h_IpcSessions[guestId] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[guestId], p_Fm->fmModuleName);
66979 + if (p_Fm->h_IpcSessions[guestId] == NULL)
66980 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("FM Master IPC session for guest %d", guestId));
66981 + *(uint8_t*)(p_IpcReply->replyBody) = 1;
66982 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
66983 + break;
66984 + }
66985 + case (FM_IS_PORT_STALLED):
66986 + {
66987 + bool tmp;
66988 +
66989 + p_IpcReply->error = (uint32_t)FmIsPortStalled(h_Fm, p_IpcMsg->msgBody[0], &tmp);
66990 + *(uint8_t*)(p_IpcReply->replyBody) = (uint8_t)tmp;
66991 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
66992 + break;
66993 + }
66994 + case (FM_RESET_MAC):
66995 + {
66996 + t_FmIpcMacParams ipcMacParams;
66997 +
66998 + memcpy((uint8_t*)&ipcMacParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacParams));
66999 + p_IpcReply->error = (uint32_t)FmResetMac(p_Fm,
67000 + (e_FmMacType)(ipcMacParams.enumType),
67001 + ipcMacParams.id);
67002 + *p_ReplyLength = sizeof(uint32_t);
67003 + break;
67004 + }
67005 + case (FM_SET_MAC_MAX_FRAME):
67006 + {
67007 + t_FmIpcMacMaxFrameParams ipcMacMaxFrameParams;
67008 +
67009 + memcpy((uint8_t*)&ipcMacMaxFrameParams, p_IpcMsg->msgBody, sizeof(t_FmIpcMacMaxFrameParams));
67010 + err = FmSetMacMaxFrame(p_Fm,
67011 + (e_FmMacType)(ipcMacMaxFrameParams.macParams.enumType),
67012 + ipcMacMaxFrameParams.macParams.id,
67013 + ipcMacMaxFrameParams.maxFrameLength);
67014 + if (err != E_OK)
67015 + REPORT_ERROR(MINOR, err, NO_MSG);
67016 + break;
67017 + }
67018 +#if (DPAA_VERSION >= 11)
67019 + case (FM_VSP_ALLOC) :
67020 + {
67021 + t_FmIpcResourceAllocParams ipcAllocParams;
67022 + uint8_t vspBase;
67023 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
67024 + vspBase = AllocVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
67025 + memcpy(p_IpcReply->replyBody, (uint8_t*)&vspBase, sizeof(uint8_t));
67026 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
67027 + break;
67028 + }
67029 + case (FM_VSP_FREE) :
67030 + {
67031 + t_FmIpcResourceAllocParams ipcAllocParams;
67032 + memcpy(&ipcAllocParams, p_IpcMsg->msgBody, sizeof(t_FmIpcResourceAllocParams));
67033 + FreeVSPsForPartition(h_Fm, (uint8_t)ipcAllocParams.base, (uint8_t)ipcAllocParams.num, ipcAllocParams.guestId);
67034 + break;
67035 + }
67036 + case (FM_VSP_SET_PORT_WINDOW) :
67037 + {
67038 + t_FmIpcVspSetPortWindow ipcVspSetPortWindow;
67039 + memcpy(&ipcVspSetPortWindow, p_IpcMsg->msgBody, sizeof(t_FmIpcVspSetPortWindow));
67040 + err = SetVSPWindow(h_Fm,
67041 + ipcVspSetPortWindow.hardwarePortId,
67042 + ipcVspSetPortWindow.baseStorageProfile,
67043 + ipcVspSetPortWindow.log2NumOfProfiles);
67044 + return err;
67045 + }
67046 + case (FM_SET_CONG_GRP_PFC_PRIO) :
67047 + {
67048 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
67049 + memcpy(&fmIpcSetCongestionGroupPfcPriority, p_IpcMsg->msgBody, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
67050 + err = FmSetCongestionGroupPFCpriority(h_Fm,
67051 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId,
67052 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap);
67053 + return err;
67054 + }
67055 +#endif /* (DPAA_VERSION >= 11) */
67056 +
67057 + case (FM_FREE_PORT):
67058 + {
67059 + t_FmInterModulePortFreeParams portParams;
67060 + t_FmIpcPortFreeParams ipcPortParams;
67061 +
67062 + memcpy((uint8_t*)&ipcPortParams, p_IpcMsg->msgBody, sizeof(t_FmIpcPortFreeParams));
67063 + portParams.hardwarePortId = ipcPortParams.hardwarePortId;
67064 + portParams.portType = (e_FmPortType)(ipcPortParams.enumPortType);
67065 + portParams.deqPipelineDepth = ipcPortParams.deqPipelineDepth;
67066 + FmFreePortParams(h_Fm, &portParams);
67067 + break;
67068 + }
67069 + case (FM_REGISTER_INTR):
67070 + {
67071 + t_FmIpcRegisterIntr ipcRegIntr;
67072 +
67073 + memcpy((uint8_t*)&ipcRegIntr, p_IpcMsg->msgBody, sizeof(ipcRegIntr));
67074 + p_Fm->intrMng[ipcRegIntr.event].guestId = ipcRegIntr.guestId;
67075 + break;
67076 + }
67077 + case (FM_GET_PARAMS):
67078 + {
67079 + t_FmIpcParams ipcParams;
67080 +
67081 + /* Get clock frequency */
67082 + ipcParams.fmClkFreq = p_Fm->p_FmStateStruct->fmClkFreq;
67083 + ipcParams.fmMacClkFreq = p_Fm->p_FmStateStruct->fmMacClkFreq;
67084 +
67085 + fman_get_revision(p_Fm->p_FmFpmRegs,&ipcParams.majorRev,&ipcParams.minorRev);
67086 +
67087 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcParams, sizeof(t_FmIpcParams));
67088 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
67089 + break;
67090 + }
67091 + case (FM_GET_FMAN_CTRL_CODE_REV):
67092 + {
67093 + t_FmCtrlCodeRevisionInfo fmanCtrlRevInfo;
67094 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
67095 +
67096 + p_IpcReply->error = (uint32_t)FM_GetFmanCtrlCodeRevision(h_Fm, &fmanCtrlRevInfo);
67097 + ipcRevInfo.packageRev = fmanCtrlRevInfo.packageRev;
67098 + ipcRevInfo.majorRev = fmanCtrlRevInfo.majorRev;
67099 + ipcRevInfo.minorRev = fmanCtrlRevInfo.minorRev;
67100 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcRevInfo, sizeof(t_FmIpcFmanCtrlCodeRevisionInfo));
67101 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcFmanCtrlCodeRevisionInfo);
67102 + break;
67103 + }
67104 +
67105 + case (FM_DMA_STAT):
67106 + {
67107 + t_FmDmaStatus dmaStatus;
67108 + t_FmIpcDmaStatus ipcDmaStatus;
67109 +
67110 + FM_GetDmaStatus(h_Fm, &dmaStatus);
67111 + ipcDmaStatus.boolCmqNotEmpty = (uint8_t)dmaStatus.cmqNotEmpty;
67112 + ipcDmaStatus.boolBusError = (uint8_t)dmaStatus.busError;
67113 + ipcDmaStatus.boolReadBufEccError = (uint8_t)dmaStatus.readBufEccError;
67114 + ipcDmaStatus.boolWriteBufEccSysError = (uint8_t)dmaStatus.writeBufEccSysError;
67115 + ipcDmaStatus.boolWriteBufEccFmError = (uint8_t)dmaStatus.writeBufEccFmError;
67116 + ipcDmaStatus.boolSinglePortEccError = (uint8_t)dmaStatus.singlePortEccError;
67117 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcDmaStatus, sizeof(t_FmIpcDmaStatus));
67118 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
67119 + break;
67120 + }
67121 + case (FM_ALLOC_FMAN_CTRL_EVENT_REG):
67122 + p_IpcReply->error = (uint32_t)FmAllocFmanCtrlEventReg(h_Fm, (uint8_t*)p_IpcReply->replyBody);
67123 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint8_t);
67124 + break;
67125 + case (FM_FREE_FMAN_CTRL_EVENT_REG):
67126 + FmFreeFmanCtrlEventReg(h_Fm, p_IpcMsg->msgBody[0]);
67127 + break;
67128 + case (FM_GET_TIMESTAMP_SCALE):
67129 + {
67130 + uint32_t timeStamp = FmGetTimeStampScale(h_Fm);
67131 +
67132 + memcpy(p_IpcReply->replyBody, (uint8_t*)&timeStamp, sizeof(uint32_t));
67133 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
67134 + break;
67135 + }
67136 + case (FM_GET_COUNTER):
67137 + {
67138 + e_FmCounters inCounter;
67139 + uint32_t outCounter;
67140 +
67141 + memcpy((uint8_t*)&inCounter, p_IpcMsg->msgBody, sizeof(uint32_t));
67142 + outCounter = FM_GetCounter(h_Fm, inCounter);
67143 + memcpy(p_IpcReply->replyBody, (uint8_t*)&outCounter, sizeof(uint32_t));
67144 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
67145 + break;
67146 + }
67147 + case (FM_SET_FMAN_CTRL_EVENTS_ENABLE):
67148 + {
67149 + t_FmIpcFmanEvents ipcFmanEvents;
67150 +
67151 + memcpy((uint8_t*)&ipcFmanEvents, p_IpcMsg->msgBody, sizeof(t_FmIpcFmanEvents));
67152 + FmSetFmanCtrlIntr(h_Fm,
67153 + ipcFmanEvents.eventRegId,
67154 + ipcFmanEvents.enableEvents);
67155 + break;
67156 + }
67157 + case (FM_GET_FMAN_CTRL_EVENTS_ENABLE):
67158 + {
67159 + uint32_t tmp = FmGetFmanCtrlIntr(h_Fm, p_IpcMsg->msgBody[0]);
67160 +
67161 + memcpy(p_IpcReply->replyBody, (uint8_t*)&tmp, sizeof(uint32_t));
67162 + *p_ReplyLength = sizeof(uint32_t) + sizeof(uint32_t);
67163 + break;
67164 + }
67165 + case (FM_GET_PHYS_MURAM_BASE):
67166 + {
67167 + t_FmPhysAddr physAddr;
67168 + t_FmIpcPhysAddr ipcPhysAddr;
67169 +
67170 + FmGetPhysicalMuramBase(h_Fm, &physAddr);
67171 + ipcPhysAddr.high = physAddr.high;
67172 + ipcPhysAddr.low = physAddr.low;
67173 + memcpy(p_IpcReply->replyBody, (uint8_t*)&ipcPhysAddr, sizeof(t_FmIpcPhysAddr));
67174 + *p_ReplyLength = sizeof(uint32_t) + sizeof(t_FmIpcPhysAddr);
67175 + break;
67176 + }
67177 + case (FM_ENABLE_RAM_ECC):
67178 + {
67179 + if (((err = FM_EnableRamsEcc(h_Fm)) != E_OK) ||
67180 + ((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, TRUE)) != E_OK) ||
67181 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, TRUE)) != E_OK))
67182 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
67183 + UNUSED(err);
67184 +#else
67185 + REPORT_ERROR(MINOR, err, NO_MSG);
67186 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
67187 + break;
67188 + }
67189 + case (FM_DISABLE_RAM_ECC):
67190 + {
67191 +
67192 + if (((err = FM_SetException(h_Fm, e_FM_EX_IRAM_ECC, FALSE)) != E_OK) ||
67193 + ((err = FM_SetException(h_Fm, e_FM_EX_MURAM_ECC, FALSE)) != E_OK) ||
67194 + ((err = FM_DisableRamsEcc(h_Fm)) != E_OK))
67195 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
67196 + UNUSED(err);
67197 +#else
67198 + REPORT_ERROR(MINOR, err, NO_MSG);
67199 +#endif /* (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0)) */
67200 + break;
67201 + }
67202 + case (FM_SET_NUM_OF_FMAN_CTRL):
67203 + {
67204 + t_FmIpcPortNumOfFmanCtrls ipcPortNumOfFmanCtrls;
67205 +
67206 + memcpy((uint8_t*)&ipcPortNumOfFmanCtrls, p_IpcMsg->msgBody, sizeof(t_FmIpcPortNumOfFmanCtrls));
67207 + err = FmSetNumOfRiscsPerPort(h_Fm,
67208 + ipcPortNumOfFmanCtrls.hardwarePortId,
67209 + ipcPortNumOfFmanCtrls.numOfFmanCtrls,
67210 + ipcPortNumOfFmanCtrls.orFmanCtrl);
67211 + if (err != E_OK)
67212 + REPORT_ERROR(MINOR, err, NO_MSG);
67213 + break;
67214 + }
67215 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
67216 + case (FM_10G_TX_ECC_WA):
67217 + p_IpcReply->error = (uint32_t)Fm10GTxEccWorkaround(h_Fm, p_IpcMsg->msgBody[0]);
67218 + *p_ReplyLength = sizeof(uint32_t);
67219 + break;
67220 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
67221 + default:
67222 + *p_ReplyLength = 0;
67223 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, ("command not found!!!"));
67224 + }
67225 + return E_OK;
67226 +}
67227 +
67228 +
67229 +/****************************************/
67230 +/* Inter-Module functions */
67231 +/****************************************/
67232 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
67233 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId)
67234 +{
67235 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67236 + t_Error err = E_OK;
67237 + t_FmIpcMsg msg;
67238 + t_FmIpcReply reply;
67239 + uint32_t replyLength;
67240 + uint8_t rxHardwarePortId, txHardwarePortId;
67241 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
67242 +
67243 + if (p_Fm->guestId != NCSW_MASTER_ID)
67244 + {
67245 + memset(&msg, 0, sizeof(msg));
67246 + memset(&reply, 0, sizeof(reply));
67247 + msg.msgId = FM_10G_TX_ECC_WA;
67248 + msg.msgBody[0] = macId;
67249 + replyLength = sizeof(uint32_t);
67250 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67251 + (uint8_t*)&msg,
67252 + sizeof(msg.msgId)+sizeof(macId),
67253 + (uint8_t*)&reply,
67254 + &replyLength,
67255 + NULL,
67256 + NULL)) != E_OK)
67257 + RETURN_ERROR(MINOR, err, NO_MSG);
67258 + if (replyLength != sizeof(uint32_t))
67259 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67260 + return (t_Error)(reply.error);
67261 + }
67262 +
67263 + SANITY_CHECK_RETURN_ERROR((macId == 0), E_NOT_SUPPORTED);
67264 + SANITY_CHECK_RETURN_ERROR(IsFmanCtrlCodeLoaded(p_Fm), E_INVALID_STATE);
67265 +
67266 + rxHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_RX_10G,
67267 + macId,
67268 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67269 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67270 + txHardwarePortId = SwPortIdToHwPortId(e_FM_PORT_TYPE_TX_10G,
67271 + macId,
67272 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67273 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67274 + if ((p_Fm->p_FmStateStruct->portsTypes[rxHardwarePortId] != e_FM_PORT_TYPE_DUMMY) ||
67275 + (p_Fm->p_FmStateStruct->portsTypes[txHardwarePortId] != e_FM_PORT_TYPE_DUMMY))
67276 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
67277 + ("MAC should be initialized prior to Rx and Tx ports!"));
67278 +
67279 + return fman_set_erratum_10gmac_a004_wa(fpm_rg);
67280 +}
67281 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
67282 +
67283 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm)
67284 +{
67285 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67286 +
67287 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67288 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
67289 +
67290 + return p_Fm->tnumAgingPeriod;
67291 +}
67292 +
67293 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm,
67294 + uint8_t portNum,
67295 + bool preFetchConfigured)
67296 +{
67297 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67298 +
67299 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67300 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
67301 +
67302 + p_Fm->portsPreFetchConfigured[portNum] = TRUE;
67303 + p_Fm->portsPreFetchValue[portNum] = preFetchConfigured;
67304 +
67305 + return E_OK;
67306 +}
67307 +
67308 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm,
67309 + uint8_t portNum,
67310 + bool *p_PortConfigured,
67311 + bool *p_PreFetchConfigured)
67312 +{
67313 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67314 +
67315 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67316 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
67317 +
67318 + /* If the prefetch wasn't configured yet (not enable or disabled)
67319 + we return the value TRUE as it was already configured */
67320 + if (!p_Fm->portsPreFetchConfigured[portNum])
67321 + {
67322 + *p_PortConfigured = FALSE;
67323 + *p_PreFetchConfigured = FALSE;
67324 + }
67325 + else
67326 + {
67327 + *p_PortConfigured = TRUE;
67328 + *p_PreFetchConfigured = (p_Fm->portsPreFetchConfigured[portNum]);
67329 + }
67330 +
67331 + return E_OK;
67332 +}
67333 +
67334 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
67335 + uint32_t congestionGroupId,
67336 + uint8_t priorityBitMap)
67337 +{
67338 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67339 + uint32_t regNum;
67340 +
67341 + ASSERT_COND(h_Fm);
67342 +
67343 + if (congestionGroupId > FM_PORT_NUM_OF_CONGESTION_GRPS)
67344 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
67345 + ("Congestion group ID bigger than %d",
67346 + FM_PORT_NUM_OF_CONGESTION_GRPS));
67347 +
67348 + if (p_Fm->guestId == NCSW_MASTER_ID)
67349 + {
67350 + ASSERT_COND(p_Fm->baseAddr);
67351 + regNum = (FM_PORT_NUM_OF_CONGESTION_GRPS - 1 - congestionGroupId) / 4;
67352 + fman_set_congestion_group_pfc_priority((uint32_t *)((p_Fm->baseAddr+FM_MM_CGP)),
67353 + congestionGroupId,
67354 + priorityBitMap,
67355 + regNum);
67356 + }
67357 + else if (p_Fm->h_IpcSessions[0])
67358 + {
67359 + t_Error err;
67360 + t_FmIpcMsg msg;
67361 + t_FmIpcSetCongestionGroupPfcPriority fmIpcSetCongestionGroupPfcPriority;
67362 +
67363 + memset(&msg, 0, sizeof(msg));
67364 + memset(&fmIpcSetCongestionGroupPfcPriority, 0, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
67365 + fmIpcSetCongestionGroupPfcPriority.congestionGroupId = congestionGroupId;
67366 + fmIpcSetCongestionGroupPfcPriority.priorityBitMap = priorityBitMap;
67367 +
67368 + msg.msgId = FM_SET_CONG_GRP_PFC_PRIO;
67369 + memcpy(msg.msgBody, &fmIpcSetCongestionGroupPfcPriority, sizeof(t_FmIpcSetCongestionGroupPfcPriority));
67370 +
67371 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67372 + (uint8_t*)&msg,
67373 + sizeof(msg.msgId),
67374 + NULL,
67375 + NULL,
67376 + NULL,
67377 + NULL);
67378 + if (err != E_OK)
67379 + RETURN_ERROR(MINOR, err, NO_MSG);
67380 + }
67381 + else
67382 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("guest without IPC!"));
67383 +
67384 + return E_OK;
67385 +}
67386 +
67387 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm)
67388 +{
67389 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67390 +
67391 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67392 +
67393 + if (!p_Fm->baseAddr)
67394 + {
67395 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
67396 + ("No base-addr; probably Guest with IPC!"));
67397 + return 0;
67398 + }
67399 +
67400 + return (p_Fm->baseAddr + FM_MM_PRS);
67401 +}
67402 +
67403 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm)
67404 +{
67405 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67406 +
67407 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67408 +
67409 + if (!p_Fm->baseAddr)
67410 + {
67411 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
67412 + ("No base-addr; probably Guest with IPC!"));
67413 + return 0;
67414 + }
67415 +
67416 + return (p_Fm->baseAddr + FM_MM_KG);
67417 +}
67418 +
67419 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm)
67420 +{
67421 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67422 +
67423 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67424 +
67425 + if (!p_Fm->baseAddr)
67426 + {
67427 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
67428 + ("No base-addr; probably Guest with IPC!"));
67429 + return 0;
67430 + }
67431 +
67432 + return (p_Fm->baseAddr + FM_MM_PLCR);
67433 +}
67434 +
67435 +#if (DPAA_VERSION >= 11)
67436 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm)
67437 +{
67438 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67439 +
67440 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
67441 +
67442 + return p_Fm->vspBaseAddr;
67443 +}
67444 +#endif /* (DPAA_VERSION >= 11) */
67445 +
67446 +t_Handle FmGetMuramHandle(t_Handle h_Fm)
67447 +{
67448 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67449 +
67450 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
67451 +
67452 + return (p_Fm->h_FmMuram);
67453 +}
67454 +
67455 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *p_FmPhysAddr)
67456 +{
67457 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67458 +
67459 + if (p_Fm->fmMuramPhysBaseAddr)
67460 + {
67461 + /* General FM driver initialization */
67462 + p_FmPhysAddr->low = (uint32_t)p_Fm->fmMuramPhysBaseAddr;
67463 + p_FmPhysAddr->high = (uint8_t)((p_Fm->fmMuramPhysBaseAddr & 0x000000ff00000000LL) >> 32);
67464 + return;
67465 + }
67466 +
67467 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
67468 +
67469 + if (p_Fm->h_IpcSessions[0])
67470 + {
67471 + t_Error err;
67472 + t_FmIpcMsg msg;
67473 + t_FmIpcReply reply;
67474 + uint32_t replyLength;
67475 + t_FmIpcPhysAddr ipcPhysAddr;
67476 +
67477 + memset(&msg, 0, sizeof(msg));
67478 + memset(&reply, 0, sizeof(reply));
67479 + msg.msgId = FM_GET_PHYS_MURAM_BASE;
67480 + replyLength = sizeof(uint32_t) + sizeof(t_FmPhysAddr);
67481 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67482 + (uint8_t*)&msg,
67483 + sizeof(msg.msgId),
67484 + (uint8_t*)&reply,
67485 + &replyLength,
67486 + NULL,
67487 + NULL);
67488 + if (err != E_OK)
67489 + {
67490 + REPORT_ERROR(MINOR, err, NO_MSG);
67491 + return;
67492 + }
67493 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmPhysAddr)))
67494 + {
67495 + REPORT_ERROR(MINOR, E_INVALID_VALUE,("IPC reply length mismatch"));
67496 + return;
67497 + }
67498 + memcpy((uint8_t*)&ipcPhysAddr, reply.replyBody, sizeof(t_FmIpcPhysAddr));
67499 + p_FmPhysAddr->high = ipcPhysAddr.high;
67500 + p_FmPhysAddr->low = ipcPhysAddr.low;
67501 + }
67502 + else
67503 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67504 + ("running in guest-mode without neither IPC nor mapped register!"));
67505 +}
67506 +
67507 +#if (DPAA_VERSION >= 11)
67508 +t_Error FmVSPAllocForPort (t_Handle h_Fm,
67509 + e_FmPortType portType,
67510 + uint8_t portId,
67511 + uint8_t numOfVSPs)
67512 +{
67513 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67514 + t_Error err = E_OK;
67515 + uint32_t profilesFound, intFlags;
67516 + uint8_t first, i;
67517 + uint8_t log2Num;
67518 + uint8_t swPortIndex=0, hardwarePortId;
67519 +
67520 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67521 +
67522 + if (!numOfVSPs)
67523 + return E_OK;
67524 +
67525 + if (numOfVSPs > FM_VSP_MAX_NUM_OF_ENTRIES)
67526 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("numProfiles can not be bigger than %d.",FM_VSP_MAX_NUM_OF_ENTRIES));
67527 +
67528 + if (!POWER_OF_2(numOfVSPs))
67529 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("numProfiles must be a power of 2."));
67530 +
67531 + LOG2((uint64_t)numOfVSPs, log2Num);
67532 +
67533 + if ((log2Num == 0) || (p_Fm->partVSPBase == 0))
67534 + first = 0;
67535 + else
67536 + first = 1<<log2Num;
67537 +
67538 + if (first > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
67539 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
67540 +
67541 + if (first < p_Fm->partVSPBase)
67542 + while (first < p_Fm->partVSPBase)
67543 + first = first + numOfVSPs;
67544 +
67545 + if ((first + numOfVSPs) > (p_Fm->partVSPBase + p_Fm->partNumOfVSPs))
67546 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("can not allocate storage profile port window"));
67547 +
67548 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
67549 + profilesFound = 0;
67550 + for (i=first; i < p_Fm->partVSPBase + p_Fm->partNumOfVSPs; )
67551 + {
67552 + if (!p_Fm->p_FmSp->profiles[i].profilesMng.allocated)
67553 + {
67554 + profilesFound++;
67555 + i++;
67556 + if (profilesFound == numOfVSPs)
67557 + break;
67558 + }
67559 + else
67560 + {
67561 + profilesFound = 0;
67562 + /* advance i to the next aligned address */
67563 + first = i = (uint8_t)(first + numOfVSPs);
67564 + }
67565 + }
67566 + if (profilesFound == numOfVSPs)
67567 + for (i = first; i<first + numOfVSPs; i++)
67568 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = TRUE;
67569 + else
67570 + {
67571 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67572 + RETURN_ERROR(MINOR, E_FULL, ("No profiles."));
67573 + }
67574 +
67575 + hardwarePortId = SwPortIdToHwPortId(portType,
67576 + portId,
67577 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67578 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67579 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67580 +
67581 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = numOfVSPs;
67582 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = first;
67583 +
67584 + if ((err = SetVSPWindow(h_Fm,hardwarePortId, first,log2Num)) != E_OK)
67585 + for (i = first; i < first + numOfVSPs; i++)
67586 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
67587 +
67588 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67589 +
67590 + return err;
67591 +}
67592 +
67593 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
67594 + e_FmPortType portType,
67595 + uint8_t portId)
67596 +{
67597 + t_Fm *p_Fm = (t_Fm *)h_Fm;
67598 + uint8_t swPortIndex=0, hardwarePortId, first, numOfVSPs, i;
67599 + uint32_t intFlags;
67600 +
67601 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67602 +
67603 + hardwarePortId = SwPortIdToHwPortId(portType,
67604 + portId,
67605 + p_Fm->p_FmStateStruct->revInfo.majorRev,
67606 + p_Fm->p_FmStateStruct->revInfo.minorRev);
67607 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
67608 +
67609 + numOfVSPs = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles;
67610 + first = (uint8_t)p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase;
67611 +
67612 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
67613 + for (i = first; i < first + numOfVSPs; i++)
67614 + p_Fm->p_FmSp->profiles[i].profilesMng.allocated = FALSE;
67615 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
67616 +
67617 + p_Fm->p_FmSp->portsMapping[swPortIndex].numOfProfiles = 0;
67618 + p_Fm->p_FmSp->portsMapping[swPortIndex].profilesBase = 0;
67619 +
67620 + return E_OK;
67621 +}
67622 +#endif /* (DPAA_VERSION >= 11) */
67623 +
67624 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId)
67625 +{
67626 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67627 + uint8_t i;
67628 +
67629 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67630 +
67631 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67632 + p_Fm->h_IpcSessions[0])
67633 + {
67634 + t_Error err;
67635 + t_FmIpcMsg msg;
67636 + t_FmIpcReply reply;
67637 + uint32_t replyLength;
67638 +
67639 + memset(&msg, 0, sizeof(msg));
67640 + memset(&reply, 0, sizeof(reply));
67641 + msg.msgId = FM_ALLOC_FMAN_CTRL_EVENT_REG;
67642 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
67643 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67644 + (uint8_t*)&msg,
67645 + sizeof(msg.msgId),
67646 + (uint8_t*)&reply,
67647 + &replyLength,
67648 + NULL,
67649 + NULL)) != E_OK)
67650 + RETURN_ERROR(MAJOR, err, NO_MSG);
67651 +
67652 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
67653 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67654 +
67655 + *p_EventId = *(uint8_t*)(reply.replyBody);
67656 +
67657 + return (t_Error)(reply.error);
67658 + }
67659 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67660 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
67661 + ("running in guest-mode without IPC!"));
67662 +
67663 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
67664 + if (!p_Fm->usedEventRegs[i])
67665 + {
67666 + p_Fm->usedEventRegs[i] = TRUE;
67667 + *p_EventId = i;
67668 + break;
67669 + }
67670 +
67671 + if (i==FM_NUM_OF_FMAN_CTRL_EVENT_REGS)
67672 + RETURN_ERROR(MAJOR, E_BUSY, ("No resource - FMan controller event register."));
67673 +
67674 + return E_OK;
67675 +}
67676 +
67677 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId)
67678 +{
67679 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67680 +
67681 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
67682 +
67683 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67684 + p_Fm->h_IpcSessions[0])
67685 + {
67686 + t_Error err;
67687 + t_FmIpcMsg msg;
67688 +
67689 + memset(&msg, 0, sizeof(msg));
67690 + msg.msgId = FM_FREE_FMAN_CTRL_EVENT_REG;
67691 + msg.msgBody[0] = eventId;
67692 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67693 + (uint8_t*)&msg,
67694 + sizeof(msg.msgId)+sizeof(eventId),
67695 + NULL,
67696 + NULL,
67697 + NULL,
67698 + NULL);
67699 + if (err != E_OK)
67700 + REPORT_ERROR(MINOR, err, NO_MSG);
67701 + return;
67702 + }
67703 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67704 + {
67705 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67706 + ("running in guest-mode without IPC!"));
67707 + return;
67708 + }
67709 +
67710 + ((t_Fm*)h_Fm)->usedEventRegs[eventId] = FALSE;
67711 +}
67712 +
67713 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents)
67714 +{
67715 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67716 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
67717 +
67718 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67719 + !p_Fm->p_FmFpmRegs &&
67720 + p_Fm->h_IpcSessions[0])
67721 + {
67722 + t_FmIpcFmanEvents fmanCtrl;
67723 + t_Error err;
67724 + t_FmIpcMsg msg;
67725 +
67726 + fmanCtrl.eventRegId = eventRegId;
67727 + fmanCtrl.enableEvents = enableEvents;
67728 + memset(&msg, 0, sizeof(msg));
67729 + msg.msgId = FM_SET_FMAN_CTRL_EVENTS_ENABLE;
67730 + memcpy(msg.msgBody, &fmanCtrl, sizeof(fmanCtrl));
67731 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67732 + (uint8_t*)&msg,
67733 + sizeof(msg.msgId)+sizeof(fmanCtrl),
67734 + NULL,
67735 + NULL,
67736 + NULL,
67737 + NULL);
67738 + if (err != E_OK)
67739 + REPORT_ERROR(MINOR, err, NO_MSG);
67740 + return;
67741 + }
67742 + else if (!p_Fm->p_FmFpmRegs)
67743 + {
67744 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67745 + ("Either IPC or 'baseAddress' is required!"));
67746 + return;
67747 + }
67748 +
67749 + ASSERT_COND(eventRegId < FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
67750 + fman_set_ctrl_intr(fpm_rg, eventRegId, enableEvents);
67751 +}
67752 +
67753 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
67754 +{
67755 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67756 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
67757 +
67758 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67759 + !p_Fm->p_FmFpmRegs &&
67760 + p_Fm->h_IpcSessions[0])
67761 + {
67762 + t_Error err;
67763 + t_FmIpcMsg msg;
67764 + t_FmIpcReply reply;
67765 + uint32_t replyLength, ctrlIntr;
67766 +
67767 + memset(&msg, 0, sizeof(msg));
67768 + memset(&reply, 0, sizeof(reply));
67769 + msg.msgId = FM_GET_FMAN_CTRL_EVENTS_ENABLE;
67770 + msg.msgBody[0] = eventRegId;
67771 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
67772 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67773 + (uint8_t*)&msg,
67774 + sizeof(msg.msgId)+sizeof(eventRegId),
67775 + (uint8_t*)&reply,
67776 + &replyLength,
67777 + NULL,
67778 + NULL);
67779 + if (err != E_OK)
67780 + {
67781 + REPORT_ERROR(MINOR, err, NO_MSG);
67782 + return 0;
67783 + }
67784 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
67785 + {
67786 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
67787 + return 0;
67788 + }
67789 + memcpy((uint8_t*)&ctrlIntr, reply.replyBody, sizeof(uint32_t));
67790 + return ctrlIntr;
67791 + }
67792 + else if (!p_Fm->p_FmFpmRegs)
67793 + {
67794 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67795 + ("Either IPC or 'baseAddress' is required!"));
67796 + return 0;
67797 + }
67798 +
67799 + return fman_get_ctrl_intr(fpm_rg, eventRegId);
67800 +}
67801 +
67802 +void FmRegisterIntr(t_Handle h_Fm,
67803 + e_FmEventModules module,
67804 + uint8_t modId,
67805 + e_FmIntrType intrType,
67806 + void (*f_Isr) (t_Handle h_Arg),
67807 + t_Handle h_Arg)
67808 +{
67809 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67810 + int event = 0;
67811 +
67812 + ASSERT_COND(h_Fm);
67813 +
67814 + GET_FM_MODULE_EVENT(module, modId, intrType, event);
67815 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
67816 +
67817 + /* register in local FM structure */
67818 + p_Fm->intrMng[event].f_Isr = f_Isr;
67819 + p_Fm->intrMng[event].h_SrcHandle = h_Arg;
67820 +
67821 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67822 + p_Fm->h_IpcSessions[0])
67823 + {
67824 + t_FmIpcRegisterIntr fmIpcRegisterIntr;
67825 + t_Error err;
67826 + t_FmIpcMsg msg;
67827 +
67828 + /* register in Master FM structure */
67829 + fmIpcRegisterIntr.event = (uint32_t)event;
67830 + fmIpcRegisterIntr.guestId = p_Fm->guestId;
67831 + memset(&msg, 0, sizeof(msg));
67832 + msg.msgId = FM_REGISTER_INTR;
67833 + memcpy(msg.msgBody, &fmIpcRegisterIntr, sizeof(fmIpcRegisterIntr));
67834 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67835 + (uint8_t*)&msg,
67836 + sizeof(msg.msgId) + sizeof(fmIpcRegisterIntr),
67837 + NULL,
67838 + NULL,
67839 + NULL,
67840 + NULL);
67841 + if (err != E_OK)
67842 + REPORT_ERROR(MINOR, err, NO_MSG);
67843 + }
67844 + else if (p_Fm->guestId != NCSW_MASTER_ID)
67845 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
67846 + ("running in guest-mode without IPC!"));
67847 +}
67848 +
67849 +void FmUnregisterIntr(t_Handle h_Fm,
67850 + e_FmEventModules module,
67851 + uint8_t modId,
67852 + e_FmIntrType intrType)
67853 +{
67854 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67855 + int event = 0;
67856 +
67857 + ASSERT_COND(h_Fm);
67858 +
67859 + GET_FM_MODULE_EVENT(module, modId,intrType, event);
67860 + ASSERT_COND(event < e_FM_EV_DUMMY_LAST);
67861 +
67862 + p_Fm->intrMng[event].f_Isr = UnimplementedIsr;
67863 + p_Fm->intrMng[event].h_SrcHandle = NULL;
67864 +}
67865 +
67866 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Arg, uint32_t event), t_Handle h_Arg)
67867 +{
67868 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67869 +
67870 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
67871 +
67872 + if (p_Fm->guestId != NCSW_MASTER_ID)
67873 + {
67874 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
67875 + return;
67876 + }
67877 +
67878 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = f_Isr;
67879 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = h_Arg;
67880 +}
67881 +
67882 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId)
67883 +{
67884 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67885 +
67886 + ASSERT_COND(eventRegId<FM_NUM_OF_FMAN_CTRL_EVENT_REGS);
67887 +
67888 + if (p_Fm->guestId != NCSW_MASTER_ID)
67889 + {
67890 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("FM in guest-mode"));
67891 + return;
67892 + }
67893 +
67894 + p_Fm->fmanCtrlIntr[eventRegId].f_Isr = UnimplementedFmanCtrlIsr;
67895 + p_Fm->fmanCtrlIntr[eventRegId].h_SrcHandle = NULL;
67896 +}
67897 +
67898 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd)
67899 +{
67900 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67901 +
67902 + if (p_Fm->h_Pcd)
67903 + REPORT_ERROR(MAJOR, E_ALREADY_EXISTS, ("PCD already set"));
67904 +
67905 + p_Fm->h_Pcd = h_FmPcd;
67906 +}
67907 +
67908 +void FmUnregisterPcd(t_Handle h_Fm)
67909 +{
67910 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67911 +
67912 + if (!p_Fm->h_Pcd)
67913 + REPORT_ERROR(MAJOR, E_NOT_FOUND, ("PCD handle!"));
67914 +
67915 + p_Fm->h_Pcd = NULL;
67916 +}
67917 +
67918 +t_Handle FmGetPcdHandle(t_Handle h_Fm)
67919 +{
67920 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67921 +
67922 + return p_Fm->h_Pcd;
67923 +}
67924 +
67925 +uint8_t FmGetId(t_Handle h_Fm)
67926 +{
67927 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67928 +
67929 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0xff);
67930 +
67931 + return p_Fm->p_FmStateStruct->fmId;
67932 +}
67933 +
67934 +t_Error FmReset(t_Handle h_Fm)
67935 +{
67936 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67937 +
67938 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67939 +
67940 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rstc, FPM_RSTC_FM_RESET);
67941 + CORE_MemoryBarrier();
67942 + XX_UDelay(100);
67943 +
67944 + return E_OK;
67945 +}
67946 +
67947 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm,
67948 + uint8_t hardwarePortId,
67949 + uint8_t numOfFmanCtrls,
67950 + t_FmFmanCtrl orFmanCtrl)
67951 +{
67952 +
67953 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67954 + struct fman_fpm_regs *fpm_rg;
67955 +
67956 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
67957 + SANITY_CHECK_RETURN_ERROR(((numOfFmanCtrls > 0) && (numOfFmanCtrls < 3)) , E_INVALID_HANDLE);
67958 +
67959 + fpm_rg = p_Fm->p_FmFpmRegs;
67960 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
67961 + !p_Fm->p_FmFpmRegs &&
67962 + p_Fm->h_IpcSessions[0])
67963 + {
67964 + t_Error err;
67965 + t_FmIpcPortNumOfFmanCtrls params;
67966 + t_FmIpcMsg msg;
67967 +
67968 + memset(&msg, 0, sizeof(msg));
67969 + params.hardwarePortId = hardwarePortId;
67970 + params.numOfFmanCtrls = numOfFmanCtrls;
67971 + params.orFmanCtrl = orFmanCtrl;
67972 + msg.msgId = FM_SET_NUM_OF_FMAN_CTRL;
67973 + memcpy(msg.msgBody, &params, sizeof(params));
67974 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
67975 + (uint8_t*)&msg,
67976 + sizeof(msg.msgId) +sizeof(params),
67977 + NULL,
67978 + NULL,
67979 + NULL,
67980 + NULL);
67981 + if (err != E_OK)
67982 + RETURN_ERROR(MINOR, err, NO_MSG);
67983 + return E_OK;
67984 + }
67985 + else if (!p_Fm->p_FmFpmRegs)
67986 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
67987 + ("Either IPC or 'baseAddress' is required!"));
67988 +
67989 + fman_set_num_of_riscs_per_port(fpm_rg, hardwarePortId, numOfFmanCtrls, orFmanCtrl);
67990 +
67991 + return E_OK;
67992 +}
67993 +
67994 +t_Error FmGetSetPortParams(t_Handle h_Fm, t_FmInterModulePortInitParams *p_PortParams)
67995 +{
67996 + t_Fm *p_Fm = (t_Fm*)h_Fm;
67997 + t_Error err;
67998 + uint32_t intFlags;
67999 + uint8_t hardwarePortId = p_PortParams->hardwarePortId, macId;
68000 + struct fman_rg fman_rg;
68001 +
68002 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
68003 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
68004 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
68005 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
68006 +
68007 + if (p_Fm->guestId != NCSW_MASTER_ID)
68008 + {
68009 + t_FmIpcPortInInitParams portInParams;
68010 + t_FmIpcPortOutInitParams portOutParams;
68011 + t_FmIpcMsg msg;
68012 + t_FmIpcReply reply;
68013 + uint32_t replyLength;
68014 +
68015 + portInParams.hardwarePortId = p_PortParams->hardwarePortId;
68016 + portInParams.enumPortType = (uint32_t)p_PortParams->portType;
68017 + portInParams.boolIndependentMode= (uint8_t)p_PortParams->independentMode;
68018 + portInParams.liodnOffset = p_PortParams->liodnOffset;
68019 + portInParams.numOfTasks = p_PortParams->numOfTasks;
68020 + portInParams.numOfExtraTasks = p_PortParams->numOfExtraTasks;
68021 + portInParams.numOfOpenDmas = p_PortParams->numOfOpenDmas;
68022 + portInParams.numOfExtraOpenDmas = p_PortParams->numOfExtraOpenDmas;
68023 + portInParams.sizeOfFifo = p_PortParams->sizeOfFifo;
68024 + portInParams.extraSizeOfFifo = p_PortParams->extraSizeOfFifo;
68025 + portInParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
68026 + portInParams.maxFrameLength = p_PortParams->maxFrameLength;
68027 + portInParams.liodnBase = p_PortParams->liodnBase;
68028 +
68029 + memset(&msg, 0, sizeof(msg));
68030 + memset(&reply, 0, sizeof(reply));
68031 + msg.msgId = FM_GET_SET_PORT_PARAMS;
68032 + memcpy(msg.msgBody, &portInParams, sizeof(portInParams));
68033 + replyLength = (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams));
68034 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68035 + (uint8_t*)&msg,
68036 + sizeof(msg.msgId) +sizeof(portInParams),
68037 + (uint8_t*)&reply,
68038 + &replyLength,
68039 + NULL,
68040 + NULL)) != E_OK)
68041 + RETURN_ERROR(MINOR, err, NO_MSG);
68042 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcPortOutInitParams)))
68043 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68044 + memcpy((uint8_t*)&portOutParams, reply.replyBody, sizeof(t_FmIpcPortOutInitParams));
68045 +
68046 + p_PortParams->fmMuramPhysBaseAddr.high = portOutParams.ipcPhysAddr.high;
68047 + p_PortParams->fmMuramPhysBaseAddr.low = portOutParams.ipcPhysAddr.low;
68048 + p_PortParams->numOfTasks = portOutParams.numOfTasks;
68049 + p_PortParams->numOfExtraTasks = portOutParams.numOfExtraTasks;
68050 + p_PortParams->numOfOpenDmas = portOutParams.numOfOpenDmas;
68051 + p_PortParams->numOfExtraOpenDmas = portOutParams.numOfExtraOpenDmas;
68052 + p_PortParams->sizeOfFifo = portOutParams.sizeOfFifo;
68053 + p_PortParams->extraSizeOfFifo = portOutParams.extraSizeOfFifo;
68054 +
68055 + return (t_Error)(reply.error);
68056 + }
68057 +
68058 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68059 +
68060 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
68061 + if (p_PortParams->independentMode)
68062 + {
68063 + /* set port parameters */
68064 + p_Fm->independentMode = p_PortParams->independentMode;
68065 + /* disable dispatch limit */
68066 + fman_qmi_disable_dispatch_limit(fman_rg.fpm_rg);
68067 + }
68068 +
68069 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
68070 + {
68071 + if (p_Fm->hcPortInitialized)
68072 + {
68073 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
68074 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Only one host command port is allowed."));
68075 + }
68076 + else
68077 + p_Fm->hcPortInitialized = TRUE;
68078 + }
68079 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = p_PortParams->portType;
68080 +
68081 + err = FmSetNumOfTasks(p_Fm, hardwarePortId, &p_PortParams->numOfTasks, &p_PortParams->numOfExtraTasks, TRUE);
68082 + if (err)
68083 + {
68084 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
68085 + RETURN_ERROR(MAJOR, err, NO_MSG);
68086 + }
68087 +
68088 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
68089 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
68090 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
68091 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
68092 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
68093 + /* for transmit & O/H ports */
68094 + {
68095 + uint8_t enqTh;
68096 + uint8_t deqTh;
68097 +
68098 + /* update qmi ENQ/DEQ threshold */
68099 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums += p_PortParams->deqPipelineDepth;
68100 + enqTh = fman_get_qmi_enq_th(fman_rg.qmi_rg);
68101 + /* if enqTh is too big, we reduce it to the max value that is still OK */
68102 + if (enqTh >= (QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums))
68103 + {
68104 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
68105 + fman_set_qmi_enq_th(fman_rg.qmi_rg, enqTh);
68106 + }
68107 +
68108 + deqTh = fman_get_qmi_deq_th(fman_rg.qmi_rg);
68109 + /* if deqTh is too small, we enlarge it to the min value that is still OK.
68110 + deqTh may not be larger than 63 (QMI_MAX_NUM_OF_TNUMS-1). */
68111 + if ((deqTh <= p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums) && (deqTh < QMI_MAX_NUM_OF_TNUMS-1))
68112 + {
68113 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
68114 + fman_set_qmi_deq_th(fman_rg.qmi_rg, deqTh);
68115 + }
68116 + }
68117 +
68118 +#ifdef FM_LOW_END_RESTRICTION
68119 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
68120 + {
68121 + if (p_Fm->p_FmStateStruct->lowEndRestriction)
68122 + {
68123 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
68124 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE, ("OP #0 cannot work with Tx Port #1."));
68125 + }
68126 + else
68127 + p_Fm->p_FmStateStruct->lowEndRestriction = TRUE;
68128 + }
68129 +#endif /* FM_LOW_END_RESTRICTION */
68130 +
68131 + err = FmSetSizeOfFifo(p_Fm,
68132 + hardwarePortId,
68133 + &p_PortParams->sizeOfFifo,
68134 + &p_PortParams->extraSizeOfFifo,
68135 + TRUE);
68136 + if (err)
68137 + {
68138 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
68139 + RETURN_ERROR(MAJOR, err, NO_MSG);
68140 + }
68141 +
68142 + err = FmSetNumOfOpenDmas(p_Fm,
68143 + hardwarePortId,
68144 + &p_PortParams->numOfOpenDmas,
68145 + &p_PortParams->numOfExtraOpenDmas,
68146 + TRUE);
68147 + if (err)
68148 + {
68149 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
68150 + RETURN_ERROR(MAJOR, err, NO_MSG);
68151 + }
68152 +
68153 + fman_set_liodn_per_port(&fman_rg,
68154 + hardwarePortId,
68155 + p_PortParams->liodnBase,
68156 + p_PortParams->liodnOffset);
68157 +
68158 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
68159 + fman_set_order_restoration_per_port(fman_rg.fpm_rg,
68160 + hardwarePortId,
68161 + p_PortParams->independentMode,
68162 + !!((p_PortParams->portType==e_FM_PORT_TYPE_RX) || (p_PortParams->portType==e_FM_PORT_TYPE_RX_10G)));
68163 +
68164 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
68165 +
68166 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
68167 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
68168 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
68169 + {
68170 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
68171 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId])
68172 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = p_PortParams->maxFrameLength;
68173 + else
68174 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
68175 + }
68176 + else
68177 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
68178 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
68179 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
68180 + {
68181 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
68182 + if (p_PortParams->maxFrameLength >= p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId])
68183 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = p_PortParams->maxFrameLength;
68184 + else
68185 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("Port maxFrameLength is smaller than MAC current MTU"));
68186 + }
68187 +
68188 + FmGetPhysicalMuramBase(p_Fm, &p_PortParams->fmMuramPhysBaseAddr);
68189 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
68190 +
68191 + return E_OK;
68192 +}
68193 +
68194 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams)
68195 +{
68196 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68197 + uint32_t intFlags;
68198 + uint8_t hardwarePortId = p_PortParams->hardwarePortId;
68199 + uint8_t numOfTasks, numOfDmas, macId;
68200 + uint16_t sizeOfFifo;
68201 + t_Error err;
68202 + t_FmIpcPortFreeParams portParams;
68203 + t_FmIpcMsg msg;
68204 + struct fman_qmi_regs *qmi_rg = p_Fm->p_FmQmiRegs;
68205 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
68206 +
68207 + if (p_Fm->guestId != NCSW_MASTER_ID)
68208 + {
68209 + portParams.hardwarePortId = p_PortParams->hardwarePortId;
68210 + portParams.enumPortType = (uint32_t)p_PortParams->portType;
68211 + portParams.deqPipelineDepth = p_PortParams->deqPipelineDepth;
68212 + memset(&msg, 0, sizeof(msg));
68213 + msg.msgId = FM_FREE_PORT;
68214 + memcpy(msg.msgBody, &portParams, sizeof(portParams));
68215 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68216 + (uint8_t*)&msg,
68217 + sizeof(msg.msgId)+sizeof(portParams),
68218 + NULL,
68219 + NULL,
68220 + NULL,
68221 + NULL);
68222 + if (err != E_OK)
68223 + REPORT_ERROR(MINOR, err, NO_MSG);
68224 + return;
68225 + }
68226 +
68227 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68228 +
68229 + intFlags = XX_LockIntrSpinlock(p_Fm->h_Spinlock);
68230 +
68231 + if (p_PortParams->portType == e_FM_PORT_TYPE_OH_HOST_COMMAND)
68232 + {
68233 + ASSERT_COND(p_Fm->hcPortInitialized);
68234 + p_Fm->hcPortInitialized = FALSE;
68235 + }
68236 +
68237 + p_Fm->p_FmStateStruct->portsTypes[hardwarePortId] = e_FM_PORT_TYPE_DUMMY;
68238 +
68239 + /* free numOfTasks */
68240 + numOfTasks = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
68241 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= numOfTasks);
68242 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= numOfTasks;
68243 +
68244 + /* free numOfOpenDmas */
68245 + numOfDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
68246 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= numOfDmas);
68247 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= numOfDmas;
68248 +
68249 +#ifdef FM_HAS_TOTAL_DMAS
68250 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
68251 + {
68252 + /* update total num of DMA's with committed number of open DMAS, and max uncommitted pool. */
68253 + fman_set_num_of_open_dmas(bmi_rg,
68254 + hardwarePortId,
68255 + 1,
68256 + 0,
68257 + (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize));
68258 + }
68259 +#endif /* FM_HAS_TOTAL_DMAS */
68260 +
68261 + /* free sizeOfFifo */
68262 + sizeOfFifo = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
68263 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= (sizeOfFifo * BMI_FIFO_UNITS));
68264 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= (sizeOfFifo * BMI_FIFO_UNITS);
68265 +
68266 +#ifdef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
68267 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
68268 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
68269 + if ((p_PortParams->portType != e_FM_PORT_TYPE_RX) &&
68270 + (p_PortParams->portType != e_FM_PORT_TYPE_RX_10G))
68271 + /* for transmit & O/H ports */
68272 + {
68273 + uint8_t enqTh;
68274 + uint8_t deqTh;
68275 +
68276 + /* update qmi ENQ/DEQ threshold */
68277 + p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums -= p_PortParams->deqPipelineDepth;
68278 +
68279 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
68280 + so we can enlarge enqTh */
68281 + enqTh = (uint8_t)(QMI_MAX_NUM_OF_TNUMS - p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums - 1);
68282 +
68283 + /* p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums is now smaller,
68284 + so we can reduce deqTh */
68285 + deqTh = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfDeqTnums + 1);
68286 +
68287 + fman_set_qmi_enq_th(qmi_rg, enqTh);
68288 + fman_set_qmi_deq_th(qmi_rg, deqTh);
68289 + }
68290 +
68291 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
68292 +
68293 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
68294 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX_10G) ||
68295 + (p_PortParams->portType == e_FM_PORT_TYPE_RX_10G))
68296 + {
68297 + ASSERT_COND(macId < FM_MAX_NUM_OF_10G_MACS);
68298 + p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] = 0;
68299 + }
68300 + else
68301 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
68302 + if ((p_PortParams->portType == e_FM_PORT_TYPE_TX) ||
68303 + (p_PortParams->portType == e_FM_PORT_TYPE_RX))
68304 + {
68305 + ASSERT_COND(macId < FM_MAX_NUM_OF_1G_MACS);
68306 + p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] = 0;
68307 + }
68308 +
68309 +#ifdef FM_LOW_END_RESTRICTION
68310 + if ((hardwarePortId==0x1) || (hardwarePortId==0x29))
68311 + p_Fm->p_FmStateStruct->lowEndRestriction = FALSE;
68312 +#endif /* FM_LOW_END_RESTRICTION */
68313 + XX_UnlockIntrSpinlock(p_Fm->h_Spinlock, intFlags);
68314 +}
68315 +
68316 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled)
68317 +{
68318 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68319 + t_Error err;
68320 + t_FmIpcMsg msg;
68321 + t_FmIpcReply reply;
68322 + uint32_t replyLength;
68323 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
68324 +
68325 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68326 + !p_Fm->baseAddr &&
68327 + p_Fm->h_IpcSessions[0])
68328 + {
68329 + memset(&msg, 0, sizeof(msg));
68330 + memset(&reply, 0, sizeof(reply));
68331 + msg.msgId = FM_IS_PORT_STALLED;
68332 + msg.msgBody[0] = hardwarePortId;
68333 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
68334 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68335 + (uint8_t*)&msg,
68336 + sizeof(msg.msgId)+sizeof(hardwarePortId),
68337 + (uint8_t*)&reply,
68338 + &replyLength,
68339 + NULL,
68340 + NULL);
68341 + if (err != E_OK)
68342 + RETURN_ERROR(MINOR, err, NO_MSG);
68343 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
68344 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68345 +
68346 + *p_IsStalled = (bool)!!(*(uint8_t*)(reply.replyBody));
68347 +
68348 + return (t_Error)(reply.error);
68349 + }
68350 + else if (!p_Fm->baseAddr)
68351 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68352 + ("Either IPC or 'baseAddress' is required!"));
68353 +
68354 + *p_IsStalled = fman_is_port_stalled(fpm_rg, hardwarePortId);
68355 +
68356 + return E_OK;
68357 +}
68358 +
68359 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId)
68360 +{
68361 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68362 + t_Error err;
68363 + bool isStalled;
68364 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
68365 +
68366 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68367 + !p_Fm->baseAddr &&
68368 + p_Fm->h_IpcSessions[0])
68369 + {
68370 + t_FmIpcMsg msg;
68371 + t_FmIpcReply reply;
68372 + uint32_t replyLength;
68373 +
68374 + memset(&msg, 0, sizeof(msg));
68375 + memset(&reply, 0, sizeof(reply));
68376 + msg.msgId = FM_RESUME_STALLED_PORT;
68377 + msg.msgBody[0] = hardwarePortId;
68378 + replyLength = sizeof(uint32_t);
68379 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68380 + (uint8_t*)&msg,
68381 + sizeof(msg.msgId) + sizeof(hardwarePortId),
68382 + (uint8_t*)&reply,
68383 + &replyLength,
68384 + NULL,
68385 + NULL);
68386 + if (err != E_OK)
68387 + RETURN_ERROR(MINOR, err, NO_MSG);
68388 + if (replyLength != sizeof(uint32_t))
68389 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68390 + return (t_Error)(reply.error);
68391 + }
68392 + else if (!p_Fm->baseAddr)
68393 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68394 + ("Either IPC or 'baseAddress' is required!"));
68395 +
68396 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68397 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Not available for this FM revision!"));
68398 +
68399 + /* Get port status */
68400 + err = FmIsPortStalled(h_Fm, hardwarePortId, &isStalled);
68401 + if (err)
68402 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Can't get port status"));
68403 + if (!isStalled)
68404 + return E_OK;
68405 +
68406 + fman_resume_stalled_port(fpm_rg, hardwarePortId);
68407 +
68408 + return E_OK;
68409 +}
68410 +
68411 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId)
68412 +{
68413 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68414 + t_Error err;
68415 + struct fman_fpm_regs *fpm_rg = p_Fm->p_FmFpmRegs;
68416 +
68417 +#if (DPAA_VERSION >= 11)
68418 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
68419 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68420 + ("FMan MAC reset!"));
68421 +#endif /*(DPAA_VERSION >= 11)*/
68422 +
68423 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68424 + !p_Fm->baseAddr &&
68425 + p_Fm->h_IpcSessions[0])
68426 + {
68427 + t_FmIpcMacParams macParams;
68428 + t_FmIpcMsg msg;
68429 + t_FmIpcReply reply;
68430 + uint32_t replyLength;
68431 +
68432 + memset(&msg, 0, sizeof(msg));
68433 + memset(&reply, 0, sizeof(reply));
68434 + macParams.id = macId;
68435 + macParams.enumType = (uint32_t)type;
68436 + msg.msgId = FM_RESET_MAC;
68437 + memcpy(msg.msgBody, &macParams, sizeof(macParams));
68438 + replyLength = sizeof(uint32_t);
68439 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68440 + (uint8_t*)&msg,
68441 + sizeof(msg.msgId)+sizeof(macParams),
68442 + (uint8_t*)&reply,
68443 + &replyLength,
68444 + NULL,
68445 + NULL);
68446 + if (err != E_OK)
68447 + RETURN_ERROR(MINOR, err, NO_MSG);
68448 + if (replyLength != sizeof(uint32_t))
68449 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68450 + return (t_Error)(reply.error);
68451 + }
68452 + else if (!p_Fm->baseAddr)
68453 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68454 + ("Either IPC or 'baseAddress' is required!"));
68455 +
68456 + err = (t_Error)fman_reset_mac(fpm_rg, macId, !!(type == e_FM_MAC_10G));
68457 +
68458 + if (err == -EBUSY)
68459 + return ERROR_CODE(E_TIMEOUT);
68460 + else if (err)
68461 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal MAC ID"));
68462 +
68463 + return E_OK;
68464 +}
68465 +
68466 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu)
68467 +{
68468 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68469 +
68470 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68471 + p_Fm->h_IpcSessions[0])
68472 + {
68473 + t_FmIpcMacMaxFrameParams macMaxFrameLengthParams;
68474 + t_Error err;
68475 + t_FmIpcMsg msg;
68476 +
68477 + memset(&msg, 0, sizeof(msg));
68478 + macMaxFrameLengthParams.macParams.id = macId;
68479 + macMaxFrameLengthParams.macParams.enumType = (uint32_t)type;
68480 + macMaxFrameLengthParams.maxFrameLength = (uint16_t)mtu;
68481 + msg.msgId = FM_SET_MAC_MAX_FRAME;
68482 + memcpy(msg.msgBody, &macMaxFrameLengthParams, sizeof(macMaxFrameLengthParams));
68483 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68484 + (uint8_t*)&msg,
68485 + sizeof(msg.msgId)+sizeof(macMaxFrameLengthParams),
68486 + NULL,
68487 + NULL,
68488 + NULL,
68489 + NULL);
68490 + if (err != E_OK)
68491 + RETURN_ERROR(MINOR, err, NO_MSG);
68492 + return E_OK;
68493 + }
68494 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68495 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
68496 + ("running in guest-mode without IPC!"));
68497 +
68498 + /* if port is already initialized, check that MaxFrameLength is smaller
68499 + * or equal to the port's max */
68500 +#if (defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS))
68501 + if (type == e_FM_MAC_10G)
68502 + {
68503 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])
68504 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId] &&
68505 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths10G[macId])))
68506 + p_Fm->p_FmStateStruct->macMaxFrameLengths10G[macId] = mtu;
68507 + else
68508 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
68509 +
68510 + }
68511 + else
68512 +#else
68513 + UNUSED(type);
68514 +#endif /* (defined(FM_MAX_NUM_OF_10G_MACS) && ... */
68515 + if ((!p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])
68516 + || (p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId] &&
68517 + (mtu <= p_Fm->p_FmStateStruct->portMaxFrameLengths1G[macId])))
68518 + p_Fm->p_FmStateStruct->macMaxFrameLengths1G[macId] = mtu;
68519 + else
68520 + RETURN_ERROR(MINOR, E_INVALID_VALUE, ("MAC maxFrameLength is larger than Port maxFrameLength"));
68521 +
68522 + return E_OK;
68523 +}
68524 +
68525 +uint16_t FmGetClockFreq(t_Handle h_Fm)
68526 +{
68527 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68528 +
68529 + /* for multicore environment: this depends on the
68530 + * fact that fmClkFreq was properly initialized at "init". */
68531 + return p_Fm->p_FmStateStruct->fmClkFreq;
68532 +}
68533 +
68534 +uint16_t FmGetMacClockFreq(t_Handle h_Fm)
68535 +{
68536 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68537 +
68538 + return p_Fm->p_FmStateStruct->fmMacClkFreq;
68539 +}
68540 +
68541 +uint32_t FmGetTimeStampScale(t_Handle h_Fm)
68542 +{
68543 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68544 +
68545 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68546 + !p_Fm->baseAddr &&
68547 + p_Fm->h_IpcSessions[0])
68548 + {
68549 + t_Error err;
68550 + t_FmIpcMsg msg;
68551 + t_FmIpcReply reply;
68552 + uint32_t replyLength, timeStamp;
68553 +
68554 + memset(&msg, 0, sizeof(msg));
68555 + memset(&reply, 0, sizeof(reply));
68556 + msg.msgId = FM_GET_TIMESTAMP_SCALE;
68557 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
68558 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68559 + (uint8_t*)&msg,
68560 + sizeof(msg.msgId),
68561 + (uint8_t*)&reply,
68562 + &replyLength,
68563 + NULL,
68564 + NULL)) != E_OK)
68565 + {
68566 + REPORT_ERROR(MAJOR, err, NO_MSG);
68567 + return 0;
68568 + }
68569 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
68570 + {
68571 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68572 + return 0;
68573 + }
68574 +
68575 + memcpy((uint8_t*)&timeStamp, reply.replyBody, sizeof(uint32_t));
68576 + return timeStamp;
68577 + }
68578 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68579 + p_Fm->baseAddr)
68580 + {
68581 + if (!(GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_tsc1) & FPM_TS_CTL_EN))
68582 + {
68583 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("timestamp is not enabled!"));
68584 + return 0;
68585 + }
68586 + }
68587 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68588 + DBG(WARNING, ("No IPC - can't validate FM if timestamp enabled."));
68589 +
68590 + return p_Fm->p_FmStateStruct->count1MicroBit;
68591 +}
68592 +
68593 +t_Error FmEnableRamsEcc(t_Handle h_Fm)
68594 +{
68595 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68596 +
68597 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68598 +
68599 + p_Fm->p_FmStateStruct->ramsEccOwners++;
68600 + p_Fm->p_FmStateStruct->internalCall = TRUE;
68601 +
68602 + return FM_EnableRamsEcc(p_Fm);
68603 +}
68604 +
68605 +t_Error FmDisableRamsEcc(t_Handle h_Fm)
68606 +{
68607 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68608 +
68609 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
68610 +
68611 + ASSERT_COND(p_Fm->p_FmStateStruct->ramsEccOwners);
68612 + p_Fm->p_FmStateStruct->ramsEccOwners--;
68613 +
68614 + if (p_Fm->p_FmStateStruct->ramsEccOwners==0)
68615 + {
68616 + p_Fm->p_FmStateStruct->internalCall = TRUE;
68617 + return FM_DisableRamsEcc(p_Fm);
68618 + }
68619 +
68620 + return E_OK;
68621 +}
68622 +
68623 +uint8_t FmGetGuestId(t_Handle h_Fm)
68624 +{
68625 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68626 +
68627 + return p_Fm->guestId;
68628 +}
68629 +
68630 +bool FmIsMaster(t_Handle h_Fm)
68631 +{
68632 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68633 +
68634 + return (p_Fm->guestId == NCSW_MASTER_ID);
68635 +}
68636 +
68637 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
68638 + uint8_t hardwarePortId,
68639 + uint32_t *p_SizeOfFifo,
68640 + uint32_t *p_ExtraSizeOfFifo,
68641 + bool initialConfig)
68642 +{
68643 + t_Fm *p_Fm = (t_Fm*)h_Fm;
68644 + t_FmIpcPortRsrcParams rsrcParams;
68645 + t_Error err;
68646 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
68647 + uint32_t sizeOfFifo = *p_SizeOfFifo, extraSizeOfFifo = *p_ExtraSizeOfFifo;
68648 + uint16_t currentVal = 0, currentExtraVal = 0;
68649 +
68650 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68651 + !p_Fm->baseAddr &&
68652 + p_Fm->h_IpcSessions[0])
68653 + {
68654 + t_FmIpcMsg msg;
68655 + t_FmIpcReply reply;
68656 + uint32_t replyLength;
68657 +
68658 + rsrcParams.hardwarePortId = hardwarePortId;
68659 + rsrcParams.val = sizeOfFifo;
68660 + rsrcParams.extra = extraSizeOfFifo;
68661 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
68662 +
68663 + memset(&msg, 0, sizeof(msg));
68664 + memset(&reply, 0, sizeof(reply));
68665 + msg.msgId = FM_SET_SIZE_OF_FIFO;
68666 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
68667 + replyLength = sizeof(uint32_t);
68668 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68669 + (uint8_t*)&msg,
68670 + sizeof(msg.msgId) + sizeof(rsrcParams),
68671 + (uint8_t*)&reply,
68672 + &replyLength,
68673 + NULL,
68674 + NULL)) != E_OK)
68675 + RETURN_ERROR(MINOR, err, NO_MSG);
68676 + if (replyLength != sizeof(uint32_t))
68677 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68678 + return (t_Error)(reply.error);
68679 + }
68680 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68681 + p_Fm->baseAddr)
68682 + {
68683 + DBG(WARNING, ("No IPC - can't validate FM total-fifo size."));
68684 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
68685 + }
68686 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68687 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
68688 + ("running in guest-mode without neither IPC nor mapped register!"));
68689 +
68690 + if (!initialConfig)
68691 + {
68692 + /* !initialConfig - runtime change of existing value.
68693 + * - read the current FIFO and extra FIFO size */
68694 + currentExtraVal = fman_get_size_of_extra_fifo(bmi_rg, hardwarePortId);
68695 + currentVal = fman_get_size_of_fifo(bmi_rg, hardwarePortId);
68696 + }
68697 +
68698 + if (extraSizeOfFifo > currentExtraVal)
68699 + {
68700 + if (extraSizeOfFifo && !p_Fm->p_FmStateStruct->extraFifoPoolSize)
68701 + /* if this is the first time a port requires extraFifoPoolSize, the total extraFifoPoolSize
68702 + * must be initialized to 1 buffer per port
68703 + */
68704 + p_Fm->p_FmStateStruct->extraFifoPoolSize = FM_MAX_NUM_OF_RX_PORTS*BMI_FIFO_UNITS;
68705 +
68706 + p_Fm->p_FmStateStruct->extraFifoPoolSize = MAX(p_Fm->p_FmStateStruct->extraFifoPoolSize, extraSizeOfFifo);
68707 + }
68708 +
68709 + /* check that there are enough uncommitted fifo size */
68710 + if ((p_Fm->p_FmStateStruct->accumulatedFifoSize - currentVal + sizeOfFifo) >
68711 + (p_Fm->p_FmStateStruct->totalFifoSize - p_Fm->p_FmStateStruct->extraFifoPoolSize)){
68712 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
68713 + ("Port request fifo size + accumulated size > total FIFO size:"));
68714 + RETURN_ERROR(MAJOR, E_INVALID_VALUE,
68715 + ("port 0x%x requested %d bytes, extra size = %d, accumulated size = %d total size = %d",
68716 + hardwarePortId, sizeOfFifo, p_Fm->p_FmStateStruct->extraFifoPoolSize,
68717 + p_Fm->p_FmStateStruct->accumulatedFifoSize,
68718 + p_Fm->p_FmStateStruct->totalFifoSize));
68719 + }
68720 + else
68721 + {
68722 + /* update accumulated */
68723 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedFifoSize >= currentVal);
68724 + p_Fm->p_FmStateStruct->accumulatedFifoSize -= currentVal;
68725 + p_Fm->p_FmStateStruct->accumulatedFifoSize += sizeOfFifo;
68726 + fman_set_size_of_fifo(bmi_rg, hardwarePortId, sizeOfFifo, extraSizeOfFifo);
68727 + }
68728 +
68729 + return E_OK;
68730 +}
68731 +
68732 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
68733 + uint8_t hardwarePortId,
68734 + uint8_t *p_NumOfTasks,
68735 + uint8_t *p_NumOfExtraTasks,
68736 + bool initialConfig)
68737 +{
68738 + t_Fm *p_Fm = (t_Fm *)h_Fm;
68739 + t_Error err;
68740 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
68741 + uint8_t currentVal = 0, currentExtraVal = 0, numOfTasks = *p_NumOfTasks, numOfExtraTasks = *p_NumOfExtraTasks;
68742 +
68743 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68744 +
68745 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68746 + !p_Fm->baseAddr &&
68747 + p_Fm->h_IpcSessions[0])
68748 + {
68749 + t_FmIpcPortRsrcParams rsrcParams;
68750 + t_FmIpcMsg msg;
68751 + t_FmIpcReply reply;
68752 + uint32_t replyLength;
68753 +
68754 + rsrcParams.hardwarePortId = hardwarePortId;
68755 + rsrcParams.val = numOfTasks;
68756 + rsrcParams.extra = numOfExtraTasks;
68757 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
68758 +
68759 + memset(&msg, 0, sizeof(msg));
68760 + memset(&reply, 0, sizeof(reply));
68761 + msg.msgId = FM_SET_NUM_OF_TASKS;
68762 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
68763 + replyLength = sizeof(uint32_t);
68764 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68765 + (uint8_t*)&msg,
68766 + sizeof(msg.msgId) + sizeof(rsrcParams),
68767 + (uint8_t*)&reply,
68768 + &replyLength,
68769 + NULL,
68770 + NULL)) != E_OK)
68771 + RETURN_ERROR(MINOR, err, NO_MSG);
68772 + if (replyLength != sizeof(uint32_t))
68773 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68774 + return (t_Error)(reply.error);
68775 + }
68776 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68777 + p_Fm->baseAddr)
68778 + {
68779 + DBG(WARNING, ("No IPC - can't validate FM total-num-of-tasks."));
68780 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
68781 + }
68782 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68783 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
68784 + ("running in guest-mode without neither IPC nor mapped register!"));
68785 +
68786 + if (!initialConfig)
68787 + {
68788 + /* !initialConfig - runtime change of existing value.
68789 + * - read the current number of tasks */
68790 + currentVal = fman_get_num_of_tasks(bmi_rg, hardwarePortId);
68791 + currentExtraVal = fman_get_num_extra_tasks(bmi_rg, hardwarePortId);
68792 + }
68793 +
68794 + if (numOfExtraTasks > currentExtraVal)
68795 + p_Fm->p_FmStateStruct->extraTasksPoolSize =
68796 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraTasksPoolSize, numOfExtraTasks);
68797 +
68798 + /* check that there are enough uncommitted tasks */
68799 + if ((p_Fm->p_FmStateStruct->accumulatedNumOfTasks - currentVal + numOfTasks) >
68800 + (p_Fm->p_FmStateStruct->totalNumOfTasks - p_Fm->p_FmStateStruct->extraTasksPoolSize))
68801 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
68802 + ("Requested numOfTasks and extra tasks pool for fm%d exceed total numOfTasks.",
68803 + p_Fm->p_FmStateStruct->fmId));
68804 + else
68805 + {
68806 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfTasks >= currentVal);
68807 + /* update accumulated */
68808 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks -= currentVal;
68809 + p_Fm->p_FmStateStruct->accumulatedNumOfTasks += numOfTasks;
68810 + fman_set_num_of_tasks(bmi_rg, hardwarePortId, numOfTasks, numOfExtraTasks);
68811 + }
68812 +
68813 + return E_OK;
68814 +}
68815 +
68816 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
68817 + uint8_t hardwarePortId,
68818 + uint8_t *p_NumOfOpenDmas,
68819 + uint8_t *p_NumOfExtraOpenDmas,
68820 + bool initialConfig)
68821 +
68822 +{
68823 + t_Fm *p_Fm = (t_Fm *)h_Fm;
68824 + t_Error err;
68825 + struct fman_bmi_regs *bmi_rg = p_Fm->p_FmBmiRegs;
68826 + uint8_t numOfOpenDmas = *p_NumOfOpenDmas, numOfExtraOpenDmas = *p_NumOfExtraOpenDmas;
68827 + uint8_t totalNumDmas = 0, currentVal = 0, currentExtraVal = 0;
68828 +
68829 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
68830 +
68831 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68832 + !p_Fm->baseAddr &&
68833 + p_Fm->h_IpcSessions[0])
68834 + {
68835 + t_FmIpcPortRsrcParams rsrcParams;
68836 + t_FmIpcMsg msg;
68837 + t_FmIpcReply reply;
68838 + uint32_t replyLength;
68839 +
68840 + rsrcParams.hardwarePortId = hardwarePortId;
68841 + rsrcParams.val = numOfOpenDmas;
68842 + rsrcParams.extra = numOfExtraOpenDmas;
68843 + rsrcParams.boolInitialConfig = (uint8_t)initialConfig;
68844 +
68845 + memset(&msg, 0, sizeof(msg));
68846 + memset(&reply, 0, sizeof(reply));
68847 + msg.msgId = FM_SET_NUM_OF_OPEN_DMAS;
68848 + memcpy(msg.msgBody, &rsrcParams, sizeof(rsrcParams));
68849 + replyLength = sizeof(uint32_t);
68850 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
68851 + (uint8_t*)&msg,
68852 + sizeof(msg.msgId) + sizeof(rsrcParams),
68853 + (uint8_t*)&reply,
68854 + &replyLength,
68855 + NULL,
68856 + NULL)) != E_OK)
68857 + RETURN_ERROR(MINOR, err, NO_MSG);
68858 + if (replyLength != sizeof(uint32_t))
68859 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
68860 + return (t_Error)(reply.error);
68861 + }
68862 +#ifdef FM_HAS_TOTAL_DMAS
68863 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68864 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("running in guest-mode without IPC!"));
68865 +#else
68866 + else if ((p_Fm->guestId != NCSW_MASTER_ID) &&
68867 + p_Fm->baseAddr &&
68868 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
68869 + {
68870 + /*DBG(WARNING, ("No IPC - can't validate FM total-num-of-dmas."));*/
68871 +
68872 + if (!numOfOpenDmas)
68873 + {
68874 + /* first config without explic it value: Do Nothing - reset value shouldn't be
68875 + changed, read register for port save */
68876 + *p_NumOfOpenDmas = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
68877 + *p_NumOfExtraOpenDmas = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
68878 + }
68879 + else
68880 + /* whether it is the first time with explicit value, or runtime "set" - write register */
68881 + fman_set_num_of_open_dmas(bmi_rg,
68882 + hardwarePortId,
68883 + numOfOpenDmas,
68884 + numOfExtraOpenDmas,
68885 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
68886 + }
68887 + else if (p_Fm->guestId != NCSW_MASTER_ID)
68888 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED,
68889 + ("running in guest-mode without neither IPC nor mapped register!"));
68890 +#endif /* FM_HAS_TOTAL_DMAS */
68891 +
68892 + if (!initialConfig)
68893 + {
68894 + /* !initialConfig - runtime change of existing value.
68895 + * - read the current number of open Dma's */
68896 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
68897 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
68898 + }
68899 +
68900 +#ifdef FM_NO_GUARANTEED_RESET_VALUES
68901 + /* it's illegal to be in a state where this is not the first set and no value is specified */
68902 + ASSERT_COND(initialConfig || numOfOpenDmas);
68903 + if (!numOfOpenDmas)
68904 + {
68905 + /* !numOfOpenDmas - first configuration according to values in regs.
68906 + * - read the current number of open Dma's */
68907 + currentExtraVal = fman_get_num_extra_dmas(bmi_rg, hardwarePortId);
68908 + currentVal = fman_get_num_of_dmas(bmi_rg, hardwarePortId);
68909 + /* This is the first configuration and user did not specify value (!numOfOpenDmas),
68910 + * reset values will be used and we just save these values for resource management */
68911 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
68912 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, currentExtraVal);
68913 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += currentVal;
68914 + *p_NumOfOpenDmas = currentVal;
68915 + *p_NumOfExtraOpenDmas = currentExtraVal;
68916 + return E_OK;
68917 + }
68918 +#endif /* FM_NO_GUARANTEED_RESET_VALUES */
68919 +
68920 + if (numOfExtraOpenDmas > currentExtraVal)
68921 + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize =
68922 + (uint8_t)MAX(p_Fm->p_FmStateStruct->extraOpenDmasPoolSize, numOfExtraOpenDmas);
68923 +
68924 +#ifdef FM_HAS_TOTAL_DMAS
68925 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev < 6) &&
68926 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas >
68927 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas))
68928 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
68929 + ("Requested numOfOpenDmas for fm%d exceeds total numOfOpenDmas.",
68930 + p_Fm->p_FmStateStruct->fmId));
68931 +#else
68932 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev >= 6) &&
68933 +#ifdef FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
68934 + !((p_Fm->p_FmStateStruct->revInfo.majorRev == 6) &&
68935 + (p_Fm->p_FmStateStruct->revInfo.minorRev == 0)) &&
68936 +#endif /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 */
68937 + (p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas - currentVal + numOfOpenDmas > DMA_THRESH_MAX_COMMQ + 1))
68938 + RETURN_ERROR(MAJOR, E_NOT_AVAILABLE,
68939 + ("Requested numOfOpenDmas for fm%d exceeds DMA Command queue (%d)",
68940 + p_Fm->p_FmStateStruct->fmId, DMA_THRESH_MAX_COMMQ+1));
68941 +#endif /* FM_HAS_TOTAL_DMAS */
68942 + else
68943 + {
68944 + ASSERT_COND(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas >= currentVal);
68945 + /* update acummulated */
68946 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas -= currentVal;
68947 + p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas += numOfOpenDmas;
68948 +
68949 +#ifdef FM_HAS_TOTAL_DMAS
68950 + if (p_Fm->p_FmStateStruct->revInfo.majorRev < 6)
68951 + totalNumDmas = (uint8_t)(p_Fm->p_FmStateStruct->accumulatedNumOfOpenDmas + p_Fm->p_FmStateStruct->extraOpenDmasPoolSize);
68952 +#endif /* FM_HAS_TOTAL_DMAS */
68953 + fman_set_num_of_open_dmas(bmi_rg,
68954 + hardwarePortId,
68955 + numOfOpenDmas,
68956 + numOfExtraOpenDmas,
68957 + totalNumDmas);
68958 + }
68959 +
68960 + return E_OK;
68961 +}
68962 +
68963 +#if (DPAA_VERSION >= 11)
68964 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
68965 + e_FmPortType portType,
68966 + uint8_t portId,
68967 + uint16_t relativeProfile)
68968 +{
68969 + t_Fm *p_Fm;
68970 + t_FmSp *p_FmPcdSp;
68971 + uint8_t swPortIndex=0, hardwarePortId;
68972 +
68973 + ASSERT_COND(h_Fm);
68974 + p_Fm = (t_Fm*)h_Fm;
68975 +
68976 + hardwarePortId = SwPortIdToHwPortId(portType,
68977 + portId,
68978 + p_Fm->p_FmStateStruct->revInfo.majorRev,
68979 + p_Fm->p_FmStateStruct->revInfo.minorRev);
68980 + ASSERT_COND(hardwarePortId);
68981 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
68982 +
68983 + p_FmPcdSp = p_Fm->p_FmSp;
68984 + ASSERT_COND(p_FmPcdSp);
68985 +
68986 + if (!p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
68987 + RETURN_ERROR(MAJOR, E_INVALID_STATE , ("Port has no allocated profiles"));
68988 + if (relativeProfile >= p_FmPcdSp->portsMapping[swPortIndex].numOfProfiles)
68989 + RETURN_ERROR(MAJOR, E_NOT_IN_RANGE , ("Profile id is out of range"));
68990 +
68991 + return E_OK;
68992 +}
68993 +
68994 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
68995 + e_FmPortType portType,
68996 + uint8_t portId,
68997 + uint16_t relativeProfile,
68998 + uint16_t *p_AbsoluteId)
68999 +{
69000 + t_Fm *p_Fm;
69001 + t_FmSp *p_FmPcdSp;
69002 + uint8_t swPortIndex=0, hardwarePortId;
69003 + t_Error err;
69004 +
69005 + ASSERT_COND(h_Fm);
69006 + p_Fm = (t_Fm*)h_Fm;
69007 +
69008 + err = FmVSPCheckRelativeProfile(h_Fm, portType, portId, relativeProfile);
69009 + if (err != E_OK)
69010 + return err;
69011 +
69012 + hardwarePortId = SwPortIdToHwPortId(portType,
69013 + portId,
69014 + p_Fm->p_FmStateStruct->revInfo.majorRev,
69015 + p_Fm->p_FmStateStruct->revInfo.minorRev);
69016 + ASSERT_COND(hardwarePortId);
69017 + HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId);
69018 +
69019 + p_FmPcdSp = p_Fm->p_FmSp;
69020 + ASSERT_COND(p_FmPcdSp);
69021 +
69022 + *p_AbsoluteId = (uint16_t)(p_FmPcdSp->portsMapping[swPortIndex].profilesBase + relativeProfile);
69023 +
69024 + return E_OK;
69025 +}
69026 +#endif /* (DPAA_VERSION >= 11) */
69027 +
69028 +static t_Error InitFmDma(t_Fm *p_Fm)
69029 +{
69030 + t_Error err;
69031 +
69032 + err = (t_Error)fman_dma_init(p_Fm->p_FmDmaRegs, p_Fm->p_FmDriverParam);
69033 + if (err != E_OK)
69034 + return err;
69035 +
69036 + /* Allocate MURAM for CAM */
69037 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
69038 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY),
69039 + DMA_CAM_ALIGN));
69040 + if (!p_Fm->camBaseAddr)
69041 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
69042 +
69043 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
69044 + 0,
69045 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*DMA_CAM_SIZEOF_ENTRY));
69046 +
69047 + if (p_Fm->p_FmStateStruct->revInfo.majorRev == 2)
69048 + {
69049 + FM_MURAM_FreeMem(p_Fm->h_FmMuram, UINT_TO_PTR(p_Fm->camBaseAddr));
69050 +
69051 + p_Fm->camBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
69052 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128),
69053 + 64));
69054 + if (!p_Fm->camBaseAddr)
69055 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for DMA CAM failed"));
69056 +
69057 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->camBaseAddr),
69058 + 0,
69059 + (uint32_t)(p_Fm->p_FmDriverParam->dma_cam_num_of_entries*72 + 128));
69060 +
69061 + switch(p_Fm->p_FmDriverParam->dma_cam_num_of_entries)
69062 + {
69063 + case (8):
69064 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xff000000);
69065 + break;
69066 + case (16):
69067 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffff0000);
69068 + break;
69069 + case (24):
69070 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffff00);
69071 + break;
69072 + case (32):
69073 + WRITE_UINT32(*(uint32_t*)p_Fm->camBaseAddr, 0xffffffff);
69074 + break;
69075 + default:
69076 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("wrong dma_cam_num_of_entries"));
69077 + }
69078 + }
69079 +
69080 + p_Fm->p_FmDriverParam->cam_base_addr =
69081 + (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->camBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
69082 +
69083 + return E_OK;
69084 +}
69085 +
69086 +static t_Error InitFmFpm(t_Fm *p_Fm)
69087 +{
69088 + return (t_Error)fman_fpm_init(p_Fm->p_FmFpmRegs, p_Fm->p_FmDriverParam);
69089 +}
69090 +
69091 +static t_Error InitFmBmi(t_Fm *p_Fm)
69092 +{
69093 + return (t_Error)fman_bmi_init(p_Fm->p_FmBmiRegs, p_Fm->p_FmDriverParam);
69094 +}
69095 +
69096 +static t_Error InitFmQmi(t_Fm *p_Fm)
69097 +{
69098 + return (t_Error)fman_qmi_init(p_Fm->p_FmQmiRegs, p_Fm->p_FmDriverParam);
69099 +}
69100 +
69101 +static t_Error InitGuestMode(t_Fm *p_Fm)
69102 +{
69103 + t_Error err = E_OK;
69104 + int i;
69105 + t_FmIpcMsg msg;
69106 + t_FmIpcReply reply;
69107 + uint32_t replyLength;
69108 +
69109 + ASSERT_COND(p_Fm);
69110 + ASSERT_COND(p_Fm->guestId != NCSW_MASTER_ID);
69111 +
69112 + /* build the FM guest partition IPC address */
69113 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, p_Fm->guestId) != (p_Fm->guestId<10 ? 6:7))
69114 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
69115 +
69116 + /* build the FM master partition IPC address */
69117 + memset(p_Fm->fmIpcHandlerModuleName, 0, (sizeof(char)) * MODULE_NAME_SIZE);
69118 + if (Sprint (p_Fm->fmIpcHandlerModuleName[0], "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
69119 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
69120 +
69121 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
69122 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
69123 +
69124 + p_Fm->h_IpcSessions[0] = XX_IpcInitSession(p_Fm->fmIpcHandlerModuleName[0], p_Fm->fmModuleName);
69125 + if (p_Fm->h_IpcSessions[0])
69126 + {
69127 + uint8_t isMasterAlive;
69128 + t_FmIpcParams ipcParams;
69129 +
69130 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmGuestHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
69131 + if (err)
69132 + RETURN_ERROR(MAJOR, err, NO_MSG);
69133 +
69134 + memset(&msg, 0, sizeof(msg));
69135 + memset(&reply, 0, sizeof(reply));
69136 + msg.msgId = FM_MASTER_IS_ALIVE;
69137 + msg.msgBody[0] = p_Fm->guestId;
69138 + replyLength = sizeof(uint32_t) + sizeof(uint8_t);
69139 + do
69140 + {
69141 + blockingFlag = TRUE;
69142 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69143 + (uint8_t*)&msg,
69144 + sizeof(msg.msgId)+sizeof(p_Fm->guestId),
69145 + (uint8_t*)&reply,
69146 + &replyLength,
69147 + IpcMsgCompletionCB,
69148 + p_Fm)) != E_OK)
69149 + REPORT_ERROR(MINOR, err, NO_MSG);
69150 + while (blockingFlag) ;
69151 + if (replyLength != (sizeof(uint32_t) + sizeof(uint8_t)))
69152 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69153 + isMasterAlive = *(uint8_t*)(reply.replyBody);
69154 + } while (!isMasterAlive);
69155 +
69156 + /* read FM parameters and save */
69157 + memset(&msg, 0, sizeof(msg));
69158 + memset(&reply, 0, sizeof(reply));
69159 + msg.msgId = FM_GET_PARAMS;
69160 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcParams);
69161 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
69162 + (uint8_t*)&msg,
69163 + sizeof(msg.msgId),
69164 + (uint8_t*)&reply,
69165 + &replyLength,
69166 + NULL,
69167 + NULL)) != E_OK)
69168 + RETURN_ERROR(MAJOR, err, NO_MSG);
69169 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcParams)))
69170 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
69171 + memcpy((uint8_t*)&ipcParams, reply.replyBody, sizeof(t_FmIpcParams));
69172 +
69173 + p_Fm->p_FmStateStruct->fmClkFreq = ipcParams.fmClkFreq;
69174 + p_Fm->p_FmStateStruct->fmMacClkFreq = ipcParams.fmMacClkFreq;
69175 + p_Fm->p_FmStateStruct->revInfo.majorRev = ipcParams.majorRev;
69176 + p_Fm->p_FmStateStruct->revInfo.minorRev = ipcParams.minorRev;
69177 + }
69178 + else
69179 + {
69180 + DBG(WARNING, ("FM Guest mode - without IPC"));
69181 + if (!p_Fm->p_FmStateStruct->fmClkFreq)
69182 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("No fmClkFreq configured for guest without IPC"));
69183 + if (p_Fm->baseAddr)
69184 + {
69185 + fman_get_revision(p_Fm->p_FmFpmRegs,
69186 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
69187 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
69188 +
69189 + }
69190 + }
69191 +
69192 +#if (DPAA_VERSION >= 11)
69193 + p_Fm->partVSPBase = AllocVSPsForPartition(p_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
69194 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
69195 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
69196 +#endif /* (DPAA_VERSION >= 11) */
69197 +
69198 + /* General FM driver initialization */
69199 + if (p_Fm->baseAddr)
69200 + p_Fm->fmMuramPhysBaseAddr =
69201 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
69202 +
69203 + XX_Free(p_Fm->p_FmDriverParam);
69204 + p_Fm->p_FmDriverParam = NULL;
69205 +
69206 + if ((p_Fm->guestId == NCSW_MASTER_ID) ||
69207 + (p_Fm->h_IpcSessions[0]))
69208 + {
69209 + FM_DisableRamsEcc(p_Fm);
69210 + FmMuramClear(p_Fm->h_FmMuram);
69211 + FM_EnableRamsEcc(p_Fm);
69212 + }
69213 +
69214 + return E_OK;
69215 +}
69216 +
69217 +static __inline__ enum fman_exceptions FmanExceptionTrans(e_FmExceptions exception)
69218 +{
69219 + switch (exception) {
69220 + case e_FM_EX_DMA_BUS_ERROR:
69221 + return E_FMAN_EX_DMA_BUS_ERROR;
69222 + case e_FM_EX_DMA_READ_ECC:
69223 + return E_FMAN_EX_DMA_READ_ECC;
69224 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC:
69225 + return E_FMAN_EX_DMA_SYSTEM_WRITE_ECC;
69226 + case e_FM_EX_DMA_FM_WRITE_ECC:
69227 + return E_FMAN_EX_DMA_FM_WRITE_ECC;
69228 + case e_FM_EX_FPM_STALL_ON_TASKS:
69229 + return E_FMAN_EX_FPM_STALL_ON_TASKS;
69230 + case e_FM_EX_FPM_SINGLE_ECC:
69231 + return E_FMAN_EX_FPM_SINGLE_ECC;
69232 + case e_FM_EX_FPM_DOUBLE_ECC:
69233 + return E_FMAN_EX_FPM_DOUBLE_ECC;
69234 + case e_FM_EX_QMI_SINGLE_ECC:
69235 + return E_FMAN_EX_QMI_SINGLE_ECC;
69236 + case e_FM_EX_QMI_DOUBLE_ECC:
69237 + return E_FMAN_EX_QMI_DOUBLE_ECC;
69238 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
69239 + return E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
69240 + case e_FM_EX_BMI_LIST_RAM_ECC:
69241 + return E_FMAN_EX_BMI_LIST_RAM_ECC;
69242 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
69243 + return E_FMAN_EX_BMI_STORAGE_PROFILE_ECC;
69244 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
69245 + return E_FMAN_EX_BMI_STATISTICS_RAM_ECC;
69246 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
69247 + return E_FMAN_EX_BMI_DISPATCH_RAM_ECC;
69248 + case e_FM_EX_IRAM_ECC:
69249 + return E_FMAN_EX_IRAM_ECC;
69250 + case e_FM_EX_MURAM_ECC:
69251 + return E_FMAN_EX_MURAM_ECC;
69252 + default:
69253 + return E_FMAN_EX_DMA_BUS_ERROR;
69254 + }
69255 +}
69256 +
69257 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev)
69258 +{
69259 + switch (type)
69260 + {
69261 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
69262 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
69263 + CHECK_PORT_ID_OH_PORTS(relativePortId);
69264 + return (uint8_t)(BASE_OH_PORTID + (relativePortId));
69265 + case (e_FM_PORT_TYPE_RX):
69266 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
69267 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
69268 + case (e_FM_PORT_TYPE_RX_10G):
69269 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
69270 + * This is the reason why the 1G port offset is used.
69271 + */
69272 + if (majorRev == 6 && minorRev == 4)
69273 + {
69274 + CHECK_PORT_ID_1G_RX_PORTS(relativePortId);
69275 + return (uint8_t)(BASE_1G_RX_PORTID + (relativePortId));
69276 + }
69277 + else
69278 + {
69279 + CHECK_PORT_ID_10G_RX_PORTS(relativePortId);
69280 + return (uint8_t)(BASE_10G_RX_PORTID + (relativePortId));
69281 + }
69282 + case (e_FM_PORT_TYPE_TX):
69283 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
69284 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
69285 + case (e_FM_PORT_TYPE_TX_10G):
69286 + /* The 10G port in T1024 (FMan Version 6.4) is the first port.
69287 + * This is the reason why the 1G port offset is used.
69288 + */
69289 + if (majorRev == 6 && minorRev == 4)
69290 + {
69291 + CHECK_PORT_ID_1G_TX_PORTS(relativePortId);
69292 + return (uint8_t)(BASE_1G_TX_PORTID + (relativePortId));
69293 + }
69294 + else
69295 + {
69296 + CHECK_PORT_ID_10G_TX_PORTS(relativePortId);
69297 + return (uint8_t)(BASE_10G_TX_PORTID + (relativePortId));
69298 + }
69299 + default:
69300 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
69301 + return 0;
69302 + }
69303 +}
69304 +
69305 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
69306 +t_Error FmDumpPortRegs (t_Handle h_Fm, uint8_t hardwarePortId)
69307 +{
69308 + t_Fm *p_Fm = (t_Fm *)h_Fm;
69309 +
69310 + DECLARE_DUMP;
69311 +
69312 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
69313 +
69314 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69315 + SANITY_CHECK_RETURN_ERROR(((p_Fm->guestId == NCSW_MASTER_ID) ||
69316 + p_Fm->baseAddr), E_INVALID_OPERATION);
69317 +
69318 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], ("fmbm_pp for port %u", (hardwarePortId)));
69319 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId-1], sizeof(uint32_t));
69320 +
69321 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], ("fmbm_pfs for port %u", (hardwarePortId )));
69322 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId-1], sizeof(uint32_t));
69323 +
69324 + DUMP_TITLE(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], ("fmbm_spliodn for port %u", (hardwarePortId)));
69325 + DUMP_MEMORY(&p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId-1], sizeof(uint32_t));
69326 +
69327 + DUMP_TITLE(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], ("fmfp_ps for port %u", (hardwarePortId)));
69328 + DUMP_MEMORY(&p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId], sizeof(uint32_t));
69329 +
69330 + DUMP_TITLE(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], ("fmdmplr for port %u", (hardwarePortId)));
69331 + DUMP_MEMORY(&p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId/2], sizeof(uint32_t));
69332 +
69333 + return E_OK;
69334 +}
69335 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
69336 +
69337 +
69338 +/*****************************************************************************/
69339 +/* API Init unit functions */
69340 +/*****************************************************************************/
69341 +t_Handle FM_Config(t_FmParams *p_FmParam)
69342 +{
69343 + t_Fm *p_Fm;
69344 + uint8_t i;
69345 + uintptr_t baseAddr;
69346 +
69347 + SANITY_CHECK_RETURN_VALUE(p_FmParam, E_NULL_POINTER, NULL);
69348 + SANITY_CHECK_RETURN_VALUE(((p_FmParam->firmware.p_Code && p_FmParam->firmware.size) ||
69349 + (!p_FmParam->firmware.p_Code && !p_FmParam->firmware.size)),
69350 + E_INVALID_VALUE, NULL);
69351 +
69352 + baseAddr = p_FmParam->baseAddr;
69353 +
69354 + /* Allocate FM structure */
69355 + p_Fm = (t_Fm *) XX_Malloc(sizeof(t_Fm));
69356 + if (!p_Fm)
69357 + {
69358 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver structure"));
69359 + return NULL;
69360 + }
69361 + memset(p_Fm, 0, sizeof(t_Fm));
69362 +
69363 + p_Fm->p_FmStateStruct = (t_FmStateStruct *) XX_Malloc(sizeof(t_FmStateStruct));
69364 + if (!p_Fm->p_FmStateStruct)
69365 + {
69366 + XX_Free(p_Fm);
69367 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM Status structure"));
69368 + return NULL;
69369 + }
69370 + memset(p_Fm->p_FmStateStruct, 0, sizeof(t_FmStateStruct));
69371 +
69372 + /* Initialize FM parameters which will be kept by the driver */
69373 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
69374 + p_Fm->guestId = p_FmParam->guestId;
69375 +
69376 + for (i=0; i<FM_MAX_NUM_OF_HW_PORT_IDS; i++)
69377 + p_Fm->p_FmStateStruct->portsTypes[i] = e_FM_PORT_TYPE_DUMMY;
69378 +
69379 + /* Allocate the FM driver's parameters structure */
69380 + p_Fm->p_FmDriverParam = (struct fman_cfg *)XX_Malloc(sizeof(struct fman_cfg));
69381 + if (!p_Fm->p_FmDriverParam)
69382 + {
69383 + XX_Free(p_Fm->p_FmStateStruct);
69384 + XX_Free(p_Fm);
69385 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM driver parameters"));
69386 + return NULL;
69387 + }
69388 + memset(p_Fm->p_FmDriverParam, 0, sizeof(struct fman_cfg));
69389 +
69390 +#if (DPAA_VERSION >= 11)
69391 + p_Fm->p_FmSp = (t_FmSp *)XX_Malloc(sizeof(t_FmSp));
69392 + if (!p_Fm->p_FmSp)
69393 + {
69394 + XX_Free(p_Fm->p_FmDriverParam);
69395 + XX_Free(p_Fm->p_FmStateStruct);
69396 + XX_Free(p_Fm);
69397 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("allocation for internal data structure failed"));
69398 + return NULL;
69399 + }
69400 + memset(p_Fm->p_FmSp, 0, sizeof(t_FmSp));
69401 +
69402 + for (i=0; i<FM_VSP_MAX_NUM_OF_ENTRIES; i++)
69403 + p_Fm->p_FmSp->profiles[i].profilesMng.ownerId = (uint8_t)ILLEGAL_BASE;
69404 +#endif /* (DPAA_VERSION >= 11) */
69405 +
69406 + /* Initialize FM parameters which will be kept by the driver */
69407 + p_Fm->p_FmStateStruct->fmId = p_FmParam->fmId;
69408 + p_Fm->h_FmMuram = p_FmParam->h_FmMuram;
69409 + p_Fm->h_App = p_FmParam->h_App;
69410 + p_Fm->p_FmStateStruct->fmClkFreq = p_FmParam->fmClkFreq;
69411 + p_Fm->p_FmStateStruct->fmMacClkFreq = p_FmParam->fmClkFreq / ((!p_FmParam->fmMacClkRatio)? 2: p_FmParam->fmMacClkRatio);
69412 + p_Fm->f_Exception = p_FmParam->f_Exception;
69413 + p_Fm->f_BusError = p_FmParam->f_BusError;
69414 + p_Fm->p_FmFpmRegs = (struct fman_fpm_regs *)UINT_TO_PTR(baseAddr + FM_MM_FPM);
69415 + p_Fm->p_FmBmiRegs = (struct fman_bmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
69416 + p_Fm->p_FmQmiRegs = (struct fman_qmi_regs *)UINT_TO_PTR(baseAddr + FM_MM_QMI);
69417 + p_Fm->p_FmDmaRegs = (struct fman_dma_regs *)UINT_TO_PTR(baseAddr + FM_MM_DMA);
69418 + p_Fm->p_FmRegs = (struct fman_regs *)UINT_TO_PTR(baseAddr + FM_MM_BMI);
69419 + p_Fm->baseAddr = baseAddr;
69420 + p_Fm->p_FmStateStruct->irq = p_FmParam->irq;
69421 + p_Fm->p_FmStateStruct->errIrq = p_FmParam->errIrq;
69422 + p_Fm->hcPortInitialized = FALSE;
69423 + p_Fm->independentMode = FALSE;
69424 +
69425 + p_Fm->h_Spinlock = XX_InitSpinlock();
69426 + if (!p_Fm->h_Spinlock)
69427 + {
69428 + XX_Free(p_Fm->p_FmDriverParam);
69429 + XX_Free(p_Fm->p_FmStateStruct);
69430 + XX_Free(p_Fm);
69431 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("can't allocate spinlock!"));
69432 + return NULL;
69433 + }
69434 +
69435 +#if (DPAA_VERSION >= 11)
69436 + p_Fm->partVSPBase = p_FmParam->partVSPBase;
69437 + p_Fm->partNumOfVSPs = p_FmParam->partNumOfVSPs;
69438 + p_Fm->vspBaseAddr = p_FmParam->vspBaseAddr;
69439 +#endif /* (DPAA_VERSION >= 11) */
69440 +
69441 + fman_defconfig(p_Fm->p_FmDriverParam,
69442 + !!(p_Fm->guestId == NCSW_MASTER_ID));
69443 +/* overide macros dependent parameters */
69444 +#ifdef FM_PEDANTIC_DMA
69445 + p_Fm->p_FmDriverParam->pedantic_dma = TRUE;
69446 + p_Fm->p_FmDriverParam->dma_aid_override = TRUE;
69447 +#endif /* FM_PEDANTIC_DMA */
69448 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
69449 + p_Fm->p_FmDriverParam->qmi_deq_option_support = TRUE;
69450 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
69451 +
69452 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
69453 + p_Fm->p_FmStateStruct->extraFifoPoolSize = 0;
69454 + p_Fm->p_FmStateStruct->exceptions = DEFAULT_exceptions;
69455 + p_Fm->resetOnInit = DEFAULT_resetOnInit;
69456 + p_Fm->f_ResetOnInitOverride = DEFAULT_resetOnInitOverrideCallback;
69457 + p_Fm->fwVerify = DEFAULT_VerifyUcode;
69458 + p_Fm->firmware.size = p_FmParam->firmware.size;
69459 + if (p_Fm->firmware.size)
69460 + {
69461 + p_Fm->firmware.p_Code = (uint32_t *)XX_Malloc(p_Fm->firmware.size);
69462 + if (!p_Fm->firmware.p_Code)
69463 + {
69464 + XX_FreeSpinlock(p_Fm->h_Spinlock);
69465 + XX_Free(p_Fm->p_FmStateStruct);
69466 + XX_Free(p_Fm->p_FmDriverParam);
69467 + XX_Free(p_Fm);
69468 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM firmware code"));
69469 + return NULL;
69470 + }
69471 + memcpy(p_Fm->firmware.p_Code, p_FmParam->firmware.p_Code ,p_Fm->firmware.size);
69472 + }
69473 +
69474 + if (p_Fm->guestId != NCSW_MASTER_ID)
69475 + return p_Fm;
69476 +
69477 + /* read revision */
69478 + /* Chip dependent, will be configured in Init */
69479 + fman_get_revision(p_Fm->p_FmFpmRegs,
69480 + &p_Fm->p_FmStateStruct->revInfo.majorRev,
69481 + &p_Fm->p_FmStateStruct->revInfo.minorRev);
69482 +
69483 +#ifdef FM_AID_MODE_NO_TNUM_SW005
69484 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
69485 + p_Fm->p_FmDriverParam->dma_aid_mode = e_FM_DMA_AID_OUT_PORT_ID;
69486 +#endif /* FM_AID_MODE_NO_TNUM_SW005 */
69487 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
69488 + if (p_Fm->p_FmStateStruct->revInfo.majorRev != 4)
69489 + p_Fm->p_FmDriverParam->qmi_def_tnums_thresh = QMI_DEF_TNUMS_THRESH;
69490 +#endif /* FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
69491 +
69492 + p_Fm->p_FmStateStruct->totalFifoSize = 0;
69493 + p_Fm->p_FmStateStruct->totalNumOfTasks =
69494 + DEFAULT_totalNumOfTasks(p_Fm->p_FmStateStruct->revInfo.majorRev,
69495 + p_Fm->p_FmStateStruct->revInfo.minorRev);
69496 +
69497 +#ifdef FM_HAS_TOTAL_DMAS
69498 + p_Fm->p_FmStateStruct->maxNumOfOpenDmas = BMI_MAX_NUM_OF_DMAS;
69499 +#endif /* FM_HAS_TOTAL_DMAS */
69500 +#if (DPAA_VERSION < 11)
69501 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = DEFAULT_dmaCommQLow;
69502 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = DEFAULT_dmaCommQHigh;
69503 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = DEFAULT_dmaCamNumOfEntries;
69504 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = DEFAULT_dmaReadIntBufLow;
69505 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = DEFAULT_dmaReadIntBufHigh;
69506 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = DEFAULT_dmaWriteIntBufLow;
69507 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = DEFAULT_dmaWriteIntBufHigh;
69508 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = DEFAULT_axiDbgNumOfBeats;
69509 +#endif /* (DPAA_VERSION < 11) */
69510 +#ifdef FM_NO_TNUM_AGING
69511 + p_Fm->p_FmDriverParam->tnum_aging_period = 0;
69512 +#endif
69513 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
69514 +
69515 + return p_Fm;
69516 +}
69517 +
69518 +/**************************************************************************//**
69519 + @Function FM_Init
69520 +
69521 + @Description Initializes the FM module
69522 +
69523 + @Param[in] h_Fm - FM module descriptor
69524 +
69525 + @Return E_OK on success; Error code otherwise.
69526 +*//***************************************************************************/
69527 +t_Error FM_Init(t_Handle h_Fm)
69528 +{
69529 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69530 + struct fman_cfg *p_FmDriverParam = NULL;
69531 + t_Error err = E_OK;
69532 + int i;
69533 + t_FmRevisionInfo revInfo;
69534 + struct fman_rg fman_rg;
69535 +
69536 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69537 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69538 +
69539 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69540 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69541 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69542 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69543 +
69544 + p_Fm->p_FmStateStruct->count1MicroBit = FM_TIMESTAMP_1_USEC_BIT;
69545 + p_Fm->p_FmDriverParam->num_of_fman_ctrl_evnt_regs = FM_NUM_OF_FMAN_CTRL_EVENT_REGS;
69546 +
69547 + if (p_Fm->guestId != NCSW_MASTER_ID)
69548 + return InitGuestMode(p_Fm);
69549 +
69550 + /* if user didn't configured totalFifoSize - (totalFifoSize=0) we configure default
69551 + * according to chip. otherwise, we use user's configuration.
69552 + */
69553 + if (p_Fm->p_FmStateStruct->totalFifoSize == 0)
69554 + p_Fm->p_FmStateStruct->totalFifoSize = DEFAULT_totalFifoSize(p_Fm->p_FmStateStruct->revInfo.majorRev,
69555 + p_Fm->p_FmStateStruct->revInfo.minorRev);
69556 +
69557 + CHECK_INIT_PARAMETERS(p_Fm, CheckFmParameters);
69558 +
69559 + p_FmDriverParam = p_Fm->p_FmDriverParam;
69560 +
69561 + FM_GetRevision(p_Fm, &revInfo);
69562 +
69563 + /* clear revision-dependent non existing exception */
69564 +#ifdef FM_NO_DISPATCH_RAM_ECC
69565 + if ((revInfo.majorRev != 4) &&
69566 + (revInfo.majorRev < 6))
69567 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_BMI_DISPATCH_RAM_ECC;
69568 +#endif /* FM_NO_DISPATCH_RAM_ECC */
69569 +
69570 +#ifdef FM_QMI_NO_ECC_EXCEPTIONS
69571 + if (revInfo.majorRev == 4)
69572 + p_Fm->p_FmStateStruct->exceptions &= ~(FM_EX_QMI_SINGLE_ECC | FM_EX_QMI_DOUBLE_ECC);
69573 +#endif /* FM_QMI_NO_ECC_EXCEPTIONS */
69574 +
69575 +#ifdef FM_QMI_NO_SINGLE_ECC_EXCEPTION
69576 + if (revInfo.majorRev >= 6)
69577 + p_Fm->p_FmStateStruct->exceptions &= ~FM_EX_QMI_SINGLE_ECC;
69578 +#endif /* FM_QMI_NO_SINGLE_ECC_EXCEPTION */
69579 +
69580 + FmMuramClear(p_Fm->h_FmMuram);
69581 +
69582 + /* clear CPG */
69583 + IOMemSet32(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_CGP), 0, FM_PORT_NUM_OF_CONGESTION_GRPS);
69584 +
69585 + /* add to the default exceptions the user's definitions */
69586 + p_Fm->p_FmStateStruct->exceptions |= p_Fm->userSetExceptions;
69587 +
69588 + /* Reset the FM if required */
69589 + if (p_Fm->resetOnInit)
69590 + {
69591 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
69592 + if ((err = FwNotResetErratumBugzilla6173WA(p_Fm)) != E_OK)
69593 + RETURN_ERROR(MAJOR, err, NO_MSG);
69594 +#else /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
69595 +
69596 + if (p_Fm->f_ResetOnInitOverride)
69597 + {
69598 + /* Perform user specific FMan reset */
69599 + p_Fm->f_ResetOnInitOverride(h_Fm);
69600 + }
69601 + else
69602 + {
69603 + /* Perform FMan reset */
69604 + FmReset(h_Fm);
69605 + }
69606 +
69607 + if (fman_is_qmi_halt_not_busy_state(p_Fm->p_FmQmiRegs))
69608 + {
69609 + fman_resume(p_Fm->p_FmFpmRegs);
69610 + XX_UDelay(100);
69611 + }
69612 +#endif /* not FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
69613 + }
69614 +
69615 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
69616 + if (!p_Fm->resetOnInit) /* Skip operations done in errata workaround */
69617 + {
69618 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
69619 + /* Load FMan-Controller code to IRAM */
69620 +
69621 + ClearIRam(p_Fm);
69622 +
69623 + if (p_Fm->firmware.p_Code && (LoadFmanCtrlCode(p_Fm) != E_OK))
69624 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
69625 +#ifdef FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
69626 + }
69627 +#endif /* FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
69628 +
69629 +#ifdef FM_CAPWAP_SUPPORT
69630 + /* save first 256 byte in MURAM */
69631 + p_Fm->resAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram, 256, 0));
69632 + if (!p_Fm->resAddr)
69633 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for reserved Area failed"));
69634 +
69635 + WRITE_BLOCK(UINT_TO_PTR(p_Fm->resAddr), 0, 256);
69636 +#endif /* FM_CAPWAP_SUPPORT */
69637 +
69638 +#if (DPAA_VERSION >= 11)
69639 + p_Fm->partVSPBase = AllocVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
69640 + if (p_Fm->partVSPBase == (uint8_t)(ILLEGAL_BASE))
69641 + DBG(WARNING, ("partition VSPs allocation is FAILED"));
69642 +#endif /* (DPAA_VERSION >= 11) */
69643 +
69644 + /* General FM driver initialization */
69645 + p_Fm->fmMuramPhysBaseAddr =
69646 + (uint64_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->baseAddr + FM_MM_MURAM)));
69647 +
69648 + for (i=0;i<e_FM_EV_DUMMY_LAST;i++)
69649 + p_Fm->intrMng[i].f_Isr = UnimplementedIsr;
69650 + for (i=0;i<FM_NUM_OF_FMAN_CTRL_EVENT_REGS;i++)
69651 + p_Fm->fmanCtrlIntr[i].f_Isr = UnimplementedFmanCtrlIsr;
69652 +
69653 + p_FmDriverParam->exceptions = p_Fm->p_FmStateStruct->exceptions;
69654 +
69655 + /**********************/
69656 + /* Init DMA Registers */
69657 + /**********************/
69658 + err = InitFmDma(p_Fm);
69659 + if (err != E_OK)
69660 + {
69661 + FreeInitResources(p_Fm);
69662 + RETURN_ERROR(MAJOR, err, NO_MSG);
69663 + }
69664 +
69665 + /**********************/
69666 + /* Init FPM Registers */
69667 + /**********************/
69668 + err = InitFmFpm(p_Fm);
69669 + if (err != E_OK)
69670 + {
69671 + FreeInitResources(p_Fm);
69672 + RETURN_ERROR(MAJOR, err, NO_MSG);
69673 + }
69674 +
69675 + /* define common resources */
69676 + /* allocate MURAM for FIFO according to total size */
69677 + p_Fm->fifoBaseAddr = PTR_TO_UINT(FM_MURAM_AllocMem(p_Fm->h_FmMuram,
69678 + p_Fm->p_FmStateStruct->totalFifoSize,
69679 + BMI_FIFO_ALIGN));
69680 + if (!p_Fm->fifoBaseAddr)
69681 + {
69682 + FreeInitResources(p_Fm);
69683 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MURAM alloc for BMI FIFO failed"));
69684 + }
69685 +
69686 + p_FmDriverParam->fifo_base_addr = (uint32_t)(XX_VirtToPhys(UINT_TO_PTR(p_Fm->fifoBaseAddr)) - p_Fm->fmMuramPhysBaseAddr);
69687 + p_FmDriverParam->total_fifo_size = p_Fm->p_FmStateStruct->totalFifoSize;
69688 + p_FmDriverParam->total_num_of_tasks = p_Fm->p_FmStateStruct->totalNumOfTasks;
69689 + p_FmDriverParam->clk_freq = p_Fm->p_FmStateStruct->fmClkFreq;
69690 +
69691 + /**********************/
69692 + /* Init BMI Registers */
69693 + /**********************/
69694 + err = InitFmBmi(p_Fm);
69695 + if (err != E_OK)
69696 + {
69697 + FreeInitResources(p_Fm);
69698 + RETURN_ERROR(MAJOR, err, NO_MSG);
69699 + }
69700 +
69701 + /**********************/
69702 + /* Init QMI Registers */
69703 + /**********************/
69704 + err = InitFmQmi(p_Fm);
69705 + if (err != E_OK)
69706 + {
69707 + FreeInitResources(p_Fm);
69708 + RETURN_ERROR(MAJOR, err, NO_MSG);
69709 + }
69710 +
69711 + /* build the FM master partition IPC address */
69712 + if (Sprint (p_Fm->fmModuleName, "FM_%d_%d",p_Fm->p_FmStateStruct->fmId, NCSW_MASTER_ID) != 6)
69713 + {
69714 + FreeInitResources(p_Fm);
69715 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Sprint failed"));
69716 + }
69717 +
69718 + err = XX_IpcRegisterMsgHandler(p_Fm->fmModuleName, FmHandleIpcMsgCB, p_Fm, FM_IPC_MAX_REPLY_SIZE);
69719 + if (err)
69720 + {
69721 + FreeInitResources(p_Fm);
69722 + RETURN_ERROR(MAJOR, err, NO_MSG);
69723 + }
69724 +
69725 + /* Register the FM interrupts handlers */
69726 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
69727 + {
69728 + XX_SetIntr(p_Fm->p_FmStateStruct->irq, FM_EventIsr, p_Fm);
69729 + XX_EnableIntr(p_Fm->p_FmStateStruct->irq);
69730 + }
69731 +
69732 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
69733 + {
69734 + XX_SetIntr(p_Fm->p_FmStateStruct->errIrq, (void (*) (t_Handle))FM_ErrorIsr, p_Fm);
69735 + XX_EnableIntr(p_Fm->p_FmStateStruct->errIrq);
69736 + }
69737 +
69738 + err = (t_Error)fman_enable(&fman_rg , p_FmDriverParam);
69739 + if (err != E_OK)
69740 + return err; /* FIXME */
69741 +
69742 + EnableTimeStamp(p_Fm);
69743 +
69744 + if (p_Fm->firmware.p_Code)
69745 + {
69746 + XX_Free(p_Fm->firmware.p_Code);
69747 + p_Fm->firmware.p_Code = NULL;
69748 + }
69749 +
69750 + XX_Free(p_Fm->p_FmDriverParam);
69751 + p_Fm->p_FmDriverParam = NULL;
69752 +
69753 + return E_OK;
69754 +}
69755 +
69756 +/**************************************************************************//**
69757 + @Function FM_Free
69758 +
69759 + @Description Frees all resources that were assigned to FM module.
69760 +
69761 + Calling this routine invalidates the descriptor.
69762 +
69763 + @Param[in] h_Fm - FM module descriptor
69764 +
69765 + @Return E_OK on success; Error code otherwise.
69766 +*//***************************************************************************/
69767 +t_Error FM_Free(t_Handle h_Fm)
69768 +{
69769 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69770 + struct fman_rg fman_rg;
69771 +
69772 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69773 +
69774 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
69775 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
69776 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
69777 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
69778 +
69779 + if (p_Fm->guestId != NCSW_MASTER_ID)
69780 + {
69781 +#if (DPAA_VERSION >= 11)
69782 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
69783 +
69784 + if (p_Fm->p_FmSp)
69785 + {
69786 + XX_Free(p_Fm->p_FmSp);
69787 + p_Fm->p_FmSp = NULL;
69788 + }
69789 +#endif /* (DPAA_VERSION >= 11) */
69790 +
69791 + if (p_Fm->fmModuleName[0] != 0)
69792 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
69793 +
69794 + if (!p_Fm->recoveryMode)
69795 + XX_Free(p_Fm->p_FmStateStruct);
69796 +
69797 + XX_Free(p_Fm);
69798 +
69799 + return E_OK;
69800 + }
69801 +
69802 + fman_free_resources(&fman_rg);
69803 +
69804 + if ((p_Fm->guestId == NCSW_MASTER_ID) && (p_Fm->fmModuleName[0] != 0))
69805 + XX_IpcUnregisterMsgHandler(p_Fm->fmModuleName);
69806 +
69807 + if (p_Fm->p_FmStateStruct)
69808 + {
69809 + if (p_Fm->p_FmStateStruct->irq != NO_IRQ)
69810 + {
69811 + XX_DisableIntr(p_Fm->p_FmStateStruct->irq);
69812 + XX_FreeIntr(p_Fm->p_FmStateStruct->irq);
69813 + }
69814 + if (p_Fm->p_FmStateStruct->errIrq != NO_IRQ)
69815 + {
69816 + XX_DisableIntr(p_Fm->p_FmStateStruct->errIrq);
69817 + XX_FreeIntr(p_Fm->p_FmStateStruct->errIrq);
69818 + }
69819 + }
69820 +
69821 +#if (DPAA_VERSION >= 11)
69822 + FreeVSPsForPartition(h_Fm, p_Fm->partVSPBase, p_Fm->partNumOfVSPs, p_Fm->guestId);
69823 +
69824 + if (p_Fm->p_FmSp)
69825 + {
69826 + XX_Free(p_Fm->p_FmSp);
69827 + p_Fm->p_FmSp = NULL;
69828 + }
69829 +#endif /* (DPAA_VERSION >= 11) */
69830 +
69831 + if (p_Fm->h_Spinlock)
69832 + XX_FreeSpinlock(p_Fm->h_Spinlock);
69833 +
69834 + if (p_Fm->p_FmDriverParam)
69835 + {
69836 + if (p_Fm->firmware.p_Code)
69837 + XX_Free(p_Fm->firmware.p_Code);
69838 + XX_Free(p_Fm->p_FmDriverParam);
69839 + p_Fm->p_FmDriverParam = NULL;
69840 + }
69841 +
69842 + FreeInitResources(p_Fm);
69843 +
69844 + if (!p_Fm->recoveryMode && p_Fm->p_FmStateStruct)
69845 + XX_Free(p_Fm->p_FmStateStruct);
69846 +
69847 + XX_Free(p_Fm);
69848 +
69849 + return E_OK;
69850 +}
69851 +
69852 +/*************************************************/
69853 +/* API Advanced Init unit functions */
69854 +/*************************************************/
69855 +
69856 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable)
69857 +{
69858 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69859 +
69860 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69861 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69862 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69863 +
69864 + p_Fm->resetOnInit = enable;
69865 +
69866 + return E_OK;
69867 +}
69868 +
69869 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride)
69870 +{
69871 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69872 +
69873 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69874 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69875 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69876 +
69877 + p_Fm->f_ResetOnInitOverride = f_ResetOnInitOverride;
69878 +
69879 + return E_OK;
69880 +}
69881 +
69882 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize)
69883 +{
69884 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69885 +
69886 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69887 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69888 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69889 +
69890 + p_Fm->p_FmStateStruct->totalFifoSize = totalFifoSize;
69891 +
69892 + return E_OK;
69893 +}
69894 +
69895 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride)
69896 +{
69897 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69898 + enum fman_dma_cache_override fsl_cache_override;
69899 +
69900 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69901 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69902 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69903 +
69904 + FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, cacheOverride)
69905 + p_Fm->p_FmDriverParam->dma_cache_override = fsl_cache_override;
69906 +
69907 + return E_OK;
69908 +}
69909 +
69910 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride)
69911 +{
69912 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69913 +
69914 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69915 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69916 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69917 +
69918 + p_Fm->p_FmDriverParam->dma_aid_override = aidOverride;
69919 +
69920 + return E_OK;
69921 +}
69922 +
69923 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode)
69924 +{
69925 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69926 + enum fman_dma_aid_mode fsl_aid_mode;
69927 +
69928 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69929 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69930 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69931 +
69932 + FMAN_AID_MODE_TRANS(fsl_aid_mode, aidMode);
69933 + p_Fm->p_FmDriverParam->dma_aid_mode = fsl_aid_mode;
69934 +
69935 + return E_OK;
69936 +}
69937 +
69938 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats)
69939 +{
69940 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69941 +
69942 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69943 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69944 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69945 +
69946 +#if (DPAA_VERSION >= 11)
69947 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
69948 +#else
69949 + p_Fm->p_FmDriverParam->dma_axi_dbg_num_of_beats = axiDbgNumOfBeats;
69950 +
69951 + return E_OK;
69952 +#endif /* (DPAA_VERSION >= 11) */
69953 +}
69954 +
69955 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries)
69956 +{
69957 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69958 +
69959 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69960 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69961 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69962 +
69963 + p_Fm->p_FmDriverParam->dma_cam_num_of_entries = numOfEntries;
69964 +
69965 + return E_OK;
69966 +}
69967 +
69968 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode)
69969 +{
69970 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69971 + enum fman_dma_dbg_cnt_mode fsl_dma_dbg_cnt;
69972 +
69973 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69974 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69975 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69976 +
69977 + FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, fmDmaDbgCntMode);
69978 + p_Fm->p_FmDriverParam->dma_dbg_cnt_mode = fsl_dma_dbg_cnt;
69979 +
69980 + return E_OK;
69981 +}
69982 +
69983 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop)
69984 +{
69985 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69986 +
69987 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
69988 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
69989 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
69990 +
69991 + p_Fm->p_FmDriverParam->dma_stop_on_bus_error = stop;
69992 +
69993 + return E_OK;
69994 +}
69995 +
69996 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency)
69997 +{
69998 + t_Fm *p_Fm = (t_Fm*)h_Fm;
69999 + enum fman_dma_emergency_level fsl_dma_emer;
70000 +
70001 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70002 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70003 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70004 +
70005 + FMAN_DMA_EMER_TRANS(fsl_dma_emer, p_Emergency->emergencyLevel);
70006 + p_Fm->p_FmDriverParam->dma_en_emergency = TRUE;
70007 + p_Fm->p_FmDriverParam->dma_emergency_bus_select = (uint32_t)p_Emergency->emergencyBusSelect;
70008 + p_Fm->p_FmDriverParam->dma_emergency_level = fsl_dma_emer;
70009 +
70010 + return E_OK;
70011 +}
70012 +
70013 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt)
70014 +{
70015 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70016 +
70017 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70018 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70019 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70020 +
70021 + p_Fm->p_FmDriverParam->dma_en_emergency_smoother = TRUE;
70022 + p_Fm->p_FmDriverParam->dma_emergency_switch_counter = emergencyCnt;
70023 +
70024 + return E_OK;
70025 +}
70026 +
70027 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr)
70028 +{
70029 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70030 + enum fman_dma_err fsl_dma_err;
70031 +
70032 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70033 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70034 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70035 +
70036 + FMAN_DMA_ERR_TRANS(fsl_dma_err, dmaErr);
70037 + p_Fm->p_FmDriverParam->dma_err = fsl_dma_err;
70038 +
70039 + return E_OK;
70040 +}
70041 +
70042 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr)
70043 +{
70044 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70045 + enum fman_catastrophic_err fsl_catastrophic_err;
70046 +
70047 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70048 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70049 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70050 +
70051 + FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, catastrophicErr);
70052 + p_Fm->p_FmDriverParam->catastrophic_err = fsl_catastrophic_err;
70053 +
70054 + return E_OK;
70055 +}
70056 +
70057 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm)
70058 +{
70059 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70060 +
70061 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70062 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70063 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70064 +
70065 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
70066 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
70067 +
70068 + p_Fm->p_FmDriverParam->en_muram_test_mode = TRUE;
70069 +
70070 + return E_OK;
70071 +}
70072 +
70073 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm)
70074 +{
70075 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70076 +
70077 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE );
70078 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70079 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70080 +
70081 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
70082 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
70083 +
70084 + p_Fm->p_FmDriverParam->en_iram_test_mode = TRUE;
70085 +
70086 + return E_OK;
70087 +}
70088 +
70089 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable)
70090 +{
70091 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70092 +
70093 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70094 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70095 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70096 +
70097 + p_Fm->p_FmDriverParam->halt_on_external_activ = enable;
70098 +
70099 + return E_OK;
70100 +}
70101 +
70102 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable)
70103 +{
70104 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70105 +
70106 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70107 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70108 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70109 +
70110 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
70111 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
70112 +
70113 + p_Fm->p_FmDriverParam->halt_on_unrecov_ecc_err = enable;
70114 +
70115 + return E_OK;
70116 +}
70117 +
70118 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
70119 +{
70120 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70121 + uint32_t bitMask = 0;
70122 +
70123 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70124 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70125 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70126 +
70127 + GET_EXCEPTION_FLAG(bitMask, exception);
70128 + if (bitMask)
70129 + {
70130 + if (enable)
70131 + p_Fm->userSetExceptions |= bitMask;
70132 + else
70133 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
70134 + }
70135 + else
70136 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
70137 +
70138 + return E_OK;
70139 +}
70140 +
70141 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable)
70142 +{
70143 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70144 +
70145 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70146 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70147 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70148 +
70149 + p_Fm->p_FmDriverParam->external_ecc_rams_enable = enable;
70150 +
70151 + return E_OK;
70152 +}
70153 +
70154 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod)
70155 +{
70156 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70157 +
70158 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70159 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70160 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70161 +
70162 + p_Fm->p_FmDriverParam->tnum_aging_period = tnumAgingPeriod;
70163 + p_Fm->tnumAgingPeriod = p_Fm->p_FmDriverParam->tnum_aging_period;
70164 +
70165 + return E_OK;
70166 +}
70167 +
70168 +/****************************************************/
70169 +/* Hidden-DEBUG Only API */
70170 +/****************************************************/
70171 +
70172 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds)
70173 +{
70174 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70175 +
70176 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70177 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70178 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70179 +
70180 + p_Fm->p_FmDriverParam->disp_limit_tsh = p_FmThresholds->dispLimit;
70181 + p_Fm->p_FmDriverParam->prs_disp_tsh = p_FmThresholds->prsDispTh;
70182 + p_Fm->p_FmDriverParam->plcr_disp_tsh = p_FmThresholds->plcrDispTh;
70183 + p_Fm->p_FmDriverParam->kg_disp_tsh = p_FmThresholds->kgDispTh;
70184 + p_Fm->p_FmDriverParam->bmi_disp_tsh = p_FmThresholds->bmiDispTh;
70185 + p_Fm->p_FmDriverParam->qmi_enq_disp_tsh = p_FmThresholds->qmiEnqDispTh;
70186 + p_Fm->p_FmDriverParam->qmi_deq_disp_tsh = p_FmThresholds->qmiDeqDispTh;
70187 + p_Fm->p_FmDriverParam->fm_ctl1_disp_tsh = p_FmThresholds->fmCtl1DispTh;
70188 + p_Fm->p_FmDriverParam->fm_ctl2_disp_tsh = p_FmThresholds->fmCtl2DispTh;
70189 +
70190 + return E_OK;
70191 +}
70192 +
70193 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency)
70194 +{
70195 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70196 +
70197 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70198 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70199 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70200 +
70201 + p_Fm->p_FmDriverParam->dma_sos_emergency = dmaSosEmergency;
70202 +
70203 + return E_OK;
70204 +}
70205 +
70206 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
70207 +
70208 +{
70209 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70210 +
70211 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70212 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70213 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70214 +
70215 +#if (DPAA_VERSION >= 11)
70216 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
70217 +#else
70218 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
70219 + p_Fm->p_FmDriverParam->dma_write_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
70220 +
70221 + return E_OK;
70222 +#endif
70223 +}
70224 +
70225 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
70226 +{
70227 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70228 +
70229 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70230 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70231 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70232 +
70233 + p_Fm->p_FmDriverParam->dma_comm_qtsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
70234 + p_Fm->p_FmDriverParam->dma_comm_qtsh_clr_emer = p_FmDmaThresholds->clearEmergency;
70235 +
70236 + return E_OK;
70237 +}
70238 +
70239 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds)
70240 +{
70241 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70242 +
70243 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70244 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70245 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70246 +
70247 +#if (DPAA_VERSION >= 11)
70248 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Not available for this FM revision!"));
70249 +#else
70250 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_clr_emer = p_FmDmaThresholds->clearEmergency;
70251 + p_Fm->p_FmDriverParam->dma_read_buf_tsh_asrt_emer = p_FmDmaThresholds->assertEmergency;
70252 +
70253 + return E_OK;
70254 +#endif
70255 +}
70256 +
70257 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchdogValue)
70258 +{
70259 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70260 +
70261 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70262 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70263 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70264 +
70265 + p_Fm->p_FmDriverParam->dma_watchdog = watchdogValue;
70266 +
70267 + return E_OK;
70268 +}
70269 +
70270 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm)
70271 +{
70272 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70273 +
70274 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70275 + SANITY_CHECK_RETURN_ERROR(p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70276 +UNUSED(p_Fm);
70277 +
70278 + return E_OK;
70279 +}
70280 +
70281 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params)
70282 +{
70283 + t_Fm* p_Fm = (t_Fm*)h_Fm;
70284 + if (p_Params->setParams.type & UPDATE_FM_CLD)
70285 + {
70286 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_cld, GET_UINT32(
70287 + p_Fm->p_FmFpmRegs->fm_cld) | 0x00000800);
70288 + }
70289 + if (p_Params->setParams.type & CLEAR_IRAM_READY)
70290 + {
70291 + t_FMIramRegs *p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
70292 + WRITE_UINT32(p_Iram->iready,GET_UINT32(p_Iram->iready) & ~IRAM_READY);
70293 + }
70294 + if (p_Params->setParams.type & UPDATE_FPM_EXTC)
70295 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x80000000);
70296 + if (p_Params->setParams.type & UPDATE_FPM_EXTC_CLEAR)
70297 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc,0x00800000);
70298 + if (p_Params->setParams.type & UPDATE_FPM_BRKC_SLP)
70299 + {
70300 + if (p_Params->setParams.sleep)
70301 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
70302 + p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_SLP);
70303 + else
70304 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc, GET_UINT32(
70305 + p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_SLP);
70306 + }
70307 + if (p_Params->getParams.type & GET_FM_CLD)
70308 + p_Params->getParams.fm_cld = GET_UINT32(p_Fm->p_FmFpmRegs->fm_cld);
70309 + if (p_Params->getParams.type & GET_FMQM_GS)
70310 + p_Params->getParams.fmqm_gs = GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gs);
70311 + if (p_Params->getParams.type & GET_FM_NPI)
70312 + p_Params->getParams.fm_npi = GET_UINT32(p_Fm->p_FmFpmRegs->fm_npi);
70313 + if (p_Params->getParams.type & GET_FMFP_EXTC)
70314 + p_Params->getParams.fmfp_extc = GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_extc);
70315 + return E_OK;
70316 +}
70317 +
70318 +
70319 +/****************************************************/
70320 +/* API Run-time Control uint functions */
70321 +/****************************************************/
70322 +void FM_EventIsr(t_Handle h_Fm)
70323 +{
70324 +#define FM_M_CALL_1G_MAC_ISR(_id) \
70325 + { \
70326 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id)].guestId) \
70327 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_1G_MAC0+_id), pending); \
70328 + else \
70329 + 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);\
70330 + }
70331 +#define FM_M_CALL_10G_MAC_ISR(_id) \
70332 + { \
70333 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id)].guestId) \
70334 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_10G_MAC0+_id), pending); \
70335 + else \
70336 + 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);\
70337 + }
70338 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70339 + uint32_t pending, event;
70340 + struct fman_fpm_regs *fpm_rg;
70341 +
70342 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70343 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70344 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70345 +
70346 + fpm_rg = p_Fm->p_FmFpmRegs;
70347 +
70348 + /* normal interrupts */
70349 + pending = fman_get_normal_pending(fpm_rg);
70350 + if (!pending)
70351 + return;
70352 + if (pending & INTR_EN_WAKEUP) // this is a wake up from sleep interrupt
70353 + {
70354 + t_FmGetSetParams fmGetSetParams;
70355 + memset(&fmGetSetParams, 0, sizeof (t_FmGetSetParams));
70356 + fmGetSetParams.setParams.type = UPDATE_FPM_BRKC_SLP;
70357 + fmGetSetParams.setParams.sleep = 0;
70358 + FmGetSetParams(h_Fm, &fmGetSetParams);
70359 + }
70360 + if (pending & INTR_EN_QMI)
70361 + QmiEvent(p_Fm);
70362 + if (pending & INTR_EN_PRS)
70363 + p_Fm->intrMng[e_FM_EV_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_PRS].h_SrcHandle);
70364 + if (pending & INTR_EN_PLCR)
70365 + p_Fm->intrMng[e_FM_EV_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_PLCR].h_SrcHandle);
70366 + if (pending & INTR_EN_TMR)
70367 + p_Fm->intrMng[e_FM_EV_TMR].f_Isr(p_Fm->intrMng[e_FM_EV_TMR].h_SrcHandle);
70368 +
70369 + /* MAC events may belong to different partitions */
70370 + if (pending & INTR_EN_1G_MAC0)
70371 + FM_M_CALL_1G_MAC_ISR(0);
70372 + if (pending & INTR_EN_1G_MAC1)
70373 + FM_M_CALL_1G_MAC_ISR(1);
70374 + if (pending & INTR_EN_1G_MAC2)
70375 + FM_M_CALL_1G_MAC_ISR(2);
70376 + if (pending & INTR_EN_1G_MAC3)
70377 + FM_M_CALL_1G_MAC_ISR(3);
70378 + if (pending & INTR_EN_1G_MAC4)
70379 + FM_M_CALL_1G_MAC_ISR(4);
70380 + if (pending & INTR_EN_1G_MAC5)
70381 + FM_M_CALL_1G_MAC_ISR(5);
70382 + if (pending & INTR_EN_1G_MAC6)
70383 + FM_M_CALL_1G_MAC_ISR(6);
70384 + if (pending & INTR_EN_1G_MAC7)
70385 + FM_M_CALL_1G_MAC_ISR(7);
70386 + if (pending & INTR_EN_10G_MAC0)
70387 + FM_M_CALL_10G_MAC_ISR(0);
70388 + if (pending & INTR_EN_10G_MAC1)
70389 + FM_M_CALL_10G_MAC_ISR(1);
70390 +
70391 + /* IM port events may belong to different partitions */
70392 + if (pending & INTR_EN_REV0)
70393 + {
70394 + event = fman_get_controller_event(fpm_rg, 0);
70395 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_0].guestId)
70396 + /*TODO IPC ISR For Fman Ctrl */
70397 + ASSERT_COND(0);
70398 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_0, pending); */
70399 + else
70400 + p_Fm->fmanCtrlIntr[0].f_Isr(p_Fm->fmanCtrlIntr[0].h_SrcHandle, event);
70401 +
70402 + }
70403 + if (pending & INTR_EN_REV1)
70404 + {
70405 + event = fman_get_controller_event(fpm_rg, 1);
70406 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_1].guestId)
70407 + /*TODO IPC ISR For Fman Ctrl */
70408 + ASSERT_COND(0);
70409 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_1, pending); */
70410 + else
70411 + p_Fm->fmanCtrlIntr[1].f_Isr(p_Fm->fmanCtrlIntr[1].h_SrcHandle, event);
70412 + }
70413 + if (pending & INTR_EN_REV2)
70414 + {
70415 + event = fman_get_controller_event(fpm_rg, 2);
70416 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_2].guestId)
70417 + /*TODO IPC ISR For Fman Ctrl */
70418 + ASSERT_COND(0);
70419 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pending); */
70420 + else
70421 + p_Fm->fmanCtrlIntr[2].f_Isr(p_Fm->fmanCtrlIntr[2].h_SrcHandle, event);
70422 + }
70423 + if (pending & INTR_EN_REV3)
70424 + {
70425 + event = fman_get_controller_event(fpm_rg, 3);
70426 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_FMAN_CTRL_3].guestId)
70427 + /*TODO IPC ISR For Fman Ctrl */
70428 + ASSERT_COND(0);
70429 + /* SendIpcIsr(p_Fm, e_FM_EV_FMAN_CTRL_2, pendin3); */
70430 + else
70431 + p_Fm->fmanCtrlIntr[3].f_Isr(p_Fm->fmanCtrlIntr[3].h_SrcHandle, event);
70432 + }
70433 +#ifdef FM_MACSEC_SUPPORT
70434 + if (pending & INTR_EN_MACSEC_MAC0)
70435 + {
70436 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].guestId)
70437 + SendIpcIsr(p_Fm, e_FM_EV_MACSEC_MAC0, pending);
70438 + else
70439 + p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_MACSEC_MAC0].h_SrcHandle);
70440 + }
70441 +#endif /* FM_MACSEC_SUPPORT */
70442 +}
70443 +
70444 +t_Error FM_ErrorIsr(t_Handle h_Fm)
70445 +{
70446 +#define FM_M_CALL_1G_MAC_ERR_ISR(_id) \
70447 + { \
70448 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id)].guestId) \
70449 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_1G_MAC0+_id), pending); \
70450 + else \
70451 + 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);\
70452 + }
70453 +#define FM_M_CALL_10G_MAC_ERR_ISR(_id) \
70454 + { \
70455 + if (p_Fm->guestId != p_Fm->intrMng[(e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id)].guestId) \
70456 + SendIpcIsr(p_Fm, (e_FmInterModuleEvent)(e_FM_EV_ERR_10G_MAC0+_id), pending); \
70457 + else \
70458 + 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);\
70459 + }
70460 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70461 + uint32_t pending;
70462 + struct fman_fpm_regs *fpm_rg;
70463 +
70464 + SANITY_CHECK_RETURN_ERROR(h_Fm, E_INVALID_HANDLE);
70465 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70466 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70467 +
70468 + fpm_rg = p_Fm->p_FmFpmRegs;
70469 +
70470 + /* error interrupts */
70471 + pending = fman_get_fpm_error_interrupts(fpm_rg);
70472 + if (!pending)
70473 + return ERROR_CODE(E_EMPTY);
70474 +
70475 + if (pending & ERR_INTR_EN_BMI)
70476 + BmiErrEvent(p_Fm);
70477 + if (pending & ERR_INTR_EN_QMI)
70478 + QmiErrEvent(p_Fm);
70479 + if (pending & ERR_INTR_EN_FPM)
70480 + FpmErrEvent(p_Fm);
70481 + if (pending & ERR_INTR_EN_DMA)
70482 + DmaErrEvent(p_Fm);
70483 + if (pending & ERR_INTR_EN_IRAM)
70484 + IramErrIntr(p_Fm);
70485 + if (pending & ERR_INTR_EN_MURAM)
70486 + MuramErrIntr(p_Fm);
70487 + if (pending & ERR_INTR_EN_PRS)
70488 + p_Fm->intrMng[e_FM_EV_ERR_PRS].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PRS].h_SrcHandle);
70489 + if (pending & ERR_INTR_EN_PLCR)
70490 + p_Fm->intrMng[e_FM_EV_ERR_PLCR].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_PLCR].h_SrcHandle);
70491 + if (pending & ERR_INTR_EN_KG)
70492 + p_Fm->intrMng[e_FM_EV_ERR_KG].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_KG].h_SrcHandle);
70493 +
70494 + /* MAC events may belong to different partitions */
70495 + if (pending & ERR_INTR_EN_1G_MAC0)
70496 + FM_M_CALL_1G_MAC_ERR_ISR(0);
70497 + if (pending & ERR_INTR_EN_1G_MAC1)
70498 + FM_M_CALL_1G_MAC_ERR_ISR(1);
70499 + if (pending & ERR_INTR_EN_1G_MAC2)
70500 + FM_M_CALL_1G_MAC_ERR_ISR(2);
70501 + if (pending & ERR_INTR_EN_1G_MAC3)
70502 + FM_M_CALL_1G_MAC_ERR_ISR(3);
70503 + if (pending & ERR_INTR_EN_1G_MAC4)
70504 + FM_M_CALL_1G_MAC_ERR_ISR(4);
70505 + if (pending & ERR_INTR_EN_1G_MAC5)
70506 + FM_M_CALL_1G_MAC_ERR_ISR(5);
70507 + if (pending & ERR_INTR_EN_1G_MAC6)
70508 + FM_M_CALL_1G_MAC_ERR_ISR(6);
70509 + if (pending & ERR_INTR_EN_1G_MAC7)
70510 + FM_M_CALL_1G_MAC_ERR_ISR(7);
70511 + if (pending & ERR_INTR_EN_10G_MAC0)
70512 + FM_M_CALL_10G_MAC_ERR_ISR(0);
70513 + if (pending & ERR_INTR_EN_10G_MAC1)
70514 + FM_M_CALL_10G_MAC_ERR_ISR(1);
70515 +
70516 +#ifdef FM_MACSEC_SUPPORT
70517 + if (pending & ERR_INTR_EN_MACSEC_MAC0)
70518 + {
70519 + if (p_Fm->guestId != p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].guestId)
70520 + SendIpcIsr(p_Fm, e_FM_EV_ERR_MACSEC_MAC0, pending);
70521 + else
70522 + p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].f_Isr(p_Fm->intrMng[e_FM_EV_ERR_MACSEC_MAC0].h_SrcHandle);
70523 + }
70524 +#endif /* FM_MACSEC_SUPPORT */
70525 +
70526 + return E_OK;
70527 +}
70528 +
70529 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth)
70530 +{
70531 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70532 + int i;
70533 + uint8_t sum;
70534 + uint8_t hardwarePortId;
70535 + uint8_t weights[64];
70536 + uint8_t weight, maxPercent = 0;
70537 + struct fman_bmi_regs *bmi_rg;
70538 +
70539 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70540 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70541 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
70542 +
70543 + bmi_rg = p_Fm->p_FmBmiRegs;
70544 +
70545 + memset(weights, 0, (sizeof(uint8_t) * 64));
70546 +
70547 + /* check that all ports add up to 100% */
70548 + sum = 0;
70549 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
70550 + sum +=p_PortsBandwidth->portsBandwidths[i].bandwidth;
70551 + if (sum != 100)
70552 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Sum of ports bandwidth differ from 100%"));
70553 +
70554 + /* find highest percent */
70555 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
70556 + {
70557 + if (p_PortsBandwidth->portsBandwidths[i].bandwidth > maxPercent)
70558 + maxPercent = p_PortsBandwidth->portsBandwidths[i].bandwidth;
70559 + }
70560 +
70561 + ASSERT_COND(maxPercent > 0); /* guaranteed by sum = 100 */
70562 +
70563 + /* calculate weight for each port */
70564 + for (i=0; i < p_PortsBandwidth->numOfPorts; i++)
70565 + {
70566 + weight = (uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) / maxPercent);
70567 + /* we want even division between 1-to-PORT_MAX_WEIGHT. so if exact division
70568 + is not reached, we round up so that:
70569 + 0 until maxPercent/PORT_MAX_WEIGHT get "1"
70570 + maxPercent/PORT_MAX_WEIGHT+1 until (maxPercent/PORT_MAX_WEIGHT)*2 get "2"
70571 + ...
70572 + maxPercent - maxPercent/PORT_MAX_WEIGHT until maxPercent get "PORT_MAX_WEIGHT: */
70573 + if ((uint8_t)((p_PortsBandwidth->portsBandwidths[i].bandwidth * PORT_MAX_WEIGHT ) % maxPercent))
70574 + weight++;
70575 +
70576 + /* find the location of this port within the register */
70577 + hardwarePortId =
70578 + SwPortIdToHwPortId(p_PortsBandwidth->portsBandwidths[i].type,
70579 + p_PortsBandwidth->portsBandwidths[i].relativePortId,
70580 + p_Fm->p_FmStateStruct->revInfo.majorRev,
70581 + p_Fm->p_FmStateStruct->revInfo.minorRev);
70582 +
70583 + ASSERT_COND(IN_RANGE(1, hardwarePortId, 63));
70584 + weights[hardwarePortId] = weight;
70585 + }
70586 +
70587 + fman_set_ports_bandwidth(bmi_rg, weights);
70588 +
70589 + return E_OK;
70590 +}
70591 +
70592 +t_Error FM_EnableRamsEcc(t_Handle h_Fm)
70593 +{
70594 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70595 + struct fman_fpm_regs *fpm_rg;
70596 +
70597 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70598 +
70599 + fpm_rg = p_Fm->p_FmFpmRegs;
70600 +
70601 + if (p_Fm->guestId != NCSW_MASTER_ID)
70602 + {
70603 + t_FmIpcMsg msg;
70604 + t_Error err;
70605 +
70606 + memset(&msg, 0, sizeof(msg));
70607 + msg.msgId = FM_ENABLE_RAM_ECC;
70608 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70609 + (uint8_t*)&msg,
70610 + sizeof(msg.msgId),
70611 + NULL,
70612 + NULL,
70613 + NULL,
70614 + NULL);
70615 + if (err != E_OK)
70616 + RETURN_ERROR(MINOR, err, NO_MSG);
70617 + return E_OK;
70618 + }
70619 +
70620 + if (!p_Fm->p_FmStateStruct->internalCall)
70621 + p_Fm->p_FmStateStruct->explicitEnable = TRUE;
70622 + p_Fm->p_FmStateStruct->internalCall = FALSE;
70623 +
70624 + if (p_Fm->p_FmStateStruct->ramsEccEnable)
70625 + return E_OK;
70626 + else
70627 + {
70628 + fman_enable_rams_ecc(fpm_rg);
70629 + p_Fm->p_FmStateStruct->ramsEccEnable = TRUE;
70630 + }
70631 +
70632 + return E_OK;
70633 +}
70634 +
70635 +t_Error FM_DisableRamsEcc(t_Handle h_Fm)
70636 +{
70637 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70638 + bool explicitDisable = FALSE;
70639 + struct fman_fpm_regs *fpm_rg;
70640 +
70641 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70642 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_HANDLE);
70643 +
70644 + fpm_rg = p_Fm->p_FmFpmRegs;
70645 +
70646 + if (p_Fm->guestId != NCSW_MASTER_ID)
70647 + {
70648 + t_Error err;
70649 + t_FmIpcMsg msg;
70650 +
70651 + memset(&msg, 0, sizeof(msg));
70652 + msg.msgId = FM_DISABLE_RAM_ECC;
70653 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70654 + (uint8_t*)&msg,
70655 + sizeof(msg.msgId),
70656 + NULL,
70657 + NULL,
70658 + NULL,
70659 + NULL)) != E_OK)
70660 + RETURN_ERROR(MINOR, err, NO_MSG);
70661 + return E_OK;
70662 + }
70663 +
70664 + if (!p_Fm->p_FmStateStruct->internalCall)
70665 + explicitDisable = TRUE;
70666 + p_Fm->p_FmStateStruct->internalCall = FALSE;
70667 +
70668 + /* if rams are already disabled, or if rams were explicitly enabled and are
70669 + currently called indirectly (not explicitly), ignore this call. */
70670 + if (!p_Fm->p_FmStateStruct->ramsEccEnable ||
70671 + (p_Fm->p_FmStateStruct->explicitEnable && !explicitDisable))
70672 + return E_OK;
70673 + else
70674 + {
70675 + if (p_Fm->p_FmStateStruct->explicitEnable)
70676 + /* This is the case were both explicit are TRUE.
70677 + Turn off this flag for cases were following ramsEnable
70678 + routines are called */
70679 + p_Fm->p_FmStateStruct->explicitEnable = FALSE;
70680 +
70681 + fman_enable_rams_ecc(fpm_rg);
70682 + p_Fm->p_FmStateStruct->ramsEccEnable = FALSE;
70683 + }
70684 +
70685 + return E_OK;
70686 +}
70687 +
70688 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable)
70689 +{
70690 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70691 + uint32_t bitMask = 0;
70692 + enum fman_exceptions fslException;
70693 + struct fman_rg fman_rg;
70694 +
70695 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70696 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70697 +
70698 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
70699 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
70700 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
70701 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
70702 +
70703 + GET_EXCEPTION_FLAG(bitMask, exception);
70704 + if (bitMask)
70705 + {
70706 + if (enable)
70707 + p_Fm->p_FmStateStruct->exceptions |= bitMask;
70708 + else
70709 + p_Fm->p_FmStateStruct->exceptions &= ~bitMask;
70710 +
70711 + fslException = FmanExceptionTrans(exception);
70712 +
70713 + return (t_Error)fman_set_exception(&fman_rg,
70714 + fslException,
70715 + enable);
70716 + }
70717 + else
70718 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
70719 +
70720 + return E_OK;
70721 +}
70722 +
70723 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo)
70724 +{
70725 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70726 +
70727 + p_FmRevisionInfo->majorRev = p_Fm->p_FmStateStruct->revInfo.majorRev;
70728 + p_FmRevisionInfo->minorRev = p_Fm->p_FmStateStruct->revInfo.minorRev;
70729 +
70730 + return E_OK;
70731 +}
70732 +
70733 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo)
70734 +{
70735 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70736 + t_FMIramRegs *p_Iram;
70737 + uint32_t revInfo;
70738 +
70739 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70740 + SANITY_CHECK_RETURN_ERROR(p_RevisionInfo, E_NULL_POINTER);
70741 +
70742 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
70743 + p_Fm->h_IpcSessions[0])
70744 + {
70745 + t_Error err;
70746 + t_FmIpcMsg msg;
70747 + t_FmIpcReply reply;
70748 + uint32_t replyLength;
70749 + t_FmIpcFmanCtrlCodeRevisionInfo ipcRevInfo;
70750 +
70751 + memset(&msg, 0, sizeof(msg));
70752 + memset(&reply, 0, sizeof(reply));
70753 + msg.msgId = FM_GET_FMAN_CTRL_CODE_REV;
70754 + replyLength = sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo);
70755 + if ((err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70756 + (uint8_t*)&msg,
70757 + sizeof(msg.msgId),
70758 + (uint8_t*)&reply,
70759 + &replyLength,
70760 + NULL,
70761 + NULL)) != E_OK)
70762 + RETURN_ERROR(MINOR, err, NO_MSG);
70763 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmCtrlCodeRevisionInfo)))
70764 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
70765 + memcpy((uint8_t*)&ipcRevInfo, reply.replyBody, sizeof(t_FmCtrlCodeRevisionInfo));
70766 + p_RevisionInfo->packageRev = ipcRevInfo.packageRev;
70767 + p_RevisionInfo->majorRev = ipcRevInfo.majorRev;
70768 + p_RevisionInfo->minorRev = ipcRevInfo.minorRev;
70769 + return (t_Error)(reply.error);
70770 + }
70771 + else if (p_Fm->guestId != NCSW_MASTER_ID)
70772 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED,
70773 + ("running in guest-mode without IPC!"));
70774 +
70775 + p_Iram = (t_FMIramRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_IMEM);
70776 + WRITE_UINT32(p_Iram->iadd, 0x4);
70777 + while (GET_UINT32(p_Iram->iadd) != 0x4) ;
70778 + revInfo = GET_UINT32(p_Iram->idata);
70779 + p_RevisionInfo->packageRev = (uint16_t)((revInfo & 0xFFFF0000) >> 16);
70780 + p_RevisionInfo->majorRev = (uint8_t)((revInfo & 0x0000FF00) >> 8);
70781 + p_RevisionInfo->minorRev = (uint8_t)(revInfo & 0x000000FF);
70782 +
70783 + return E_OK;
70784 +}
70785 +
70786 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter)
70787 +{
70788 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70789 + t_Error err;
70790 + uint32_t counterValue;
70791 + struct fman_rg fman_rg;
70792 + enum fman_counters fsl_counter;
70793 +
70794 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, 0);
70795 + SANITY_CHECK_RETURN_VALUE(!p_Fm->p_FmDriverParam, E_INVALID_STATE, 0);
70796 +
70797 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
70798 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
70799 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
70800 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
70801 +
70802 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
70803 + !p_Fm->baseAddr &&
70804 + p_Fm->h_IpcSessions[0])
70805 + {
70806 + t_FmIpcMsg msg;
70807 + t_FmIpcReply reply;
70808 + uint32_t replyLength, outCounter;
70809 +
70810 + memset(&msg, 0, sizeof(msg));
70811 + memset(&reply, 0, sizeof(reply));
70812 + msg.msgId = FM_GET_COUNTER;
70813 + memcpy(msg.msgBody, (uint8_t *)&counter, sizeof(uint32_t));
70814 + replyLength = sizeof(uint32_t) + sizeof(uint32_t);
70815 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70816 + (uint8_t*)&msg,
70817 + sizeof(msg.msgId) +sizeof(counterValue),
70818 + (uint8_t*)&reply,
70819 + &replyLength,
70820 + NULL,
70821 + NULL);
70822 + if (err != E_OK)
70823 + {
70824 + REPORT_ERROR(MAJOR, err, NO_MSG);
70825 + return 0;
70826 + }
70827 + if (replyLength != (sizeof(uint32_t) + sizeof(uint32_t)))
70828 + {
70829 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
70830 + return 0;
70831 + }
70832 +
70833 + memcpy((uint8_t*)&outCounter, reply.replyBody, sizeof(uint32_t));
70834 + return outCounter;
70835 + }
70836 + else if (!p_Fm->baseAddr)
70837 + {
70838 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Either IPC or 'baseAddress' is required!"));
70839 + return 0;
70840 + }
70841 +
70842 + /* When applicable (when there is an 'enable counters' bit,
70843 + check that counters are enabled */
70844 + switch (counter)
70845 + {
70846 + case (e_FM_COUNTERS_DEQ_1):
70847 + case (e_FM_COUNTERS_DEQ_2):
70848 + case (e_FM_COUNTERS_DEQ_3):
70849 + if ((p_Fm->p_FmStateStruct->revInfo.majorRev == 4) ||
70850 + (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6))
70851 + {
70852 + REPORT_ERROR(MAJOR, E_NOT_SUPPORTED, ("Requested counter not supported"));
70853 + return 0;
70854 + }
70855 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
70856 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
70857 + case (e_FM_COUNTERS_DEQ_0):
70858 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
70859 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
70860 + case (e_FM_COUNTERS_DEQ_FROM_FD):
70861 + case (e_FM_COUNTERS_DEQ_CONFIRM):
70862 + if (!(GET_UINT32(p_Fm->p_FmQmiRegs->fmqm_gc) & QMI_CFG_EN_COUNTERS))
70863 + {
70864 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Requested counter was not enabled"));
70865 + return 0;
70866 + }
70867 + break;
70868 + default:
70869 + break;
70870 + }
70871 +
70872 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
70873 + return fman_get_counter(&fman_rg, fsl_counter);
70874 +}
70875 +
70876 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val)
70877 +{
70878 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70879 + struct fman_rg fman_rg;
70880 + enum fman_counters fsl_counter;
70881 +
70882 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
70883 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70884 +
70885 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
70886 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
70887 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
70888 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
70889 +
70890 + FMAN_COUNTERS_TRANS(fsl_counter, counter);
70891 + return (t_Error)fman_modify_counter(&fman_rg, fsl_counter, val);
70892 +}
70893 +
70894 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable)
70895 +{
70896 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70897 + struct fman_dma_regs *dma_rg;
70898 +
70899 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70900 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70901 +
70902 + dma_rg = p_Fm->p_FmDmaRegs;
70903 +
70904 + fman_set_dma_emergency(dma_rg, !!(muramPort==e_FM_DMA_MURAM_PORT_WRITE), enable);
70905 +}
70906 +
70907 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri)
70908 +{
70909 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70910 + struct fman_dma_regs *dma_rg;
70911 +
70912 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70913 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70914 +
70915 + dma_rg = p_Fm->p_FmDmaRegs;
70916 +
70917 + fman_set_dma_ext_bus_pri(dma_rg, pri);
70918 +}
70919 +
70920 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus)
70921 +{
70922 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70923 + uint32_t dmaStatus;
70924 + struct fman_dma_regs *dma_rg;
70925 +
70926 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70927 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
70928 +
70929 + dma_rg = p_Fm->p_FmDmaRegs;
70930 +
70931 + if ((p_Fm->guestId != NCSW_MASTER_ID) &&
70932 + !p_Fm->baseAddr &&
70933 + p_Fm->h_IpcSessions[0])
70934 + {
70935 + t_FmIpcDmaStatus ipcDmaStatus;
70936 + t_FmIpcMsg msg;
70937 + t_FmIpcReply reply;
70938 + t_Error err;
70939 + uint32_t replyLength;
70940 +
70941 + memset(&msg, 0, sizeof(msg));
70942 + memset(&reply, 0, sizeof(reply));
70943 + msg.msgId = FM_DMA_STAT;
70944 + replyLength = sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus);
70945 + err = XX_IpcSendMessage(p_Fm->h_IpcSessions[0],
70946 + (uint8_t*)&msg,
70947 + sizeof(msg.msgId),
70948 + (uint8_t*)&reply,
70949 + &replyLength,
70950 + NULL,
70951 + NULL);
70952 + if (err != E_OK)
70953 + {
70954 + REPORT_ERROR(MINOR, err, NO_MSG);
70955 + return;
70956 + }
70957 + if (replyLength != (sizeof(uint32_t) + sizeof(t_FmIpcDmaStatus)))
70958 + {
70959 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("IPC reply length mismatch"));
70960 + return;
70961 + }
70962 + memcpy((uint8_t*)&ipcDmaStatus, reply.replyBody, sizeof(t_FmIpcDmaStatus));
70963 +
70964 + p_FmDmaStatus->cmqNotEmpty = (bool)ipcDmaStatus.boolCmqNotEmpty; /**< Command queue is not empty */
70965 + p_FmDmaStatus->busError = (bool)ipcDmaStatus.boolBusError; /**< Bus error occurred */
70966 + p_FmDmaStatus->readBufEccError = (bool)ipcDmaStatus.boolReadBufEccError; /**< Double ECC error on buffer Read */
70967 + p_FmDmaStatus->writeBufEccSysError =(bool)ipcDmaStatus.boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
70968 + p_FmDmaStatus->writeBufEccFmError = (bool)ipcDmaStatus.boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
70969 + p_FmDmaStatus->singlePortEccError = (bool)ipcDmaStatus.boolSinglePortEccError; /**< Double ECC error on buffer write from FM side */
70970 + return;
70971 + }
70972 + else if (!p_Fm->baseAddr)
70973 + {
70974 + REPORT_ERROR(MINOR, E_NOT_SUPPORTED,
70975 + ("Either IPC or 'baseAddress' is required!"));
70976 + return;
70977 + }
70978 +
70979 + dmaStatus = fman_get_dma_status(dma_rg);
70980 +
70981 + p_FmDmaStatus->cmqNotEmpty = (bool)(dmaStatus & DMA_STATUS_CMD_QUEUE_NOT_EMPTY);
70982 + p_FmDmaStatus->busError = (bool)(dmaStatus & DMA_STATUS_BUS_ERR);
70983 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
70984 + p_FmDmaStatus->singlePortEccError = (bool)(dmaStatus & DMA_STATUS_FM_SPDAT_ECC);
70985 + else
70986 + {
70987 + p_FmDmaStatus->readBufEccError = (bool)(dmaStatus & DMA_STATUS_READ_ECC);
70988 + p_FmDmaStatus->writeBufEccSysError = (bool)(dmaStatus & DMA_STATUS_SYSTEM_WRITE_ECC);
70989 + p_FmDmaStatus->writeBufEccFmError = (bool)(dmaStatus & DMA_STATUS_FM_WRITE_ECC);
70990 + }
70991 +}
70992 +
70993 +void FM_Resume(t_Handle h_Fm)
70994 +{
70995 + t_Fm *p_Fm = (t_Fm*)h_Fm;
70996 + struct fman_fpm_regs *fpm_rg;
70997 +
70998 + SANITY_CHECK_RETURN(p_Fm, E_INVALID_HANDLE);
70999 + SANITY_CHECK_RETURN(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
71000 + SANITY_CHECK_RETURN((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
71001 +
71002 + fpm_rg = p_Fm->p_FmFpmRegs;
71003 +
71004 + fman_resume(fpm_rg);
71005 +}
71006 +
71007 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
71008 + fmSpecialOperations_t spOper,
71009 + uint8_t *p_SpOperCoding)
71010 +{
71011 + t_Fm *p_Fm = (t_Fm*)h_Fm;
71012 + t_FmCtrlCodeRevisionInfo revInfo;
71013 + t_Error err;
71014 +
71015 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
71016 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
71017 + SANITY_CHECK_RETURN_ERROR(p_SpOperCoding, E_NULL_POINTER);
71018 +
71019 + if (!spOper)
71020 + {
71021 + *p_SpOperCoding = 0;
71022 + return E_OK;
71023 + }
71024 +
71025 + if ((err = FM_GetFmanCtrlCodeRevision(p_Fm, &revInfo)) != E_OK)
71026 + {
71027 + DBG(WARNING, ("FM in guest-mode without IPC, can't validate firmware revision."));
71028 + revInfo.packageRev = IP_OFFLOAD_PACKAGE_NUMBER;
71029 + }
71030 + else if (!IS_OFFLOAD_PACKAGE(revInfo.packageRev))
71031 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("Fman ctrl code package"));
71032 +
71033 + switch (spOper)
71034 + {
71035 + case (FM_SP_OP_CAPWAP_DTLS_DEC):
71036 + *p_SpOperCoding = 9;
71037 + break;
71038 + case (FM_SP_OP_CAPWAP_DTLS_ENC):
71039 + *p_SpOperCoding = 10;
71040 + break;
71041 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP):
71042 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
71043 + *p_SpOperCoding = 5;
71044 + break;
71045 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP):
71046 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_MANIP|FM_SP_OP_RPD):
71047 + *p_SpOperCoding = 6;
71048 + break;
71049 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_RPD):
71050 + *p_SpOperCoding = 3;
71051 + break;
71052 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN):
71053 + *p_SpOperCoding = 1;
71054 + break;
71055 + case (FM_SP_OP_IPSEC|FM_SP_OP_IPSEC_UPDATE_UDP_LEN|FM_SP_OP_IPSEC_NO_ETH_HDR):
71056 + *p_SpOperCoding = 12;
71057 + break;
71058 + case (FM_SP_OP_IPSEC|FM_SP_OP_RPD):
71059 + *p_SpOperCoding = 4;
71060 + break;
71061 + case (FM_SP_OP_IPSEC):
71062 + *p_SpOperCoding = 2;
71063 + break;
71064 + case (FM_SP_OP_DCL4C):
71065 + *p_SpOperCoding = 7;
71066 + break;
71067 + case (FM_SP_OP_CLEAR_RPD):
71068 + *p_SpOperCoding = 8;
71069 + break;
71070 + default:
71071 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
71072 + }
71073 +
71074 + return E_OK;
71075 +}
71076 +
71077 +t_Error FM_CtrlMonStart(t_Handle h_Fm)
71078 +{
71079 + t_Fm *p_Fm = (t_Fm *)h_Fm;
71080 + t_FmTrbRegs *p_MonRegs;
71081 + uint8_t i;
71082 +
71083 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
71084 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
71085 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
71086 +
71087 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
71088 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) | FPM_BRKC_RDBG);
71089 +
71090 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
71091 + {
71092 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
71093 +
71094 + /* Reset control registers */
71095 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_RESET);
71096 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET);
71097 +
71098 + /* Configure: counter #1 counts all stalls in risc - ldsched stall
71099 + counter #2 counts all stalls in risc - other stall*/
71100 + WRITE_UINT32(p_MonRegs->tcrl, TRB_TCRL_RESET | TRB_TCRL_UTIL);
71101 +
71102 + /* Enable monitoring */
71103 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_ENABLE_COUNTERS);
71104 + }
71105 +
71106 + return E_OK;
71107 +}
71108 +
71109 +t_Error FM_CtrlMonStop(t_Handle h_Fm)
71110 +{
71111 + t_Fm *p_Fm = (t_Fm *)h_Fm;
71112 + t_FmTrbRegs *p_MonRegs;
71113 + uint8_t i;
71114 +
71115 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
71116 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
71117 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
71118 +
71119 + for (i = 0; i < FM_NUM_OF_CTRL; i++)
71120 + {
71121 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(i));
71122 + WRITE_UINT32(p_MonRegs->tcrh, TRB_TCRH_DISABLE_COUNTERS);
71123 + }
71124 +
71125 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc,
71126 + GET_UINT32(p_Fm->p_FmFpmRegs->fmfp_brkc) & ~FPM_BRKC_RDBG);
71127 +
71128 + return E_OK;
71129 +}
71130 +
71131 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon)
71132 +{
71133 + t_Fm *p_Fm = (t_Fm *)h_Fm;
71134 + t_FmTrbRegs *p_MonRegs;
71135 + uint64_t clkCnt, utilValue, effValue;
71136 +
71137 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
71138 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
71139 + SANITY_CHECK_RETURN_ERROR((p_Fm->guestId == NCSW_MASTER_ID), E_NOT_SUPPORTED);
71140 + SANITY_CHECK_RETURN_ERROR(p_Mon, E_NULL_POINTER);
71141 +
71142 + if (fmCtrlIndex >= FM_NUM_OF_CTRL)
71143 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("FM Controller index"));
71144 +
71145 + p_MonRegs = (t_FmTrbRegs *)UINT_TO_PTR(p_Fm->baseAddr + FM_MM_TRB(fmCtrlIndex));
71146 +
71147 + clkCnt = (uint64_t)
71148 + ((uint64_t)GET_UINT32(p_MonRegs->tpcch) << 32 | GET_UINT32(p_MonRegs->tpccl));
71149 +
71150 + utilValue = (uint64_t)
71151 + ((uint64_t)GET_UINT32(p_MonRegs->tpc1h) << 32 | GET_UINT32(p_MonRegs->tpc1l));
71152 +
71153 + effValue = (uint64_t)
71154 + ((uint64_t)GET_UINT32(p_MonRegs->tpc2h) << 32 | GET_UINT32(p_MonRegs->tpc2l));
71155 +
71156 + p_Mon->percentCnt[0] = (uint8_t)div64_u64((clkCnt - utilValue) * 100, clkCnt);
71157 + if (clkCnt != utilValue)
71158 + p_Mon->percentCnt[1] = (uint8_t)div64_u64(((clkCnt - utilValue) - effValue) * 100, clkCnt - utilValue);
71159 + else
71160 + p_Mon->percentCnt[1] = 0;
71161 +
71162 + return E_OK;
71163 +}
71164 +
71165 +t_Handle FM_GetMuramHandle(t_Handle h_Fm)
71166 +{
71167 + t_Fm *p_Fm = (t_Fm*)h_Fm;
71168 +
71169 + SANITY_CHECK_RETURN_VALUE(p_Fm, E_INVALID_HANDLE, NULL);
71170 +
71171 + return (p_Fm->h_FmMuram);
71172 +}
71173 +
71174 +/****************************************************/
71175 +/* Hidden-DEBUG Only API */
71176 +/****************************************************/
71177 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception)
71178 +{
71179 + t_Fm *p_Fm = (t_Fm*)h_Fm;
71180 + enum fman_exceptions fslException;
71181 + struct fman_rg fman_rg;
71182 +
71183 + SANITY_CHECK_RETURN_ERROR(p_Fm, E_INVALID_HANDLE);
71184 + SANITY_CHECK_RETURN_ERROR(!p_Fm->p_FmDriverParam, E_INVALID_STATE);
71185 +
71186 + fman_rg.bmi_rg = p_Fm->p_FmBmiRegs;
71187 + fman_rg.qmi_rg = p_Fm->p_FmQmiRegs;
71188 + fman_rg.fpm_rg = p_Fm->p_FmFpmRegs;
71189 + fman_rg.dma_rg = p_Fm->p_FmDmaRegs;
71190 +
71191 + switch (exception)
71192 + {
71193 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
71194 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID))
71195 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
71196 + break;
71197 + case e_FM_EX_QMI_SINGLE_ECC:
71198 + if (p_Fm->p_FmStateStruct->revInfo.majorRev >= 6)
71199 + RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("e_FM_EX_QMI_SINGLE_ECC not supported on this integration."));
71200 +
71201 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_SINGLE_ECC))
71202 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
71203 + break;
71204 + case e_FM_EX_QMI_DOUBLE_ECC:
71205 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_QMI_DOUBLE_ECC))
71206 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
71207 + break;
71208 + case e_FM_EX_BMI_LIST_RAM_ECC:
71209 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_LIST_RAM_ECC))
71210 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
71211 + break;
71212 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC:
71213 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STORAGE_PROFILE_ECC))
71214 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
71215 + break;
71216 + case e_FM_EX_BMI_STATISTICS_RAM_ECC:
71217 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_STATISTICS_RAM_ECC))
71218 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
71219 + break;
71220 + case e_FM_EX_BMI_DISPATCH_RAM_ECC:
71221 + if (!(p_Fm->p_FmStateStruct->exceptions & FM_EX_BMI_DISPATCH_RAM_ECC))
71222 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception is masked"));
71223 + break;
71224 + default:
71225 + RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("The selected exception may not be forced"));
71226 + }
71227 +
71228 + fslException = FmanExceptionTrans(exception);
71229 + fman_force_intr (&fman_rg, fslException);
71230 +
71231 + return E_OK;
71232 +}
71233 +
71234 +t_Handle FmGetPcd(t_Handle h_Fm)
71235 +{
71236 + return ((t_Fm*)h_Fm)->h_Pcd;
71237 +}
71238 +#if (DPAA_VERSION >= 11)
71239 +extern void *g_MemacRegs;
71240 +void fm_clk_down(void);
71241 +uint32_t fman_memac_get_event(void *regs, uint32_t ev_mask);
71242 +void FM_ChangeClock(t_Handle h_Fm, int hardwarePortId)
71243 +{
71244 + int macId;
71245 + uint32_t event, rcr;
71246 + t_Fm *p_Fm = (t_Fm*)h_Fm;
71247 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
71248 + rcr |= 0x04000000;
71249 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
71250 +
71251 + HW_PORT_ID_TO_SW_PORT_ID(macId, hardwarePortId);
71252 + do
71253 + {
71254 + event = fman_memac_get_event(g_MemacRegs, 0xFFFFFFFF);
71255 + } while ((event & 0x00000020) == 0);
71256 + fm_clk_down();
71257 + rcr = GET_UINT32(p_Fm->p_FmFpmRegs->fm_rcr);
71258 + rcr &= ~0x04000000;
71259 + WRITE_UINT32(p_Fm->p_FmFpmRegs->fm_rcr, rcr);
71260 +}
71261 +#endif
71262 --- /dev/null
71263 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm.h
71264 @@ -0,0 +1,648 @@
71265 +/*
71266 + * Copyright 2008-2012 Freescale Semiconductor Inc.
71267 + *
71268 + * Redistribution and use in source and binary forms, with or without
71269 + * modification, are permitted provided that the following conditions are met:
71270 + * * Redistributions of source code must retain the above copyright
71271 + * notice, this list of conditions and the following disclaimer.
71272 + * * Redistributions in binary form must reproduce the above copyright
71273 + * notice, this list of conditions and the following disclaimer in the
71274 + * documentation and/or other materials provided with the distribution.
71275 + * * Neither the name of Freescale Semiconductor nor the
71276 + * names of its contributors may be used to endorse or promote products
71277 + * derived from this software without specific prior written permission.
71278 + *
71279 + *
71280 + * ALTERNATIVELY, this software may be distributed under the terms of the
71281 + * GNU General Public License ("GPL") as published by the Free Software
71282 + * Foundation, either version 2 of that License or (at your option) any
71283 + * later version.
71284 + *
71285 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
71286 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
71287 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71288 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
71289 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
71290 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
71291 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
71292 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71293 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
71294 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71295 + */
71296 +
71297 +
71298 +/******************************************************************************
71299 + @File fm.h
71300 +
71301 + @Description FM internal structures and definitions.
71302 +*//***************************************************************************/
71303 +#ifndef __FM_H
71304 +#define __FM_H
71305 +
71306 +#include "error_ext.h"
71307 +#include "std_ext.h"
71308 +#include "fm_ext.h"
71309 +#include "fm_ipc.h"
71310 +
71311 +#include "fsl_fman.h"
71312 +
71313 +#define __ERR_MODULE__ MODULE_FM
71314 +
71315 +#define FM_MAX_NUM_OF_HW_PORT_IDS 64
71316 +#define FM_MAX_NUM_OF_GUESTS 100
71317 +
71318 +/**************************************************************************//**
71319 + @Description Exceptions
71320 +*//***************************************************************************/
71321 +#define FM_EX_DMA_BUS_ERROR 0x80000000 /**< DMA bus error. */
71322 +#define FM_EX_DMA_READ_ECC 0x40000000
71323 +#define FM_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
71324 +#define FM_EX_DMA_FM_WRITE_ECC 0x10000000
71325 +#define FM_EX_FPM_STALL_ON_TASKS 0x08000000 /**< Stall of tasks on FPM */
71326 +#define FM_EX_FPM_SINGLE_ECC 0x04000000 /**< Single ECC on FPM */
71327 +#define FM_EX_FPM_DOUBLE_ECC 0x02000000
71328 +#define FM_EX_QMI_SINGLE_ECC 0x01000000 /**< Single ECC on FPM */
71329 +#define FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000 /**< Dequeu from default queue id */
71330 +#define FM_EX_QMI_DOUBLE_ECC 0x00400000
71331 +#define FM_EX_BMI_LIST_RAM_ECC 0x00200000
71332 +#define FM_EX_BMI_STORAGE_PROFILE_ECC 0x00100000
71333 +#define FM_EX_BMI_STATISTICS_RAM_ECC 0x00080000
71334 +#define FM_EX_IRAM_ECC 0x00040000
71335 +#define FM_EX_MURAM_ECC 0x00020000
71336 +#define FM_EX_BMI_DISPATCH_RAM_ECC 0x00010000
71337 +#define FM_EX_DMA_SINGLE_PORT_ECC 0x00008000
71338 +
71339 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
71340 +
71341 +#define DMA_THRESH_COMMQ_MASK 0xFF000000
71342 +#define DMA_THRESH_READ_INT_BUF_MASK 0x007F0000
71343 +#define DMA_THRESH_WRITE_INT_BUF_MASK 0x0000007F
71344 +
71345 +#define GET_EXCEPTION_FLAG(bitMask, exception) \
71346 +switch (exception){ \
71347 + case e_FM_EX_DMA_BUS_ERROR: \
71348 + bitMask = FM_EX_DMA_BUS_ERROR; break; \
71349 + case e_FM_EX_DMA_SINGLE_PORT_ECC: \
71350 + bitMask = FM_EX_DMA_SINGLE_PORT_ECC; break; \
71351 + case e_FM_EX_DMA_READ_ECC: \
71352 + bitMask = FM_EX_DMA_READ_ECC; break; \
71353 + case e_FM_EX_DMA_SYSTEM_WRITE_ECC: \
71354 + bitMask = FM_EX_DMA_SYSTEM_WRITE_ECC; break; \
71355 + case e_FM_EX_DMA_FM_WRITE_ECC: \
71356 + bitMask = FM_EX_DMA_FM_WRITE_ECC; break; \
71357 + case e_FM_EX_FPM_STALL_ON_TASKS: \
71358 + bitMask = FM_EX_FPM_STALL_ON_TASKS; break; \
71359 + case e_FM_EX_FPM_SINGLE_ECC: \
71360 + bitMask = FM_EX_FPM_SINGLE_ECC; break; \
71361 + case e_FM_EX_FPM_DOUBLE_ECC: \
71362 + bitMask = FM_EX_FPM_DOUBLE_ECC; break; \
71363 + case e_FM_EX_QMI_SINGLE_ECC: \
71364 + bitMask = FM_EX_QMI_SINGLE_ECC; break; \
71365 + case e_FM_EX_QMI_DOUBLE_ECC: \
71366 + bitMask = FM_EX_QMI_DOUBLE_ECC; break; \
71367 + case e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID: \
71368 + bitMask = FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID; break; \
71369 + case e_FM_EX_BMI_LIST_RAM_ECC: \
71370 + bitMask = FM_EX_BMI_LIST_RAM_ECC; break; \
71371 + case e_FM_EX_BMI_STORAGE_PROFILE_ECC: \
71372 + bitMask = FM_EX_BMI_STORAGE_PROFILE_ECC; break; \
71373 + case e_FM_EX_BMI_STATISTICS_RAM_ECC: \
71374 + bitMask = FM_EX_BMI_STATISTICS_RAM_ECC; break; \
71375 + case e_FM_EX_BMI_DISPATCH_RAM_ECC: \
71376 + bitMask = FM_EX_BMI_DISPATCH_RAM_ECC; break; \
71377 + case e_FM_EX_IRAM_ECC: \
71378 + bitMask = FM_EX_IRAM_ECC; break; \
71379 + case e_FM_EX_MURAM_ECC: \
71380 + bitMask = FM_EX_MURAM_ECC; break; \
71381 + default: bitMask = 0;break; \
71382 +}
71383 +
71384 +#define GET_FM_MODULE_EVENT(_mod, _id, _intrType, _event) \
71385 + switch (_mod) { \
71386 + case e_FM_MOD_PRS: \
71387 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
71388 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PRS : e_FM_EV_PRS; \
71389 + break; \
71390 + case e_FM_MOD_KG: \
71391 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
71392 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_KG : e_FM_EV_DUMMY_LAST; \
71393 + break; \
71394 + case e_FM_MOD_PLCR: \
71395 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
71396 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_PLCR : e_FM_EV_PLCR; \
71397 + break; \
71398 + case e_FM_MOD_TMR: \
71399 + if (_id) _event = e_FM_EV_DUMMY_LAST; \
71400 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_DUMMY_LAST : e_FM_EV_TMR; \
71401 + break; \
71402 + case e_FM_MOD_10G_MAC: \
71403 + if (_id >= FM_MAX_NUM_OF_10G_MACS) _event = e_FM_EV_DUMMY_LAST; \
71404 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_10G_MAC0 + _id) : (e_FM_EV_10G_MAC0 + _id); \
71405 + break; \
71406 + case e_FM_MOD_1G_MAC: \
71407 + if (_id >= FM_MAX_NUM_OF_1G_MACS) _event = e_FM_EV_DUMMY_LAST; \
71408 + else _event = (_intrType == e_FM_INTR_TYPE_ERR) ? (e_FM_EV_ERR_1G_MAC0 + _id) : (e_FM_EV_1G_MAC0 + _id); \
71409 + break; \
71410 + case e_FM_MOD_MACSEC: \
71411 + switch (_id){ \
71412 + case (0): _event = (_intrType == e_FM_INTR_TYPE_ERR) ? e_FM_EV_ERR_MACSEC_MAC0:e_FM_EV_MACSEC_MAC0; \
71413 + break; \
71414 + } \
71415 + break; \
71416 + case e_FM_MOD_FMAN_CTRL: \
71417 + if (_intrType == e_FM_INTR_TYPE_ERR) _event = e_FM_EV_DUMMY_LAST; \
71418 + else _event = (e_FM_EV_FMAN_CTRL_0 + _id); \
71419 + break; \
71420 + default: _event = e_FM_EV_DUMMY_LAST; \
71421 + break; \
71422 + }
71423 +
71424 +#define FMAN_CACHE_OVERRIDE_TRANS(fsl_cache_override, _cache_override) \
71425 + switch (_cache_override){ \
71426 + case e_FM_DMA_NO_CACHE_OR: \
71427 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
71428 + case e_FM_DMA_NO_STASH_DATA: \
71429 + fsl_cache_override = E_FMAN_DMA_NO_STASH_DATA; break; \
71430 + case e_FM_DMA_MAY_STASH_DATA: \
71431 + fsl_cache_override = E_FMAN_DMA_MAY_STASH_DATA; break; \
71432 + case e_FM_DMA_STASH_DATA: \
71433 + fsl_cache_override = E_FMAN_DMA_STASH_DATA; break; \
71434 + default: \
71435 + fsl_cache_override = E_FMAN_DMA_NO_CACHE_OR; break; \
71436 + }
71437 +
71438 +#define FMAN_AID_MODE_TRANS(fsl_aid_mode, _aid_mode) \
71439 + switch (_aid_mode){ \
71440 + case e_FM_DMA_AID_OUT_PORT_ID: \
71441 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
71442 + case e_FM_DMA_AID_OUT_TNUM: \
71443 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_TNUM; break; \
71444 + default: \
71445 + fsl_aid_mode = E_FMAN_DMA_AID_OUT_PORT_ID; break; \
71446 + }
71447 +
71448 +#define FMAN_DMA_DBG_CNT_TRANS(fsl_dma_dbg_cnt, _dma_dbg_cnt) \
71449 + switch (_dma_dbg_cnt){ \
71450 + case e_FM_DMA_DBG_NO_CNT: \
71451 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
71452 + case e_FM_DMA_DBG_CNT_DONE: \
71453 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_DONE; break; \
71454 + case e_FM_DMA_DBG_CNT_COMM_Q_EM: \
71455 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_COMM_Q_EM; break; \
71456 + case e_FM_DMA_DBG_CNT_INT_READ_EM: \
71457 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_READ_EM; break; \
71458 + case e_FM_DMA_DBG_CNT_INT_WRITE_EM: \
71459 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_INT_WRITE_EM ; break; \
71460 + case e_FM_DMA_DBG_CNT_FPM_WAIT: \
71461 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_FPM_WAIT ; break; \
71462 + case e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC: \
71463 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC ; break; \
71464 + case e_FM_DMA_DBG_CNT_RAW_WAR_PROT: \
71465 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT ; break; \
71466 + default: \
71467 + fsl_dma_dbg_cnt = E_FMAN_DMA_DBG_NO_CNT; break; \
71468 + }
71469 +
71470 +#define FMAN_DMA_EMER_TRANS(fsl_dma_emer, _dma_emer) \
71471 + switch (_dma_emer){ \
71472 + case e_FM_DMA_EM_EBS: \
71473 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
71474 + case e_FM_DMA_EM_SOS: \
71475 + fsl_dma_emer = E_FMAN_DMA_EM_SOS; break; \
71476 + default: \
71477 + fsl_dma_emer = E_FMAN_DMA_EM_EBS; break; \
71478 + }
71479 +
71480 +#define FMAN_DMA_ERR_TRANS(fsl_dma_err, _dma_err) \
71481 + switch (_dma_err){ \
71482 + case e_FM_DMA_ERR_CATASTROPHIC: \
71483 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
71484 + case e_FM_DMA_ERR_REPORT: \
71485 + fsl_dma_err = E_FMAN_DMA_ERR_REPORT; break; \
71486 + default: \
71487 + fsl_dma_err = E_FMAN_DMA_ERR_CATASTROPHIC; break; \
71488 + }
71489 +
71490 +#define FMAN_CATASTROPHIC_ERR_TRANS(fsl_catastrophic_err, _catastrophic_err) \
71491 + switch (_catastrophic_err){ \
71492 + case e_FM_CATASTROPHIC_ERR_STALL_PORT: \
71493 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
71494 + case e_FM_CATASTROPHIC_ERR_STALL_TASK: \
71495 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_TASK; break; \
71496 + default: \
71497 + fsl_catastrophic_err = E_FMAN_CATAST_ERR_STALL_PORT; break; \
71498 + }
71499 +
71500 +#define FMAN_COUNTERS_TRANS(fsl_counters, _counters) \
71501 + switch (_counters){ \
71502 + case e_FM_COUNTERS_ENQ_TOTAL_FRAME: \
71503 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
71504 + case e_FM_COUNTERS_DEQ_TOTAL_FRAME: \
71505 + fsl_counters = E_FMAN_COUNTERS_DEQ_TOTAL_FRAME; break; \
71506 + case e_FM_COUNTERS_DEQ_0: \
71507 + fsl_counters = E_FMAN_COUNTERS_DEQ_0; break; \
71508 + case e_FM_COUNTERS_DEQ_1: \
71509 + fsl_counters = E_FMAN_COUNTERS_DEQ_1; break; \
71510 + case e_FM_COUNTERS_DEQ_2: \
71511 + fsl_counters = E_FMAN_COUNTERS_DEQ_2; break; \
71512 + case e_FM_COUNTERS_DEQ_3: \
71513 + fsl_counters = E_FMAN_COUNTERS_DEQ_3; break; \
71514 + case e_FM_COUNTERS_DEQ_FROM_DEFAULT: \
71515 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_DEFAULT; break; \
71516 + case e_FM_COUNTERS_DEQ_FROM_CONTEXT: \
71517 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_CONTEXT; break; \
71518 + case e_FM_COUNTERS_DEQ_FROM_FD: \
71519 + fsl_counters = E_FMAN_COUNTERS_DEQ_FROM_FD; break; \
71520 + case e_FM_COUNTERS_DEQ_CONFIRM: \
71521 + fsl_counters = E_FMAN_COUNTERS_DEQ_CONFIRM; break; \
71522 + default: \
71523 + fsl_counters = E_FMAN_COUNTERS_ENQ_TOTAL_FRAME; break; \
71524 + }
71525 +
71526 +/**************************************************************************//**
71527 + @Description defaults
71528 +*//***************************************************************************/
71529 +#define DEFAULT_exceptions (FM_EX_DMA_BUS_ERROR |\
71530 + FM_EX_DMA_READ_ECC |\
71531 + FM_EX_DMA_SYSTEM_WRITE_ECC |\
71532 + FM_EX_DMA_FM_WRITE_ECC |\
71533 + FM_EX_FPM_STALL_ON_TASKS |\
71534 + FM_EX_FPM_SINGLE_ECC |\
71535 + FM_EX_FPM_DOUBLE_ECC |\
71536 + FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID|\
71537 + FM_EX_BMI_LIST_RAM_ECC |\
71538 + FM_EX_BMI_STORAGE_PROFILE_ECC |\
71539 + FM_EX_BMI_STATISTICS_RAM_ECC |\
71540 + FM_EX_IRAM_ECC |\
71541 + FM_EX_MURAM_ECC |\
71542 + FM_EX_BMI_DISPATCH_RAM_ECC |\
71543 + FM_EX_QMI_DOUBLE_ECC |\
71544 + FM_EX_QMI_SINGLE_ECC)
71545 +
71546 +#define DEFAULT_eccEnable FALSE
71547 +#ifdef FM_PEDANTIC_DMA
71548 +#define DEFAULT_aidOverride TRUE
71549 +#else
71550 +#define DEFAULT_aidOverride FALSE
71551 +#endif /* FM_PEDANTIC_DMA */
71552 +#define DEFAULT_aidMode e_FM_DMA_AID_OUT_TNUM
71553 +#define DEFAULT_dmaStopOnBusError FALSE
71554 +#define DEFAULT_stopAtBusError FALSE
71555 +#define DEFAULT_axiDbgNumOfBeats 1
71556 +#define DEFAULT_dmaReadIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
71557 +#define DEFAULT_dmaReadIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
71558 +#define DEFAULT_dmaWriteIntBufLow ((DMA_THRESH_MAX_BUF+1)/2)
71559 +#define DEFAULT_dmaWriteIntBufHigh ((DMA_THRESH_MAX_BUF+1)*3/4)
71560 +#define DEFAULT_catastrophicErr e_FM_CATASTROPHIC_ERR_STALL_PORT
71561 +#define DEFAULT_dmaErr e_FM_DMA_ERR_CATASTROPHIC
71562 +#define DEFAULT_resetOnInit FALSE
71563 +#define DEFAULT_resetOnInitOverrideCallback NULL
71564 +#define DEFAULT_haltOnExternalActivation FALSE /* do not change! if changed, must be disabled for rev1 ! */
71565 +#define DEFAULT_haltOnUnrecoverableEccError FALSE /* do not change! if changed, must be disabled for rev1 ! */
71566 +#define DEFAULT_externalEccRamsEnable FALSE
71567 +#define DEFAULT_VerifyUcode FALSE
71568 +
71569 +#if (DPAA_VERSION < 11)
71570 +#define DEFAULT_totalFifoSize(major, minor) \
71571 + (((major == 2) || (major == 5)) ? \
71572 + (100*KILOBYTE) : ((major == 4) ? \
71573 + (49*KILOBYTE) : (122*KILOBYTE)))
71574 +#define DEFAULT_totalNumOfTasks(major, minor) \
71575 + BMI_MAX_NUM_OF_TASKS
71576 +
71577 +#define DEFAULT_dmaCommQLow ((DMA_THRESH_MAX_COMMQ+1)/2)
71578 +#define DEFAULT_dmaCommQHigh ((DMA_THRESH_MAX_COMMQ+1)*3/4)
71579 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
71580 +#define DEFAULT_dmaCamNumOfEntries 32
71581 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
71582 +#define DEFAULT_dmaEnEmergency FALSE
71583 +#define DEFAULT_dmaSosEmergency 0
71584 +#define DEFAULT_dmaWatchdog 0 /* disabled */
71585 +#define DEFAULT_dmaEnEmergencySmoother FALSE
71586 +#define DEFAULT_dmaEmergencySwitchCounter 0
71587 +
71588 +#define DEFAULT_dispLimit 0
71589 +#define DEFAULT_prsDispTh 16
71590 +#define DEFAULT_plcrDispTh 16
71591 +#define DEFAULT_kgDispTh 16
71592 +#define DEFAULT_bmiDispTh 16
71593 +#define DEFAULT_qmiEnqDispTh 16
71594 +#define DEFAULT_qmiDeqDispTh 16
71595 +#define DEFAULT_fmCtl1DispTh 16
71596 +#define DEFAULT_fmCtl2DispTh 16
71597 +
71598 +#else /* (DPAA_VERSION < 11) */
71599 +/* Defaults are registers' reset values */
71600 +#define DEFAULT_totalFifoSize(major, minor) \
71601 + (((major == 6) && ((minor == 1) || (minor == 4))) ? \
71602 + (156*KILOBYTE) : (295*KILOBYTE))
71603 +
71604 +/* According to the default value of FMBM_CFG2[TNTSKS] */
71605 +#define DEFAULT_totalNumOfTasks(major, minor) \
71606 + (((major == 6) && ((minor == 1) || (minor == 4))) ? 59 : 124)
71607 +
71608 +#define DEFAULT_dmaCommQLow 0x2A
71609 +#define DEFAULT_dmaCommQHigh 0x3F
71610 +#define DEFAULT_cacheOverride e_FM_DMA_NO_CACHE_OR
71611 +#define DEFAULT_dmaCamNumOfEntries 64
71612 +#define DEFAULT_dmaDbgCntMode e_FM_DMA_DBG_NO_CNT
71613 +#define DEFAULT_dmaEnEmergency FALSE
71614 +#define DEFAULT_dmaSosEmergency 0
71615 +#define DEFAULT_dmaWatchdog 0 /* disabled */
71616 +#define DEFAULT_dmaEnEmergencySmoother FALSE
71617 +#define DEFAULT_dmaEmergencySwitchCounter 0
71618 +
71619 +#define DEFAULT_dispLimit 0
71620 +#define DEFAULT_prsDispTh 16
71621 +#define DEFAULT_plcrDispTh 16
71622 +#define DEFAULT_kgDispTh 16
71623 +#define DEFAULT_bmiDispTh 16
71624 +#define DEFAULT_qmiEnqDispTh 16
71625 +#define DEFAULT_qmiDeqDispTh 16
71626 +#define DEFAULT_fmCtl1DispTh 16
71627 +#define DEFAULT_fmCtl2DispTh 16
71628 +#endif /* (DPAA_VERSION < 11) */
71629 +
71630 +#define FM_TIMESTAMP_1_USEC_BIT 8
71631 +
71632 +/**************************************************************************//**
71633 + @Collection Defines used for enabling/disabling FM interrupts
71634 + @{
71635 +*//***************************************************************************/
71636 +#define ERR_INTR_EN_DMA 0x00010000
71637 +#define ERR_INTR_EN_FPM 0x80000000
71638 +#define ERR_INTR_EN_BMI 0x00800000
71639 +#define ERR_INTR_EN_QMI 0x00400000
71640 +#define ERR_INTR_EN_PRS 0x00200000
71641 +#define ERR_INTR_EN_KG 0x00100000
71642 +#define ERR_INTR_EN_PLCR 0x00080000
71643 +#define ERR_INTR_EN_MURAM 0x00040000
71644 +#define ERR_INTR_EN_IRAM 0x00020000
71645 +#define ERR_INTR_EN_10G_MAC0 0x00008000
71646 +#define ERR_INTR_EN_10G_MAC1 0x00000040
71647 +#define ERR_INTR_EN_1G_MAC0 0x00004000
71648 +#define ERR_INTR_EN_1G_MAC1 0x00002000
71649 +#define ERR_INTR_EN_1G_MAC2 0x00001000
71650 +#define ERR_INTR_EN_1G_MAC3 0x00000800
71651 +#define ERR_INTR_EN_1G_MAC4 0x00000400
71652 +#define ERR_INTR_EN_1G_MAC5 0x00000200
71653 +#define ERR_INTR_EN_1G_MAC6 0x00000100
71654 +#define ERR_INTR_EN_1G_MAC7 0x00000080
71655 +#define ERR_INTR_EN_MACSEC_MAC0 0x00000001
71656 +
71657 +#define INTR_EN_QMI 0x40000000
71658 +#define INTR_EN_PRS 0x20000000
71659 +#define INTR_EN_WAKEUP 0x10000000
71660 +#define INTR_EN_PLCR 0x08000000
71661 +#define INTR_EN_1G_MAC0 0x00080000
71662 +#define INTR_EN_1G_MAC1 0x00040000
71663 +#define INTR_EN_1G_MAC2 0x00020000
71664 +#define INTR_EN_1G_MAC3 0x00010000
71665 +#define INTR_EN_1G_MAC4 0x00000040
71666 +#define INTR_EN_1G_MAC5 0x00000020
71667 +#define INTR_EN_1G_MAC6 0x00000008
71668 +#define INTR_EN_1G_MAC7 0x00000002
71669 +#define INTR_EN_10G_MAC0 0x00200000
71670 +#define INTR_EN_10G_MAC1 0x00100000
71671 +#define INTR_EN_REV0 0x00008000
71672 +#define INTR_EN_REV1 0x00004000
71673 +#define INTR_EN_REV2 0x00002000
71674 +#define INTR_EN_REV3 0x00001000
71675 +#define INTR_EN_BRK 0x00000080
71676 +#define INTR_EN_TMR 0x01000000
71677 +#define INTR_EN_MACSEC_MAC0 0x00000001
71678 +/* @} */
71679 +
71680 +/**************************************************************************//**
71681 + @Description Memory Mapped Registers
71682 +*//***************************************************************************/
71683 +
71684 +#if defined(__MWERKS__) && !defined(__GNUC__)
71685 +#pragma pack(push,1)
71686 +#endif /* defined(__MWERKS__) && ... */
71687 +
71688 +typedef struct
71689 +{
71690 + volatile uint32_t iadd; /**< FM IRAM instruction address register */
71691 + volatile uint32_t idata; /**< FM IRAM instruction data register */
71692 + volatile uint32_t itcfg; /**< FM IRAM timing config register */
71693 + volatile uint32_t iready; /**< FM IRAM ready register */
71694 + volatile uint32_t res[0x1FFFC];
71695 +} t_FMIramRegs;
71696 +
71697 +/* Trace buffer registers -
71698 + each FM Controller has its own trace buffer residing at FM_MM_TRB(fmCtrlIndex) offset */
71699 +typedef struct t_FmTrbRegs
71700 +{
71701 + volatile uint32_t tcrh;
71702 + volatile uint32_t tcrl;
71703 + volatile uint32_t tesr;
71704 + volatile uint32_t tecr0h;
71705 + volatile uint32_t tecr0l;
71706 + volatile uint32_t terf0h;
71707 + volatile uint32_t terf0l;
71708 + volatile uint32_t tecr1h;
71709 + volatile uint32_t tecr1l;
71710 + volatile uint32_t terf1h;
71711 + volatile uint32_t terf1l;
71712 + volatile uint32_t tpcch;
71713 + volatile uint32_t tpccl;
71714 + volatile uint32_t tpc1h;
71715 + volatile uint32_t tpc1l;
71716 + volatile uint32_t tpc2h;
71717 + volatile uint32_t tpc2l;
71718 + volatile uint32_t twdimr;
71719 + volatile uint32_t twicvr;
71720 + volatile uint32_t tar;
71721 + volatile uint32_t tdr;
71722 + volatile uint32_t tsnum1;
71723 + volatile uint32_t tsnum2;
71724 + volatile uint32_t tsnum3;
71725 + volatile uint32_t tsnum4;
71726 +} t_FmTrbRegs;
71727 +
71728 +#if defined(__MWERKS__) && !defined(__GNUC__)
71729 +#pragma pack(pop)
71730 +#endif /* defined(__MWERKS__) && ... */
71731 +
71732 +/**************************************************************************//**
71733 + @Description General defines
71734 +*//***************************************************************************/
71735 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
71736 +#define FM_FW_DEBUG_INSTRUCTION 0x6ffff805UL
71737 +
71738 +/**************************************************************************//**
71739 + @Description FPM defines
71740 +*//***************************************************************************/
71741 +/* masks */
71742 +#define FPM_BRKC_RDBG 0x00000200
71743 +#define FPM_BRKC_SLP 0x00000800
71744 +/**************************************************************************//**
71745 + @Description BMI defines
71746 +*//***************************************************************************/
71747 +/* masks */
71748 +#define BMI_INIT_START 0x80000000
71749 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
71750 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
71751 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
71752 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
71753 +/**************************************************************************//**
71754 + @Description QMI defines
71755 +*//***************************************************************************/
71756 +/* masks */
71757 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
71758 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
71759 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
71760 +
71761 +/**************************************************************************//**
71762 + @Description IRAM defines
71763 +*//***************************************************************************/
71764 +/* masks */
71765 +#define IRAM_IADD_AIE 0x80000000
71766 +#define IRAM_READY 0x80000000
71767 +
71768 +/**************************************************************************//**
71769 + @Description TRB defines
71770 +*//***************************************************************************/
71771 +/* masks */
71772 +#define TRB_TCRH_RESET 0x04000000
71773 +#define TRB_TCRH_ENABLE_COUNTERS 0x84008000
71774 +#define TRB_TCRH_DISABLE_COUNTERS 0x8400C000
71775 +#define TRB_TCRL_RESET 0x20000000
71776 +#define TRB_TCRL_UTIL 0x00000460
71777 +typedef struct {
71778 + void (*f_Isr) (t_Handle h_Arg, uint32_t event);
71779 + t_Handle h_SrcHandle;
71780 +} t_FmanCtrlIntrSrc;
71781 +
71782 +
71783 +typedef void (t_FmanCtrlIsr)( t_Handle h_Fm, uint32_t event);
71784 +
71785 +typedef struct
71786 +{
71787 +/***************************/
71788 +/* Master/Guest parameters */
71789 +/***************************/
71790 + uint8_t fmId;
71791 + e_FmPortType portsTypes[FM_MAX_NUM_OF_HW_PORT_IDS];
71792 + uint16_t fmClkFreq;
71793 + uint16_t fmMacClkFreq;
71794 + t_FmRevisionInfo revInfo;
71795 +/**************************/
71796 +/* Master Only parameters */
71797 +/**************************/
71798 + bool enabledTimeStamp;
71799 + uint8_t count1MicroBit;
71800 + uint8_t totalNumOfTasks;
71801 + uint32_t totalFifoSize;
71802 + uint8_t maxNumOfOpenDmas;
71803 + uint8_t accumulatedNumOfTasks;
71804 + uint32_t accumulatedFifoSize;
71805 + uint8_t accumulatedNumOfOpenDmas;
71806 + uint8_t accumulatedNumOfDeqTnums;
71807 +#ifdef FM_LOW_END_RESTRICTION
71808 + bool lowEndRestriction;
71809 +#endif /* FM_LOW_END_RESTRICTION */
71810 + uint32_t exceptions;
71811 + int irq;
71812 + int errIrq;
71813 + bool ramsEccEnable;
71814 + bool explicitEnable;
71815 + bool internalCall;
71816 + uint8_t ramsEccOwners;
71817 + uint32_t extraFifoPoolSize;
71818 + uint8_t extraTasksPoolSize;
71819 + uint8_t extraOpenDmasPoolSize;
71820 +#if defined(FM_MAX_NUM_OF_10G_MACS) && (FM_MAX_NUM_OF_10G_MACS)
71821 + uint16_t portMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
71822 + uint16_t macMaxFrameLengths10G[FM_MAX_NUM_OF_10G_MACS];
71823 +#endif /* defined(FM_MAX_NUM_OF_10G_MACS) && ... */
71824 + uint16_t portMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
71825 + uint16_t macMaxFrameLengths1G[FM_MAX_NUM_OF_1G_MACS];
71826 +} t_FmStateStruct;
71827 +
71828 +#if (DPAA_VERSION >= 11)
71829 +typedef struct t_FmMapParam {
71830 + uint16_t profilesBase;
71831 + uint16_t numOfProfiles;
71832 + t_Handle h_FmPort;
71833 +} t_FmMapParam;
71834 +
71835 +typedef struct t_FmAllocMng {
71836 + bool allocated;
71837 + uint8_t ownerId; /* guestId for KG in multi-partition only,
71838 + portId for PLCR in any environment */
71839 +} t_FmAllocMng;
71840 +
71841 +typedef struct t_FmPcdSpEntry {
71842 + bool valid;
71843 + t_FmAllocMng profilesMng;
71844 +} t_FmPcdSpEntry;
71845 +
71846 +typedef struct t_FmSp {
71847 + void *p_FmPcdStoragePrflRegs;
71848 + t_FmPcdSpEntry profiles[FM_VSP_MAX_NUM_OF_ENTRIES];
71849 + t_FmMapParam portsMapping[FM_MAX_NUM_OF_PORTS];
71850 +} t_FmSp;
71851 +#endif /* (DPAA_VERSION >= 11) */
71852 +
71853 +typedef struct t_Fm
71854 +{
71855 +/***************************/
71856 +/* Master/Guest parameters */
71857 +/***************************/
71858 +/* locals for recovery */
71859 + uintptr_t baseAddr;
71860 +
71861 +/* un-needed for recovery */
71862 + t_Handle h_Pcd;
71863 + char fmModuleName[MODULE_NAME_SIZE];
71864 + char fmIpcHandlerModuleName[FM_MAX_NUM_OF_GUESTS][MODULE_NAME_SIZE];
71865 + t_Handle h_IpcSessions[FM_MAX_NUM_OF_GUESTS];
71866 + t_FmIntrSrc intrMng[e_FM_EV_DUMMY_LAST]; /* FM exceptions user callback */
71867 + uint8_t guestId;
71868 +/**************************/
71869 +/* Master Only parameters */
71870 +/**************************/
71871 +/* locals for recovery */
71872 + struct fman_fpm_regs *p_FmFpmRegs;
71873 + struct fman_bmi_regs *p_FmBmiRegs;
71874 + struct fman_qmi_regs *p_FmQmiRegs;
71875 + struct fman_dma_regs *p_FmDmaRegs;
71876 + struct fman_regs *p_FmRegs;
71877 + t_FmExceptionsCallback *f_Exception;
71878 + t_FmBusErrorCallback *f_BusError;
71879 + t_Handle h_App; /* Application handle */
71880 + t_Handle h_Spinlock;
71881 + bool recoveryMode;
71882 + t_FmStateStruct *p_FmStateStruct;
71883 + uint16_t tnumAgingPeriod;
71884 +#if (DPAA_VERSION >= 11)
71885 + t_FmSp *p_FmSp;
71886 + uint8_t partNumOfVSPs;
71887 + uint8_t partVSPBase;
71888 + uintptr_t vspBaseAddr;
71889 +#endif /* (DPAA_VERSION >= 11) */
71890 + bool portsPreFetchConfigured[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
71891 + bool portsPreFetchValue[FM_MAX_NUM_OF_HW_PORT_IDS]; /* Prefetch configration per Tx-port */
71892 +
71893 +/* un-needed for recovery */
71894 + struct fman_cfg *p_FmDriverParam;
71895 + t_Handle h_FmMuram;
71896 + uint64_t fmMuramPhysBaseAddr;
71897 + bool independentMode;
71898 + bool hcPortInitialized;
71899 + uintptr_t camBaseAddr; /* save for freeing */
71900 + uintptr_t resAddr;
71901 + uintptr_t fifoBaseAddr; /* save for freeing */
71902 + t_FmanCtrlIntrSrc fmanCtrlIntr[FM_NUM_OF_FMAN_CTRL_EVENT_REGS]; /* FM exceptions user callback */
71903 + bool usedEventRegs[FM_NUM_OF_FMAN_CTRL_EVENT_REGS];
71904 + t_FmFirmwareParams firmware;
71905 + bool fwVerify;
71906 + bool resetOnInit;
71907 + t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride;
71908 + uint32_t userSetExceptions;
71909 +} t_Fm;
71910 +
71911 +
71912 +#endif /* __FM_H */
71913 --- /dev/null
71914 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_ipc.h
71915 @@ -0,0 +1,465 @@
71916 +/*
71917 + * Copyright 2008-2012 Freescale Semiconductor Inc.
71918 + *
71919 + * Redistribution and use in source and binary forms, with or without
71920 + * modification, are permitted provided that the following conditions are met:
71921 + * * Redistributions of source code must retain the above copyright
71922 + * notice, this list of conditions and the following disclaimer.
71923 + * * Redistributions in binary form must reproduce the above copyright
71924 + * notice, this list of conditions and the following disclaimer in the
71925 + * documentation and/or other materials provided with the distribution.
71926 + * * Neither the name of Freescale Semiconductor nor the
71927 + * names of its contributors may be used to endorse or promote products
71928 + * derived from this software without specific prior written permission.
71929 + *
71930 + *
71931 + * ALTERNATIVELY, this software may be distributed under the terms of the
71932 + * GNU General Public License ("GPL") as published by the Free Software
71933 + * Foundation, either version 2 of that License or (at your option) any
71934 + * later version.
71935 + *
71936 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
71937 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
71938 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
71939 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
71940 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
71941 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
71942 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
71943 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
71944 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
71945 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71946 + */
71947 +
71948 +
71949 +/**************************************************************************//**
71950 + @File fm_ipc.h
71951 +
71952 + @Description FM Inter-Partition prototypes, structures and definitions.
71953 +*//***************************************************************************/
71954 +#ifndef __FM_IPC_H
71955 +#define __FM_IPC_H
71956 +
71957 +#include "error_ext.h"
71958 +#include "std_ext.h"
71959 +
71960 +
71961 +/**************************************************************************//**
71962 + @Group FM_grp Frame Manager API
71963 +
71964 + @Description FM API functions, definitions and enums
71965 +
71966 + @{
71967 +*//***************************************************************************/
71968 +
71969 +/**************************************************************************//**
71970 + @Group FM_IPC_grp FM Inter-Partition messaging Unit
71971 +
71972 + @Description FM Inter-Partition messaging unit API definitions and enums.
71973 +
71974 + @{
71975 +*//***************************************************************************/
71976 +
71977 +#if defined(__MWERKS__) && !defined(__GNUC__)
71978 +#pragma pack(push,1)
71979 +#endif /* defined(__MWERKS__) && ... */
71980 +
71981 +/**************************************************************************//**
71982 + @Description enum for defining MAC types
71983 +*//***************************************************************************/
71984 +
71985 +/**************************************************************************//**
71986 + @Description A structure of parameters for specifying a MAC.
71987 +*//***************************************************************************/
71988 +typedef _Packed struct
71989 +{
71990 + uint8_t id;
71991 + uint32_t enumType;
71992 +} _PackedType t_FmIpcMacParams;
71993 +
71994 +/**************************************************************************//**
71995 + @Description A structure of parameters for specifying a MAC.
71996 +*//***************************************************************************/
71997 +typedef _Packed struct
71998 +{
71999 + t_FmIpcMacParams macParams;
72000 + uint16_t maxFrameLength;
72001 +} _PackedType t_FmIpcMacMaxFrameParams;
72002 +
72003 +/**************************************************************************//**
72004 + @Description FM physical Address
72005 +*//***************************************************************************/
72006 +typedef _Packed struct t_FmIpcPhysAddr
72007 +{
72008 + volatile uint8_t high;
72009 + volatile uint32_t low;
72010 +} _PackedType t_FmIpcPhysAddr;
72011 +
72012 +
72013 +typedef _Packed struct t_FmIpcPortOutInitParams {
72014 + uint8_t numOfTasks; /**< OUT */
72015 + uint8_t numOfExtraTasks; /**< OUT */
72016 + uint8_t numOfOpenDmas; /**< OUT */
72017 + uint8_t numOfExtraOpenDmas; /**< OUT */
72018 + uint32_t sizeOfFifo; /**< OUT */
72019 + uint32_t extraSizeOfFifo; /**< OUT */
72020 + t_FmIpcPhysAddr ipcPhysAddr; /**< OUT */
72021 +} _PackedType t_FmIpcPortOutInitParams;
72022 +
72023 +/**************************************************************************//**
72024 + @Description Structure for IPC communication during FM_PORT_Init.
72025 +*//***************************************************************************/
72026 +typedef _Packed struct t_FmIpcPortInInitParams {
72027 + uint8_t hardwarePortId; /**< IN. port Id */
72028 + uint32_t enumPortType; /**< IN. Port type */
72029 + uint8_t boolIndependentMode;/**< IN. TRUE if FM Port operates in independent mode */
72030 + uint16_t liodnOffset; /**< IN. Port's requested resource */
72031 + uint8_t numOfTasks; /**< IN. Port's requested resource */
72032 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
72033 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
72034 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
72035 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
72036 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
72037 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
72038 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
72039 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
72040 + LIODN base for this port, to be
72041 + used together with LIODN offset. */
72042 +} _PackedType t_FmIpcPortInInitParams;
72043 +
72044 +
72045 +/**************************************************************************//**
72046 + @Description Structure for IPC communication between port and FM
72047 + regarding tasks and open DMA resources management.
72048 +*//***************************************************************************/
72049 +typedef _Packed struct t_FmIpcPortRsrcParams {
72050 + uint8_t hardwarePortId; /**< IN. port Id */
72051 + uint32_t val; /**< IN. Port's requested resource */
72052 + uint32_t extra; /**< IN. Port's requested resource */
72053 + uint8_t boolInitialConfig;
72054 +} _PackedType t_FmIpcPortRsrcParams;
72055 +
72056 +
72057 +/**************************************************************************//**
72058 + @Description Structure for IPC communication between port and FM
72059 + regarding tasks and open DMA resources management.
72060 +*//***************************************************************************/
72061 +typedef _Packed struct t_FmIpcPortFifoParams {
72062 + t_FmIpcPortRsrcParams rsrcParams;
72063 + uint32_t enumPortType;
72064 + uint8_t boolIndependentMode;
72065 + uint8_t deqPipelineDepth;
72066 + uint8_t numOfPools;
72067 + uint16_t secondLargestBufSize;
72068 + uint16_t largestBufSize;
72069 + uint8_t boolInitialConfig;
72070 +} _PackedType t_FmIpcPortFifoParams;
72071 +
72072 +/**************************************************************************//**
72073 + @Description Structure for port-FM communication during FM_PORT_Free.
72074 +*//***************************************************************************/
72075 +typedef _Packed struct t_FmIpcPortFreeParams {
72076 + uint8_t hardwarePortId; /**< IN. port Id */
72077 + uint32_t enumPortType; /**< IN. Port type */
72078 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
72079 +} _PackedType t_FmIpcPortFreeParams;
72080 +
72081 +/**************************************************************************//**
72082 + @Description Structure for defining DMA status
72083 +*//***************************************************************************/
72084 +typedef _Packed struct t_FmIpcDmaStatus {
72085 + uint8_t boolCmqNotEmpty; /**< Command queue is not empty */
72086 + uint8_t boolBusError; /**< Bus error occurred */
72087 + uint8_t boolReadBufEccError; /**< Double ECC error on buffer Read */
72088 + uint8_t boolWriteBufEccSysError; /**< Double ECC error on buffer write from system side */
72089 + uint8_t boolWriteBufEccFmError; /**< Double ECC error on buffer write from FM side */
72090 + uint8_t boolSinglePortEccError; /**< Single port ECC error from FM side */
72091 +} _PackedType t_FmIpcDmaStatus;
72092 +
72093 +typedef _Packed struct t_FmIpcRegisterIntr
72094 +{
72095 + uint8_t guestId; /* IN */
72096 + uint32_t event; /* IN */
72097 +} _PackedType t_FmIpcRegisterIntr;
72098 +
72099 +typedef _Packed struct t_FmIpcIsr
72100 +{
72101 + uint8_t boolErr; /* IN */
72102 + uint32_t pendingReg; /* IN */
72103 +} _PackedType t_FmIpcIsr;
72104 +
72105 +/**************************************************************************//**
72106 + @Description structure for returning FM parameters
72107 +*//***************************************************************************/
72108 +typedef _Packed struct t_FmIpcParams {
72109 + uint16_t fmClkFreq; /**< OUT: FM Clock frequency */
72110 + uint16_t fmMacClkFreq; /**< OUT: FM MAC clock frequence */
72111 + uint8_t majorRev; /**< OUT: FM Major revision */
72112 + uint8_t minorRev; /**< OUT: FM Minor revision */
72113 +} _PackedType t_FmIpcParams;
72114 +
72115 +
72116 +/**************************************************************************//**
72117 + @Description structure for returning Fman Ctrl Code revision information
72118 +*//***************************************************************************/
72119 +typedef _Packed struct t_FmIpcFmanCtrlCodeRevisionInfo {
72120 + uint16_t packageRev; /**< OUT: Package revision */
72121 + uint8_t majorRev; /**< OUT: Major revision */
72122 + uint8_t minorRev; /**< OUT: Minor revision */
72123 +} _PackedType t_FmIpcFmanCtrlCodeRevisionInfo;
72124 +
72125 +/**************************************************************************//**
72126 + @Description Structure for defining Fm number of Fman controlers
72127 +*//***************************************************************************/
72128 +typedef _Packed struct t_FmIpcPortNumOfFmanCtrls {
72129 + uint8_t hardwarePortId; /**< IN. port Id */
72130 + uint8_t numOfFmanCtrls; /**< IN. Port type */
72131 + t_FmFmanCtrl orFmanCtrl; /**< IN. fman controller for order restoration*/
72132 +} t_FmIpcPortNumOfFmanCtrls;
72133 +
72134 +/**************************************************************************//**
72135 + @Description structure for setting Fman contriller events
72136 +*//***************************************************************************/
72137 +typedef _Packed struct t_FmIpcFmanEvents {
72138 + uint8_t eventRegId; /**< IN: Fman controller event register id */
72139 + uint32_t enableEvents; /**< IN/OUT: required enabled events mask */
72140 +} _PackedType t_FmIpcFmanEvents;
72141 +
72142 +typedef _Packed struct t_FmIpcResourceAllocParams {
72143 + uint8_t guestId;
72144 + uint16_t base;
72145 + uint16_t num;
72146 +}_PackedType t_FmIpcResourceAllocParams;
72147 +
72148 +typedef _Packed struct t_FmIpcVspSetPortWindow {
72149 + uint8_t hardwarePortId;
72150 + uint8_t baseStorageProfile;
72151 + uint8_t log2NumOfProfiles;
72152 +}_PackedType t_FmIpcVspSetPortWindow;
72153 +
72154 +typedef _Packed struct t_FmIpcSetCongestionGroupPfcPriority {
72155 + uint32_t congestionGroupId;
72156 + uint8_t priorityBitMap;
72157 +}_PackedType t_FmIpcSetCongestionGroupPfcPriority;
72158 +
72159 +#define FM_IPC_MAX_REPLY_BODY_SIZE 20
72160 +#define FM_IPC_MAX_REPLY_SIZE (FM_IPC_MAX_REPLY_BODY_SIZE + sizeof(uint32_t))
72161 +#define FM_IPC_MAX_MSG_SIZE 30
72162 +
72163 +typedef _Packed struct t_FmIpcMsg
72164 +{
72165 + uint32_t msgId;
72166 + uint8_t msgBody[FM_IPC_MAX_MSG_SIZE];
72167 +} _PackedType t_FmIpcMsg;
72168 +
72169 +typedef _Packed struct t_FmIpcReply
72170 +{
72171 + uint32_t error;
72172 + uint8_t replyBody[FM_IPC_MAX_REPLY_BODY_SIZE];
72173 +} _PackedType t_FmIpcReply;
72174 +
72175 +#if defined(__MWERKS__) && !defined(__GNUC__)
72176 +#pragma pack(pop)
72177 +#endif /* defined(__MWERKS__) && ... */
72178 +
72179 +
72180 +/***************************************************************************/
72181 +/************************ FRONT-END-TO-BACK-END*****************************/
72182 +/***************************************************************************/
72183 +
72184 +/**************************************************************************//**
72185 + @Function FM_GET_TIMESTAMP_SCALE
72186 +
72187 + @Description Used by FM front-end.
72188 +
72189 + @Param[out] uint32_t Pointer
72190 +*//***************************************************************************/
72191 +#define FM_GET_TIMESTAMP_SCALE 1
72192 +
72193 +/**************************************************************************//**
72194 + @Function FM_GET_COUNTER
72195 +
72196 + @Description Used by FM front-end.
72197 +
72198 + @Param[in/out] t_FmIpcGetCounter Pointer
72199 +*//***************************************************************************/
72200 +#define FM_GET_COUNTER 2
72201 +
72202 +/**************************************************************************//**
72203 + @Function FM_GET_SET_PORT_PARAMS
72204 +
72205 + @Description Used by FM front-end for the PORT module in order to set and get
72206 + parameters in/from master FM module on FM PORT initialization time.
72207 +
72208 + @Param[in/out] t_FmIcPortInitParams Pointer
72209 +*//***************************************************************************/
72210 +#define FM_GET_SET_PORT_PARAMS 4
72211 +
72212 +/**************************************************************************//**
72213 + @Function FM_FREE_PORT
72214 +
72215 + @Description Used by FM front-end for the PORT module when a port is freed
72216 + to free all FM PORT resources.
72217 +
72218 + @Param[in] uint8_t Pointer
72219 +*//***************************************************************************/
72220 +#define FM_FREE_PORT 5
72221 +
72222 +/**************************************************************************//**
72223 + @Function FM_RESET_MAC
72224 +
72225 + @Description Used by front-end for the MAC module to reset the MAC registers
72226 +
72227 + @Param[in] t_FmIpcMacParams Pointer .
72228 +*//***************************************************************************/
72229 +#define FM_RESET_MAC 6
72230 +
72231 +/**************************************************************************//**
72232 + @Function FM_RESUME_STALLED_PORT
72233 +
72234 + @Description Used by FM front-end for the PORT module in order to
72235 + release a stalled FM Port.
72236 +
72237 + @Param[in] uint8_t Pointer
72238 +*//***************************************************************************/
72239 +#define FM_RESUME_STALLED_PORT 7
72240 +
72241 +/**************************************************************************//**
72242 + @Function FM_IS_PORT_STALLED
72243 +
72244 + @Description Used by FM front-end for the PORT module in order to check whether
72245 + an FM port is stalled.
72246 +
72247 + @Param[in/out] t_FmIcPortIsStalled Pointer
72248 +*//***************************************************************************/
72249 +#define FM_IS_PORT_STALLED 8
72250 +
72251 +/**************************************************************************//**
72252 + @Function FM_GET_PARAMS
72253 +
72254 + @Description Used by FM front-end for the PORT module in order to dump
72255 + return FM parameters.
72256 +
72257 + @Param[in] uint8_t Pointer
72258 +*//***************************************************************************/
72259 +#define FM_GET_PARAMS 10
72260 +
72261 +/**************************************************************************//**
72262 + @Function FM_REGISTER_INTR
72263 +
72264 + @Description Used by FM front-end to register an interrupt handler to
72265 + be called upon interrupt for guest.
72266 +
72267 + @Param[out] t_FmIpcRegisterIntr Pointer
72268 +*//***************************************************************************/
72269 +#define FM_REGISTER_INTR 11
72270 +
72271 +/**************************************************************************//**
72272 + @Function FM_DMA_STAT
72273 +
72274 + @Description Used by FM front-end to read the FM DMA status.
72275 +
72276 + @Param[out] t_FmIpcDmaStatus Pointer
72277 +*//***************************************************************************/
72278 +#define FM_DMA_STAT 13
72279 +
72280 +/**************************************************************************//**
72281 + @Function FM_ALLOC_FMAN_CTRL_EVENT_REG
72282 +
72283 + @Description Used by FM front-end to allocate event register.
72284 +
72285 + @Param[out] Event register id Pointer
72286 +*//***************************************************************************/
72287 +#define FM_ALLOC_FMAN_CTRL_EVENT_REG 14
72288 +
72289 +/**************************************************************************//**
72290 + @Function FM_FREE_FMAN_CTRL_EVENT_REG
72291 +
72292 + @Description Used by FM front-end to free locate event register.
72293 +
72294 + @Param[in] uint8_t Pointer - Event register id
72295 +*//***************************************************************************/
72296 +#define FM_FREE_FMAN_CTRL_EVENT_REG 15
72297 +
72298 +/**************************************************************************//**
72299 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
72300 +
72301 + @Description Used by FM front-end to enable events in the FPM
72302 + Fman controller event register.
72303 +
72304 + @Param[in] t_FmIpcFmanEvents Pointer
72305 +*//***************************************************************************/
72306 +#define FM_SET_FMAN_CTRL_EVENTS_ENABLE 16
72307 +
72308 +/**************************************************************************//**
72309 + @Function FM_SET_FMAN_CTRL_EVENTS_ENABLE
72310 +
72311 + @Description Used by FM front-end to enable events in the FPM
72312 + Fman controller event register.
72313 +
72314 + @Param[in/out] t_FmIpcFmanEvents Pointer
72315 +*//***************************************************************************/
72316 +#define FM_GET_FMAN_CTRL_EVENTS_ENABLE 17
72317 +
72318 +/**************************************************************************//**
72319 + @Function FM_SET_MAC_MAX_FRAME
72320 +
72321 + @Description Used by FM front-end to set MAC's MTU/RTU's in
72322 + back-end.
72323 +
72324 + @Param[in/out] t_FmIpcMacMaxFrameParams Pointer
72325 +*//***************************************************************************/
72326 +#define FM_SET_MAC_MAX_FRAME 18
72327 +
72328 +/**************************************************************************//**
72329 + @Function FM_GET_PHYS_MURAM_BASE
72330 +
72331 + @Description Used by FM front-end in order to get MURAM base address
72332 +
72333 + @Param[in/out] t_FmIpcPhysAddr Pointer
72334 +*//***************************************************************************/
72335 +#define FM_GET_PHYS_MURAM_BASE 19
72336 +
72337 +/**************************************************************************//**
72338 + @Function FM_MASTER_IS_ALIVE
72339 +
72340 + @Description Used by FM front-end in order to verify Master is up
72341 +
72342 + @Param[in/out] bool
72343 +*//***************************************************************************/
72344 +#define FM_MASTER_IS_ALIVE 20
72345 +
72346 +#define FM_ENABLE_RAM_ECC 21
72347 +#define FM_DISABLE_RAM_ECC 22
72348 +#define FM_SET_NUM_OF_FMAN_CTRL 23
72349 +#define FM_SET_SIZE_OF_FIFO 24
72350 +#define FM_SET_NUM_OF_TASKS 25
72351 +#define FM_SET_NUM_OF_OPEN_DMAS 26
72352 +#define FM_VSP_ALLOC 27
72353 +#define FM_VSP_FREE 28
72354 +#define FM_VSP_SET_PORT_WINDOW 29
72355 +#define FM_GET_FMAN_CTRL_CODE_REV 30
72356 +#define FM_SET_CONG_GRP_PFC_PRIO 31
72357 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
72358 +#define FM_10G_TX_ECC_WA 100
72359 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
72360 +
72361 +/***************************************************************************/
72362 +/************************ BACK-END-TO-FRONT-END*****************************/
72363 +/***************************************************************************/
72364 +
72365 +/**************************************************************************//**
72366 + @Function FM_GUEST_ISR
72367 +
72368 + @Description Used by FM back-end to report an interrupt to the front-end.
72369 +
72370 + @Param[out] t_FmIpcIsr Pointer
72371 +*//***************************************************************************/
72372 +#define FM_GUEST_ISR 1
72373 +
72374 +
72375 +
72376 +/** @} */ /* end of FM_IPC_grp group */
72377 +/** @} */ /* end of FM_grp group */
72378 +
72379 +
72380 +#endif /* __FM_IPC_H */
72381 --- /dev/null
72382 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fm_muram.c
72383 @@ -0,0 +1,174 @@
72384 +/*
72385 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72386 + *
72387 + * Redistribution and use in source and binary forms, with or without
72388 + * modification, are permitted provided that the following conditions are met:
72389 + * * Redistributions of source code must retain the above copyright
72390 + * notice, this list of conditions and the following disclaimer.
72391 + * * Redistributions in binary form must reproduce the above copyright
72392 + * notice, this list of conditions and the following disclaimer in the
72393 + * documentation and/or other materials provided with the distribution.
72394 + * * Neither the name of Freescale Semiconductor nor the
72395 + * names of its contributors may be used to endorse or promote products
72396 + * derived from this software without specific prior written permission.
72397 + *
72398 + *
72399 + * ALTERNATIVELY, this software may be distributed under the terms of the
72400 + * GNU General Public License ("GPL") as published by the Free Software
72401 + * Foundation, either version 2 of that License or (at your option) any
72402 + * later version.
72403 + *
72404 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72405 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72406 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72407 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72408 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72409 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72410 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72411 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72412 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72413 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72414 + */
72415 +
72416 +
72417 +/******************************************************************************
72418 + @File FM_muram.c
72419 +
72420 + @Description FM MURAM ...
72421 +*//***************************************************************************/
72422 +#include "error_ext.h"
72423 +#include "std_ext.h"
72424 +#include "mm_ext.h"
72425 +#include "string_ext.h"
72426 +#include "sprint_ext.h"
72427 +#include "fm_muram_ext.h"
72428 +#include "fm_common.h"
72429 +
72430 +#define __ERR_MODULE__ MODULE_FM_MURAM
72431 +
72432 +
72433 +typedef struct
72434 +{
72435 + t_Handle h_Mem;
72436 + uintptr_t baseAddr;
72437 + uint32_t size;
72438 +} t_FmMuram;
72439 +
72440 +
72441 +void FmMuramClear(t_Handle h_FmMuram)
72442 +{
72443 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72444 +
72445 + SANITY_CHECK_RETURN(h_FmMuram, E_INVALID_HANDLE);
72446 + IOMemSet32(UINT_TO_PTR(p_FmMuram->baseAddr), 0, p_FmMuram->size);
72447 +}
72448 +
72449 +
72450 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size)
72451 +{
72452 + t_Handle h_Mem;
72453 + t_FmMuram *p_FmMuram;
72454 +
72455 + if (!baseAddress)
72456 + {
72457 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress 0 is not supported"));
72458 + return NULL;
72459 + }
72460 +
72461 + if (baseAddress%4)
72462 + {
72463 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("baseAddress not 4 bytes aligned!"));
72464 + return NULL;
72465 + }
72466 +
72467 + /* Allocate FM MURAM structure */
72468 + p_FmMuram = (t_FmMuram *) XX_Malloc(sizeof(t_FmMuram));
72469 + if (!p_FmMuram)
72470 + {
72471 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FM MURAM driver structure"));
72472 + return NULL;
72473 + }
72474 + memset(p_FmMuram, 0, sizeof(t_FmMuram));
72475 +
72476 +
72477 + if ((MM_Init(&h_Mem, baseAddress, size) != E_OK) || (!h_Mem))
72478 + {
72479 + XX_Free(p_FmMuram);
72480 + REPORT_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM partition!!!"));
72481 + return NULL;
72482 + }
72483 +
72484 + /* Initialize FM MURAM parameters which will be kept by the driver */
72485 + p_FmMuram->baseAddr = baseAddress;
72486 + p_FmMuram->size = size;
72487 + p_FmMuram->h_Mem = h_Mem;
72488 +
72489 + return p_FmMuram;
72490 +}
72491 +
72492 +t_Error FM_MURAM_Free(t_Handle h_FmMuram)
72493 +{
72494 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72495 +
72496 + if (p_FmMuram->h_Mem)
72497 + MM_Free(p_FmMuram->h_Mem);
72498 +
72499 + XX_Free(h_FmMuram);
72500 +
72501 + return E_OK;
72502 +}
72503 +
72504 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align)
72505 +{
72506 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72507 + uintptr_t addr;
72508 +
72509 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
72510 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
72511 +
72512 + addr = (uintptr_t)MM_Get(p_FmMuram->h_Mem, size, align ,"FM MURAM");
72513 +
72514 + if (addr == ILLEGAL_BASE)
72515 + return NULL;
72516 +
72517 + return UINT_TO_PTR(addr);
72518 +}
72519 +
72520 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size)
72521 +{
72522 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72523 + uintptr_t addr;
72524 +
72525 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, NULL);
72526 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, NULL);
72527 +
72528 + addr = (uintptr_t)MM_GetForce(p_FmMuram->h_Mem, base, size, "FM MURAM");
72529 +
72530 + if (addr == ILLEGAL_BASE)
72531 + return NULL;
72532 +
72533 + return UINT_TO_PTR(addr);
72534 +}
72535 +
72536 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr)
72537 +{
72538 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72539 +
72540 + SANITY_CHECK_RETURN_ERROR(h_FmMuram, E_INVALID_HANDLE);
72541 + SANITY_CHECK_RETURN_ERROR(p_FmMuram->h_Mem, E_INVALID_HANDLE);
72542 +
72543 + if (MM_Put(p_FmMuram->h_Mem, PTR_TO_UINT(ptr)) == 0)
72544 + RETURN_ERROR(MINOR, E_INVALID_ADDRESS, ("memory pointer!!!"));
72545 +
72546 + return E_OK;
72547 +}
72548 +
72549 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram)
72550 +{
72551 + t_FmMuram *p_FmMuram = ( t_FmMuram *)h_FmMuram;
72552 +
72553 + SANITY_CHECK_RETURN_VALUE(h_FmMuram, E_INVALID_HANDLE, 0);
72554 + SANITY_CHECK_RETURN_VALUE(p_FmMuram->h_Mem, E_INVALID_HANDLE, 0);
72555 +
72556 + return MM_GetFreeMemSize(p_FmMuram->h_Mem);
72557 +}
72558 --- /dev/null
72559 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/fman.c
72560 @@ -0,0 +1,1400 @@
72561 +/*
72562 + * Copyright 2008-2012 Freescale Semiconductor Inc.
72563 + *
72564 + * Redistribution and use in source and binary forms, with or without
72565 + * modification, are permitted provided that the following conditions are met:
72566 + * * Redistributions of source code must retain the above copyright
72567 + * notice, this list of conditions and the following disclaimer.
72568 + * * Redistributions in binary form must reproduce the above copyright
72569 + * notice, this list of conditions and the following disclaimer in the
72570 + * documentation and/or other materials provided with the distribution.
72571 + * * Neither the name of Freescale Semiconductor nor the
72572 + * names of its contributors may be used to endorse or promote products
72573 + * derived from this software without specific prior written permission.
72574 + *
72575 + *
72576 + * ALTERNATIVELY, this software may be distributed under the terms of the
72577 + * GNU General Public License ("GPL") as published by the Free Software
72578 + * Foundation, either version 2 of that License or (at your option) any
72579 + * later version.
72580 + *
72581 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
72582 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
72583 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72584 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
72585 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
72586 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
72587 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
72588 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
72589 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
72590 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72591 + */
72592 +
72593 +
72594 +#include "std_ext.h"
72595 +#include "error_ext.h"
72596 +#include <linux/math64.h>
72597 +#include "fsl_fman.h"
72598 +#include "dpaa_integration_ext.h"
72599 +
72600 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg)
72601 +{
72602 + uint32_t event, mask, force;
72603 +
72604 + event = ioread32be(&bmi_rg->fmbm_ievr);
72605 + mask = ioread32be(&bmi_rg->fmbm_ier);
72606 + event &= mask;
72607 + /* clear the forced events */
72608 + force = ioread32be(&bmi_rg->fmbm_ifr);
72609 + if (force & event)
72610 + iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
72611 + /* clear the acknowledged events */
72612 + iowrite32be(event, &bmi_rg->fmbm_ievr);
72613 + return event;
72614 +}
72615 +
72616 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg)
72617 +{
72618 + uint32_t event, mask, force;
72619 +
72620 + event = ioread32be(&qmi_rg->fmqm_eie);
72621 + mask = ioread32be(&qmi_rg->fmqm_eien);
72622 + event &= mask;
72623 +
72624 + /* clear the forced events */
72625 + force = ioread32be(&qmi_rg->fmqm_eif);
72626 + if (force & event)
72627 + iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
72628 + /* clear the acknowledged events */
72629 + iowrite32be(event, &qmi_rg->fmqm_eie);
72630 + return event;
72631 +}
72632 +
72633 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg)
72634 +{
72635 + return ioread32be(&dma_rg->fmdmtcid);
72636 +}
72637 +
72638 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg)
72639 +{
72640 + uint64_t addr;
72641 +
72642 + addr = (uint64_t)ioread32be(&dma_rg->fmdmtal);
72643 + addr |= ((uint64_t)(ioread32be(&dma_rg->fmdmtah)) << 32);
72644 +
72645 + return addr;
72646 +}
72647 +
72648 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg)
72649 +{
72650 + uint32_t status, mask;
72651 +
72652 + status = ioread32be(&dma_rg->fmdmsr);
72653 + mask = ioread32be(&dma_rg->fmdmmr);
72654 +
72655 + /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
72656 + if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
72657 + status &= ~DMA_STATUS_BUS_ERR;
72658 +
72659 + /* clear relevant bits if mask has no DMA_MODE_ECC */
72660 + if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
72661 + status &= ~(DMA_STATUS_FM_SPDAT_ECC |
72662 + DMA_STATUS_READ_ECC |
72663 + DMA_STATUS_SYSTEM_WRITE_ECC |
72664 + DMA_STATUS_FM_WRITE_ECC);
72665 +
72666 + /* clear set events */
72667 + iowrite32be(status, &dma_rg->fmdmsr);
72668 +
72669 + return status;
72670 +}
72671 +
72672 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg)
72673 +{
72674 + uint32_t event;
72675 +
72676 + event = ioread32be(&fpm_rg->fmfp_ee);
72677 + /* clear the all occurred events */
72678 + iowrite32be(event, &fpm_rg->fmfp_ee);
72679 + return event;
72680 +}
72681 +
72682 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg)
72683 +{
72684 + uint32_t event, mask;
72685 +
72686 + event = ioread32be(&fpm_rg->fm_rcr);
72687 + mask = ioread32be(&fpm_rg->fm_rie);
72688 +
72689 + /* clear MURAM event bit (do not clear IRAM event) */
72690 + iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
72691 +
72692 + if ((mask & FPM_MURAM_ECC_ERR_EX_EN))
72693 + return event;
72694 + else
72695 + return 0;
72696 +}
72697 +
72698 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg)
72699 +{
72700 + uint32_t event, mask;
72701 +
72702 + event = ioread32be(&fpm_rg->fm_rcr) ;
72703 + mask = ioread32be(&fpm_rg->fm_rie);
72704 + /* clear IRAM event bit (do not clear MURAM event) */
72705 + iowrite32be(event & ~FPM_RAM_MURAM_ECC,
72706 + &fpm_rg->fm_rcr);
72707 +
72708 + if ((mask & FPM_IRAM_ECC_ERR_EX_EN))
72709 + return event;
72710 + else
72711 + return 0;
72712 +}
72713 +
72714 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg)
72715 +{
72716 + uint32_t event, mask, force;
72717 +
72718 + event = ioread32be(&qmi_rg->fmqm_ie);
72719 + mask = ioread32be(&qmi_rg->fmqm_ien);
72720 + event &= mask;
72721 + /* clear the forced events */
72722 + force = ioread32be(&qmi_rg->fmqm_if);
72723 + if (force & event)
72724 + iowrite32be(force & ~event, &qmi_rg->fmqm_if);
72725 + /* clear the acknowledged events */
72726 + iowrite32be(event, &qmi_rg->fmqm_ie);
72727 + return event;
72728 +}
72729 +
72730 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
72731 + uint8_t count1ubit,
72732 + uint16_t fm_clk_freq)
72733 +{
72734 + uint32_t tmp;
72735 + uint64_t frac;
72736 + uint32_t intgr;
72737 + uint32_t ts_freq = (uint32_t)(1 << count1ubit); /* in Mhz */
72738 +
72739 + /* configure timestamp so that bit 8 will count 1 microsecond
72740 + * Find effective count rate at TIMESTAMP least significant bits:
72741 + * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
72742 + * Find frequency ratio between effective count rate and the clock:
72743 + * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
72744 + * 256/600 = 0.4266666... */
72745 +
72746 + intgr = ts_freq / fm_clk_freq;
72747 + /* we multiply by 2^16 to keep the fraction of the division
72748 + * we do not div back, since we write this value as a fraction
72749 + * see spec */
72750 +
72751 + frac = ((uint64_t)ts_freq << 16) - ((uint64_t)intgr << 16) * fm_clk_freq;
72752 + /* we check remainder of the division in order to round up if not int */
72753 + if (do_div(frac, fm_clk_freq))
72754 + frac++;
72755 +
72756 + tmp = (intgr << FPM_TS_INT_SHIFT) | (uint16_t)frac;
72757 + iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
72758 +
72759 + /* enable timestamp with original clock */
72760 + iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
72761 +}
72762 +
72763 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg)
72764 +{
72765 + return ioread32be(&fpm_rg->fm_epi);
72766 +}
72767 +
72768 +
72769 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg)
72770 +{
72771 + int timeout = 100;
72772 +
72773 + iowrite32be(0x40000000, &fpm_rg->fmfp_extc);
72774 +
72775 + while ((ioread32be(&fpm_rg->fmfp_extc) & 0x40000000) && --timeout)
72776 + udelay(10);
72777 +
72778 + if (!timeout)
72779 + return -EBUSY;
72780 + return 0;
72781 +}
72782 +
72783 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg,
72784 + uint8_t event_reg_id,
72785 + uint32_t enable_events)
72786 +{
72787 + iowrite32be(enable_events, &fpm_rg->fmfp_cee[event_reg_id]);
72788 +}
72789 +
72790 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id)
72791 +{
72792 + return ioread32be(&fpm_rg->fmfp_cee[event_reg_id]);
72793 +}
72794 +
72795 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
72796 + uint8_t port_id,
72797 + uint8_t num_fman_ctrls,
72798 + uint32_t or_fman_ctrl)
72799 +{
72800 + uint32_t tmp = 0;
72801 +
72802 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
72803 + /*TODO - maybe to put CTL# according to another criteria*/
72804 + if (num_fman_ctrls == 2)
72805 + tmp = FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
72806 + /* order restoration */
72807 + tmp |= (or_fman_ctrl << FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | or_fman_ctrl;
72808 +
72809 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
72810 +}
72811 +
72812 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
72813 + uint8_t port_id,
72814 + bool independent_mode,
72815 + bool is_rx_port)
72816 +{
72817 + uint32_t tmp = 0;
72818 +
72819 + tmp = (uint32_t)(port_id << FPM_PORT_FM_CTL_PORTID_SHIFT);
72820 + if (independent_mode) {
72821 + if (is_rx_port)
72822 + tmp |= (FPM_PRT_FM_CTL1 <<
72823 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL1;
72824 + else
72825 + tmp |= (FPM_PRT_FM_CTL2 <<
72826 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT) | FPM_PRT_FM_CTL2;
72827 + } else {
72828 + tmp |= (FPM_PRT_FM_CTL2|FPM_PRT_FM_CTL1);
72829 +
72830 + /* order restoration */
72831 + if (port_id % 2)
72832 + tmp |= (FPM_PRT_FM_CTL1 <<
72833 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
72834 + else
72835 + tmp |= (FPM_PRT_FM_CTL2 <<
72836 + FPM_PRC_ORA_FM_CTL_SEL_SHIFT);
72837 + }
72838 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
72839 +}
72840 +
72841 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg)
72842 +{
72843 + return (uint8_t)ioread32be(&qmi_rg->fmqm_gc);
72844 +}
72845 +
72846 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg)
72847 +{
72848 + return (uint8_t)(ioread32be(&qmi_rg->fmqm_gc) >> 8);
72849 +}
72850 +
72851 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
72852 +{
72853 + uint32_t tmp_reg;
72854 +
72855 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
72856 + tmp_reg &= ~QMI_CFG_ENQ_MASK;
72857 + tmp_reg |= ((uint32_t)val << 8);
72858 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
72859 +}
72860 +
72861 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val)
72862 +{
72863 + uint32_t tmp_reg;
72864 +
72865 + tmp_reg = ioread32be(&qmi_rg->fmqm_gc);
72866 + tmp_reg &= ~QMI_CFG_DEQ_MASK;
72867 + tmp_reg |= (uint32_t)val;
72868 + iowrite32be(tmp_reg, &qmi_rg->fmqm_gc);
72869 +}
72870 +
72871 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg)
72872 +{
72873 + iowrite32be(0, &fpm_rg->fmfp_mxd);
72874 +}
72875 +
72876 +void fman_set_liodn_per_port(struct fman_rg *fman_rg, uint8_t port_id,
72877 + uint16_t liodn_base,
72878 + uint16_t liodn_ofst)
72879 +{
72880 + uint32_t tmp;
72881 +
72882 + if ((port_id > 63) || (port_id < 1))
72883 + return;
72884 +
72885 + /* set LIODN base for this port */
72886 + tmp = ioread32be(&fman_rg->dma_rg->fmdmplr[port_id / 2]);
72887 + if (port_id % 2) {
72888 + tmp &= ~FM_LIODN_BASE_MASK;
72889 + tmp |= (uint32_t)liodn_base;
72890 + } else {
72891 + tmp &= ~(FM_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
72892 + tmp |= (uint32_t)liodn_base << DMA_LIODN_SHIFT;
72893 + }
72894 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmplr[port_id / 2]);
72895 + iowrite32be((uint32_t)liodn_ofst,
72896 + &fman_rg->bmi_rg->fmbm_spliodn[port_id - 1]);
72897 +}
72898 +
72899 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
72900 +{
72901 + return (bool)!!(ioread32be(&fpm_rg->fmfp_ps[port_id]) & FPM_PS_STALLED);
72902 +}
72903 +
72904 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id)
72905 +{
72906 + uint32_t tmp;
72907 +
72908 + tmp = (uint32_t)((port_id << FPM_PORT_FM_CTL_PORTID_SHIFT) |
72909 + FPM_PRC_REALSE_STALLED);
72910 + iowrite32be(tmp, &fpm_rg->fmfp_prc);
72911 +}
72912 +
72913 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t mac_id, bool is_10g)
72914 +{
72915 + uint32_t msk, timeout = 100;
72916 +
72917 + /* Get the relevant bit mask */
72918 + if (is_10g) {
72919 + switch (mac_id) {
72920 + case(0):
72921 + msk = FPM_RSTC_10G0_RESET;
72922 + break;
72923 + case(1):
72924 + msk = FPM_RSTC_10G1_RESET;
72925 + break;
72926 + default:
72927 + return -EINVAL;
72928 + }
72929 + } else {
72930 + switch (mac_id) {
72931 + case(0):
72932 + msk = FPM_RSTC_1G0_RESET;
72933 + break;
72934 + case(1):
72935 + msk = FPM_RSTC_1G1_RESET;
72936 + break;
72937 + case(2):
72938 + msk = FPM_RSTC_1G2_RESET;
72939 + break;
72940 + case(3):
72941 + msk = FPM_RSTC_1G3_RESET;
72942 + break;
72943 + case(4):
72944 + msk = FPM_RSTC_1G4_RESET;
72945 + break;
72946 + case (5):
72947 + msk = FPM_RSTC_1G5_RESET;
72948 + break;
72949 + case (6):
72950 + msk = FPM_RSTC_1G6_RESET;
72951 + break;
72952 + case (7):
72953 + msk = FPM_RSTC_1G7_RESET;
72954 + break;
72955 + default:
72956 + return -EINVAL;
72957 + }
72958 + }
72959 + /* reset */
72960 + iowrite32be(msk, &fpm_rg->fm_rstc);
72961 + while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
72962 + udelay(10);
72963 +
72964 + if (!timeout)
72965 + return -EBUSY;
72966 + return 0;
72967 +}
72968 +
72969 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
72970 +{
72971 + uint32_t tmp_reg;
72972 +
72973 + if ((port_id > 63) || (port_id < 1))
72974 + return 0;
72975 +
72976 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id - 1]);
72977 + return (uint16_t)((tmp_reg & BMI_FIFO_SIZE_MASK) + 1);
72978 +}
72979 +
72980 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg)
72981 +{
72982 + uint32_t reg, res;
72983 +
72984 + reg = ioread32be(&bmi_rg->fmbm_cfg1);
72985 + res = (reg >> BMI_CFG1_FIFO_SIZE_SHIFT) & 0x3ff;
72986 + return res * FMAN_BMI_FIFO_UNITS;
72987 +}
72988 +
72989 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
72990 + uint8_t port_id)
72991 +{
72992 + uint32_t tmp_reg;
72993 +
72994 + if ((port_id > 63) || (port_id < 1))
72995 + return 0;
72996 +
72997 + tmp_reg = ioread32be(&bmi_rg->fmbm_pfs[port_id-1]);
72998 + return (uint16_t)((tmp_reg & BMI_EXTRA_FIFO_SIZE_MASK) >>
72999 + BMI_EXTRA_FIFO_SIZE_SHIFT);
73000 +}
73001 +
73002 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
73003 + uint8_t port_id,
73004 + uint32_t sz_fifo,
73005 + uint32_t extra_sz_fifo)
73006 +{
73007 + uint32_t tmp;
73008 +
73009 + if ((port_id > 63) || (port_id < 1))
73010 + return;
73011 +
73012 + /* calculate reg */
73013 + tmp = (uint32_t)((sz_fifo / FMAN_BMI_FIFO_UNITS - 1) |
73014 + ((extra_sz_fifo / FMAN_BMI_FIFO_UNITS) <<
73015 + BMI_EXTRA_FIFO_SIZE_SHIFT));
73016 + iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
73017 +}
73018 +
73019 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
73020 +{
73021 + uint32_t tmp;
73022 +
73023 + if ((port_id > 63) || (port_id < 1))
73024 + return 0;
73025 +
73026 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
73027 + return (uint8_t)(((tmp & BMI_NUM_OF_TASKS_MASK) >>
73028 + BMI_NUM_OF_TASKS_SHIFT) + 1);
73029 +}
73030 +
73031 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
73032 +{
73033 + uint32_t tmp;
73034 +
73035 + if ((port_id > 63) || (port_id < 1))
73036 + return 0;
73037 +
73038 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
73039 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_TASKS_MASK) >>
73040 + BMI_EXTRA_NUM_OF_TASKS_SHIFT);
73041 +}
73042 +
73043 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
73044 + uint8_t port_id,
73045 + uint8_t num_tasks,
73046 + uint8_t num_extra_tasks)
73047 +{
73048 + uint32_t tmp;
73049 +
73050 + if ((port_id > 63) || (port_id < 1))
73051 + return;
73052 +
73053 + /* calculate reg */
73054 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
73055 + ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
73056 + tmp |= (uint32_t)(((num_tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
73057 + (num_extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
73058 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
73059 +}
73060 +
73061 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
73062 +{
73063 + uint32_t tmp;
73064 +
73065 + if ((port_id > 63) || (port_id < 1))
73066 + return 0;
73067 +
73068 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
73069 + return (uint8_t)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
73070 + BMI_NUM_OF_DMAS_SHIFT) + 1);
73071 +}
73072 +
73073 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id)
73074 +{
73075 + uint32_t tmp;
73076 +
73077 + if ((port_id > 63) || (port_id < 1))
73078 + return 0;
73079 +
73080 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
73081 + return (uint8_t)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
73082 + BMI_EXTRA_NUM_OF_DMAS_SHIFT);
73083 +}
73084 +
73085 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
73086 + uint8_t port_id,
73087 + uint8_t num_open_dmas,
73088 + uint8_t num_extra_open_dmas,
73089 + uint8_t total_num_dmas)
73090 +{
73091 + uint32_t tmp = 0;
73092 +
73093 + if ((port_id > 63) || (port_id < 1))
73094 + return;
73095 +
73096 + /* calculate reg */
73097 + tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
73098 + ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
73099 + tmp |= (uint32_t)(((num_open_dmas-1) << BMI_NUM_OF_DMAS_SHIFT) |
73100 + (num_extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
73101 + iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
73102 +
73103 + /* update total num of DMA's with committed number of open DMAS,
73104 + * and max uncommitted pool. */
73105 + if (total_num_dmas)
73106 + {
73107 + tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
73108 + tmp |= (uint32_t)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
73109 + iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
73110 + }
73111 +}
73112 +
73113 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
73114 + uint8_t port_id,
73115 + uint8_t base_storage_profile,
73116 + uint8_t log2_num_of_profiles)
73117 +{
73118 + uint32_t tmp = 0;
73119 + if ((port_id > 63) || (port_id < 1))
73120 + return;
73121 +
73122 + tmp = ioread32be(&bmi_rg->fmbm_spliodn[port_id-1]);
73123 + tmp |= (uint32_t)((uint32_t)base_storage_profile & 0x3f) << 16;
73124 + tmp |= (uint32_t)log2_num_of_profiles << 28;
73125 + iowrite32be(tmp, &bmi_rg->fmbm_spliodn[port_id-1]);
73126 +}
73127 +
73128 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
73129 + uint32_t congestion_group_id,
73130 + uint8_t priority_bit_map,
73131 + uint32_t reg_num)
73132 +{
73133 + uint32_t offset, tmp = 0;
73134 +
73135 + offset = (congestion_group_id%4)*8;
73136 +
73137 + tmp = ioread32be(&cpg_rg[reg_num]);
73138 + tmp &= ~(0xFF<<offset);
73139 + tmp |= (uint32_t)priority_bit_map << offset;
73140 +
73141 + iowrite32be(tmp,&cpg_rg[reg_num]);
73142 +}
73143 +
73144 +/*****************************************************************************/
73145 +/* API Init unit functions */
73146 +/*****************************************************************************/
73147 +void fman_defconfig(struct fman_cfg *cfg, bool is_master)
73148 +{
73149 + memset(cfg, 0, sizeof(struct fman_cfg));
73150 +
73151 + cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
73152 + cfg->dma_err = DEFAULT_DMA_ERR;
73153 + cfg->halt_on_external_activ = DEFAULT_HALT_ON_EXTERNAL_ACTIVATION;
73154 + cfg->halt_on_unrecov_ecc_err = DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR;
73155 + cfg->en_iram_test_mode = FALSE;
73156 + cfg->en_muram_test_mode = FALSE;
73157 + cfg->external_ecc_rams_enable = DEFAULT_EXTERNAL_ECC_RAMS_ENABLE;
73158 +
73159 + if (!is_master)
73160 + return;
73161 +
73162 + cfg->dma_aid_override = DEFAULT_AID_OVERRIDE;
73163 + cfg->dma_aid_mode = DEFAULT_AID_MODE;
73164 + cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
73165 + cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
73166 + cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
73167 + cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
73168 + cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
73169 + cfg->dma_en_emergency = DEFAULT_DMA_EN_EMERGENCY;
73170 + cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
73171 + cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
73172 + cfg->dma_en_emergency_smoother = DEFAULT_DMA_EN_EMERGENCY_SMOOTHER;
73173 + cfg->dma_emergency_switch_counter = DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER;
73174 + cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
73175 + cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
73176 + cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
73177 + cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
73178 + cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
73179 + cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
73180 + cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
73181 + cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
73182 + cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
73183 +
73184 + cfg->pedantic_dma = FALSE;
73185 + cfg->tnum_aging_period = DEFAULT_TNUM_AGING_PERIOD;
73186 + cfg->dma_stop_on_bus_error = FALSE;
73187 + cfg->qmi_deq_option_support = FALSE;
73188 +}
73189 +
73190 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg)
73191 +{
73192 + uint32_t tmp_reg;
73193 +
73194 + /* read the values from the registers as they are initialized by the HW with
73195 + * the required values.
73196 + */
73197 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg1);
73198 + cfg->total_fifo_size =
73199 + (((tmp_reg & BMI_TOTAL_FIFO_SIZE_MASK) >> BMI_CFG1_FIFO_SIZE_SHIFT) + 1) * FMAN_BMI_FIFO_UNITS;
73200 +
73201 + tmp_reg = ioread32be(&fman_rg->bmi_rg->fmbm_cfg2);
73202 + cfg->total_num_of_tasks =
73203 + (uint8_t)(((tmp_reg & BMI_TOTAL_NUM_OF_TASKS_MASK) >> BMI_CFG2_TASKS_SHIFT) + 1);
73204 +
73205 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmtr);
73206 + cfg->dma_comm_qtsh_asrt_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
73207 +
73208 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmhy);
73209 + cfg->dma_comm_qtsh_clr_emer = (uint8_t)(tmp_reg >> DMA_THRESH_COMMQ_SHIFT);
73210 +
73211 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmmr);
73212 + cfg->dma_cache_override = (enum fman_dma_cache_override)((tmp_reg & DMA_MODE_CACHE_OR_MASK) >> DMA_MODE_CACHE_OR_SHIFT);
73213 + cfg->dma_cam_num_of_entries = (uint8_t)((((tmp_reg & DMA_MODE_CEN_MASK) >> DMA_MODE_CEN_SHIFT) +1)*DMA_CAM_UNITS);
73214 + cfg->dma_aid_override = (bool)((tmp_reg & DMA_MODE_AID_OR)? TRUE:FALSE);
73215 + cfg->dma_dbg_cnt_mode = (enum fman_dma_dbg_cnt_mode)((tmp_reg & DMA_MODE_DBG_MASK) >> DMA_MODE_DBG_SHIFT);
73216 + cfg->dma_en_emergency = (bool)((tmp_reg & DMA_MODE_EB)? TRUE : FALSE);
73217 +
73218 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_mxd);
73219 + cfg->disp_limit_tsh = (uint8_t)((tmp_reg & FPM_DISP_LIMIT_MASK) >> FPM_DISP_LIMIT_SHIFT);
73220 +
73221 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist1);
73222 + cfg->prs_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PRS_MASK ) >> FPM_THR1_PRS_SHIFT);
73223 + cfg->plcr_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_KG_MASK ) >> FPM_THR1_KG_SHIFT);
73224 + cfg->kg_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_PLCR_MASK ) >> FPM_THR1_PLCR_SHIFT);
73225 + cfg->bmi_disp_tsh = (uint8_t)((tmp_reg & FPM_THR1_BMI_MASK ) >> FPM_THR1_BMI_SHIFT);
73226 +
73227 + tmp_reg = ioread32be(&fman_rg->fpm_rg->fmfp_dist2);
73228 + cfg->qmi_enq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_ENQ_MASK ) >> FPM_THR2_QMI_ENQ_SHIFT);
73229 + cfg->qmi_deq_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_QMI_DEQ_MASK ) >> FPM_THR2_QMI_DEQ_SHIFT);
73230 + cfg->fm_ctl1_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL1_MASK ) >> FPM_THR2_FM_CTL1_SHIFT);
73231 + cfg->fm_ctl2_disp_tsh = (uint8_t)((tmp_reg & FPM_THR2_FM_CTL2_MASK ) >> FPM_THR2_FM_CTL2_SHIFT);
73232 +
73233 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmsetr);
73234 + cfg->dma_sos_emergency = tmp_reg;
73235 +
73236 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmwcr);
73237 + cfg->dma_watchdog = tmp_reg/cfg->clk_freq;
73238 +
73239 + tmp_reg = ioread32be(&fman_rg->dma_rg->fmdmemsr);
73240 + cfg->dma_en_emergency_smoother = (bool)((tmp_reg & DMA_EMSR_EMSTR_MASK)? TRUE : FALSE);
73241 + cfg->dma_emergency_switch_counter = (tmp_reg & DMA_EMSR_EMSTR_MASK);
73242 +}
73243 +
73244 +void fman_reset(struct fman_fpm_regs *fpm_rg)
73245 +{
73246 + iowrite32be(FPM_RSTC_FM_RESET, &fpm_rg->fm_rstc);
73247 +}
73248 +
73249 +/**************************************************************************//**
73250 + @Function FM_Init
73251 +
73252 + @Description Initializes the FM module
73253 +
73254 + @Param[in] h_Fm - FM module descriptor
73255 +
73256 + @Return E_OK on success; Error code otherwise.
73257 +*//***************************************************************************/
73258 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg)
73259 +{
73260 + uint32_t tmp_reg;
73261 +
73262 + /**********************/
73263 + /* Init DMA Registers */
73264 + /**********************/
73265 + /* clear status reg events */
73266 + /* oren - check!!! */
73267 + tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
73268 + DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
73269 + iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg,
73270 + &dma_rg->fmdmsr);
73271 +
73272 + /* configure mode register */
73273 + tmp_reg = 0;
73274 + tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
73275 + if (cfg->dma_aid_override)
73276 + tmp_reg |= DMA_MODE_AID_OR;
73277 + if (cfg->exceptions & FMAN_EX_DMA_BUS_ERROR)
73278 + tmp_reg |= DMA_MODE_BER;
73279 + if ((cfg->exceptions & FMAN_EX_DMA_SYSTEM_WRITE_ECC) |
73280 + (cfg->exceptions & FMAN_EX_DMA_READ_ECC) |
73281 + (cfg->exceptions & FMAN_EX_DMA_FM_WRITE_ECC))
73282 + tmp_reg |= DMA_MODE_ECC;
73283 + if (cfg->dma_stop_on_bus_error)
73284 + tmp_reg |= DMA_MODE_SBER;
73285 + if(cfg->dma_axi_dbg_num_of_beats)
73286 + tmp_reg |= (uint32_t)(DMA_MODE_AXI_DBG_MASK &
73287 + ((cfg->dma_axi_dbg_num_of_beats - 1) << DMA_MODE_AXI_DBG_SHIFT));
73288 +
73289 + if (cfg->dma_en_emergency) {
73290 + tmp_reg |= cfg->dma_emergency_bus_select;
73291 + tmp_reg |= cfg->dma_emergency_level << DMA_MODE_EMER_LVL_SHIFT;
73292 + if (cfg->dma_en_emergency_smoother)
73293 + iowrite32be(cfg->dma_emergency_switch_counter,
73294 + &dma_rg->fmdmemsr);
73295 + }
73296 + tmp_reg |= ((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) <<
73297 + DMA_MODE_CEN_SHIFT;
73298 + tmp_reg |= DMA_MODE_SECURE_PROT;
73299 + tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
73300 + tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
73301 +
73302 + if (cfg->pedantic_dma)
73303 + tmp_reg |= DMA_MODE_EMER_READ;
73304 +
73305 + iowrite32be(tmp_reg, &dma_rg->fmdmmr);
73306 +
73307 + /* configure thresholds register */
73308 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_asrt_emer <<
73309 + DMA_THRESH_COMMQ_SHIFT) |
73310 + ((uint32_t)cfg->dma_read_buf_tsh_asrt_emer <<
73311 + DMA_THRESH_READ_INT_BUF_SHIFT) |
73312 + ((uint32_t)cfg->dma_write_buf_tsh_asrt_emer);
73313 +
73314 + iowrite32be(tmp_reg, &dma_rg->fmdmtr);
73315 +
73316 + /* configure hysteresis register */
73317 + tmp_reg = ((uint32_t)cfg->dma_comm_qtsh_clr_emer <<
73318 + DMA_THRESH_COMMQ_SHIFT) |
73319 + ((uint32_t)cfg->dma_read_buf_tsh_clr_emer <<
73320 + DMA_THRESH_READ_INT_BUF_SHIFT) |
73321 + ((uint32_t)cfg->dma_write_buf_tsh_clr_emer);
73322 +
73323 + iowrite32be(tmp_reg, &dma_rg->fmdmhy);
73324 +
73325 + /* configure emergency threshold */
73326 + iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
73327 +
73328 + /* configure Watchdog */
73329 + iowrite32be((cfg->dma_watchdog * cfg->clk_freq),
73330 + &dma_rg->fmdmwcr);
73331 +
73332 + iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
73333 +
73334 + return 0;
73335 +}
73336 +
73337 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg)
73338 +{
73339 + uint32_t tmp_reg;
73340 + int i;
73341 +
73342 + /**********************/
73343 + /* Init FPM Registers */
73344 + /**********************/
73345 + tmp_reg = (uint32_t)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
73346 + iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
73347 +
73348 + tmp_reg = (((uint32_t)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
73349 + ((uint32_t)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
73350 + ((uint32_t)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
73351 + ((uint32_t)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
73352 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
73353 +
73354 + tmp_reg = (((uint32_t)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
73355 + ((uint32_t)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
73356 + ((uint32_t)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
73357 + ((uint32_t)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
73358 + iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
73359 +
73360 + /* define exceptions and error behavior */
73361 + tmp_reg = 0;
73362 + /* Clear events */
73363 + tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
73364 + FPM_EV_MASK_SINGLE_ECC);
73365 + /* enable interrupts */
73366 + if (cfg->exceptions & FMAN_EX_FPM_STALL_ON_TASKS)
73367 + tmp_reg |= FPM_EV_MASK_STALL_EN;
73368 + if (cfg->exceptions & FMAN_EX_FPM_SINGLE_ECC)
73369 + tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
73370 + if (cfg->exceptions & FMAN_EX_FPM_DOUBLE_ECC)
73371 + tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
73372 + tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
73373 + tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
73374 + if (!cfg->halt_on_external_activ)
73375 + tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
73376 + if (!cfg->halt_on_unrecov_ecc_err)
73377 + tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
73378 + iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
73379 +
73380 + /* clear all fmCtls event registers */
73381 + for (i = 0; i < cfg->num_of_fman_ctrl_evnt_regs; i++)
73382 + iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
73383 +
73384 + /* RAM ECC - enable and clear events*/
73385 + /* first we need to clear all parser memory,
73386 + * as it is uninitialized and may cause ECC errors */
73387 + /* event bits */
73388 + tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
73389 + /* Rams enable not effected by RCR bit, but by a COP configuration */
73390 + if (cfg->external_ecc_rams_enable)
73391 + tmp_reg |= FPM_RAM_RAMS_ECC_EN_SRC_SEL;
73392 +
73393 + /* enable test mode */
73394 + if (cfg->en_muram_test_mode)
73395 + tmp_reg |= FPM_RAM_MURAM_TEST_ECC;
73396 + if (cfg->en_iram_test_mode)
73397 + tmp_reg |= FPM_RAM_IRAM_TEST_ECC;
73398 + iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
73399 +
73400 + tmp_reg = 0;
73401 + if (cfg->exceptions & FMAN_EX_IRAM_ECC) {
73402 + tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
73403 + fman_enable_rams_ecc(fpm_rg);
73404 + }
73405 + if (cfg->exceptions & FMAN_EX_NURAM_ECC) {
73406 + tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
73407 + fman_enable_rams_ecc(fpm_rg);
73408 + }
73409 + iowrite32be(tmp_reg, &fpm_rg->fm_rie);
73410 +
73411 + return 0;
73412 +}
73413 +
73414 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg)
73415 +{
73416 + uint32_t tmp_reg;
73417 +
73418 + /**********************/
73419 + /* Init BMI Registers */
73420 + /**********************/
73421 +
73422 + /* define common resources */
73423 + tmp_reg = cfg->fifo_base_addr;
73424 + tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
73425 +
73426 + tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
73427 + BMI_CFG1_FIFO_SIZE_SHIFT);
73428 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
73429 +
73430 + tmp_reg = ((uint32_t)(cfg->total_num_of_tasks - 1) <<
73431 + BMI_CFG2_TASKS_SHIFT);
73432 + /* num of DMA's will be dynamically updated when each port is set */
73433 + iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
73434 +
73435 + /* define unmaskable exceptions, enable and clear events */
73436 + tmp_reg = 0;
73437 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
73438 + BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
73439 + BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
73440 + BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
73441 + &bmi_rg->fmbm_ievr);
73442 +
73443 + if (cfg->exceptions & FMAN_EX_BMI_LIST_RAM_ECC)
73444 + tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
73445 + if (cfg->exceptions & FMAN_EX_BMI_PIPELINE_ECC)
73446 + tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
73447 + if (cfg->exceptions & FMAN_EX_BMI_STATISTICS_RAM_ECC)
73448 + tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
73449 + if (cfg->exceptions & FMAN_EX_BMI_DISPATCH_RAM_ECC)
73450 + tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
73451 + iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
73452 +
73453 + return 0;
73454 +}
73455 +
73456 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg)
73457 +{
73458 + uint32_t tmp_reg;
73459 + uint16_t period_in_fm_clocks;
73460 + uint8_t remainder;
73461 + /**********************/
73462 + /* Init QMI Registers */
73463 + /**********************/
73464 + /* Clear error interrupt events */
73465 +
73466 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
73467 + &qmi_rg->fmqm_eie);
73468 + tmp_reg = 0;
73469 + if (cfg->exceptions & FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
73470 + tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
73471 + if (cfg->exceptions & FMAN_EX_QMI_DOUBLE_ECC)
73472 + tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
73473 + /* enable events */
73474 + iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
73475 +
73476 + if (cfg->tnum_aging_period) {
73477 + /* tnum_aging_period is in units of usec, p_FmClockFreq in Mhz */
73478 + period_in_fm_clocks = (uint16_t)
73479 + (cfg->tnum_aging_period * cfg->clk_freq);
73480 + /* period_in_fm_clocks must be a 64 multiply */
73481 + remainder = (uint8_t)(period_in_fm_clocks % 64);
73482 + if (remainder)
73483 + tmp_reg = (uint32_t)((period_in_fm_clocks / 64) + 1);
73484 + else{
73485 + tmp_reg = (uint32_t)(period_in_fm_clocks / 64);
73486 + if (!tmp_reg)
73487 + tmp_reg = 1;
73488 + }
73489 + tmp_reg <<= QMI_TAPC_TAP;
73490 + iowrite32be(tmp_reg, &qmi_rg->fmqm_tapc);
73491 + }
73492 + tmp_reg = 0;
73493 + /* Clear interrupt events */
73494 + iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
73495 + if (cfg->exceptions & FMAN_EX_QMI_SINGLE_ECC)
73496 + tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
73497 + /* enable events */
73498 + iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
73499 +
73500 + return 0;
73501 +}
73502 +
73503 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg)
73504 +{
73505 + uint32_t cfg_reg = 0;
73506 +
73507 + /**********************/
73508 + /* Enable all modules */
73509 + /**********************/
73510 + /* clear & enable global counters - calculate reg and save for later,
73511 + because it's the same reg for QMI enable */
73512 + cfg_reg = QMI_CFG_EN_COUNTERS;
73513 + if (cfg->qmi_deq_option_support)
73514 + cfg_reg |= (uint32_t)(((cfg->qmi_def_tnums_thresh) << 8) |
73515 + (uint32_t)cfg->qmi_def_tnums_thresh);
73516 +
73517 + iowrite32be(BMI_INIT_START, &fman_rg->bmi_rg->fmbm_init);
73518 + iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
73519 + &fman_rg->qmi_rg->fmqm_gc);
73520 +
73521 + return 0;
73522 +}
73523 +
73524 +void fman_free_resources(struct fman_rg *fman_rg)
73525 +{
73526 + /* disable BMI and QMI */
73527 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_init);
73528 + iowrite32be(0, &fman_rg->qmi_rg->fmqm_gc);
73529 +
73530 + /* release BMI resources */
73531 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg2);
73532 + iowrite32be(0, &fman_rg->bmi_rg->fmbm_cfg1);
73533 +
73534 + /* disable ECC */
73535 + iowrite32be(0, &fman_rg->fpm_rg->fm_rcr);
73536 +}
73537 +
73538 +/****************************************************/
73539 +/* API Run-time Control uint functions */
73540 +/****************************************************/
73541 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg)
73542 +{
73543 + return ioread32be(&fpm_rg->fm_npi);
73544 +}
73545 +
73546 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg, uint8_t reg_id)
73547 +{
73548 + uint32_t event;
73549 +
73550 + event = ioread32be(&fpm_rg->fmfp_fcev[reg_id]) &
73551 + ioread32be(&fpm_rg->fmfp_cee[reg_id]);
73552 + iowrite32be(event, &fpm_rg->fmfp_cev[reg_id]);
73553 +
73554 + return event;
73555 +}
73556 +
73557 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg)
73558 +{
73559 + return ioread32be(&fpm_rg->fm_epi);
73560 +}
73561 +
73562 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights)
73563 +{
73564 + int i;
73565 + uint8_t shift;
73566 + uint32_t tmp = 0;
73567 +
73568 + for (i = 0; i < 64; i++) {
73569 + if (weights[i] > 1) { /* no need to write 1 since it is 0 */
73570 + /* Add this port to tmp_reg */
73571 + /* (each 8 ports result in one register)*/
73572 + shift = (uint8_t)(32 - 4 * ((i % 8) + 1));
73573 + tmp |= ((weights[i] - 1) << shift);
73574 + }
73575 + if (i % 8 == 7) { /* last in this set */
73576 + iowrite32be(tmp, &bmi_rg->fmbm_arb[i / 8]);
73577 + tmp = 0;
73578 + }
73579 + }
73580 +}
73581 +
73582 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg)
73583 +{
73584 + uint32_t tmp;
73585 +
73586 + tmp = ioread32be(&fpm_rg->fm_rcr);
73587 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
73588 + iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN,
73589 + &fpm_rg->fm_rcr);
73590 + else
73591 + iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
73592 + FPM_RAM_IRAM_ECC_EN,
73593 + &fpm_rg->fm_rcr);
73594 +}
73595 +
73596 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg)
73597 +{
73598 + uint32_t tmp;
73599 +
73600 + tmp = ioread32be(&fpm_rg->fm_rcr);
73601 + if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
73602 + iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN,
73603 + &fpm_rg->fm_rcr);
73604 + else
73605 + iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
73606 + &fpm_rg->fm_rcr);
73607 +}
73608 +
73609 +int fman_set_exception(struct fman_rg *fman_rg,
73610 + enum fman_exceptions exception,
73611 + bool enable)
73612 +{
73613 + uint32_t tmp;
73614 +
73615 + switch (exception) {
73616 + case(E_FMAN_EX_DMA_BUS_ERROR):
73617 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
73618 + if (enable)
73619 + tmp |= DMA_MODE_BER;
73620 + else
73621 + tmp &= ~DMA_MODE_BER;
73622 + /* disable bus error */
73623 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
73624 + break;
73625 + case(E_FMAN_EX_DMA_READ_ECC):
73626 + case(E_FMAN_EX_DMA_SYSTEM_WRITE_ECC):
73627 + case(E_FMAN_EX_DMA_FM_WRITE_ECC):
73628 + tmp = ioread32be(&fman_rg->dma_rg->fmdmmr);
73629 + if (enable)
73630 + tmp |= DMA_MODE_ECC;
73631 + else
73632 + tmp &= ~DMA_MODE_ECC;
73633 + iowrite32be(tmp, &fman_rg->dma_rg->fmdmmr);
73634 + break;
73635 + case(E_FMAN_EX_FPM_STALL_ON_TASKS):
73636 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
73637 + if (enable)
73638 + tmp |= FPM_EV_MASK_STALL_EN;
73639 + else
73640 + tmp &= ~FPM_EV_MASK_STALL_EN;
73641 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
73642 + break;
73643 + case(E_FMAN_EX_FPM_SINGLE_ECC):
73644 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
73645 + if (enable)
73646 + tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
73647 + else
73648 + tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
73649 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
73650 + break;
73651 + case(E_FMAN_EX_FPM_DOUBLE_ECC):
73652 + tmp = ioread32be(&fman_rg->fpm_rg->fmfp_ee);
73653 + if (enable)
73654 + tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
73655 + else
73656 + tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
73657 + iowrite32be(tmp, &fman_rg->fpm_rg->fmfp_ee);
73658 + break;
73659 + case(E_FMAN_EX_QMI_SINGLE_ECC):
73660 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_ien);
73661 + if (enable)
73662 + tmp |= QMI_INTR_EN_SINGLE_ECC;
73663 + else
73664 + tmp &= ~QMI_INTR_EN_SINGLE_ECC;
73665 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_ien);
73666 + break;
73667 + case(E_FMAN_EX_QMI_DOUBLE_ECC):
73668 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
73669 + if (enable)
73670 + tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
73671 + else
73672 + tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
73673 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
73674 + break;
73675 + case(E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID):
73676 + tmp = ioread32be(&fman_rg->qmi_rg->fmqm_eien);
73677 + if (enable)
73678 + tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
73679 + else
73680 + tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
73681 + iowrite32be(tmp, &fman_rg->qmi_rg->fmqm_eien);
73682 + break;
73683 + case(E_FMAN_EX_BMI_LIST_RAM_ECC):
73684 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
73685 + if (enable)
73686 + tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
73687 + else
73688 + tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
73689 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
73690 + break;
73691 + case(E_FMAN_EX_BMI_STORAGE_PROFILE_ECC):
73692 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
73693 + if (enable)
73694 + tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
73695 + else
73696 + tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
73697 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
73698 + break;
73699 + case(E_FMAN_EX_BMI_STATISTICS_RAM_ECC):
73700 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
73701 + if (enable)
73702 + tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
73703 + else
73704 + tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
73705 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
73706 + break;
73707 + case(E_FMAN_EX_BMI_DISPATCH_RAM_ECC):
73708 + tmp = ioread32be(&fman_rg->bmi_rg->fmbm_ier);
73709 + if (enable)
73710 + tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
73711 + else
73712 + tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
73713 + iowrite32be(tmp, &fman_rg->bmi_rg->fmbm_ier);
73714 + break;
73715 + case(E_FMAN_EX_IRAM_ECC):
73716 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
73717 + if (enable) {
73718 + /* enable ECC if not enabled */
73719 + fman_enable_rams_ecc(fman_rg->fpm_rg);
73720 + /* enable ECC interrupts */
73721 + tmp |= FPM_IRAM_ECC_ERR_EX_EN;
73722 + } else {
73723 + /* ECC mechanism may be disabled,
73724 + * depending on driver status */
73725 + fman_disable_rams_ecc(fman_rg->fpm_rg);
73726 + tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
73727 + }
73728 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
73729 + break;
73730 + case(E_FMAN_EX_MURAM_ECC):
73731 + tmp = ioread32be(&fman_rg->fpm_rg->fm_rie);
73732 + if (enable) {
73733 + /* enable ECC if not enabled */
73734 + fman_enable_rams_ecc(fman_rg->fpm_rg);
73735 + /* enable ECC interrupts */
73736 + tmp |= FPM_MURAM_ECC_ERR_EX_EN;
73737 + } else {
73738 + /* ECC mechanism may be disabled,
73739 + * depending on driver status */
73740 + fman_disable_rams_ecc(fman_rg->fpm_rg);
73741 + tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
73742 + }
73743 + iowrite32be(tmp, &fman_rg->fpm_rg->fm_rie);
73744 + break;
73745 + default:
73746 + return -EINVAL;
73747 + }
73748 + return 0;
73749 +}
73750 +
73751 +void fman_get_revision(struct fman_fpm_regs *fpm_rg,
73752 + uint8_t *major,
73753 + uint8_t *minor)
73754 +{
73755 + uint32_t tmp;
73756 +
73757 + tmp = ioread32be(&fpm_rg->fm_ip_rev_1);
73758 + *major = (uint8_t)((tmp & FPM_REV1_MAJOR_MASK) >> FPM_REV1_MAJOR_SHIFT);
73759 + *minor = (uint8_t)((tmp & FPM_REV1_MINOR_MASK) >> FPM_REV1_MINOR_SHIFT);
73760 +
73761 +}
73762 +
73763 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
73764 + enum fman_counters reg_name)
73765 +{
73766 + uint32_t ret_val;
73767 +
73768 + switch (reg_name) {
73769 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
73770 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_etfc);
73771 + break;
73772 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
73773 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dtfc);
73774 + break;
73775 + case(E_FMAN_COUNTERS_DEQ_0):
73776 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc0);
73777 + break;
73778 + case(E_FMAN_COUNTERS_DEQ_1):
73779 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc1);
73780 + break;
73781 + case(E_FMAN_COUNTERS_DEQ_2):
73782 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc2);
73783 + break;
73784 + case(E_FMAN_COUNTERS_DEQ_3):
73785 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dc3);
73786 + break;
73787 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
73788 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfdc);
73789 + break;
73790 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
73791 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dfcc);
73792 + break;
73793 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
73794 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dffc);
73795 + break;
73796 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
73797 + ret_val = ioread32be(&fman_rg->qmi_rg->fmqm_dcc);
73798 + break;
73799 + default:
73800 + ret_val = 0;
73801 + }
73802 + return ret_val;
73803 +}
73804 +
73805 +int fman_modify_counter(struct fman_rg *fman_rg,
73806 + enum fman_counters reg_name,
73807 + uint32_t val)
73808 +{
73809 + /* When applicable (when there is an 'enable counters' bit,
73810 + * check that counters are enabled */
73811 + switch (reg_name) {
73812 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
73813 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
73814 + case(E_FMAN_COUNTERS_DEQ_0):
73815 + case(E_FMAN_COUNTERS_DEQ_1):
73816 + case(E_FMAN_COUNTERS_DEQ_2):
73817 + case(E_FMAN_COUNTERS_DEQ_3):
73818 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
73819 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
73820 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
73821 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
73822 + if (!(ioread32be(&fman_rg->qmi_rg->fmqm_gc) &
73823 + QMI_CFG_EN_COUNTERS))
73824 + return -EINVAL;
73825 + break;
73826 + default:
73827 + break;
73828 + }
73829 + /* Set counter */
73830 + switch (reg_name) {
73831 + case(E_FMAN_COUNTERS_ENQ_TOTAL_FRAME):
73832 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_etfc);
73833 + break;
73834 + case(E_FMAN_COUNTERS_DEQ_TOTAL_FRAME):
73835 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dtfc);
73836 + break;
73837 + case(E_FMAN_COUNTERS_DEQ_0):
73838 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc0);
73839 + break;
73840 + case(E_FMAN_COUNTERS_DEQ_1):
73841 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc1);
73842 + break;
73843 + case(E_FMAN_COUNTERS_DEQ_2):
73844 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc2);
73845 + break;
73846 + case(E_FMAN_COUNTERS_DEQ_3):
73847 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dc3);
73848 + break;
73849 + case(E_FMAN_COUNTERS_DEQ_FROM_DEFAULT):
73850 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfdc);
73851 + break;
73852 + case(E_FMAN_COUNTERS_DEQ_FROM_CONTEXT):
73853 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dfcc);
73854 + break;
73855 + case(E_FMAN_COUNTERS_DEQ_FROM_FD):
73856 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dffc);
73857 + break;
73858 + case(E_FMAN_COUNTERS_DEQ_CONFIRM):
73859 + iowrite32be(val, &fman_rg->qmi_rg->fmqm_dcc);
73860 + break;
73861 + case(E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT):
73862 + iowrite32be(val, &fman_rg->dma_rg->fmdmsefrc);
73863 + break;
73864 + case(E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT):
73865 + iowrite32be(val, &fman_rg->dma_rg->fmdmsqfrc);
73866 + break;
73867 + case(E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT):
73868 + iowrite32be(val, &fman_rg->dma_rg->fmdmssrc);
73869 + break;
73870 + default:
73871 + break;
73872 + }
73873 + return 0;
73874 +}
73875 +
73876 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg,
73877 + bool is_write,
73878 + bool enable)
73879 +{
73880 + uint32_t msk;
73881 +
73882 + msk = (uint32_t)(is_write ? DMA_MODE_EMER_WRITE : DMA_MODE_EMER_READ);
73883 +
73884 + if (enable)
73885 + iowrite32be(ioread32be(&dma_rg->fmdmmr) | msk,
73886 + &dma_rg->fmdmmr);
73887 + else /* disable */
73888 + iowrite32be(ioread32be(&dma_rg->fmdmmr) & ~msk,
73889 + &dma_rg->fmdmmr);
73890 +}
73891 +
73892 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri)
73893 +{
73894 + uint32_t tmp;
73895 +
73896 + tmp = ioread32be(&dma_rg->fmdmmr) |
73897 + (pri << DMA_MODE_BUS_PRI_SHIFT);
73898 +
73899 + iowrite32be(tmp, &dma_rg->fmdmmr);
73900 +}
73901 +
73902 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg)
73903 +{
73904 + return ioread32be(&dma_rg->fmdmsr);
73905 +}
73906 +
73907 +void fman_force_intr(struct fman_rg *fman_rg,
73908 + enum fman_exceptions exception)
73909 +{
73910 + switch (exception) {
73911 + case E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
73912 + iowrite32be(QMI_ERR_INTR_EN_DEQ_FROM_DEF,
73913 + &fman_rg->qmi_rg->fmqm_eif);
73914 + break;
73915 + case E_FMAN_EX_QMI_SINGLE_ECC:
73916 + iowrite32be(QMI_INTR_EN_SINGLE_ECC,
73917 + &fman_rg->qmi_rg->fmqm_if);
73918 + break;
73919 + case E_FMAN_EX_QMI_DOUBLE_ECC:
73920 + iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC,
73921 + &fman_rg->qmi_rg->fmqm_eif);
73922 + break;
73923 + case E_FMAN_EX_BMI_LIST_RAM_ECC:
73924 + iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC,
73925 + &fman_rg->bmi_rg->fmbm_ifr);
73926 + break;
73927 + case E_FMAN_EX_BMI_STORAGE_PROFILE_ECC:
73928 + iowrite32be(BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC,
73929 + &fman_rg->bmi_rg->fmbm_ifr);
73930 + break;
73931 + case E_FMAN_EX_BMI_STATISTICS_RAM_ECC:
73932 + iowrite32be(BMI_ERR_INTR_EN_STATISTICS_RAM_ECC,
73933 + &fman_rg->bmi_rg->fmbm_ifr);
73934 + break;
73935 + case E_FMAN_EX_BMI_DISPATCH_RAM_ECC:
73936 + iowrite32be(BMI_ERR_INTR_EN_DISPATCH_RAM_ECC,
73937 + &fman_rg->bmi_rg->fmbm_ifr);
73938 + break;
73939 + default:
73940 + break;
73941 + }
73942 +}
73943 +
73944 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg)
73945 +{
73946 + return (bool)!!(ioread32be(&qmi_rg->fmqm_gs) & QMI_GS_HALT_NOT_BUSY);
73947 +}
73948 +void fman_resume(struct fman_fpm_regs *fpm_rg)
73949 +{
73950 + uint32_t tmp;
73951 +
73952 + tmp = ioread32be(&fpm_rg->fmfp_ee);
73953 + /* clear tmp_reg event bits in order not to clear standing events */
73954 + tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
73955 + FPM_EV_MASK_STALL |
73956 + FPM_EV_MASK_SINGLE_ECC);
73957 + tmp |= FPM_EV_MASK_RELEASE_FM;
73958 +
73959 + iowrite32be(tmp, &fpm_rg->fmfp_ee);
73960 +}
73961 --- /dev/null
73962 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_common.h
73963 @@ -0,0 +1,1214 @@
73964 +/*
73965 + * Copyright 2008-2012 Freescale Semiconductor Inc.
73966 + *
73967 + * Redistribution and use in source and binary forms, with or without
73968 + * modification, are permitted provided that the following conditions are met:
73969 + * * Redistributions of source code must retain the above copyright
73970 + * notice, this list of conditions and the following disclaimer.
73971 + * * Redistributions in binary form must reproduce the above copyright
73972 + * notice, this list of conditions and the following disclaimer in the
73973 + * documentation and/or other materials provided with the distribution.
73974 + * * Neither the name of Freescale Semiconductor nor the
73975 + * names of its contributors may be used to endorse or promote products
73976 + * derived from this software without specific prior written permission.
73977 + *
73978 + *
73979 + * ALTERNATIVELY, this software may be distributed under the terms of the
73980 + * GNU General Public License ("GPL") as published by the Free Software
73981 + * Foundation, either version 2 of that License or (at your option) any
73982 + * later version.
73983 + *
73984 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
73985 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
73986 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
73987 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
73988 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
73989 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
73990 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
73991 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
73992 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
73993 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
73994 + */
73995 +
73996 +
73997 +/******************************************************************************
73998 + @File fm_common.h
73999 +
74000 + @Description FM internal structures and definitions.
74001 +*//***************************************************************************/
74002 +#ifndef __FM_COMMON_H
74003 +#define __FM_COMMON_H
74004 +
74005 +#include "error_ext.h"
74006 +#include "std_ext.h"
74007 +#include "fm_pcd_ext.h"
74008 +#include "fm_ext.h"
74009 +#include "fm_port_ext.h"
74010 +
74011 +
74012 +#define e_FM_PORT_TYPE_OH_HOST_COMMAND e_FM_PORT_TYPE_DUMMY
74013 +
74014 +#define CLS_PLAN_NUM_PER_GRP 8
74015 +
74016 +#define IP_OFFLOAD_PACKAGE_NUMBER 106
74017 +#define CAPWAP_OFFLOAD_PACKAGE_NUMBER 108
74018 +#define IS_OFFLOAD_PACKAGE(num) ((num == IP_OFFLOAD_PACKAGE_NUMBER) || (num == CAPWAP_OFFLOAD_PACKAGE_NUMBER))
74019 +
74020 +
74021 +
74022 +/**************************************************************************//**
74023 + @Description Modules registers offsets
74024 +*//***************************************************************************/
74025 +#define FM_MM_MURAM 0x00000000
74026 +#define FM_MM_BMI 0x00080000
74027 +#define FM_MM_QMI 0x00080400
74028 +#define FM_MM_PRS 0x000c7000
74029 +#define FM_MM_KG 0x000C1000
74030 +#define FM_MM_DMA 0x000C2000
74031 +#define FM_MM_FPM 0x000C3000
74032 +#define FM_MM_PLCR 0x000C0000
74033 +#define FM_MM_IMEM 0x000C4000
74034 +#define FM_MM_CGP 0x000DB000
74035 +#define FM_MM_TRB(i) (0x000D0200 + 0x400 * (i))
74036 +#if (DPAA_VERSION >= 11)
74037 +#define FM_MM_SP 0x000dc000
74038 +#endif /* (DPAA_VERSION >= 11) */
74039 +
74040 +
74041 +/**************************************************************************//**
74042 + @Description Enum for inter-module interrupts registration
74043 +*//***************************************************************************/
74044 +typedef enum e_FmEventModules{
74045 + e_FM_MOD_PRS, /**< Parser event */
74046 + e_FM_MOD_KG, /**< Keygen event */
74047 + e_FM_MOD_PLCR, /**< Policer event */
74048 + e_FM_MOD_10G_MAC, /**< 10G MAC event */
74049 + e_FM_MOD_1G_MAC, /**< 1G MAC event */
74050 + e_FM_MOD_TMR, /**< Timer event */
74051 + e_FM_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
74052 + e_FM_MOD_MACSEC,
74053 + e_FM_MOD_DUMMY_LAST
74054 +} e_FmEventModules;
74055 +
74056 +/**************************************************************************//**
74057 + @Description Enum for interrupts types
74058 +*//***************************************************************************/
74059 +typedef enum e_FmIntrType {
74060 + e_FM_INTR_TYPE_ERR,
74061 + e_FM_INTR_TYPE_NORMAL
74062 +} e_FmIntrType;
74063 +
74064 +/**************************************************************************//**
74065 + @Description Enum for inter-module interrupts registration
74066 +*//***************************************************************************/
74067 +typedef enum e_FmInterModuleEvent
74068 +{
74069 + e_FM_EV_PRS = 0, /**< Parser event */
74070 + e_FM_EV_ERR_PRS, /**< Parser error event */
74071 + e_FM_EV_KG, /**< Keygen event */
74072 + e_FM_EV_ERR_KG, /**< Keygen error event */
74073 + e_FM_EV_PLCR, /**< Policer event */
74074 + e_FM_EV_ERR_PLCR, /**< Policer error event */
74075 + e_FM_EV_ERR_10G_MAC0, /**< 10G MAC 0 error event */
74076 + e_FM_EV_ERR_10G_MAC1, /**< 10G MAC 1 error event */
74077 + e_FM_EV_ERR_1G_MAC0, /**< 1G MAC 0 error event */
74078 + e_FM_EV_ERR_1G_MAC1, /**< 1G MAC 1 error event */
74079 + e_FM_EV_ERR_1G_MAC2, /**< 1G MAC 2 error event */
74080 + e_FM_EV_ERR_1G_MAC3, /**< 1G MAC 3 error event */
74081 + e_FM_EV_ERR_1G_MAC4, /**< 1G MAC 4 error event */
74082 + e_FM_EV_ERR_1G_MAC5, /**< 1G MAC 5 error event */
74083 + e_FM_EV_ERR_1G_MAC6, /**< 1G MAC 6 error event */
74084 + e_FM_EV_ERR_1G_MAC7, /**< 1G MAC 7 error event */
74085 + e_FM_EV_ERR_MACSEC_MAC0,
74086 + e_FM_EV_TMR, /**< Timer event */
74087 + e_FM_EV_10G_MAC0, /**< 10G MAC 0 event (Magic packet detection)*/
74088 + e_FM_EV_10G_MAC1, /**< 10G MAC 1 event (Magic packet detection)*/
74089 + e_FM_EV_1G_MAC0, /**< 1G MAC 0 event (Magic packet detection)*/
74090 + e_FM_EV_1G_MAC1, /**< 1G MAC 1 event (Magic packet detection)*/
74091 + e_FM_EV_1G_MAC2, /**< 1G MAC 2 (Magic packet detection)*/
74092 + e_FM_EV_1G_MAC3, /**< 1G MAC 3 (Magic packet detection)*/
74093 + e_FM_EV_1G_MAC4, /**< 1G MAC 4 (Magic packet detection)*/
74094 + e_FM_EV_1G_MAC5, /**< 1G MAC 5 (Magic packet detection)*/
74095 + e_FM_EV_1G_MAC6, /**< 1G MAC 6 (Magic packet detection)*/
74096 + e_FM_EV_1G_MAC7, /**< 1G MAC 7 (Magic packet detection)*/
74097 + e_FM_EV_MACSEC_MAC0, /**< MACSEC MAC 0 event */
74098 + e_FM_EV_FMAN_CTRL_0, /**< Fman controller event 0 */
74099 + e_FM_EV_FMAN_CTRL_1, /**< Fman controller event 1 */
74100 + e_FM_EV_FMAN_CTRL_2, /**< Fman controller event 2 */
74101 + e_FM_EV_FMAN_CTRL_3, /**< Fman controller event 3 */
74102 + e_FM_EV_DUMMY_LAST
74103 +} e_FmInterModuleEvent;
74104 +
74105 +
74106 +#if defined(__MWERKS__) && !defined(__GNUC__)
74107 +#pragma pack(push,1)
74108 +#endif /* defined(__MWERKS__) && ... */
74109 +
74110 +/**************************************************************************//**
74111 + @Description PCD KG scheme registers
74112 +*//***************************************************************************/
74113 +typedef _Packed struct t_FmPcdPlcrProfileRegs {
74114 + volatile uint32_t fmpl_pemode; /* 0x090 FMPL_PEMODE - FM Policer Profile Entry Mode*/
74115 + volatile uint32_t fmpl_pegnia; /* 0x094 FMPL_PEGNIA - FM Policer Profile Entry GREEN Next Invoked Action*/
74116 + volatile uint32_t fmpl_peynia; /* 0x098 FMPL_PEYNIA - FM Policer Profile Entry YELLOW Next Invoked Action*/
74117 + volatile uint32_t fmpl_pernia; /* 0x09C FMPL_PERNIA - FM Policer Profile Entry RED Next Invoked Action*/
74118 + volatile uint32_t fmpl_pecir; /* 0x0A0 FMPL_PECIR - FM Policer Profile Entry Committed Information Rate*/
74119 + volatile uint32_t fmpl_pecbs; /* 0x0A4 FMPL_PECBS - FM Policer Profile Entry Committed Burst Size*/
74120 + volatile uint32_t fmpl_pepepir_eir; /* 0x0A8 FMPL_PEPIR_EIR - FM Policer Profile Entry Peak/Excess Information Rate*/
74121 + volatile uint32_t fmpl_pepbs_ebs; /* 0x0AC FMPL_PEPBS_EBS - FM Policer Profile Entry Peak/Excess Information Rate*/
74122 + volatile uint32_t fmpl_pelts; /* 0x0B0 FMPL_PELTS - FM Policer Profile Entry Last TimeStamp*/
74123 + volatile uint32_t fmpl_pects; /* 0x0B4 FMPL_PECTS - FM Policer Profile Entry Committed Token Status*/
74124 + volatile uint32_t fmpl_pepts_ets; /* 0x0B8 FMPL_PEPTS_ETS - FM Policer Profile Entry Peak/Excess Token Status*/
74125 + volatile uint32_t fmpl_pegpc; /* 0x0BC FMPL_PEGPC - FM Policer Profile Entry GREEN Packet Counter*/
74126 + volatile uint32_t fmpl_peypc; /* 0x0C0 FMPL_PEYPC - FM Policer Profile Entry YELLOW Packet Counter*/
74127 + volatile uint32_t fmpl_perpc; /* 0x0C4 FMPL_PERPC - FM Policer Profile Entry RED Packet Counter */
74128 + volatile uint32_t fmpl_perypc; /* 0x0C8 FMPL_PERYPC - FM Policer Profile Entry Recolored YELLOW Packet Counter*/
74129 + volatile uint32_t fmpl_perrpc; /* 0x0CC FMPL_PERRPC - FM Policer Profile Entry Recolored RED Packet Counter*/
74130 + volatile uint32_t fmpl_res1[12]; /* 0x0D0-0x0FF Reserved */
74131 +} _PackedType t_FmPcdPlcrProfileRegs;
74132 +
74133 +
74134 +typedef _Packed struct t_FmPcdCcCapwapReassmTimeoutParams {
74135 + volatile uint32_t portIdAndCapwapReassmTbl;
74136 + volatile uint32_t fqidForTimeOutFrames;
74137 + volatile uint32_t timeoutRequestTime;
74138 +}_PackedType t_FmPcdCcCapwapReassmTimeoutParams;
74139 +
74140 +/**************************************************************************//**
74141 + @Description PCD CTRL Parameters Page
74142 +*//***************************************************************************/
74143 +typedef _Packed struct t_FmPcdCtrlParamsPage {
74144 + volatile uint8_t reserved0[16];
74145 + volatile uint32_t iprIpv4Nia;
74146 + volatile uint32_t iprIpv6Nia;
74147 + volatile uint8_t reserved1[24];
74148 + volatile uint32_t ipfOptionsCounter;
74149 + volatile uint8_t reserved2[12];
74150 + volatile uint32_t misc;
74151 + volatile uint32_t errorsDiscardMask;
74152 + volatile uint32_t discardMask;
74153 + volatile uint8_t reserved3[4];
74154 + volatile uint32_t postBmiFetchNia;
74155 + volatile uint8_t reserved4[172];
74156 +} _PackedType t_FmPcdCtrlParamsPage;
74157 +
74158 +
74159 +
74160 +#if defined(__MWERKS__) && !defined(__GNUC__)
74161 +#pragma pack(pop)
74162 +#endif /* defined(__MWERKS__) && ... */
74163 +
74164 +
74165 +/*for UNDER_CONSTRUCTION_FM_RMU_USE_SEC its defined in fm_ext.h*/
74166 +typedef uint32_t t_FmFmanCtrl;
74167 +
74168 +#define FPM_PORT_FM_CTL1 0x00000001
74169 +#define FPM_PORT_FM_CTL2 0x00000002
74170 +
74171 +
74172 +
74173 +typedef struct t_FmPcdCcFragScratchPoolCmdParams {
74174 + uint32_t numOfBuffers;
74175 + uint8_t bufferPoolId;
74176 +} t_FmPcdCcFragScratchPoolCmdParams;
74177 +
74178 +typedef struct t_FmPcdCcReassmTimeoutParams {
74179 + bool activate;
74180 + uint8_t tsbs;
74181 + uint32_t iprcpt;
74182 +} t_FmPcdCcReassmTimeoutParams;
74183 +
74184 +typedef struct {
74185 + uint8_t baseEntry;
74186 + uint16_t numOfClsPlanEntries;
74187 + uint32_t vectors[FM_PCD_MAX_NUM_OF_CLS_PLANS];
74188 +} t_FmPcdKgInterModuleClsPlanSet;
74189 +
74190 +/**************************************************************************//**
74191 + @Description Structure for binding a port to keygen schemes.
74192 +*//***************************************************************************/
74193 +typedef struct t_FmPcdKgInterModuleBindPortToSchemes {
74194 + uint8_t hardwarePortId;
74195 + uint8_t netEnvId;
74196 + bool useClsPlan; /**< TRUE if this port uses the clsPlan mechanism */
74197 + uint8_t numOfSchemes;
74198 + uint8_t schemesIds[FM_PCD_KG_NUM_OF_SCHEMES];
74199 +} t_FmPcdKgInterModuleBindPortToSchemes;
74200 +
74201 +typedef struct {
74202 + uint32_t nextCcNodeInfo;
74203 + t_List node;
74204 +} t_CcNodeInfo;
74205 +
74206 +typedef struct
74207 +{
74208 + t_Handle h_CcNode;
74209 + uint16_t index;
74210 + t_List node;
74211 +}t_CcNodeInformation;
74212 +#define CC_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInformation, node)
74213 +
74214 +typedef enum e_ModifyState
74215 +{
74216 + e_MODIFY_STATE_ADD = 0,
74217 + e_MODIFY_STATE_REMOVE,
74218 + e_MODIFY_STATE_CHANGE
74219 +} e_ModifyState;
74220 +
74221 +typedef struct
74222 +{
74223 + t_Handle h_Manip;
74224 + t_List node;
74225 +}t_ManipInfo;
74226 +#define CC_NEXT_NODE_F_OBJECT(ptr) LIST_OBJECT(ptr, t_CcNodeInfo, node)
74227 +
74228 +typedef struct {
74229 + uint32_t type;
74230 + uint8_t prOffset;
74231 + uint16_t dataOffset;
74232 + uint8_t internalBufferOffset;
74233 + uint8_t numOfTasks;
74234 + uint8_t numOfExtraTasks;
74235 + uint8_t hardwarePortId;
74236 + t_FmRevisionInfo revInfo;
74237 + uint32_t nia;
74238 + uint32_t discardMask;
74239 +} t_GetCcParams;
74240 +
74241 +typedef struct {
74242 + uint32_t type;
74243 + int psoSize;
74244 + uint32_t nia;
74245 + t_FmFmanCtrl orFmanCtrl;
74246 + bool overwrite;
74247 + uint8_t ofpDpde;
74248 +} t_SetCcParams;
74249 +
74250 +typedef struct {
74251 + t_GetCcParams getCcParams;
74252 + t_SetCcParams setCcParams;
74253 +} t_FmPortGetSetCcParams;
74254 +
74255 +typedef struct {
74256 + uint32_t type;
74257 + bool sleep;
74258 +} t_FmSetParams;
74259 +
74260 +typedef struct {
74261 + uint32_t type;
74262 + uint32_t fmqm_gs;
74263 + uint32_t fm_npi;
74264 + uint32_t fm_cld;
74265 + uint32_t fmfp_extc;
74266 +} t_FmGetParams;
74267 +
74268 +typedef struct {
74269 + t_FmSetParams setParams;
74270 + t_FmGetParams getParams;
74271 +} t_FmGetSetParams;
74272 +
74273 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_Params);
74274 +
74275 +static __inline__ bool TRY_LOCK(t_Handle h_Spinlock, volatile bool *p_Flag)
74276 +{
74277 + uint32_t intFlags;
74278 + if (h_Spinlock)
74279 + intFlags = XX_LockIntrSpinlock(h_Spinlock);
74280 + else
74281 + intFlags = XX_DisableAllIntr();
74282 +
74283 + if (*p_Flag)
74284 + {
74285 + if (h_Spinlock)
74286 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
74287 + else
74288 + XX_RestoreAllIntr(intFlags);
74289 + return FALSE;
74290 + }
74291 + *p_Flag = TRUE;
74292 +
74293 + if (h_Spinlock)
74294 + XX_UnlockIntrSpinlock(h_Spinlock, intFlags);
74295 + else
74296 + XX_RestoreAllIntr(intFlags);
74297 +
74298 + return TRUE;
74299 +}
74300 +
74301 +#define RELEASE_LOCK(_flag) _flag = FALSE;
74302 +
74303 +/**************************************************************************//**
74304 + @Collection Defines used for manipulation CC and BMI
74305 + @{
74306 +*//***************************************************************************/
74307 +#define INTERNAL_CONTEXT_OFFSET 0x80000000
74308 +#define OFFSET_OF_PR 0x40000000
74309 +#define MANIP_EXTRA_SPACE 0x20000000
74310 +#define NUM_OF_TASKS 0x10000000
74311 +#define OFFSET_OF_DATA 0x08000000
74312 +#define HW_PORT_ID 0x04000000
74313 +#define FM_REV 0x02000000
74314 +#define GET_NIA_FPNE 0x01000000
74315 +#define GET_NIA_PNDN 0x00800000
74316 +#define NUM_OF_EXTRA_TASKS 0x00400000
74317 +#define DISCARD_MASK 0x00200000
74318 +
74319 +#define UPDATE_NIA_PNEN 0x80000000
74320 +#define UPDATE_PSO 0x40000000
74321 +#define UPDATE_NIA_PNDN 0x20000000
74322 +#define UPDATE_FMFP_PRC_WITH_ONE_RISC_ONLY 0x10000000
74323 +#define UPDATE_OFP_DPTE 0x08000000
74324 +#define UPDATE_NIA_FENE 0x04000000
74325 +#define UPDATE_NIA_CMNE 0x02000000
74326 +#define UPDATE_NIA_FPNE 0x01000000
74327 +/* @} */
74328 +
74329 +/**************************************************************************//**
74330 + @Collection Defines used for manipulation CC and CC
74331 + @{
74332 +*//***************************************************************************/
74333 +#define UPDATE_NIA_ENQ_WITHOUT_DMA 0x80000000
74334 +#define UPDATE_CC_WITH_TREE 0x40000000
74335 +#define UPDATE_CC_WITH_DELETE_TREE 0x20000000
74336 +#define UPDATE_KG_NIA_CC_WA 0x10000000
74337 +#define UPDATE_KG_OPT_MODE 0x08000000
74338 +#define UPDATE_KG_NIA 0x04000000
74339 +#define UPDATE_CC_SHADOW_CLEAR 0x02000000
74340 +/* @} */
74341 +
74342 +#define UPDATE_FPM_BRKC_SLP 0x80000000
74343 +#define UPDATE_FPM_EXTC 0x40000000
74344 +#define UPDATE_FPM_EXTC_CLEAR 0x20000000
74345 +#define GET_FMQM_GS 0x10000000
74346 +#define GET_FM_NPI 0x08000000
74347 +#define GET_FMFP_EXTC 0x04000000
74348 +#define CLEAR_IRAM_READY 0x02000000
74349 +#define UPDATE_FM_CLD 0x01000000
74350 +#define GET_FM_CLD 0x00800000
74351 +#define FM_MAX_NUM_OF_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
74352 + FM_MAX_NUM_OF_1G_RX_PORTS + \
74353 + FM_MAX_NUM_OF_10G_RX_PORTS + \
74354 + FM_MAX_NUM_OF_1G_TX_PORTS + \
74355 + FM_MAX_NUM_OF_10G_TX_PORTS)
74356 +
74357 +#define MODULE_NAME_SIZE 30
74358 +#define DUMMY_PORT_ID 0
74359 +
74360 +#define FM_LIODN_OFFSET_MASK 0x3FF
74361 +
74362 +/**************************************************************************//**
74363 + @Description NIA Description
74364 +*//***************************************************************************/
74365 +#define NIA_ENG_MASK 0x007C0000
74366 +#define NIA_AC_MASK 0x0003ffff
74367 +
74368 +#define NIA_ORDER_RESTOR 0x00800000
74369 +#define NIA_ENG_FM_CTL 0x00000000
74370 +#define NIA_ENG_PRS 0x00440000
74371 +#define NIA_ENG_KG 0x00480000
74372 +#define NIA_ENG_PLCR 0x004C0000
74373 +#define NIA_ENG_BMI 0x00500000
74374 +#define NIA_ENG_QMI_ENQ 0x00540000
74375 +#define NIA_ENG_QMI_DEQ 0x00580000
74376 +
74377 +#define NIA_FM_CTL_AC_CC 0x00000006
74378 +#define NIA_FM_CTL_AC_HC 0x0000000C
74379 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
74380 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
74381 +#define NIA_FM_CTL_AC_POP_TO_N_STEP 0x0000000e
74382 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_HEADER 0x00000010
74383 +#define NIA_FM_CTL_AC_PRE_BMI_FETCH_FULL_FRAME 0x00000018
74384 +#define NIA_FM_CTL_AC_POST_BMI_FETCH 0x00000012
74385 +#define NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME 0x0000001A
74386 +#define NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME 0x0000001E
74387 +#define NIA_FM_CTL_AC_POST_BMI_ENQ_ORR 0x00000014
74388 +#define NIA_FM_CTL_AC_POST_BMI_ENQ 0x00000022
74389 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
74390 +#define NIA_FM_CTL_AC_POST_TX 0x00000024
74391 +/* V3 only */
74392 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME 0x00000028
74393 +#define NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME 0x0000002A
74394 +#define NIA_FM_CTL_AC_NO_IPACC_POP_TO_N_STEP 0x0000002C
74395 +
74396 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
74397 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
74398 +#define NIA_BMI_AC_RELEASE 0x000000C0
74399 +#define NIA_BMI_AC_DISCARD 0x000000C1
74400 +#define NIA_BMI_AC_TX 0x00000274
74401 +#define NIA_BMI_AC_FETCH 0x00000208
74402 +#define NIA_BMI_AC_MASK 0x000003FF
74403 +
74404 +#define NIA_KG_DIRECT 0x00000100
74405 +#define NIA_KG_CC_EN 0x00000200
74406 +#define NIA_PLCR_ABSOLUTE 0x00008000
74407 +
74408 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
74409 +
74410 +#if defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || defined(FM_ERROR_VSP_NO_MATCH_SW006)
74411 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
74412 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
74413 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
74414 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME))
74415 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
74416 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
74417 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
74418 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_DISCARD_FRAME))
74419 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
74420 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_NO_IPACC_PRE_BMI_ENQ_FRAME)
74421 +#else
74422 +#define GET_NIA_BMI_AC_ENQ_FRAME(h_FmPcd) \
74423 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
74424 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_ENQ_FRAME) : \
74425 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME))
74426 +#define GET_NIA_BMI_AC_DISCARD_FRAME(h_FmPcd) \
74427 + (uint32_t)((FmPcdIsAdvancedOffloadSupported(h_FmPcd)) ? \
74428 + (NIA_ENG_FM_CTL | NIA_FM_CTL_AC_PRE_BMI_DISCARD_FRAME) : \
74429 + (NIA_ENG_BMI | NIA_BMI_AC_DISCARD))
74430 +#define GET_NO_PCD_NIA_BMI_AC_ENQ_FRAME() \
74431 + (NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME)
74432 +#endif /* defined(FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675) || ... */
74433 +
74434 +/**************************************************************************//**
74435 + @Description CTRL Parameters Page defines
74436 +*//***************************************************************************/
74437 +#define FM_CTL_PARAMS_PAGE_OP_FIX_EN 0x80000000
74438 +#define FM_CTL_PARAMS_PAGE_OFFLOAD_SUPPORT_EN 0x40000000
74439 +#define FM_CTL_PARAMS_PAGE_ALWAYS_ON 0x00000100
74440 +
74441 +#define FM_CTL_PARAMS_PAGE_ERROR_VSP_MASK 0x0000003f
74442 +
74443 +/**************************************************************************//**
74444 + @Description Port Id defines
74445 +*//***************************************************************************/
74446 +#if (DPAA_VERSION == 10)
74447 +#define BASE_OH_PORTID 1
74448 +#else
74449 +#define BASE_OH_PORTID 2
74450 +#endif /* (DPAA_VERSION == 10) */
74451 +#define BASE_1G_RX_PORTID 8
74452 +#define BASE_10G_RX_PORTID 0x10
74453 +#define BASE_1G_TX_PORTID 0x28
74454 +#define BASE_10G_TX_PORTID 0x30
74455 +
74456 +#define FM_PCD_PORT_OH_BASE_INDX 0
74457 +#define FM_PCD_PORT_1G_RX_BASE_INDX (FM_PCD_PORT_OH_BASE_INDX+FM_MAX_NUM_OF_OH_PORTS)
74458 +#define FM_PCD_PORT_10G_RX_BASE_INDX (FM_PCD_PORT_1G_RX_BASE_INDX+FM_MAX_NUM_OF_1G_RX_PORTS)
74459 +#define FM_PCD_PORT_1G_TX_BASE_INDX (FM_PCD_PORT_10G_RX_BASE_INDX+FM_MAX_NUM_OF_10G_RX_PORTS)
74460 +#define FM_PCD_PORT_10G_TX_BASE_INDX (FM_PCD_PORT_1G_TX_BASE_INDX+FM_MAX_NUM_OF_1G_TX_PORTS)
74461 +
74462 +#if (FM_MAX_NUM_OF_OH_PORTS > 0)
74463 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
74464 + if ((_relativePortId) >= FM_MAX_NUM_OF_OH_PORTS) \
74465 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
74466 +#else
74467 +#define CHECK_PORT_ID_OH_PORTS(_relativePortId) \
74468 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal OH_PORT port id"))
74469 +#endif
74470 +#if (FM_MAX_NUM_OF_1G_RX_PORTS > 0)
74471 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
74472 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_RX_PORTS) \
74473 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
74474 +#else
74475 +#define CHECK_PORT_ID_1G_RX_PORTS(_relativePortId) \
74476 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_RX_PORT port id"))
74477 +#endif
74478 +#if (FM_MAX_NUM_OF_10G_RX_PORTS > 0)
74479 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
74480 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_RX_PORTS) \
74481 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
74482 +#else
74483 +#define CHECK_PORT_ID_10G_RX_PORTS(_relativePortId) \
74484 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_RX_PORT port id"))
74485 +#endif
74486 +#if (FM_MAX_NUM_OF_1G_TX_PORTS > 0)
74487 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
74488 + if ((_relativePortId) >= FM_MAX_NUM_OF_1G_TX_PORTS) \
74489 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
74490 +#else
74491 +#define CHECK_PORT_ID_1G_TX_PORTS(_relativePortId) \
74492 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 1G_TX_PORT port id"))
74493 +#endif
74494 +#if (FM_MAX_NUM_OF_10G_TX_PORTS > 0)
74495 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
74496 + if ((_relativePortId) >= FM_MAX_NUM_OF_10G_TX_PORTS) \
74497 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
74498 +#else
74499 +#define CHECK_PORT_ID_10G_TX_PORTS(_relativePortId) \
74500 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal 10G_TX_PORT port id"))
74501 +#endif
74502 +
74503 +uint8_t SwPortIdToHwPortId(e_FmPortType type, uint8_t relativePortId, uint8_t majorRev, uint8_t minorRev);
74504 +
74505 +#define HW_PORT_ID_TO_SW_PORT_ID(_relativePortId, hardwarePortId) \
74506 +{ if (((hardwarePortId) >= BASE_OH_PORTID) && \
74507 + ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
74508 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_OH_PORTID); \
74509 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
74510 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
74511 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID); \
74512 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
74513 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
74514 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID); \
74515 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
74516 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
74517 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID); \
74518 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
74519 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
74520 + _relativePortId = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID); \
74521 + else { \
74522 + _relativePortId = (uint8_t)DUMMY_PORT_ID; \
74523 + ASSERT_COND(TRUE); \
74524 + } \
74525 +}
74526 +
74527 +#define HW_PORT_ID_TO_SW_PORT_INDX(swPortIndex, hardwarePortId) \
74528 +do { \
74529 + if (((hardwarePortId) >= BASE_OH_PORTID) && ((hardwarePortId) < BASE_OH_PORTID+FM_MAX_NUM_OF_OH_PORTS)) \
74530 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_OH_PORTID+FM_PCD_PORT_OH_BASE_INDX); \
74531 + else if (((hardwarePortId) >= BASE_1G_RX_PORTID) && \
74532 + ((hardwarePortId) < BASE_1G_RX_PORTID+FM_MAX_NUM_OF_1G_RX_PORTS)) \
74533 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_RX_PORTID+FM_PCD_PORT_1G_RX_BASE_INDX); \
74534 + else if (((hardwarePortId) >= BASE_10G_RX_PORTID) && \
74535 + ((hardwarePortId) < BASE_10G_RX_PORTID+FM_MAX_NUM_OF_10G_RX_PORTS)) \
74536 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_RX_PORTID+FM_PCD_PORT_10G_RX_BASE_INDX); \
74537 + else if (((hardwarePortId) >= BASE_1G_TX_PORTID) && \
74538 + ((hardwarePortId) < BASE_1G_TX_PORTID+FM_MAX_NUM_OF_1G_TX_PORTS)) \
74539 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_1G_TX_PORTID+FM_PCD_PORT_1G_TX_BASE_INDX); \
74540 + else if (((hardwarePortId) >= BASE_10G_TX_PORTID) && \
74541 + ((hardwarePortId) < BASE_10G_TX_PORTID+FM_MAX_NUM_OF_10G_TX_PORTS)) \
74542 + swPortIndex = (uint8_t)((hardwarePortId)-BASE_10G_TX_PORTID+FM_PCD_PORT_10G_TX_BASE_INDX); \
74543 + else ASSERT_COND(FALSE); \
74544 +} while (0)
74545 +
74546 +#define SW_PORT_INDX_TO_HW_PORT_ID(hardwarePortId, swPortIndex) \
74547 +do { \
74548 + if (((swPortIndex) >= FM_PCD_PORT_OH_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_1G_RX_BASE_INDX)) \
74549 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_OH_BASE_INDX+BASE_OH_PORTID); \
74550 + else if (((swPortIndex) >= FM_PCD_PORT_1G_RX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_RX_BASE_INDX)) \
74551 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_RX_BASE_INDX+BASE_1G_RX_PORTID); \
74552 + else if (((swPortIndex) >= FM_PCD_PORT_10G_RX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
74553 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_RX_BASE_INDX+BASE_10G_RX_PORTID); \
74554 + else if (((swPortIndex) >= FM_PCD_PORT_1G_TX_BASE_INDX) && ((swPortIndex) < FM_PCD_PORT_10G_TX_BASE_INDX)) \
74555 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_1G_TX_BASE_INDX+BASE_1G_TX_PORTID); \
74556 + else if (((swPortIndex) >= FM_PCD_PORT_10G_TX_BASE_INDX) && ((swPortIndex) < FM_MAX_NUM_OF_PORTS)) \
74557 + hardwarePortId = (uint8_t)((swPortIndex)-FM_PCD_PORT_10G_TX_BASE_INDX+BASE_10G_TX_PORTID); \
74558 + else ASSERT_COND(FALSE); \
74559 +} while (0)
74560 +
74561 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
74562 +#define BMI_FIFO_UNITS 0x100
74563 +
74564 +typedef struct {
74565 + void (*f_Isr) (t_Handle h_Arg);
74566 + t_Handle h_SrcHandle;
74567 + uint8_t guestId;
74568 +} t_FmIntrSrc;
74569 +
74570 +#define ILLEGAL_HDR_NUM 0xFF
74571 +#define NO_HDR_NUM FM_PCD_PRS_NUM_OF_HDRS
74572 +
74573 +#define IS_PRIVATE_HEADER(hdr) (((hdr) == HEADER_TYPE_USER_DEFINED_SHIM1) || \
74574 + ((hdr) == HEADER_TYPE_USER_DEFINED_SHIM2))
74575 +#define IS_SPECIAL_HEADER(hdr) ((hdr) == HEADER_TYPE_MACSEC)
74576 +
74577 +static __inline__ uint8_t GetPrsHdrNum(e_NetHeaderType hdr)
74578 +{
74579 + switch (hdr)
74580 + { case (HEADER_TYPE_ETH): return 0;
74581 + case (HEADER_TYPE_LLC_SNAP): return 1;
74582 + case (HEADER_TYPE_VLAN): return 2;
74583 + case (HEADER_TYPE_PPPoE): return 3;
74584 + case (HEADER_TYPE_PPP): return 3;
74585 + case (HEADER_TYPE_MPLS): return 4;
74586 + case (HEADER_TYPE_IPv4): return 5;
74587 + case (HEADER_TYPE_IPv6): return 6;
74588 + case (HEADER_TYPE_GRE): return 7;
74589 + case (HEADER_TYPE_MINENCAP): return 8;
74590 + case (HEADER_TYPE_USER_DEFINED_L3): return 9;
74591 + case (HEADER_TYPE_TCP): return 10;
74592 + case (HEADER_TYPE_UDP): return 11;
74593 + case (HEADER_TYPE_IPSEC_AH):
74594 + case (HEADER_TYPE_IPSEC_ESP): return 12;
74595 + case (HEADER_TYPE_SCTP): return 13;
74596 + case (HEADER_TYPE_DCCP): return 14;
74597 + case (HEADER_TYPE_USER_DEFINED_L4): return 15;
74598 + case (HEADER_TYPE_USER_DEFINED_SHIM1):
74599 + case (HEADER_TYPE_USER_DEFINED_SHIM2):
74600 + case (HEADER_TYPE_MACSEC): return NO_HDR_NUM;
74601 + default:
74602 + return ILLEGAL_HDR_NUM;
74603 + }
74604 +}
74605 +
74606 +#define FM_PCD_MAX_NUM_OF_OPTIONS(clsPlanEntries) ((clsPlanEntries==256)? 8:((clsPlanEntries==128)? 7: ((clsPlanEntries==64)? 6: ((clsPlanEntries==32)? 5:0))))
74607 +
74608 +
74609 +/**************************************************************************//**
74610 + @Description A structure for initializing a keygen classification plan group
74611 +*//***************************************************************************/
74612 +typedef struct t_FmPcdKgInterModuleClsPlanGrpParams {
74613 + uint8_t netEnvId; /* IN */
74614 + bool grpExists; /* OUT (unused in FmPcdKgBuildClsPlanGrp)*/
74615 + uint8_t clsPlanGrpId; /* OUT */
74616 + bool emptyClsPlanGrp; /* OUT */
74617 + uint8_t numOfOptions; /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
74618 + protocolOpt_t options[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
74619 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
74620 + uint32_t optVectors[FM_PCD_MAX_NUM_OF_OPTIONS(FM_PCD_MAX_NUM_OF_CLS_PLANS)];
74621 + /* OUT in FmPcdGetSetClsPlanGrpParams IN in FmPcdKgBuildClsPlanGrp*/
74622 +} t_FmPcdKgInterModuleClsPlanGrpParams;
74623 +
74624 +typedef struct t_FmPcdLock {
74625 + t_Handle h_Spinlock;
74626 + volatile bool flag;
74627 + t_List node;
74628 +} t_FmPcdLock;
74629 +#define FM_PCD_LOCK_OBJ(ptr) LIST_OBJECT(ptr, t_FmPcdLock, node)
74630 +
74631 +
74632 +typedef t_Error (t_FmPortGetSetCcParamsCallback) (t_Handle h_FmPort,
74633 + t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
74634 +
74635 +
74636 +/***********************************************************************/
74637 +/* Common API for FM-PCD module */
74638 +/***********************************************************************/
74639 +t_Handle FmPcdGetHcHandle(t_Handle h_FmPcd);
74640 +uint32_t FmPcdGetSwPrsOffset(t_Handle h_FmPcd, e_NetHeaderType hdr, uint8_t indexPerHdr);
74641 +uint32_t FmPcdGetLcv(t_Handle h_FmPcd, uint32_t netEnvId, uint8_t hdrNum);
74642 +uint32_t FmPcdGetMacsecLcv(t_Handle h_FmPcd, uint32_t netEnvId);
74643 +void FmPcdIncNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
74644 +void FmPcdDecNetEnvOwners(t_Handle h_FmPcd, uint8_t netEnvId);
74645 +uint8_t FmPcdGetNetEnvId(t_Handle h_NetEnv);
74646 +void FmPcdPortRegister(t_Handle h_FmPcd, t_Handle h_FmPort, uint8_t hardwarePortId);
74647 +uint32_t FmPcdLock(t_Handle h_FmPcd);
74648 +void FmPcdUnlock(t_Handle h_FmPcd, uint32_t intFlags);
74649 +bool FmPcdNetEnvIsHdrExist(t_Handle h_FmPcd, uint8_t netEnvId, e_NetHeaderType hdr);
74650 +t_Error FmPcdFragHcScratchPoolInit(t_Handle h_FmPcd, uint8_t scratchBpid);
74651 +t_Error FmPcdRegisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
74652 +t_Error FmPcdUnregisterReassmPort(t_Handle h_FmPcd, t_Handle h_IpReasmCommonPramTbl);
74653 +bool FmPcdIsAdvancedOffloadSupported(t_Handle h_FmPcd);
74654 +bool FmPcdLockTryLockAll(t_Handle h_FmPcd);
74655 +void FmPcdLockUnlockAll(t_Handle h_FmPcd);
74656 +t_Error FmPcdHcSync(t_Handle h_FmPcd);
74657 +t_Handle FmGetPcd(t_Handle h_Fm);
74658 +/***********************************************************************/
74659 +/* Common API for FM-PCD KG module */
74660 +/***********************************************************************/
74661 +uint8_t FmPcdKgGetClsPlanGrpBase(t_Handle h_FmPcd, uint8_t clsPlanGrp);
74662 +uint16_t FmPcdKgGetClsPlanGrpSize(t_Handle h_FmPcd, uint8_t clsPlanGrp);
74663 +t_Error FmPcdKgBuildClsPlanGrp(t_Handle h_FmPcd, t_FmPcdKgInterModuleClsPlanGrpParams *p_Grp, t_FmPcdKgInterModuleClsPlanSet *p_ClsPlanSet);
74664 +
74665 +uint8_t FmPcdKgGetSchemeId(t_Handle h_Scheme);
74666 +#if (DPAA_VERSION >= 11)
74667 +bool FmPcdKgGetVspe(t_Handle h_Scheme);
74668 +#endif /* (DPAA_VERSION >= 11) */
74669 +uint8_t FmPcdKgGetRelativeSchemeId(t_Handle h_FmPcd, uint8_t schemeId);
74670 +void FmPcdKgDestroyClsPlanGrp(t_Handle h_FmPcd, uint8_t grpId);
74671 +t_Error FmPcdKgCheckInvalidateSchemeSw(t_Handle h_Scheme);
74672 +t_Error FmPcdKgBuildBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_BindPortToSchemes, uint32_t *p_SpReg, bool add);
74673 +bool FmPcdKgHwSchemeIsValid(uint32_t schemeModeReg);
74674 +uint32_t FmPcdKgBuildWriteSchemeActionReg(uint8_t schemeId, bool updateCounter);
74675 +uint32_t FmPcdKgBuildReadSchemeActionReg(uint8_t schemeId);
74676 +uint32_t FmPcdKgBuildWriteClsPlanBlockActionReg(uint8_t grpId);
74677 +uint32_t FmPcdKgBuildWritePortSchemeBindActionReg(uint8_t hardwarePortId);
74678 +uint32_t FmPcdKgBuildReadPortSchemeBindActionReg(uint8_t hardwarePortId);
74679 +uint32_t FmPcdKgBuildWritePortClsPlanBindActionReg(uint8_t hardwarePortId);
74680 +bool FmPcdKgIsSchemeValidSw(t_Handle h_Scheme);
74681 +
74682 +t_Error FmPcdKgBindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
74683 +t_Error FmPcdKgUnbindPortToSchemes(t_Handle h_FmPcd , t_FmPcdKgInterModuleBindPortToSchemes *p_SchemeBind);
74684 +uint32_t FmPcdKgGetRequiredAction(t_Handle h_FmPcd, uint8_t schemeId);
74685 +uint32_t FmPcdKgGetRequiredActionFlag(t_Handle h_FmPcd, uint8_t schemeId);
74686 +e_FmPcdDoneAction FmPcdKgGetDoneAction(t_Handle h_FmPcd, uint8_t schemeId);
74687 +e_FmPcdEngine FmPcdKgGetNextEngine(t_Handle h_FmPcd, uint8_t schemeId);
74688 +void FmPcdKgUpdateRequiredAction(t_Handle h_Scheme, uint32_t requiredAction);
74689 +bool FmPcdKgIsDirectPlcr(t_Handle h_FmPcd, uint8_t schemeId);
74690 +bool FmPcdKgIsDistrOnPlcrProfile(t_Handle h_FmPcd, uint8_t schemeId);
74691 +uint16_t FmPcdKgGetRelativeProfileId(t_Handle h_FmPcd, uint8_t schemeId);
74692 +t_Handle FmPcdKgGetSchemeHandle(t_Handle h_FmPcd, uint8_t relativeSchemeId);
74693 +bool FmPcdKgIsSchemeHasOwners(t_Handle h_Scheme);
74694 +t_Error FmPcdKgCcGetSetParams(t_Handle h_FmPcd, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
74695 +t_Error FmPcdKgSetOrBindToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t netEnvId, protocolOpt_t *p_OptArray, uint8_t *p_ClsPlanGrpId, bool *p_IsEmptyClsPlanGrp);
74696 +t_Error FmPcdKgDeleteOrUnbindPortToClsPlanGrp(t_Handle h_FmPcd, uint8_t hardwarePortId, uint8_t clsPlanGrpId);
74697 +
74698 +/***********************************************************************/
74699 +/* Common API for FM-PCD parser module */
74700 +/***********************************************************************/
74701 +t_Error FmPcdPrsIncludePortInStatistics(t_Handle p_FmPcd, uint8_t hardwarePortId, bool include);
74702 +
74703 +/***********************************************************************/
74704 +/* Common API for FM-PCD policer module */
74705 +/***********************************************************************/
74706 +t_Error FmPcdPlcrAllocProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId, uint16_t numOfProfiles);
74707 +t_Error FmPcdPlcrFreeProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
74708 +bool FmPcdPlcrIsProfileValid(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74709 +uint16_t FmPcdPlcrGetPortProfilesBase(t_Handle h_FmPcd, uint8_t hardwarePortId);
74710 +uint16_t FmPcdPlcrGetPortNumOfProfiles(t_Handle h_FmPcd, uint8_t hardwarePortId);
74711 +uint32_t FmPcdPlcrBuildWritePlcrActionRegs(uint16_t absoluteProfileId);
74712 +uint32_t FmPcdPlcrBuildCounterProfileReg(e_FmPcdPlcrProfileCounters counter);
74713 +uint32_t FmPcdPlcrBuildWritePlcrActionReg(uint16_t absoluteProfileId);
74714 +uint32_t FmPcdPlcrBuildReadPlcrActionReg(uint16_t absoluteProfileId);
74715 +uint16_t FmPcdPlcrProfileGetAbsoluteId(t_Handle h_Profile);
74716 +t_Error FmPcdPlcrGetAbsoluteIdByProfileParams(t_Handle h_FmPcd,
74717 + e_FmPcdProfileTypeSelection profileType,
74718 + t_Handle h_FmPort,
74719 + uint16_t relativeProfile,
74720 + uint16_t *p_AbsoluteId);
74721 +void FmPcdPlcrInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74722 +void FmPcdPlcrValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74723 +bool FmPcdPlcrHwProfileIsValid(uint32_t profileModeReg);
74724 +uint32_t FmPcdPlcrGetRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74725 +uint32_t FmPcdPlcrGetRequiredActionFlag(t_Handle h_FmPcd, uint16_t absoluteProfileId);
74726 +uint32_t FmPcdPlcrBuildNiaProfileReg(bool green, bool yellow, bool red);
74727 +void FmPcdPlcrUpdateRequiredAction(t_Handle h_FmPcd, uint16_t absoluteProfileId, uint32_t requiredAction);
74728 +t_Error FmPcdPlcrCcGetSetParams(t_Handle h_FmPcd, uint16_t profileIndx,uint32_t requiredAction);
74729 +
74730 +/***********************************************************************/
74731 +/* Common API for FM-PCD CC module */
74732 +/***********************************************************************/
74733 +uint8_t FmPcdCcGetParseCode(t_Handle h_CcNode);
74734 +uint8_t FmPcdCcGetOffset(t_Handle h_CcNode);
74735 +t_Error FmPcdCcRemoveKey(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex);
74736 +t_Error FmPcdCcAddKey(t_Handle h_FmPcd, t_Handle h_CcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPCdCcKeyParams);
74737 +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);
74738 +t_Error FmPcdCcModifyKeyAndNextEngine(t_Handle h_FmPcd, t_Handle h_FmPcdCcNode, uint16_t keyIndex, uint8_t keySize, t_FmPcdCcKeyParams *p_FmPcdCcKeyParams);
74739 +t_Error FmPcdCcModifyMissNextEngineParamNode(t_Handle h_FmPcd,t_Handle h_FmPcdCcNode, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
74740 +t_Error FmPcdCcModifyNextEngineParamTree(t_Handle h_FmPcd, t_Handle h_FmPcdCcTree, uint8_t grpId, uint8_t index, t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
74741 +uint32_t FmPcdCcGetNodeAddrOffsetFromNodeInfo(t_Handle h_FmPcd, t_Handle h_Pointer);
74742 +t_Handle FmPcdCcTreeGetSavedManipParams(t_Handle h_FmTree);
74743 +void FmPcdCcTreeSetSavedManipParams(t_Handle h_FmTree, t_Handle h_SavedManipParams);
74744 +t_Error FmPcdCcTreeAddIPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
74745 +t_Error FmPcdCcTreeAddCPR(t_Handle h_FmPcd, t_Handle h_FmTree, t_Handle h_NetEnv, t_Handle h_ReassemblyManip, bool schemes);
74746 +t_Error FmPcdCcBindTree(t_Handle h_FmPcd, t_Handle h_PcdParams, t_Handle h_CcTree, uint32_t *p_Offset,t_Handle h_FmPort);
74747 +t_Error FmPcdCcUnbindTree(t_Handle h_FmPcd, t_Handle h_CcTree);
74748 +
74749 +/***********************************************************************/
74750 +/* Common API for FM-PCD Manip module */
74751 +/***********************************************************************/
74752 +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);
74753 +
74754 +/***********************************************************************/
74755 +/* Common API for FM-Port module */
74756 +/***********************************************************************/
74757 +#if (DPAA_VERSION >= 11)
74758 +typedef enum e_FmPortGprFuncType
74759 +{
74760 + e_FM_PORT_GPR_EMPTY = 0,
74761 + e_FM_PORT_GPR_MURAM_PAGE
74762 +} e_FmPortGprFuncType;
74763 +
74764 +t_Error FmPortSetGprFunc(t_Handle h_FmPort, e_FmPortGprFuncType gprFunc, void **p_Value);
74765 +#endif /* DPAA_VERSION >= 11) */
74766 +t_Error FmGetSetParams(t_Handle h_Fm, t_FmGetSetParams *p_FmGetSetParams);
74767 +t_Error FmPortGetSetCcParams(t_Handle h_FmPort, t_FmPortGetSetCcParams *p_FmPortGetSetCcParams);
74768 +uint8_t FmPortGetNetEnvId(t_Handle h_FmPort);
74769 +uint8_t FmPortGetHardwarePortId(t_Handle h_FmPort);
74770 +uint32_t FmPortGetPcdEngines(t_Handle h_FmPort);
74771 +void FmPortPcdKgSwUnbindClsPlanGrp (t_Handle h_FmPort);
74772 +
74773 +
74774 +#if (DPAA_VERSION >= 11)
74775 +t_Error FmPcdFrmReplicUpdate(t_Handle h_FmPcd, t_Handle h_FmPort, t_Handle h_FrmReplic);
74776 +#endif /* (DPAA_VERSION >= 11) */
74777 +
74778 +/**************************************************************************//**
74779 + @Function FmRegisterIntr
74780 +
74781 + @Description Used to register an inter-module event handler to be processed by FM
74782 +
74783 + @Param[in] h_Fm A handle to an FM Module.
74784 + @Param[in] mod The module that causes the event
74785 + @Param[in] modId Module id - if more than 1 instansiation of this
74786 + mode exists,0 otherwise.
74787 + @Param[in] intrType Interrupt type (error/normal) selection.
74788 + @Param[in] f_Isr The interrupt service routine.
74789 + @Param[in] h_Arg Argument to be passed to f_Isr.
74790 +
74791 + @Return None.
74792 +*//***************************************************************************/
74793 +void FmRegisterIntr(t_Handle h_Fm,
74794 + e_FmEventModules mod,
74795 + uint8_t modId,
74796 + e_FmIntrType intrType,
74797 + void (*f_Isr) (t_Handle h_Arg),
74798 + t_Handle h_Arg);
74799 +
74800 +/**************************************************************************//**
74801 + @Function FmUnregisterIntr
74802 +
74803 + @Description Used to un-register an inter-module event handler that was processed by FM
74804 +
74805 + @Param[in] h_Fm A handle to an FM Module.
74806 + @Param[in] mod The module that causes the event
74807 + @Param[in] modId Module id - if more than 1 instansiation of this
74808 + mode exists,0 otherwise.
74809 + @Param[in] intrType Interrupt type (error/normal) selection.
74810 +
74811 + @Return None.
74812 +*//***************************************************************************/
74813 +void FmUnregisterIntr(t_Handle h_Fm,
74814 + e_FmEventModules mod,
74815 + uint8_t modId,
74816 + e_FmIntrType intrType);
74817 +
74818 +/**************************************************************************//**
74819 + @Function FmRegisterFmCtlIntr
74820 +
74821 + @Description Used to register to one of the fmCtl events in the FM module
74822 +
74823 + @Param[in] h_Fm A handle to an FM Module.
74824 + @Param[in] eventRegId FmCtl event id (0-7).
74825 + @Param[in] f_Isr The interrupt service routine.
74826 +
74827 + @Return E_OK on success; Error code otherwise.
74828 +
74829 + @Cautions Allowed only following FM_Init().
74830 +*//***************************************************************************/
74831 +void FmRegisterFmCtlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event));
74832 +
74833 +
74834 +/**************************************************************************//**
74835 + @Description enum for defining MAC types
74836 +*//***************************************************************************/
74837 +typedef enum e_FmMacType {
74838 + e_FM_MAC_10G = 0, /**< 10G MAC */
74839 + e_FM_MAC_1G /**< 1G MAC */
74840 +} e_FmMacType;
74841 +
74842 +/**************************************************************************//**
74843 + @Description Structure for port-FM communication during FM_PORT_Init.
74844 + Fields commented 'IN' are passed by the port module to be used
74845 + by the FM module.
74846 + Fields commented 'OUT' will be filled by FM before returning to port.
74847 + Some fields are optional (depending on configuration) and
74848 + will be analized by the port and FM modules accordingly.
74849 +*//***************************************************************************/
74850 +typedef struct t_FmInterModulePortInitParams {
74851 + uint8_t hardwarePortId; /**< IN. port Id */
74852 + e_FmPortType portType; /**< IN. Port type */
74853 + bool independentMode; /**< IN. TRUE if FM Port operates in independent mode */
74854 + uint16_t liodnOffset; /**< IN. Port's requested resource */
74855 + uint8_t numOfTasks; /**< IN. Port's requested resource */
74856 + uint8_t numOfExtraTasks; /**< IN. Port's requested resource */
74857 + uint8_t numOfOpenDmas; /**< IN. Port's requested resource */
74858 + uint8_t numOfExtraOpenDmas; /**< IN. Port's requested resource */
74859 + uint32_t sizeOfFifo; /**< IN. Port's requested resource */
74860 + uint32_t extraSizeOfFifo; /**< IN. Port's requested resource */
74861 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
74862 + uint16_t maxFrameLength; /**< IN. Port's max frame length. */
74863 + uint16_t liodnBase; /**< IN. Irrelevant for P4080 rev 1.
74864 + LIODN base for this port, to be
74865 + used together with LIODN offset. */
74866 + t_FmPhysAddr fmMuramPhysBaseAddr;/**< OUT. FM-MURAM physical address*/
74867 +} t_FmInterModulePortInitParams;
74868 +
74869 +/**************************************************************************//**
74870 + @Description Structure for port-FM communication during FM_PORT_Free.
74871 +*//***************************************************************************/
74872 +typedef struct t_FmInterModulePortFreeParams {
74873 + uint8_t hardwarePortId; /**< IN. port Id */
74874 + e_FmPortType portType; /**< IN. Port type */
74875 + uint8_t deqPipelineDepth; /**< IN. Port's requested resource */
74876 +} t_FmInterModulePortFreeParams;
74877 +
74878 +/**************************************************************************//**
74879 + @Function FmGetPcdPrsBaseAddr
74880 +
74881 + @Description Get the base address of the Parser from the FM module
74882 +
74883 + @Param[in] h_Fm A handle to an FM Module.
74884 +
74885 + @Return Base address.
74886 +*//***************************************************************************/
74887 +uintptr_t FmGetPcdPrsBaseAddr(t_Handle h_Fm);
74888 +
74889 +/**************************************************************************//**
74890 + @Function FmGetPcdKgBaseAddr
74891 +
74892 + @Description Get the base address of the Keygen from the FM module
74893 +
74894 + @Param[in] h_Fm A handle to an FM Module.
74895 +
74896 + @Return Base address.
74897 +*//***************************************************************************/
74898 +uintptr_t FmGetPcdKgBaseAddr(t_Handle h_Fm);
74899 +
74900 +/**************************************************************************//**
74901 + @Function FmGetPcdPlcrBaseAddr
74902 +
74903 + @Description Get the base address of the Policer from the FM module
74904 +
74905 + @Param[in] h_Fm A handle to an FM Module.
74906 +
74907 + @Return Base address.
74908 +*//***************************************************************************/
74909 +uintptr_t FmGetPcdPlcrBaseAddr(t_Handle h_Fm);
74910 +
74911 +/**************************************************************************//**
74912 + @Function FmGetMuramHandle
74913 +
74914 + @Description Get the handle of the MURAM from the FM module
74915 +
74916 + @Param[in] h_Fm A handle to an FM Module.
74917 +
74918 + @Return MURAM module handle.
74919 +*//***************************************************************************/
74920 +t_Handle FmGetMuramHandle(t_Handle h_Fm);
74921 +
74922 +/**************************************************************************//**
74923 + @Function FmGetPhysicalMuramBase
74924 +
74925 + @Description Get the physical base address of the MURAM from the FM module
74926 +
74927 + @Param[in] h_Fm A handle to an FM Module.
74928 + @Param[in] fmPhysAddr Physical MURAM base
74929 +
74930 + @Return Physical base address.
74931 +*//***************************************************************************/
74932 +void FmGetPhysicalMuramBase(t_Handle h_Fm, t_FmPhysAddr *fmPhysAddr);
74933 +
74934 +/**************************************************************************//**
74935 + @Function FmGetTimeStampScale
74936 +
74937 + @Description Used internally by other modules in order to get the timeStamp
74938 + period as requested by the application.
74939 +
74940 + This function returns bit number that is incremented every 1 usec.
74941 + To calculate timestamp period in nsec, use
74942 + 1000 / (1 << FmGetTimeStampScale()).
74943 +
74944 + @Param[in] h_Fm A handle to an FM Module.
74945 +
74946 + @Return Bit that counts 1 usec.
74947 +
74948 + @Cautions Allowed only following FM_Init().
74949 +*//***************************************************************************/
74950 +uint32_t FmGetTimeStampScale(t_Handle h_Fm);
74951 +
74952 +/**************************************************************************//**
74953 + @Function FmResumeStalledPort
74954 +
74955 + @Description Used internally by FM port to release a stalled port.
74956 +
74957 + @Param[in] h_Fm A handle to an FM Module.
74958 + @Param[in] hardwarePortId HW port id.
74959 +
74960 + @Return E_OK on success; Error code otherwise.
74961 +
74962 + @Cautions Allowed only following FM_Init().
74963 +*//***************************************************************************/
74964 +t_Error FmResumeStalledPort(t_Handle h_Fm, uint8_t hardwarePortId);
74965 +
74966 +/**************************************************************************//**
74967 + @Function FmIsPortStalled
74968 +
74969 + @Description Used internally by FM port to read the port's status.
74970 +
74971 + @Param[in] h_Fm A handle to an FM Module.
74972 + @Param[in] hardwarePortId HW port id.
74973 + @Param[in] p_IsStalled A pointer to the boolean port stalled state
74974 +
74975 + @Return E_OK on success; Error code otherwise.
74976 +
74977 + @Cautions Allowed only following FM_Init().
74978 +*//***************************************************************************/
74979 +t_Error FmIsPortStalled(t_Handle h_Fm, uint8_t hardwarePortId, bool *p_IsStalled);
74980 +
74981 +/**************************************************************************//**
74982 + @Function FmResetMac
74983 +
74984 + @Description Used by MAC driver to reset the MAC registers
74985 +
74986 + @Param[in] h_Fm A handle to an FM Module.
74987 + @Param[in] type MAC type.
74988 + @Param[in] macId MAC id - according to type.
74989 +
74990 + @Return E_OK on success; Error code otherwise.
74991 +
74992 + @Cautions Allowed only following FM_Init().
74993 +*//***************************************************************************/
74994 +t_Error FmResetMac(t_Handle h_Fm, e_FmMacType type, uint8_t macId);
74995 +
74996 +/**************************************************************************//**
74997 + @Function FmGetClockFreq
74998 +
74999 + @Description Used by MAC driver to get the FM clock frequency
75000 +
75001 + @Param[in] h_Fm A handle to an FM Module.
75002 +
75003 + @Return clock-freq on success; 0 otherwise.
75004 +
75005 + @Cautions Allowed only following FM_Init().
75006 +*//***************************************************************************/
75007 +uint16_t FmGetClockFreq(t_Handle h_Fm);
75008 +
75009 +/**************************************************************************//**
75010 + @Function FmGetMacClockFreq
75011 +
75012 + @Description Used by MAC driver to get the MAC clock frequency
75013 +
75014 + @Param[in] h_Fm A handle to an FM Module.
75015 +
75016 + @Return clock-freq on success; 0 otherwise.
75017 +
75018 + @Cautions Allowed only following FM_Init().
75019 +*//***************************************************************************/
75020 +uint16_t FmGetMacClockFreq(t_Handle h_Fm);
75021 +
75022 +/**************************************************************************//**
75023 + @Function FmGetId
75024 +
75025 + @Description Used by PCD driver to read rhe FM id
75026 +
75027 + @Param[in] h_Fm A handle to an FM Module.
75028 +
75029 + @Return E_OK on success; Error code otherwise.
75030 +
75031 + @Cautions Allowed only following FM_Init().
75032 +*//***************************************************************************/
75033 +uint8_t FmGetId(t_Handle h_Fm);
75034 +
75035 +/**************************************************************************//**
75036 + @Function FmReset
75037 +
75038 + @Description Used to reset the FM
75039 +
75040 + @Param[in] h_Fm A handle to an FM Module.
75041 +
75042 + @Return E_OK on success; Error code otherwise.
75043 +*//***************************************************************************/
75044 +t_Error FmReset(t_Handle h_Fm);
75045 +
75046 +/**************************************************************************//**
75047 + @Function FmGetSetPortParams
75048 +
75049 + @Description Used by FM-PORT driver to pass and receive parameters between
75050 + PORT and FM modules.
75051 +
75052 + @Param[in] h_Fm A handle to an FM Module.
75053 + @Param[in,out] p_PortParams A structure of FM Port parameters.
75054 +
75055 + @Return E_OK on success; Error code otherwise.
75056 +
75057 + @Cautions Allowed only following FM_Init().
75058 +*//***************************************************************************/
75059 +t_Error FmGetSetPortParams(t_Handle h_Fm,t_FmInterModulePortInitParams *p_PortParams);
75060 +
75061 +/**************************************************************************//**
75062 + @Function FmFreePortParams
75063 +
75064 + @Description Used by FM-PORT driver to free port's resources within the FM.
75065 +
75066 + @Param[in] h_Fm A handle to an FM Module.
75067 + @Param[in,out] p_PortParams A structure of FM Port parameters.
75068 +
75069 + @Return None.
75070 +
75071 + @Cautions Allowed only following FM_Init().
75072 +*//***************************************************************************/
75073 +void FmFreePortParams(t_Handle h_Fm,t_FmInterModulePortFreeParams *p_PortParams);
75074 +
75075 +/**************************************************************************//**
75076 + @Function FmSetNumOfRiscsPerPort
75077 +
75078 + @Description Used by FM-PORT driver to pass parameter between
75079 + PORT and FM modules for working with number of RISC..
75080 +
75081 + @Param[in] h_Fm A handle to an FM Module.
75082 + @Param[in] hardwarePortId hardware port Id.
75083 + @Param[in] numOfFmanCtrls number of Fman Controllers.
75084 + @Param[in] orFmanCtrl Fman Controller for order restoration.
75085 +
75086 + @Return None.
75087 +
75088 + @Cautions Allowed only following FM_Init().
75089 +*//***************************************************************************/
75090 +t_Error FmSetNumOfRiscsPerPort(t_Handle h_Fm, uint8_t hardwarePortId, uint8_t numOfFmanCtrls, t_FmFmanCtrl orFmanCtrl);
75091 +
75092 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
75093 +/**************************************************************************//*
75094 + @Function FmDumpPortRegs
75095 +
75096 + @Description Dumps FM port registers which are part of FM common registers
75097 +
75098 + @Param[in] h_Fm A handle to an FM Module.
75099 + @Param[in] hardwarePortId HW port id.
75100 +
75101 + @Return E_OK on success; Error code otherwise.
75102 +
75103 + @Cautions Allowed only FM_Init().
75104 +*//***************************************************************************/
75105 +t_Error FmDumpPortRegs(t_Handle h_Fm,uint8_t hardwarePortId);
75106 +#endif /* (defined(DEBUG_ERRORS) && ... */
75107 +
75108 +void FmRegisterPcd(t_Handle h_Fm, t_Handle h_FmPcd);
75109 +void FmUnregisterPcd(t_Handle h_Fm);
75110 +t_Handle FmGetPcdHandle(t_Handle h_Fm);
75111 +t_Error FmEnableRamsEcc(t_Handle h_Fm);
75112 +t_Error FmDisableRamsEcc(t_Handle h_Fm);
75113 +void FmGetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
75114 +t_Error FmAllocFmanCtrlEventReg(t_Handle h_Fm, uint8_t *p_EventId);
75115 +void FmFreeFmanCtrlEventReg(t_Handle h_Fm, uint8_t eventId);
75116 +void FmSetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, uint32_t enableEvents);
75117 +uint32_t FmGetFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
75118 +void FmRegisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId, void (*f_Isr) (t_Handle h_Fm, uint32_t event), t_Handle h_Arg);
75119 +void FmUnregisterFmanCtrlIntr(t_Handle h_Fm, uint8_t eventRegId);
75120 +t_Error FmSetMacMaxFrame(t_Handle h_Fm, e_FmMacType type, uint8_t macId, uint16_t mtu);
75121 +bool FmIsMaster(t_Handle h_Fm);
75122 +uint8_t FmGetGuestId(t_Handle h_Fm);
75123 +uint16_t FmGetTnumAgingPeriod(t_Handle h_Fm);
75124 +t_Error FmSetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool preFetchConfigured);
75125 +t_Error FmGetPortPreFetchConfiguration(t_Handle h_Fm, uint8_t portNum, bool *p_PortConfigured, bool *p_PreFetchConfigured);
75126 +
75127 +
75128 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
75129 +t_Error Fm10GTxEccWorkaround(t_Handle h_Fm, uint8_t macId);
75130 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
75131 +
75132 +void FmMuramClear(t_Handle h_FmMuram);
75133 +t_Error FmSetNumOfOpenDmas(t_Handle h_Fm,
75134 + uint8_t hardwarePortId,
75135 + uint8_t *p_NumOfOpenDmas,
75136 + uint8_t *p_NumOfExtraOpenDmas,
75137 + bool initialConfig);
75138 +t_Error FmSetNumOfTasks(t_Handle h_Fm,
75139 + uint8_t hardwarePortId,
75140 + uint8_t *p_NumOfTasks,
75141 + uint8_t *p_NumOfExtraTasks,
75142 + bool initialConfig);
75143 +t_Error FmSetSizeOfFifo(t_Handle h_Fm,
75144 + uint8_t hardwarePortId,
75145 + uint32_t *p_SizeOfFifo,
75146 + uint32_t *p_ExtraSizeOfFifo,
75147 + bool initialConfig);
75148 +
75149 +t_Error FmSetCongestionGroupPFCpriority(t_Handle h_Fm,
75150 + uint32_t congestionGroupId,
75151 + uint8_t priorityBitMap);
75152 +
75153 +#if (DPAA_VERSION >= 11)
75154 +t_Error FmVSPAllocForPort(t_Handle h_Fm,
75155 + e_FmPortType portType,
75156 + uint8_t portId,
75157 + uint8_t numOfStorageProfiles);
75158 +
75159 +t_Error FmVSPFreeForPort(t_Handle h_Fm,
75160 + e_FmPortType portType,
75161 + uint8_t portId);
75162 +
75163 +t_Error FmVSPGetAbsoluteProfileId(t_Handle h_Fm,
75164 + e_FmPortType portType,
75165 + uint8_t portId,
75166 + uint16_t relativeProfile,
75167 + uint16_t *p_AbsoluteId);
75168 +t_Error FmVSPCheckRelativeProfile(t_Handle h_Fm,
75169 + e_FmPortType portType,
75170 + uint8_t portId,
75171 + uint16_t relativeProfile);
75172 +
75173 +uintptr_t FmGetVSPBaseAddr(t_Handle h_Fm);
75174 +#endif /* (DPAA_VERSION >= 11) */
75175 +
75176 +
75177 +#endif /* __FM_COMMON_H */
75178 --- /dev/null
75179 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_hc.h
75180 @@ -0,0 +1,93 @@
75181 +/*
75182 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75183 + *
75184 + * Redistribution and use in source and binary forms, with or without
75185 + * modification, are permitted provided that the following conditions are met:
75186 + * * Redistributions of source code must retain the above copyright
75187 + * notice, this list of conditions and the following disclaimer.
75188 + * * Redistributions in binary form must reproduce the above copyright
75189 + * notice, this list of conditions and the following disclaimer in the
75190 + * documentation and/or other materials provided with the distribution.
75191 + * * Neither the name of Freescale Semiconductor nor the
75192 + * names of its contributors may be used to endorse or promote products
75193 + * derived from this software without specific prior written permission.
75194 + *
75195 + *
75196 + * ALTERNATIVELY, this software may be distributed under the terms of the
75197 + * GNU General Public License ("GPL") as published by the Free Software
75198 + * Foundation, either version 2 of that License or (at your option) any
75199 + * later version.
75200 + *
75201 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75202 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75203 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75204 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75205 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75206 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75207 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75208 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75209 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75210 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75211 + */
75212 +
75213 +
75214 +#ifndef __FM_HC_H
75215 +#define __FM_HC_H
75216 +
75217 +#include "std_ext.h"
75218 +#include "error_ext.h"
75219 +#include "fsl_fman_kg.h"
75220 +
75221 +#define __ERR_MODULE__ MODULE_FM_PCD
75222 +
75223 +
75224 +typedef struct t_FmHcParams {
75225 + t_Handle h_Fm;
75226 + t_Handle h_FmPcd;
75227 + t_FmPcdHcParams params;
75228 +} t_FmHcParams;
75229 +
75230 +
75231 +t_Handle FmHcConfigAndInit(t_FmHcParams *p_FmHcParams);
75232 +void FmHcFree(t_Handle h_FmHc);
75233 +t_Error FmHcSetFramesDataMemory(t_Handle h_FmHc,
75234 + uint8_t memId);
75235 +t_Error FmHcDumpRegs(t_Handle h_FmHc);
75236 +
75237 +void FmHcTxConf(t_Handle h_FmHc, t_DpaaFD *p_Fd);
75238 +
75239 +t_Error FmHcPcdKgSetScheme(t_Handle h_FmHc,
75240 + t_Handle h_Scheme,
75241 + struct fman_kg_scheme_regs *p_SchemeRegs,
75242 + bool updateCounter);
75243 +t_Error FmHcPcdKgDeleteScheme(t_Handle h_FmHc, t_Handle h_Scheme);
75244 +t_Error FmHcPcdCcCapwapTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcCapwapReassmTimeoutParams *p_CcCapwapReassmTimeoutParams );
75245 +t_Error FmHcPcdCcIpFragScratchPollCmd(t_Handle h_FmHc, bool fill, t_FmPcdCcFragScratchPoolCmdParams *p_FmPcdCcFragScratchPoolCmdParams);
75246 +t_Error FmHcPcdCcTimeoutReassm(t_Handle h_FmHc, t_FmPcdCcReassmTimeoutParams *p_CcReassmTimeoutParams, uint8_t *p_Result);
75247 +t_Error FmHcPcdKgSetClsPlan(t_Handle h_FmHc, t_FmPcdKgInterModuleClsPlanSet *p_Set);
75248 +t_Error FmHcPcdKgDeleteClsPlan(t_Handle h_FmHc, uint8_t clsPlanGrpId);
75249 +
75250 +t_Error FmHcPcdKgSetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t value);
75251 +uint32_t FmHcPcdKgGetSchemeCounter(t_Handle h_FmHc, t_Handle h_Scheme);
75252 +
75253 +t_Error FmHcPcdCcDoDynamicChange(t_Handle h_FmHc, uint32_t oldAdAddrOffset, uint32_t newAdAddrOffset);
75254 +
75255 +t_Error FmHcPcdPlcrSetProfile(t_Handle h_FmHc, t_Handle h_Profile, t_FmPcdPlcrProfileRegs *p_PlcrRegs);
75256 +t_Error FmHcPcdPlcrDeleteProfile(t_Handle h_FmHc, t_Handle h_Profile);
75257 +
75258 +t_Error FmHcPcdPlcrSetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter, uint32_t value);
75259 +uint32_t FmHcPcdPlcrGetProfileCounter(t_Handle h_FmHc, t_Handle h_Profile, e_FmPcdPlcrProfileCounters counter);
75260 +
75261 +t_Error FmHcKgWriteSp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t spReg, bool add);
75262 +t_Error FmHcKgWriteCpp(t_Handle h_FmHc, uint8_t hardwarePortId, uint32_t cppReg);
75263 +
75264 +t_Error FmHcPcdKgCcGetSetParams(t_Handle h_FmHc, t_Handle h_Scheme, uint32_t requiredAction, uint32_t value);
75265 +t_Error FmHcPcdPlcrCcGetSetParams(t_Handle h_FmHc,uint16_t absoluteProfileId, uint32_t requiredAction);
75266 +
75267 +t_Error FmHcPcdSync(t_Handle h_FmHc);
75268 +t_Handle FmHcGetPort(t_Handle h_FmHc);
75269 +
75270 +
75271 +
75272 +
75273 +#endif /* __FM_HC_H */
75274 --- /dev/null
75275 +++ b/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc/fm_sp_common.h
75276 @@ -0,0 +1,117 @@
75277 +/*
75278 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75279 + *
75280 + * Redistribution and use in source and binary forms, with or without
75281 + * modification, are permitted provided that the following conditions are met:
75282 + * * Redistributions of source code must retain the above copyright
75283 + * notice, this list of conditions and the following disclaimer.
75284 + * * Redistributions in binary form must reproduce the above copyright
75285 + * notice, this list of conditions and the following disclaimer in the
75286 + * documentation and/or other materials provided with the distribution.
75287 + * * Neither the name of Freescale Semiconductor nor the
75288 + * names of its contributors may be used to endorse or promote products
75289 + * derived from this software without specific prior written permission.
75290 + *
75291 + *
75292 + * ALTERNATIVELY, this software may be distributed under the terms of the
75293 + * GNU General Public License ("GPL") as published by the Free Software
75294 + * Foundation, either version 2 of that License or (at your option) any
75295 + * later version.
75296 + *
75297 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75298 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75299 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75300 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75301 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75302 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75303 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75304 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75305 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75306 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75307 + */
75308 +
75309 +
75310 +/******************************************************************************
75311 + @File fm_sp_common.h
75312 +
75313 + @Description FM SP ...
75314 +*//***************************************************************************/
75315 +#ifndef __FM_SP_COMMON_H
75316 +#define __FM_SP_COMMON_H
75317 +
75318 +#include "std_ext.h"
75319 +#include "error_ext.h"
75320 +#include "list_ext.h"
75321 +
75322 +#include "fm_ext.h"
75323 +#include "fm_pcd_ext.h"
75324 +#include "fsl_fman.h"
75325 +
75326 +/**************************************************************************//**
75327 + @Description defaults
75328 +*//***************************************************************************/
75329 +#define DEFAULT_FM_SP_bufferPrefixContent_privDataSize 0
75330 +#define DEFAULT_FM_SP_bufferPrefixContent_passPrsResult FALSE
75331 +#define DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp FALSE
75332 +#define DEFAULT_FM_SP_bufferPrefixContent_allOtherPCDInfo FALSE
75333 +#define DEFAULT_FM_SP_bufferPrefixContent_dataAlign 64
75334 +
75335 +/**************************************************************************//**
75336 + @Description structure for defining internal context copying
75337 +*//***************************************************************************/
75338 +typedef struct
75339 +{
75340 + uint16_t extBufOffset; /**< Offset in External buffer to which internal
75341 + context is copied to (Rx) or taken from (Tx, Op). */
75342 + uint8_t intContextOffset; /**< Offset within internal context to copy from
75343 + (Rx) or to copy to (Tx, Op). */
75344 + uint16_t size; /**< Internal offset size to be copied */
75345 +} t_FmSpIntContextDataCopy;
75346 +
75347 +/**************************************************************************//**
75348 + @Description struct for defining external buffer margins
75349 +*//***************************************************************************/
75350 +typedef struct {
75351 + uint16_t startMargins; /**< Number of bytes to be left at the beginning
75352 + of the external buffer (must be divisible by 16) */
75353 + uint16_t endMargins; /**< number of bytes to be left at the end
75354 + of the external buffer(must be divisible by 16) */
75355 +} t_FmSpBufMargins;
75356 +
75357 +typedef struct {
75358 + uint32_t dataOffset;
75359 + uint32_t prsResultOffset;
75360 + uint32_t timeStampOffset;
75361 + uint32_t hashResultOffset;
75362 + uint32_t pcdInfoOffset;
75363 + uint32_t manipOffset;
75364 +} t_FmSpBufferOffsets;
75365 +
75366 +
75367 +t_Error FmSpBuildBufferStructure(t_FmSpIntContextDataCopy *p_FmPortIntContextDataCopy,
75368 + t_FmBufferPrefixContent *p_BufferPrefixContent,
75369 + t_FmSpBufMargins *p_FmPortBufMargins,
75370 + t_FmSpBufferOffsets *p_FmPortBufferOffsets,
75371 + uint8_t *internalBufferOffset);
75372 +
75373 +t_Error FmSpCheckIntContextParams(t_FmSpIntContextDataCopy *p_FmSpIntContextDataCopy);
75374 +t_Error FmSpCheckBufPoolsParams(t_FmExtPools *p_FmExtPools,
75375 + t_FmBackupBmPools *p_FmBackupBmPools,
75376 + t_FmBufPoolDepletion *p_FmBufPoolDepletion);
75377 +t_Error FmSpCheckBufMargins(t_FmSpBufMargins *p_FmSpBufMargins);
75378 +void FmSpSetBufPoolsInAscOrderOfBufSizes(t_FmExtPools *p_FmExtPools, uint8_t *orderedArray, uint16_t *sizesArray);
75379 +
75380 +t_Error FmPcdSpAllocProfiles(t_Handle h_FmPcd,
75381 + uint8_t hardwarePortId,
75382 + uint16_t numOfStorageProfiles,
75383 + uint16_t *base,
75384 + uint8_t *log2Num);
75385 +t_Error FmPcdSpGetAbsoluteProfileId(t_Handle h_FmPcd,
75386 + t_Handle h_FmPort,
75387 + uint16_t relativeProfile,
75388 + uint16_t *p_AbsoluteId);
75389 +void SpInvalidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
75390 +void SpValidateProfileSw(t_Handle h_FmPcd, uint16_t absoluteProfileId);
75391 +
75392 +
75393 +#endif /* __FM_SP_COMMON_H */
75394 --- /dev/null
75395 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/Makefile
75396 @@ -0,0 +1,12 @@
75397 +#
75398 +# Makefile for the Freescale Ethernet controllers
75399 +#
75400 +ccflags-y += -DVERSION=\"\"
75401 +#
75402 +#Include netcomm SW specific definitions
75403 +
75404 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
75405 +
75406 +obj-y += fsl-ncsw-etc.o
75407 +
75408 +fsl-ncsw-etc-objs := mm.o memcpy.o sprint.o list.o error.o
75409 --- /dev/null
75410 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/error.c
75411 @@ -0,0 +1,95 @@
75412 +/*
75413 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75414 + *
75415 + * Redistribution and use in source and binary forms, with or without
75416 + * modification, are permitted provided that the following conditions are met:
75417 + * * Redistributions of source code must retain the above copyright
75418 + * notice, this list of conditions and the following disclaimer.
75419 + * * Redistributions in binary form must reproduce the above copyright
75420 + * notice, this list of conditions and the following disclaimer in the
75421 + * documentation and/or other materials provided with the distribution.
75422 + * * Neither the name of Freescale Semiconductor nor the
75423 + * names of its contributors may be used to endorse or promote products
75424 + * derived from this software without specific prior written permission.
75425 + *
75426 + *
75427 + * ALTERNATIVELY, this software may be distributed under the terms of the
75428 + * GNU General Public License ("GPL") as published by the Free Software
75429 + * Foundation, either version 2 of that License or (at your option) any
75430 + * later version.
75431 + *
75432 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75433 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75434 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75435 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75436 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75437 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75438 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75439 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75440 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75441 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75442 + */
75443 +
75444 +
75445 +/*
75446 +
75447 + @File error.c
75448 +
75449 + @Description General errors and events reporting utilities.
75450 +*//***************************************************************************/
75451 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
75452 +#include "error_ext.h"
75453 +
75454 +
75455 +const char *dbgLevelStrings[] =
75456 +{
75457 + "CRITICAL"
75458 + ,"MAJOR"
75459 + ,"MINOR"
75460 + ,"WARNING"
75461 + ,"INFO"
75462 + ,"TRACE"
75463 +};
75464 +
75465 +
75466 +char * ErrTypeStrings (e_ErrorType err)
75467 +{
75468 + switch (err)
75469 + {
75470 + case (E_OK): return "OK";
75471 + case (E_WRITE_FAILED): return "Write Access Failed";
75472 + case (E_NO_DEVICE): return "No Device";
75473 + case (E_NOT_AVAILABLE): return "Resource Is Unavailable";
75474 + case (E_NO_MEMORY): return "Memory Allocation Failed";
75475 + case (E_INVALID_ADDRESS): return "Invalid Address";
75476 + case (E_BUSY): return "Resource Is Busy";
75477 + case (E_ALREADY_EXISTS): return "Resource Already Exists";
75478 + case (E_INVALID_OPERATION): return "Invalid Operation";
75479 + case (E_INVALID_VALUE): return "Invalid Value";
75480 + case (E_NOT_IN_RANGE): return "Value Out Of Range";
75481 + case (E_NOT_SUPPORTED): return "Unsupported Operation";
75482 + case (E_INVALID_STATE): return "Invalid State";
75483 + case (E_INVALID_HANDLE): return "Invalid Handle";
75484 + case (E_INVALID_ID): return "Invalid ID";
75485 + case (E_NULL_POINTER): return "Unexpected NULL Pointer";
75486 + case (E_INVALID_SELECTION): return "Invalid Selection";
75487 + case (E_INVALID_COMM_MODE): return "Invalid Communication Mode";
75488 + case (E_INVALID_MEMORY_TYPE): return "Invalid Memory Type";
75489 + case (E_INVALID_CLOCK): return "Invalid Clock";
75490 + case (E_CONFLICT): return "Conflict In Settings";
75491 + case (E_NOT_ALIGNED): return "Incorrect Alignment";
75492 + case (E_NOT_FOUND): return "Resource Not Found";
75493 + case (E_FULL): return "Resource Is Full";
75494 + case (E_EMPTY): return "Resource Is Empty";
75495 + case (E_ALREADY_FREE): return "Resource Already Free";
75496 + case (E_READ_FAILED): return "Read Access Failed";
75497 + case (E_INVALID_FRAME): return "Invalid Frame";
75498 + case (E_SEND_FAILED): return "Send Operation Failed";
75499 + case (E_RECEIVE_FAILED): return "Receive Operation Failed";
75500 + case (E_TIMEOUT): return "Operation Timed Out";
75501 + default:
75502 + break;
75503 + }
75504 + return NULL;
75505 +}
75506 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
75507 --- /dev/null
75508 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/list.c
75509 @@ -0,0 +1,71 @@
75510 +/*
75511 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75512 + *
75513 + * Redistribution and use in source and binary forms, with or without
75514 + * modification, are permitted provided that the following conditions are met:
75515 + * * Redistributions of source code must retain the above copyright
75516 + * notice, this list of conditions and the following disclaimer.
75517 + * * Redistributions in binary form must reproduce the above copyright
75518 + * notice, this list of conditions and the following disclaimer in the
75519 + * documentation and/or other materials provided with the distribution.
75520 + * * Neither the name of Freescale Semiconductor nor the
75521 + * names of its contributors may be used to endorse or promote products
75522 + * derived from this software without specific prior written permission.
75523 + *
75524 + *
75525 + * ALTERNATIVELY, this software may be distributed under the terms of the
75526 + * GNU General Public License ("GPL") as published by the Free Software
75527 + * Foundation, either version 2 of that License or (at your option) any
75528 + * later version.
75529 + *
75530 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75531 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75532 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75533 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75534 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75535 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75536 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75537 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75538 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75539 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75540 + */
75541 +
75542 +
75543 +/**************************************************************************//**
75544 +
75545 + @File list.c
75546 +
75547 + @Description Implementation of list.
75548 +*//***************************************************************************/
75549 +#include "std_ext.h"
75550 +#include "list_ext.h"
75551 +
75552 +
75553 +void LIST_Append(t_List *p_NewList, t_List *p_Head)
75554 +{
75555 + t_List *p_First = LIST_FIRST(p_NewList);
75556 +
75557 + if (p_First != p_NewList)
75558 + {
75559 + t_List *p_Last = LIST_LAST(p_NewList);
75560 + t_List *p_Cur = LIST_NEXT(p_Head);
75561 +
75562 + LIST_PREV(p_First) = p_Head;
75563 + LIST_FIRST(p_Head) = p_First;
75564 + LIST_NEXT(p_Last) = p_Cur;
75565 + LIST_LAST(p_Cur) = p_Last;
75566 + }
75567 +}
75568 +
75569 +
75570 +int LIST_NumOfObjs(t_List *p_List)
75571 +{
75572 + t_List *p_Tmp;
75573 + int numOfObjs = 0;
75574 +
75575 + if (!LIST_IsEmpty(p_List))
75576 + LIST_FOR_EACH(p_Tmp, p_List)
75577 + numOfObjs++;
75578 +
75579 + return numOfObjs;
75580 +}
75581 --- /dev/null
75582 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/memcpy.c
75583 @@ -0,0 +1,620 @@
75584 +/*
75585 + * Copyright 2008-2012 Freescale Semiconductor Inc.
75586 + *
75587 + * Redistribution and use in source and binary forms, with or without
75588 + * modification, are permitted provided that the following conditions are met:
75589 + * * Redistributions of source code must retain the above copyright
75590 + * notice, this list of conditions and the following disclaimer.
75591 + * * Redistributions in binary form must reproduce the above copyright
75592 + * notice, this list of conditions and the following disclaimer in the
75593 + * documentation and/or other materials provided with the distribution.
75594 + * * Neither the name of Freescale Semiconductor nor the
75595 + * names of its contributors may be used to endorse or promote products
75596 + * derived from this software without specific prior written permission.
75597 + *
75598 + *
75599 + * ALTERNATIVELY, this software may be distributed under the terms of the
75600 + * GNU General Public License ("GPL") as published by the Free Software
75601 + * Foundation, either version 2 of that License or (at your option) any
75602 + * later version.
75603 + *
75604 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
75605 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75606 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
75607 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
75608 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
75609 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
75610 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
75611 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
75612 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
75613 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
75614 + */
75615 +
75616 +
75617 +
75618 +#include "std_ext.h"
75619 +#include "xx_ext.h"
75620 +#include "memcpy_ext.h"
75621 +
75622 +void * MemCpy8(void* pDst, void* pSrc, uint32_t size)
75623 +{
75624 + int i;
75625 +
75626 + for(i = 0; i < size; ++i)
75627 + *(((uint8_t*)(pDst)) + i) = *(((uint8_t*)(pSrc)) + i);
75628 +
75629 + return pDst;
75630 +}
75631 +
75632 +void * MemSet8(void* pDst, int c, uint32_t size)
75633 +{
75634 + int i;
75635 +
75636 + for(i = 0; i < size; ++i)
75637 + *(((uint8_t*)(pDst)) + i) = (uint8_t)(c);
75638 +
75639 + return pDst;
75640 +}
75641 +
75642 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size)
75643 +{
75644 + uint32_t leftAlign;
75645 + uint32_t rightAlign;
75646 + uint32_t lastWord;
75647 + uint32_t currWord;
75648 + uint32_t *p_Src32;
75649 + uint32_t *p_Dst32;
75650 + uint8_t *p_Src8;
75651 + uint8_t *p_Dst8;
75652 +
75653 + p_Src8 = (uint8_t*)(pSrc);
75654 + p_Dst8 = (uint8_t*)(pDst);
75655 + /* first copy byte by byte till the source first alignment
75656 + * this step is necessary to ensure we do not even try to access
75657 + * data which is before the source buffer, hence it is not ours.
75658 + */
75659 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
75660 + {
75661 + *p_Dst8++ = *p_Src8++;
75662 + size--;
75663 + }
75664 +
75665 + /* align destination (possibly disaligning source)*/
75666 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75667 + {
75668 + *p_Dst8++ = *p_Src8++;
75669 + size--;
75670 + }
75671 +
75672 + /* dest is aligned and source is not necessarily aligned */
75673 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
75674 + rightAlign = 32 - leftAlign;
75675 +
75676 +
75677 + if (leftAlign == 0)
75678 + {
75679 + /* source is also aligned */
75680 + p_Src32 = (uint32_t*)(p_Src8);
75681 + p_Dst32 = (uint32_t*)(p_Dst8);
75682 + while (size >> 2) /* size >= 4 */
75683 + {
75684 + *p_Dst32++ = *p_Src32++;
75685 + size -= 4;
75686 + }
75687 + p_Src8 = (uint8_t*)(p_Src32);
75688 + p_Dst8 = (uint8_t*)(p_Dst32);
75689 + }
75690 + else
75691 + {
75692 + /* source is not aligned (destination is aligned)*/
75693 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
75694 + p_Dst32 = (uint32_t*)(p_Dst8);
75695 + lastWord = *p_Src32++;
75696 + while(size >> 3) /* size >= 8 */
75697 + {
75698 + currWord = *p_Src32;
75699 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
75700 + lastWord = currWord;
75701 + p_Src32++;
75702 + p_Dst32++;
75703 + size -= 4;
75704 + }
75705 + p_Dst8 = (uint8_t*)(p_Dst32);
75706 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
75707 + }
75708 +
75709 + /* complete the left overs */
75710 + while (size--)
75711 + *p_Dst8++ = *p_Src8++;
75712 +
75713 + return pDst;
75714 +}
75715 +
75716 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size)
75717 +{
75718 + uint32_t leftAlign;
75719 + uint32_t rightAlign;
75720 + uint32_t lastWord;
75721 + uint32_t currWord;
75722 + uint32_t *p_Src32;
75723 + uint32_t *p_Dst32;
75724 + uint8_t *p_Src8;
75725 + uint8_t *p_Dst8;
75726 +
75727 + p_Src8 = (uint8_t*)(pSrc);
75728 + p_Dst8 = (uint8_t*)(pDst);
75729 + /* first copy byte by byte till the source first alignment
75730 + * this step is necessary to ensure we do not even try to access
75731 + * data which is before the source buffer, hence it is not ours.
75732 + */
75733 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
75734 + {
75735 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
75736 + p_Dst8++;p_Src8++;
75737 + size--;
75738 + }
75739 +
75740 + /* align destination (possibly disaligning source)*/
75741 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75742 + {
75743 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
75744 + p_Dst8++;p_Src8++;
75745 + size--;
75746 + }
75747 +
75748 + /* dest is aligned and source is not necessarily aligned */
75749 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
75750 + rightAlign = 32 - leftAlign;
75751 +
75752 + if (leftAlign == 0)
75753 + {
75754 + /* source is also aligned */
75755 + p_Src32 = (uint32_t*)(p_Src8);
75756 + p_Dst32 = (uint32_t*)(p_Dst8);
75757 + while (size >> 2) /* size >= 4 */
75758 + {
75759 + WRITE_UINT32(*p_Dst32, GET_UINT32(*p_Src32));
75760 + p_Dst32++;p_Src32++;
75761 + size -= 4;
75762 + }
75763 + p_Src8 = (uint8_t*)(p_Src32);
75764 + p_Dst8 = (uint8_t*)(p_Dst32);
75765 + }
75766 + else
75767 + {
75768 + /* source is not aligned (destination is aligned)*/
75769 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
75770 + p_Dst32 = (uint32_t*)(p_Dst8);
75771 + lastWord = GET_UINT32(*p_Src32);
75772 + p_Src32++;
75773 + while(size >> 3) /* size >= 8 */
75774 + {
75775 + currWord = GET_UINT32(*p_Src32);
75776 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
75777 + lastWord = currWord;
75778 + p_Src32++;p_Dst32++;
75779 + size -= 4;
75780 + }
75781 + p_Dst8 = (uint8_t*)(p_Dst32);
75782 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
75783 + }
75784 +
75785 + /* complete the left overs */
75786 + while (size--)
75787 + {
75788 + WRITE_UINT8(*p_Dst8, GET_UINT8(*p_Src8));
75789 + p_Dst8++;p_Src8++;
75790 + }
75791 +
75792 + return pDst;
75793 +}
75794 +
75795 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size)
75796 +{
75797 + uint32_t leftAlign;
75798 + uint32_t rightAlign;
75799 + uint32_t lastWord;
75800 + uint32_t currWord;
75801 + uint32_t *p_Src32;
75802 + uint32_t *p_Dst32;
75803 + uint8_t *p_Src8;
75804 + uint8_t *p_Dst8;
75805 +
75806 + p_Src8 = (uint8_t*)(pSrc);
75807 + p_Dst8 = (uint8_t*)(pDst);
75808 + /* first copy byte by byte till the source first alignment
75809 + * this step is necessary to ensure we do not even try to access
75810 + * data which is before the source buffer, hence it is not ours.
75811 + */
75812 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
75813 + {
75814 + WRITE_UINT8(*p_Dst8, *p_Src8);
75815 + p_Dst8++;p_Src8++;
75816 + size--;
75817 + }
75818 +
75819 + /* align destination (possibly disaligning source)*/
75820 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75821 + {
75822 + WRITE_UINT8(*p_Dst8, *p_Src8);
75823 + p_Dst8++;p_Src8++;
75824 + size--;
75825 + }
75826 +
75827 + /* dest is aligned and source is not necessarily aligned */
75828 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
75829 + rightAlign = 32 - leftAlign;
75830 +
75831 + if (leftAlign == 0)
75832 + {
75833 + /* source is also aligned */
75834 + p_Src32 = (uint32_t*)(p_Src8);
75835 + p_Dst32 = (uint32_t*)(p_Dst8);
75836 + while (size >> 2) /* size >= 4 */
75837 + {
75838 + WRITE_UINT32(*p_Dst32, *p_Src32);
75839 + p_Dst32++;p_Src32++;
75840 + size -= 4;
75841 + }
75842 + p_Src8 = (uint8_t*)(p_Src32);
75843 + p_Dst8 = (uint8_t*)(p_Dst32);
75844 + }
75845 + else
75846 + {
75847 + /* source is not aligned (destination is aligned)*/
75848 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
75849 + p_Dst32 = (uint32_t*)(p_Dst8);
75850 + lastWord = *p_Src32++;
75851 + while(size >> 3) /* size >= 8 */
75852 + {
75853 + currWord = *p_Src32;
75854 + WRITE_UINT32(*p_Dst32, (lastWord << leftAlign) | (currWord >> rightAlign));
75855 + lastWord = currWord;
75856 + p_Src32++;p_Dst32++;
75857 + size -= 4;
75858 + }
75859 + p_Dst8 = (uint8_t*)(p_Dst32);
75860 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
75861 + }
75862 +
75863 + /* complete the left overs */
75864 + while (size--)
75865 + {
75866 + WRITE_UINT8(*p_Dst8, *p_Src8);
75867 + p_Dst8++;p_Src8++;
75868 + }
75869 +
75870 + return pDst;
75871 +}
75872 +
75873 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size)
75874 +{
75875 + uint32_t leftAlign;
75876 + uint32_t rightAlign;
75877 + uint32_t lastWord;
75878 + uint32_t currWord;
75879 + uint32_t *p_Src32;
75880 + uint32_t *p_Dst32;
75881 + uint8_t *p_Src8;
75882 + uint8_t *p_Dst8;
75883 +
75884 + p_Src8 = (uint8_t*)(pSrc);
75885 + p_Dst8 = (uint8_t*)(pDst);
75886 + /* first copy byte by byte till the source first alignment
75887 + * this step is necessary to ensure we do not even try to access
75888 + * data which is before the source buffer, hence it is not ours.
75889 + */
75890 + while((PTR_TO_UINT(p_Src8) & 3) && size) /* (pSrc mod 4) > 0 and size > 0 */
75891 + {
75892 + *p_Dst8 = GET_UINT8(*p_Src8);
75893 + p_Dst8++;p_Src8++;
75894 + size--;
75895 + }
75896 +
75897 + /* align destination (possibly disaligning source)*/
75898 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
75899 + {
75900 + *p_Dst8 = GET_UINT8(*p_Src8);
75901 + p_Dst8++;p_Src8++;
75902 + size--;
75903 + }
75904 +
75905 + /* dest is aligned and source is not necessarily aligned */
75906 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 3) << 3); /* leftAlign = (pSrc mod 4)*8 */
75907 + rightAlign = 32 - leftAlign;
75908 +
75909 + if (leftAlign == 0)
75910 + {
75911 + /* source is also aligned */
75912 + p_Src32 = (uint32_t*)(p_Src8);
75913 + p_Dst32 = (uint32_t*)(p_Dst8);
75914 + while (size >> 2) /* size >= 4 */
75915 + {
75916 + *p_Dst32 = GET_UINT32(*p_Src32);
75917 + p_Dst32++;p_Src32++;
75918 + size -= 4;
75919 + }
75920 + p_Src8 = (uint8_t*)(p_Src32);
75921 + p_Dst8 = (uint8_t*)(p_Dst32);
75922 + }
75923 + else
75924 + {
75925 + /* source is not aligned (destination is aligned)*/
75926 + p_Src32 = (uint32_t*)(p_Src8 - (leftAlign >> 3));
75927 + p_Dst32 = (uint32_t*)(p_Dst8);
75928 + lastWord = GET_UINT32(*p_Src32);
75929 + p_Src32++;
75930 + while(size >> 3) /* size >= 8 */
75931 + {
75932 + currWord = GET_UINT32(*p_Src32);
75933 + *p_Dst32 = (lastWord << leftAlign) | (currWord >> rightAlign);
75934 + lastWord = currWord;
75935 + p_Src32++;p_Dst32++;
75936 + size -= 4;
75937 + }
75938 + p_Dst8 = (uint8_t*)(p_Dst32);
75939 + p_Src8 = (uint8_t*)(p_Src32) - 4 + (leftAlign >> 3);
75940 + }
75941 +
75942 + /* complete the left overs */
75943 + while (size--)
75944 + {
75945 + *p_Dst8 = GET_UINT8(*p_Src8);
75946 + p_Dst8++;p_Src8++;
75947 + }
75948 +
75949 + return pDst;
75950 +}
75951 +
75952 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size)
75953 +{
75954 + uint32_t leftAlign;
75955 + uint32_t rightAlign;
75956 + uint64_t lastWord;
75957 + uint64_t currWord;
75958 + uint64_t *pSrc64;
75959 + uint64_t *pDst64;
75960 + uint8_t *p_Src8;
75961 + uint8_t *p_Dst8;
75962 +
75963 + p_Src8 = (uint8_t*)(pSrc);
75964 + p_Dst8 = (uint8_t*)(pDst);
75965 + /* first copy byte by byte till the source first alignment
75966 + * this step is necessarily to ensure we do not even try to access
75967 + * data which is before the source buffer, hence it is not ours.
75968 + */
75969 + while((PTR_TO_UINT(p_Src8) & 7) && size) /* (pSrc mod 8) > 0 and size > 0 */
75970 + {
75971 + *p_Dst8++ = *p_Src8++;
75972 + size--;
75973 + }
75974 +
75975 + /* align destination (possibly disaligning source)*/
75976 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
75977 + {
75978 + *p_Dst8++ = *p_Src8++;
75979 + size--;
75980 + }
75981 +
75982 + /* dest is aligned and source is not necessarily aligned */
75983 + leftAlign = (uint32_t)((PTR_TO_UINT(p_Src8) & 7) << 3); /* leftAlign = (pSrc mod 8)*8 */
75984 + rightAlign = 64 - leftAlign;
75985 +
75986 +
75987 + if (leftAlign == 0)
75988 + {
75989 + /* source is also aligned */
75990 + pSrc64 = (uint64_t*)(p_Src8);
75991 + pDst64 = (uint64_t*)(p_Dst8);
75992 + while (size >> 3) /* size >= 8 */
75993 + {
75994 + *pDst64++ = *pSrc64++;
75995 + size -= 8;
75996 + }
75997 + p_Src8 = (uint8_t*)(pSrc64);
75998 + p_Dst8 = (uint8_t*)(pDst64);
75999 + }
76000 + else
76001 + {
76002 + /* source is not aligned (destination is aligned)*/
76003 + pSrc64 = (uint64_t*)(p_Src8 - (leftAlign >> 3));
76004 + pDst64 = (uint64_t*)(p_Dst8);
76005 + lastWord = *pSrc64++;
76006 + while(size >> 4) /* size >= 16 */
76007 + {
76008 + currWord = *pSrc64;
76009 + *pDst64 = (lastWord << leftAlign) | (currWord >> rightAlign);
76010 + lastWord = currWord;
76011 + pSrc64++;
76012 + pDst64++;
76013 + size -= 8;
76014 + }
76015 + p_Dst8 = (uint8_t*)(pDst64);
76016 + p_Src8 = (uint8_t*)(pSrc64) - 8 + (leftAlign >> 3);
76017 + }
76018 +
76019 + /* complete the left overs */
76020 + while (size--)
76021 + *p_Dst8++ = *p_Src8++;
76022 +
76023 + return pDst;
76024 +}
76025 +
76026 +void * MemSet32(void* pDst, uint8_t val, uint32_t size)
76027 +{
76028 + uint32_t val32;
76029 + uint32_t *p_Dst32;
76030 + uint8_t *p_Dst8;
76031 +
76032 + p_Dst8 = (uint8_t*)(pDst);
76033 +
76034 + /* generate four 8-bit val's in 32-bit container */
76035 + val32 = (uint32_t) val;
76036 + val32 |= (val32 << 8);
76037 + val32 |= (val32 << 16);
76038 +
76039 + /* align destination to 32 */
76040 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
76041 + {
76042 + *p_Dst8++ = val;
76043 + size--;
76044 + }
76045 +
76046 + /* 32-bit chunks */
76047 + p_Dst32 = (uint32_t*)(p_Dst8);
76048 + while (size >> 2) /* size >= 4 */
76049 + {
76050 + *p_Dst32++ = val32;
76051 + size -= 4;
76052 + }
76053 +
76054 + /* complete the leftovers */
76055 + p_Dst8 = (uint8_t*)(p_Dst32);
76056 + while (size--)
76057 + *p_Dst8++ = val;
76058 +
76059 + return pDst;
76060 +}
76061 +
76062 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size)
76063 +{
76064 + uint32_t val32;
76065 + uint32_t *p_Dst32;
76066 + uint8_t *p_Dst8;
76067 +
76068 + p_Dst8 = (uint8_t*)(pDst);
76069 +
76070 + /* generate four 8-bit val's in 32-bit container */
76071 + val32 = (uint32_t) val;
76072 + val32 |= (val32 << 8);
76073 + val32 |= (val32 << 16);
76074 +
76075 + /* align destination to 32 */
76076 + while((PTR_TO_UINT(p_Dst8) & 3) && size) /* (pDst mod 4) > 0 and size > 0 */
76077 + {
76078 + WRITE_UINT8(*p_Dst8, val);
76079 + p_Dst8++;
76080 + size--;
76081 + }
76082 +
76083 + /* 32-bit chunks */
76084 + p_Dst32 = (uint32_t*)(p_Dst8);
76085 + while (size >> 2) /* size >= 4 */
76086 + {
76087 + WRITE_UINT32(*p_Dst32, val32);
76088 + p_Dst32++;
76089 + size -= 4;
76090 + }
76091 +
76092 + /* complete the leftovers */
76093 + p_Dst8 = (uint8_t*)(p_Dst32);
76094 + while (size--)
76095 + {
76096 + WRITE_UINT8(*p_Dst8, val);
76097 + p_Dst8++;
76098 + }
76099 +
76100 + return pDst;
76101 +}
76102 +
76103 +void * MemSet64(void* pDst, uint8_t val, uint32_t size)
76104 +{
76105 + uint64_t val64;
76106 + uint64_t *pDst64;
76107 + uint8_t *p_Dst8;
76108 +
76109 + p_Dst8 = (uint8_t*)(pDst);
76110 +
76111 + /* generate four 8-bit val's in 32-bit container */
76112 + val64 = (uint64_t) val;
76113 + val64 |= (val64 << 8);
76114 + val64 |= (val64 << 16);
76115 + val64 |= (val64 << 24);
76116 + val64 |= (val64 << 32);
76117 +
76118 + /* align destination to 64 */
76119 + while((PTR_TO_UINT(p_Dst8) & 7) && size) /* (pDst mod 8) > 0 and size > 0 */
76120 + {
76121 + *p_Dst8++ = val;
76122 + size--;
76123 + }
76124 +
76125 + /* 64-bit chunks */
76126 + pDst64 = (uint64_t*)(p_Dst8);
76127 + while (size >> 4) /* size >= 8 */
76128 + {
76129 + *pDst64++ = val64;
76130 + size -= 8;
76131 + }
76132 +
76133 + /* complete the leftovers */
76134 + p_Dst8 = (uint8_t*)(pDst64);
76135 + while (size--)
76136 + *p_Dst8++ = val;
76137 +
76138 + return pDst;
76139 +}
76140 +
76141 +void MemDisp(uint8_t *p, int size)
76142 +{
76143 + uint32_t space = (uint32_t)(PTR_TO_UINT(p) & 0x3);
76144 + uint8_t *p_Limit;
76145 +
76146 + if (space)
76147 + {
76148 + p_Limit = (p - space + 4);
76149 +
76150 + XX_Print("0x%08X: ", (p - space));
76151 +
76152 + while (space--)
76153 + {
76154 + XX_Print("--");
76155 + }
76156 + while (size && (p < p_Limit))
76157 + {
76158 + XX_Print("%02x", *(uint8_t*)p);
76159 + size--;
76160 + p++;
76161 + }
76162 +
76163 + XX_Print(" ");
76164 + p_Limit += 12;
76165 +
76166 + while ((size > 3) && (p < p_Limit))
76167 + {
76168 + XX_Print("%08x ", *(uint32_t*)p);
76169 + size -= 4;
76170 + p += 4;
76171 + }
76172 + XX_Print("\r\n");
76173 + }
76174 +
76175 + while (size > 15)
76176 + {
76177 + XX_Print("0x%08X: %08x %08x %08x %08x\r\n",
76178 + p, *(uint32_t *)p, *(uint32_t *)(p + 4),
76179 + *(uint32_t *)(p + 8), *(uint32_t *)(p + 12));
76180 + size -= 16;
76181 + p += 16;
76182 + }
76183 +
76184 + if (size)
76185 + {
76186 + XX_Print("0x%08X: ", p);
76187 +
76188 + while (size > 3)
76189 + {
76190 + XX_Print("%08x ", *(uint32_t *)p);
76191 + size -= 4;
76192 + p += 4;
76193 + }
76194 + while (size)
76195 + {
76196 + XX_Print("%02x", *(uint8_t *)p);
76197 + size--;
76198 + p++;
76199 + }
76200 +
76201 + XX_Print("\r\n");
76202 + }
76203 +}
76204 --- /dev/null
76205 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.c
76206 @@ -0,0 +1,1155 @@
76207 +/*
76208 + * Copyright 2008-2012 Freescale Semiconductor Inc.
76209 + *
76210 + * Redistribution and use in source and binary forms, with or without
76211 + * modification, are permitted provided that the following conditions are met:
76212 + * * Redistributions of source code must retain the above copyright
76213 + * notice, this list of conditions and the following disclaimer.
76214 + * * Redistributions in binary form must reproduce the above copyright
76215 + * notice, this list of conditions and the following disclaimer in the
76216 + * documentation and/or other materials provided with the distribution.
76217 + * * Neither the name of Freescale Semiconductor nor the
76218 + * names of its contributors may be used to endorse or promote products
76219 + * derived from this software without specific prior written permission.
76220 + *
76221 + *
76222 + * ALTERNATIVELY, this software may be distributed under the terms of the
76223 + * GNU General Public License ("GPL") as published by the Free Software
76224 + * Foundation, either version 2 of that License or (at your option) any
76225 + * later version.
76226 + *
76227 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
76228 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
76229 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76230 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
76231 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76232 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
76233 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
76234 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
76235 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
76236 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76237 + */
76238 +
76239 +
76240 +#include "string_ext.h"
76241 +#include "error_ext.h"
76242 +#include "std_ext.h"
76243 +#include "part_ext.h"
76244 +#include "xx_ext.h"
76245 +
76246 +#include "mm.h"
76247 +
76248 +
76249 +
76250 +
76251 +/**********************************************************************
76252 + * MM internal routines set *
76253 + **********************************************************************/
76254 +
76255 +/****************************************************************
76256 + * Routine: CreateBusyBlock
76257 + *
76258 + * Description:
76259 + * Initializes a new busy block of "size" bytes and started
76260 + * rom "base" address. Each busy block has a name that
76261 + * specified the purpose of the memory allocation.
76262 + *
76263 + * Arguments:
76264 + * base - base address of the busy block
76265 + * size - size of the busy block
76266 + * name - name that specified the busy block
76267 + *
76268 + * Return value:
76269 + * A pointer to new created structure returned on success;
76270 + * Otherwise, NULL.
76271 + ****************************************************************/
76272 +static t_BusyBlock * CreateBusyBlock(uint64_t base, uint64_t size, char *name)
76273 +{
76274 + t_BusyBlock *p_BusyBlock;
76275 + uint32_t n;
76276 +
76277 + p_BusyBlock = (t_BusyBlock *)XX_Malloc(sizeof(t_BusyBlock));
76278 + if ( !p_BusyBlock )
76279 + {
76280 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76281 + return NULL;
76282 + }
76283 +
76284 + p_BusyBlock->base = base;
76285 + p_BusyBlock->end = base + size;
76286 +
76287 + n = strlen(name);
76288 + if (n >= MM_MAX_NAME_LEN)
76289 + n = MM_MAX_NAME_LEN - 1;
76290 + strncpy(p_BusyBlock->name, name, MM_MAX_NAME_LEN-1);
76291 + p_BusyBlock->name[n] = '\0';
76292 + p_BusyBlock->p_Next = 0;
76293 +
76294 + return p_BusyBlock;
76295 +}
76296 +
76297 +/****************************************************************
76298 + * Routine: CreateNewBlock
76299 + *
76300 + * Description:
76301 + * Initializes a new memory block of "size" bytes and started
76302 + * from "base" address.
76303 + *
76304 + * Arguments:
76305 + * base - base address of the memory block
76306 + * size - size of the memory block
76307 + *
76308 + * Return value:
76309 + * A pointer to new created structure returned on success;
76310 + * Otherwise, NULL.
76311 + ****************************************************************/
76312 +static t_MemBlock * CreateNewBlock(uint64_t base, uint64_t size)
76313 +{
76314 + t_MemBlock *p_MemBlock;
76315 +
76316 + p_MemBlock = (t_MemBlock *)XX_Malloc(sizeof(t_MemBlock));
76317 + if ( !p_MemBlock )
76318 + {
76319 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76320 + return NULL;
76321 + }
76322 +
76323 + p_MemBlock->base = base;
76324 + p_MemBlock->end = base+size;
76325 + p_MemBlock->p_Next = 0;
76326 +
76327 + return p_MemBlock;
76328 +}
76329 +
76330 +/****************************************************************
76331 + * Routine: CreateFreeBlock
76332 + *
76333 + * Description:
76334 + * Initializes a new free block of of "size" bytes and
76335 + * started from "base" address.
76336 + *
76337 + * Arguments:
76338 + * base - base address of the free block
76339 + * size - size of the free block
76340 + *
76341 + * Return value:
76342 + * A pointer to new created structure returned on success;
76343 + * Otherwise, NULL.
76344 + ****************************************************************/
76345 +static t_FreeBlock * CreateFreeBlock(uint64_t base, uint64_t size)
76346 +{
76347 + t_FreeBlock *p_FreeBlock;
76348 +
76349 + p_FreeBlock = (t_FreeBlock *)XX_Malloc(sizeof(t_FreeBlock));
76350 + if ( !p_FreeBlock )
76351 + {
76352 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76353 + return NULL;
76354 + }
76355 +
76356 + p_FreeBlock->base = base;
76357 + p_FreeBlock->end = base + size;
76358 + p_FreeBlock->p_Next = 0;
76359 +
76360 + return p_FreeBlock;
76361 +}
76362 +
76363 +/****************************************************************
76364 + * Routine: AddFree
76365 + *
76366 + * Description:
76367 + * Adds a new free block to the free lists. It updates each
76368 + * free list to include a new free block.
76369 + * Note, that all free block in each free list are ordered
76370 + * by their base address.
76371 + *
76372 + * Arguments:
76373 + * p_MM - pointer to the MM object
76374 + * base - base address of a given free block
76375 + * end - end address of a given free block
76376 + *
76377 + * Return value:
76378 + *
76379 + *
76380 + ****************************************************************/
76381 +static t_Error AddFree(t_MM *p_MM, uint64_t base, uint64_t end)
76382 +{
76383 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
76384 + uint64_t alignment;
76385 + uint64_t alignBase;
76386 + int i;
76387 +
76388 + /* Updates free lists to include a just released block */
76389 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76390 + {
76391 + p_PrevB = p_NewB = 0;
76392 + p_CurrB = p_MM->freeBlocks[i];
76393 +
76394 + alignment = (uint64_t)(0x1 << i);
76395 + alignBase = MAKE_ALIGNED(base, alignment);
76396 +
76397 + /* Goes to the next free list if there is no block to free */
76398 + if (alignBase >= end)
76399 + continue;
76400 +
76401 + /* Looks for a free block that should be updated */
76402 + while ( p_CurrB )
76403 + {
76404 + if ( alignBase <= p_CurrB->end )
76405 + {
76406 + if ( end > p_CurrB->end )
76407 + {
76408 + t_FreeBlock *p_NextB;
76409 + while ( p_CurrB->p_Next && end > p_CurrB->p_Next->end )
76410 + {
76411 + p_NextB = p_CurrB->p_Next;
76412 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
76413 + XX_Free(p_NextB);
76414 + }
76415 +
76416 + p_NextB = p_CurrB->p_Next;
76417 + if ( !p_NextB || (p_NextB && end < p_NextB->base) )
76418 + {
76419 + p_CurrB->end = end;
76420 + }
76421 + else
76422 + {
76423 + p_CurrB->end = p_NextB->end;
76424 + p_CurrB->p_Next = p_NextB->p_Next;
76425 + XX_Free(p_NextB);
76426 + }
76427 + }
76428 + else if ( (end < p_CurrB->base) && ((end-alignBase) >= alignment) )
76429 + {
76430 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
76431 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76432 +
76433 + p_NewB->p_Next = p_CurrB;
76434 + if (p_PrevB)
76435 + p_PrevB->p_Next = p_NewB;
76436 + else
76437 + p_MM->freeBlocks[i] = p_NewB;
76438 + break;
76439 + }
76440 +
76441 + if ((alignBase < p_CurrB->base) && (end >= p_CurrB->base))
76442 + {
76443 + p_CurrB->base = alignBase;
76444 + }
76445 +
76446 + /* if size of the free block is less then alignment
76447 + * deletes that free block from the free list. */
76448 + if ( (p_CurrB->end - p_CurrB->base) < alignment)
76449 + {
76450 + if ( p_PrevB )
76451 + p_PrevB->p_Next = p_CurrB->p_Next;
76452 + else
76453 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
76454 + XX_Free(p_CurrB);
76455 + p_CurrB = NULL;
76456 + }
76457 + break;
76458 + }
76459 + else
76460 + {
76461 + p_PrevB = p_CurrB;
76462 + p_CurrB = p_CurrB->p_Next;
76463 + }
76464 + }
76465 +
76466 + /* If no free block found to be updated, insert a new free block
76467 + * to the end of the free list.
76468 + */
76469 + if ( !p_CurrB && ((((uint64_t)(end-base)) & ((uint64_t)(alignment-1))) == 0) )
76470 + {
76471 + if ((p_NewB = CreateFreeBlock(alignBase, end-base)) == NULL)
76472 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76473 +
76474 + if (p_PrevB)
76475 + p_PrevB->p_Next = p_NewB;
76476 + else
76477 + p_MM->freeBlocks[i] = p_NewB;
76478 + }
76479 +
76480 + /* Update boundaries of the new free block */
76481 + if ((alignment == 1) && !p_NewB)
76482 + {
76483 + if ( p_CurrB && base > p_CurrB->base )
76484 + base = p_CurrB->base;
76485 + if ( p_CurrB && end < p_CurrB->end )
76486 + end = p_CurrB->end;
76487 + }
76488 + }
76489 +
76490 + return (E_OK);
76491 +}
76492 +
76493 +/****************************************************************
76494 + * Routine: CutFree
76495 + *
76496 + * Description:
76497 + * Cuts a free block from holdBase to holdEnd from the free lists.
76498 + * That is, it updates all free lists of the MM object do
76499 + * not include a block of memory from holdBase to holdEnd.
76500 + * For each free lists it seek for a free block that holds
76501 + * either holdBase or holdEnd. If such block is found it updates it.
76502 + *
76503 + * Arguments:
76504 + * p_MM - pointer to the MM object
76505 + * holdBase - base address of the allocated block
76506 + * holdEnd - end address of the allocated block
76507 + *
76508 + * Return value:
76509 + * E_OK is returned on success,
76510 + * otherwise returns an error code.
76511 + *
76512 + ****************************************************************/
76513 +static t_Error CutFree(t_MM *p_MM, uint64_t holdBase, uint64_t holdEnd)
76514 +{
76515 + t_FreeBlock *p_PrevB, *p_CurrB, *p_NewB;
76516 + uint64_t alignBase, base, end;
76517 + uint64_t alignment;
76518 + int i;
76519 +
76520 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76521 + {
76522 + p_PrevB = p_NewB = 0;
76523 + p_CurrB = p_MM->freeBlocks[i];
76524 +
76525 + alignment = (uint64_t)(0x1 << i);
76526 + alignBase = MAKE_ALIGNED(holdEnd, alignment);
76527 +
76528 + while ( p_CurrB )
76529 + {
76530 + base = p_CurrB->base;
76531 + end = p_CurrB->end;
76532 +
76533 + if ( (holdBase <= base) && (holdEnd <= end) && (holdEnd > base) )
76534 + {
76535 + if ( alignBase >= end ||
76536 + (alignBase < end && ((end-alignBase) < alignment)) )
76537 + {
76538 + if (p_PrevB)
76539 + p_PrevB->p_Next = p_CurrB->p_Next;
76540 + else
76541 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
76542 + XX_Free(p_CurrB);
76543 + }
76544 + else
76545 + {
76546 + p_CurrB->base = alignBase;
76547 + }
76548 + break;
76549 + }
76550 + else if ( (holdBase > base) && (holdEnd <= end) )
76551 + {
76552 + if ( (holdBase-base) >= alignment )
76553 + {
76554 + if ( (alignBase < end) && ((end-alignBase) >= alignment) )
76555 + {
76556 + if ((p_NewB = CreateFreeBlock(alignBase, end-alignBase)) == NULL)
76557 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76558 + p_NewB->p_Next = p_CurrB->p_Next;
76559 + p_CurrB->p_Next = p_NewB;
76560 + }
76561 + p_CurrB->end = holdBase;
76562 + }
76563 + else if ( (alignBase < end) && ((end-alignBase) >= alignment) )
76564 + {
76565 + p_CurrB->base = alignBase;
76566 + }
76567 + else
76568 + {
76569 + if (p_PrevB)
76570 + p_PrevB->p_Next = p_CurrB->p_Next;
76571 + else
76572 + p_MM->freeBlocks[i] = p_CurrB->p_Next;
76573 + XX_Free(p_CurrB);
76574 + }
76575 + break;
76576 + }
76577 + else
76578 + {
76579 + p_PrevB = p_CurrB;
76580 + p_CurrB = p_CurrB->p_Next;
76581 + }
76582 + }
76583 + }
76584 +
76585 + return (E_OK);
76586 +}
76587 +
76588 +/****************************************************************
76589 + * Routine: AddBusy
76590 + *
76591 + * Description:
76592 + * Adds a new busy block to the list of busy blocks. Note,
76593 + * that all busy blocks are ordered by their base address in
76594 + * the busy list.
76595 + *
76596 + * Arguments:
76597 + * MM - handler to the MM object
76598 + * p_NewBusyB - pointer to the a busy block
76599 + *
76600 + * Return value:
76601 + * None.
76602 + *
76603 + ****************************************************************/
76604 +static void AddBusy(t_MM *p_MM, t_BusyBlock *p_NewBusyB)
76605 +{
76606 + t_BusyBlock *p_CurrBusyB, *p_PrevBusyB;
76607 +
76608 + /* finds a place of a new busy block in the list of busy blocks */
76609 + p_PrevBusyB = 0;
76610 + p_CurrBusyB = p_MM->busyBlocks;
76611 +
76612 + while ( p_CurrBusyB && p_NewBusyB->base > p_CurrBusyB->base )
76613 + {
76614 + p_PrevBusyB = p_CurrBusyB;
76615 + p_CurrBusyB = p_CurrBusyB->p_Next;
76616 + }
76617 +
76618 + /* insert the new busy block into the list of busy blocks */
76619 + if ( p_CurrBusyB )
76620 + p_NewBusyB->p_Next = p_CurrBusyB;
76621 + if ( p_PrevBusyB )
76622 + p_PrevBusyB->p_Next = p_NewBusyB;
76623 + else
76624 + p_MM->busyBlocks = p_NewBusyB;
76625 +}
76626 +
76627 +/****************************************************************
76628 + * Routine: CutBusy
76629 + *
76630 + * Description:
76631 + * Cuts a block from base to end from the list of busy blocks.
76632 + * This is done by updating the list of busy blocks do not
76633 + * include a given block, that block is going to be free. If a
76634 + * given block is a part of some other busy block, so that
76635 + * busy block is updated. If there are number of busy blocks
76636 + * included in the given block, so all that blocks are removed
76637 + * from the busy list and the end blocks are updated.
76638 + * If the given block devides some block into two parts, a new
76639 + * busy block is added to the busy list.
76640 + *
76641 + * Arguments:
76642 + * p_MM - pointer to the MM object
76643 + * base - base address of a given busy block
76644 + * end - end address of a given busy block
76645 + *
76646 + * Return value:
76647 + * E_OK on success, E_NOMEMORY otherwise.
76648 + *
76649 + ****************************************************************/
76650 +static t_Error CutBusy(t_MM *p_MM, uint64_t base, uint64_t end)
76651 +{
76652 + t_BusyBlock *p_CurrB, *p_PrevB, *p_NewB;
76653 +
76654 + p_CurrB = p_MM->busyBlocks;
76655 + p_PrevB = p_NewB = 0;
76656 +
76657 + while ( p_CurrB )
76658 + {
76659 + if ( base < p_CurrB->end )
76660 + {
76661 + if ( end > p_CurrB->end )
76662 + {
76663 + t_BusyBlock *p_NextB;
76664 + while ( p_CurrB->p_Next && end >= p_CurrB->p_Next->end )
76665 + {
76666 + p_NextB = p_CurrB->p_Next;
76667 + p_CurrB->p_Next = p_CurrB->p_Next->p_Next;
76668 + XX_Free(p_NextB);
76669 + }
76670 +
76671 + p_NextB = p_CurrB->p_Next;
76672 + if ( p_NextB && end > p_NextB->base )
76673 + {
76674 + p_NextB->base = end;
76675 + }
76676 + }
76677 +
76678 + if ( base <= p_CurrB->base )
76679 + {
76680 + if ( end < p_CurrB->end && end > p_CurrB->base )
76681 + {
76682 + p_CurrB->base = end;
76683 + }
76684 + else if ( end >= p_CurrB->end )
76685 + {
76686 + if ( p_PrevB )
76687 + p_PrevB->p_Next = p_CurrB->p_Next;
76688 + else
76689 + p_MM->busyBlocks = p_CurrB->p_Next;
76690 + XX_Free(p_CurrB);
76691 + }
76692 + }
76693 + else
76694 + {
76695 + if ( end < p_CurrB->end && end > p_CurrB->base )
76696 + {
76697 + if ((p_NewB = CreateBusyBlock(end,
76698 + p_CurrB->end-end,
76699 + p_CurrB->name)) == NULL)
76700 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76701 + p_NewB->p_Next = p_CurrB->p_Next;
76702 + p_CurrB->p_Next = p_NewB;
76703 + }
76704 + p_CurrB->end = base;
76705 + }
76706 + break;
76707 + }
76708 + else
76709 + {
76710 + p_PrevB = p_CurrB;
76711 + p_CurrB = p_CurrB->p_Next;
76712 + }
76713 + }
76714 +
76715 + return (E_OK);
76716 +}
76717 +
76718 +/****************************************************************
76719 + * Routine: MmGetGreaterAlignment
76720 + *
76721 + * Description:
76722 + * Allocates a block of memory according to the given size
76723 + * and the alignment. That routine is called from the MM_Get
76724 + * routine if the required alignment is greater then MM_MAX_ALIGNMENT.
76725 + * In that case, it goes over free blocks of 64 byte align list
76726 + * and checks if it has the required size of bytes of the required
76727 + * alignment. If no blocks found returns ILLEGAL_BASE.
76728 + * After the block is found and data is allocated, it calls
76729 + * the internal CutFree routine to update all free lists
76730 + * do not include a just allocated block. Of course, each
76731 + * free list contains a free blocks with the same alignment.
76732 + * It is also creates a busy block that holds
76733 + * information about an allocated block.
76734 + *
76735 + * Arguments:
76736 + * MM - handle to the MM object
76737 + * size - size of the MM
76738 + * alignment - index as a power of two defines
76739 + * a required alignment that is greater then 64.
76740 + * name - the name that specifies an allocated block.
76741 + *
76742 + * Return value:
76743 + * base address of an allocated block.
76744 + * ILLEGAL_BASE if can't allocate a block
76745 + *
76746 + ****************************************************************/
76747 +static uint64_t MmGetGreaterAlignment(t_MM *p_MM, uint64_t size, uint64_t alignment, char* name)
76748 +{
76749 + t_FreeBlock *p_FreeB;
76750 + t_BusyBlock *p_NewBusyB;
76751 + uint64_t holdBase, holdEnd, alignBase = 0;
76752 +
76753 + /* goes over free blocks of the 64 byte alignment list
76754 + and look for a block of the suitable size and
76755 + base address according to the alignment. */
76756 + p_FreeB = p_MM->freeBlocks[MM_MAX_ALIGNMENT];
76757 +
76758 + while ( p_FreeB )
76759 + {
76760 + alignBase = MAKE_ALIGNED(p_FreeB->base, alignment);
76761 +
76762 + /* the block is found if the aligned base inside the block
76763 + * and has the anough size. */
76764 + if ( alignBase >= p_FreeB->base &&
76765 + alignBase < p_FreeB->end &&
76766 + size <= (p_FreeB->end - alignBase) )
76767 + break;
76768 + else
76769 + p_FreeB = p_FreeB->p_Next;
76770 + }
76771 +
76772 + /* If such block isn't found */
76773 + if ( !p_FreeB )
76774 + return (uint64_t)(ILLEGAL_BASE);
76775 +
76776 + holdBase = alignBase;
76777 + holdEnd = alignBase + size;
76778 +
76779 + /* init a new busy block */
76780 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
76781 + return (uint64_t)(ILLEGAL_BASE);
76782 +
76783 + /* calls Update routine to update a lists of free blocks */
76784 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
76785 + {
76786 + XX_Free(p_NewBusyB);
76787 + return (uint64_t)(ILLEGAL_BASE);
76788 + }
76789 +
76790 + /* insert the new busy block into the list of busy blocks */
76791 + AddBusy ( p_MM, p_NewBusyB );
76792 +
76793 + return (holdBase);
76794 +}
76795 +
76796 +
76797 +/**********************************************************************
76798 + * MM API routines set *
76799 + **********************************************************************/
76800 +
76801 +/*****************************************************************************/
76802 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size)
76803 +{
76804 + t_MM *p_MM;
76805 + uint64_t newBase, newSize;
76806 + int i;
76807 +
76808 + if (!size)
76809 + {
76810 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Size (should be positive)"));
76811 + }
76812 +
76813 + /* Initializes a new MM object */
76814 + p_MM = (t_MM *)XX_Malloc(sizeof(t_MM));
76815 + if (!p_MM)
76816 + {
76817 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76818 + }
76819 +
76820 + p_MM->h_Spinlock = XX_InitSpinlock();
76821 + if (!p_MM->h_Spinlock)
76822 + {
76823 + XX_Free(p_MM);
76824 + RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MM spinlock!"));
76825 + }
76826 +
76827 + /* Initializes counter of free memory to total size */
76828 + p_MM->freeMemSize = size;
76829 +
76830 + /* A busy list is empty */
76831 + p_MM->busyBlocks = 0;
76832 +
76833 + /* Initializes a new memory block */
76834 + if ((p_MM->memBlocks = CreateNewBlock(base, size)) == NULL)
76835 + {
76836 + MM_Free(p_MM);
76837 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76838 + }
76839 +
76840 + /* Initializes a new free block for each free list*/
76841 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76842 + {
76843 + newBase = MAKE_ALIGNED( base, (0x1 << i) );
76844 + newSize = size - (newBase - base);
76845 +
76846 + if ((p_MM->freeBlocks[i] = CreateFreeBlock(newBase, newSize)) == NULL)
76847 + {
76848 + MM_Free(p_MM);
76849 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
76850 + }
76851 + }
76852 +
76853 + *h_MM = p_MM;
76854 +
76855 + return (E_OK);
76856 +}
76857 +
76858 +/*****************************************************************************/
76859 +void MM_Free(t_Handle h_MM)
76860 +{
76861 + t_MM *p_MM = (t_MM *)h_MM;
76862 + t_MemBlock *p_MemBlock;
76863 + t_BusyBlock *p_BusyBlock;
76864 + t_FreeBlock *p_FreeBlock;
76865 + void *p_Block;
76866 + int i;
76867 +
76868 + ASSERT_COND(p_MM);
76869 +
76870 + /* release memory allocated for busy blocks */
76871 + p_BusyBlock = p_MM->busyBlocks;
76872 + while ( p_BusyBlock )
76873 + {
76874 + p_Block = p_BusyBlock;
76875 + p_BusyBlock = p_BusyBlock->p_Next;
76876 + XX_Free(p_Block);
76877 + }
76878 +
76879 + /* release memory allocated for free blocks */
76880 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
76881 + {
76882 + p_FreeBlock = p_MM->freeBlocks[i];
76883 + while ( p_FreeBlock )
76884 + {
76885 + p_Block = p_FreeBlock;
76886 + p_FreeBlock = p_FreeBlock->p_Next;
76887 + XX_Free(p_Block);
76888 + }
76889 + }
76890 +
76891 + /* release memory allocated for memory blocks */
76892 + p_MemBlock = p_MM->memBlocks;
76893 + while ( p_MemBlock )
76894 + {
76895 + p_Block = p_MemBlock;
76896 + p_MemBlock = p_MemBlock->p_Next;
76897 + XX_Free(p_Block);
76898 + }
76899 +
76900 + if (p_MM->h_Spinlock)
76901 + XX_FreeSpinlock(p_MM->h_Spinlock);
76902 +
76903 + /* release memory allocated for MM object itself */
76904 + XX_Free(p_MM);
76905 +}
76906 +
76907 +/*****************************************************************************/
76908 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char* name)
76909 +{
76910 + t_MM *p_MM = (t_MM *)h_MM;
76911 + t_FreeBlock *p_FreeB;
76912 + t_BusyBlock *p_NewBusyB;
76913 + uint64_t holdBase, holdEnd, j, i = 0;
76914 + uint32_t intFlags;
76915 +
76916 + SANITY_CHECK_RETURN_VALUE(p_MM, E_INVALID_HANDLE, (uint64_t)ILLEGAL_BASE);
76917 +
76918 + /* checks that alignment value is greater then zero */
76919 + if (alignment == 0)
76920 + {
76921 + alignment = 1;
76922 + }
76923 +
76924 + j = alignment;
76925 +
76926 + /* checks if alignment is a power of two, if it correct and if the
76927 + required size is multiple of the given alignment. */
76928 + while ((j & 0x1) == 0)
76929 + {
76930 + i++;
76931 + j = j >> 1;
76932 + }
76933 +
76934 + /* if the given alignment isn't power of two, returns an error */
76935 + if (j != 1)
76936 + {
76937 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("alignment (should be power of 2)"));
76938 + return (uint64_t)ILLEGAL_BASE;
76939 + }
76940 +
76941 + if (i > MM_MAX_ALIGNMENT)
76942 + {
76943 + return (MmGetGreaterAlignment(p_MM, size, alignment, name));
76944 + }
76945 +
76946 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
76947 + /* look for a block of the size greater or equal to the required size. */
76948 + p_FreeB = p_MM->freeBlocks[i];
76949 + while ( p_FreeB && (p_FreeB->end - p_FreeB->base) < size )
76950 + p_FreeB = p_FreeB->p_Next;
76951 +
76952 + /* If such block is found */
76953 + if ( !p_FreeB )
76954 + {
76955 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76956 + return (uint64_t)(ILLEGAL_BASE);
76957 + }
76958 +
76959 + holdBase = p_FreeB->base;
76960 + holdEnd = holdBase + size;
76961 +
76962 + /* init a new busy block */
76963 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
76964 + {
76965 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76966 + return (uint64_t)(ILLEGAL_BASE);
76967 + }
76968 +
76969 + /* calls Update routine to update a lists of free blocks */
76970 + if ( CutFree ( p_MM, holdBase, holdEnd ) != E_OK )
76971 + {
76972 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76973 + XX_Free(p_NewBusyB);
76974 + return (uint64_t)(ILLEGAL_BASE);
76975 + }
76976 +
76977 + /* Decreasing the allocated memory size from free memory size */
76978 + p_MM->freeMemSize -= size;
76979 +
76980 + /* insert the new busy block into the list of busy blocks */
76981 + AddBusy ( p_MM, p_NewBusyB );
76982 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
76983 +
76984 + return (holdBase);
76985 +}
76986 +
76987 +/*****************************************************************************/
76988 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char* name)
76989 +{
76990 + t_MM *p_MM = (t_MM *)h_MM;
76991 + t_FreeBlock *p_FreeB;
76992 + t_BusyBlock *p_NewBusyB;
76993 + uint32_t intFlags;
76994 + bool blockIsFree = FALSE;
76995 +
76996 + ASSERT_COND(p_MM);
76997 +
76998 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
76999 + p_FreeB = p_MM->freeBlocks[0]; /* The biggest free blocks are in the
77000 + free list with alignment 1 */
77001 +
77002 + while ( p_FreeB )
77003 + {
77004 + if ( base >= p_FreeB->base && (base+size) <= p_FreeB->end )
77005 + {
77006 + blockIsFree = TRUE;
77007 + break;
77008 + }
77009 + else
77010 + p_FreeB = p_FreeB->p_Next;
77011 + }
77012 +
77013 + if ( !blockIsFree )
77014 + {
77015 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77016 + return (uint64_t)(ILLEGAL_BASE);
77017 + }
77018 +
77019 + /* init a new busy block */
77020 + if ((p_NewBusyB = CreateBusyBlock(base, size, name)) == NULL)
77021 + {
77022 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77023 + return (uint64_t)(ILLEGAL_BASE);
77024 + }
77025 +
77026 + /* calls Update routine to update a lists of free blocks */
77027 + if ( CutFree ( p_MM, base, base+size ) != E_OK )
77028 + {
77029 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77030 + XX_Free(p_NewBusyB);
77031 + return (uint64_t)(ILLEGAL_BASE);
77032 + }
77033 +
77034 + /* Decreasing the allocated memory size from free memory size */
77035 + p_MM->freeMemSize -= size;
77036 +
77037 + /* insert the new busy block into the list of busy blocks */
77038 + AddBusy ( p_MM, p_NewBusyB );
77039 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77040 +
77041 + return (base);
77042 +}
77043 +
77044 +/*****************************************************************************/
77045 +uint64_t MM_GetForceMin(t_Handle h_MM, uint64_t size, uint64_t alignment, uint64_t min, char* name)
77046 +{
77047 + t_MM *p_MM = (t_MM *)h_MM;
77048 + t_FreeBlock *p_FreeB;
77049 + t_BusyBlock *p_NewBusyB;
77050 + uint64_t holdBase, holdEnd, j = alignment, i=0;
77051 + uint32_t intFlags;
77052 +
77053 + ASSERT_COND(p_MM);
77054 +
77055 + /* checks if alignment is a power of two, if it correct and if the
77056 + required size is multiple of the given alignment. */
77057 + while ((j & 0x1) == 0)
77058 + {
77059 + i++;
77060 + j = j >> 1;
77061 + }
77062 +
77063 + if ( (j != 1) || (i > MM_MAX_ALIGNMENT) )
77064 + {
77065 + return (uint64_t)(ILLEGAL_BASE);
77066 + }
77067 +
77068 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
77069 + p_FreeB = p_MM->freeBlocks[i];
77070 +
77071 + /* look for the first block that contains the minimum
77072 + base address. If the whole required size may be fit
77073 + into it, use that block, otherwise look for the next
77074 + block of size greater or equal to the required size. */
77075 + while ( p_FreeB && (min >= p_FreeB->end))
77076 + p_FreeB = p_FreeB->p_Next;
77077 +
77078 + /* If such block is found */
77079 + if ( !p_FreeB )
77080 + {
77081 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77082 + return (uint64_t)(ILLEGAL_BASE);
77083 + }
77084 +
77085 + /* if this block is large enough, use this block */
77086 + holdBase = ( min <= p_FreeB->base ) ? p_FreeB->base : min;
77087 + if ((holdBase + size) <= p_FreeB->end )
77088 + {
77089 + holdEnd = holdBase + size;
77090 + }
77091 + else
77092 + {
77093 + p_FreeB = p_FreeB->p_Next;
77094 + while ( p_FreeB && ((p_FreeB->end - p_FreeB->base) < size) )
77095 + p_FreeB = p_FreeB->p_Next;
77096 +
77097 + /* If such block is found */
77098 + if ( !p_FreeB )
77099 + {
77100 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77101 + return (uint64_t)(ILLEGAL_BASE);
77102 + }
77103 +
77104 + holdBase = p_FreeB->base;
77105 + holdEnd = holdBase + size;
77106 + }
77107 +
77108 + /* init a new busy block */
77109 + if ((p_NewBusyB = CreateBusyBlock(holdBase, size, name)) == NULL)
77110 + {
77111 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77112 + return (uint64_t)(ILLEGAL_BASE);
77113 + }
77114 +
77115 + /* calls Update routine to update a lists of free blocks */
77116 + if ( CutFree( p_MM, holdBase, holdEnd ) != E_OK )
77117 + {
77118 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77119 + XX_Free(p_NewBusyB);
77120 + return (uint64_t)(ILLEGAL_BASE);
77121 + }
77122 +
77123 + /* Decreasing the allocated memory size from free memory size */
77124 + p_MM->freeMemSize -= size;
77125 +
77126 + /* insert the new busy block into the list of busy blocks */
77127 + AddBusy( p_MM, p_NewBusyB );
77128 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77129 +
77130 + return (holdBase);
77131 +}
77132 +
77133 +/*****************************************************************************/
77134 +uint64_t MM_Put(t_Handle h_MM, uint64_t base)
77135 +{
77136 + t_MM *p_MM = (t_MM *)h_MM;
77137 + t_BusyBlock *p_BusyB, *p_PrevBusyB;
77138 + uint64_t size;
77139 + uint32_t intFlags;
77140 +
77141 + ASSERT_COND(p_MM);
77142 +
77143 + /* Look for a busy block that have the given base value.
77144 + * That block will be returned back to the memory.
77145 + */
77146 + p_PrevBusyB = 0;
77147 +
77148 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
77149 + p_BusyB = p_MM->busyBlocks;
77150 + while ( p_BusyB && base != p_BusyB->base )
77151 + {
77152 + p_PrevBusyB = p_BusyB;
77153 + p_BusyB = p_BusyB->p_Next;
77154 + }
77155 +
77156 + if ( !p_BusyB )
77157 + {
77158 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77159 + return (uint64_t)(0);
77160 + }
77161 +
77162 + if ( AddFree( p_MM, p_BusyB->base, p_BusyB->end ) != E_OK )
77163 + {
77164 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77165 + return (uint64_t)(0);
77166 + }
77167 +
77168 + /* removes a busy block form the list of busy blocks */
77169 + if ( p_PrevBusyB )
77170 + p_PrevBusyB->p_Next = p_BusyB->p_Next;
77171 + else
77172 + p_MM->busyBlocks = p_BusyB->p_Next;
77173 +
77174 + size = p_BusyB->end - p_BusyB->base;
77175 +
77176 + /* Adding the deallocated memory size to free memory size */
77177 + p_MM->freeMemSize += size;
77178 +
77179 + XX_Free(p_BusyB);
77180 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77181 +
77182 + return (size);
77183 +}
77184 +
77185 +/*****************************************************************************/
77186 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size)
77187 +{
77188 + t_MM *p_MM = (t_MM *)h_MM;
77189 + uint64_t end = base + size;
77190 + uint32_t intFlags;
77191 +
77192 + ASSERT_COND(p_MM);
77193 +
77194 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
77195 +
77196 + if ( CutBusy( p_MM, base, end ) != E_OK )
77197 + {
77198 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77199 + return (uint64_t)(0);
77200 + }
77201 +
77202 + if ( AddFree ( p_MM, base, end ) != E_OK )
77203 + {
77204 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77205 + return (uint64_t)(0);
77206 + }
77207 +
77208 + /* Adding the deallocated memory size to free memory size */
77209 + p_MM->freeMemSize += size;
77210 +
77211 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77212 +
77213 + return (size);
77214 +}
77215 +
77216 +/*****************************************************************************/
77217 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size)
77218 +{
77219 + t_MM *p_MM = (t_MM *)h_MM;
77220 + t_MemBlock *p_MemB, *p_NewMemB;
77221 + t_Error errCode;
77222 + uint32_t intFlags;
77223 +
77224 + ASSERT_COND(p_MM);
77225 +
77226 + /* find a last block in the list of memory blocks to insert a new
77227 + * memory block
77228 + */
77229 + intFlags = XX_LockIntrSpinlock(p_MM->h_Spinlock);
77230 +
77231 + p_MemB = p_MM->memBlocks;
77232 + while ( p_MemB->p_Next )
77233 + {
77234 + if ( base >= p_MemB->base && base < p_MemB->end )
77235 + {
77236 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77237 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
77238 + }
77239 + p_MemB = p_MemB->p_Next;
77240 + }
77241 + /* check for a last memory block */
77242 + if ( base >= p_MemB->base && base < p_MemB->end )
77243 + {
77244 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77245 + RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
77246 + }
77247 +
77248 + /* create a new memory block */
77249 + if ((p_NewMemB = CreateNewBlock(base, size)) == NULL)
77250 + {
77251 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77252 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
77253 + }
77254 +
77255 + /* append a new memory block to the end of the list of memory blocks */
77256 + p_MemB->p_Next = p_NewMemB;
77257 +
77258 + /* add a new free block to the free lists */
77259 + errCode = AddFree(p_MM, base, base+size);
77260 + if (errCode)
77261 + {
77262 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77263 + p_MemB->p_Next = 0;
77264 + XX_Free(p_NewMemB);
77265 + return ((t_Error)errCode);
77266 + }
77267 +
77268 + /* Adding the new block size to free memory size */
77269 + p_MM->freeMemSize += size;
77270 +
77271 + XX_UnlockIntrSpinlock(p_MM->h_Spinlock, intFlags);
77272 +
77273 + return (E_OK);
77274 +}
77275 +
77276 +/*****************************************************************************/
77277 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index)
77278 +{
77279 + t_MM *p_MM = (t_MM*)h_MM;
77280 + t_MemBlock *p_MemBlock;
77281 + int i;
77282 +
77283 + ASSERT_COND(p_MM);
77284 +
77285 + p_MemBlock = p_MM->memBlocks;
77286 + for (i=0; i < index; i++)
77287 + p_MemBlock = p_MemBlock->p_Next;
77288 +
77289 + if ( p_MemBlock )
77290 + return (p_MemBlock->base);
77291 + else
77292 + return (uint64_t)ILLEGAL_BASE;
77293 +}
77294 +
77295 +/*****************************************************************************/
77296 +uint64_t MM_GetBase(t_Handle h_MM)
77297 +{
77298 + t_MM *p_MM = (t_MM*)h_MM;
77299 + t_MemBlock *p_MemBlock;
77300 +
77301 + ASSERT_COND(p_MM);
77302 +
77303 + p_MemBlock = p_MM->memBlocks;
77304 + return p_MemBlock->base;
77305 +}
77306 +
77307 +/*****************************************************************************/
77308 +bool MM_InRange(t_Handle h_MM, uint64_t addr)
77309 +{
77310 + t_MM *p_MM = (t_MM*)h_MM;
77311 + t_MemBlock *p_MemBlock;
77312 +
77313 + ASSERT_COND(p_MM);
77314 +
77315 + p_MemBlock = p_MM->memBlocks;
77316 +
77317 + if ((addr >= p_MemBlock->base) && (addr < p_MemBlock->end))
77318 + return TRUE;
77319 + else
77320 + return FALSE;
77321 +}
77322 +
77323 +/*****************************************************************************/
77324 +uint64_t MM_GetFreeMemSize(t_Handle h_MM)
77325 +{
77326 + t_MM *p_MM = (t_MM*)h_MM;
77327 +
77328 + ASSERT_COND(p_MM);
77329 +
77330 + return p_MM->freeMemSize;
77331 +}
77332 +
77333 +/*****************************************************************************/
77334 +void MM_Dump(t_Handle h_MM)
77335 +{
77336 + t_MM *p_MM = (t_MM *)h_MM;
77337 + t_FreeBlock *p_FreeB;
77338 + t_BusyBlock *p_BusyB;
77339 + int i;
77340 +
77341 + p_BusyB = p_MM->busyBlocks;
77342 + XX_Print("List of busy blocks:\n");
77343 + while (p_BusyB)
77344 + {
77345 + XX_Print("\t0x%p: (%s: b=0x%llx, e=0x%llx)\n", p_BusyB, p_BusyB->name, p_BusyB->base, p_BusyB->end );
77346 + p_BusyB = p_BusyB->p_Next;
77347 + }
77348 +
77349 + XX_Print("\nLists of free blocks according to alignment:\n");
77350 + for (i=0; i <= MM_MAX_ALIGNMENT; i++)
77351 + {
77352 + XX_Print("%d alignment:\n", (0x1 << i));
77353 + p_FreeB = p_MM->freeBlocks[i];
77354 + while (p_FreeB)
77355 + {
77356 + XX_Print("\t0x%p: (b=0x%llx, e=0x%llx)\n", p_FreeB, p_FreeB->base, p_FreeB->end);
77357 + p_FreeB = p_FreeB->p_Next;
77358 + }
77359 + XX_Print("\n");
77360 + }
77361 +}
77362 --- /dev/null
77363 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/mm.h
77364 @@ -0,0 +1,105 @@
77365 +/*
77366 + * Copyright 2008-2012 Freescale Semiconductor Inc.
77367 + *
77368 + * Redistribution and use in source and binary forms, with or without
77369 + * modification, are permitted provided that the following conditions are met:
77370 + * * Redistributions of source code must retain the above copyright
77371 + * notice, this list of conditions and the following disclaimer.
77372 + * * Redistributions in binary form must reproduce the above copyright
77373 + * notice, this list of conditions and the following disclaimer in the
77374 + * documentation and/or other materials provided with the distribution.
77375 + * * Neither the name of Freescale Semiconductor nor the
77376 + * names of its contributors may be used to endorse or promote products
77377 + * derived from this software without specific prior written permission.
77378 + *
77379 + *
77380 + * ALTERNATIVELY, this software may be distributed under the terms of the
77381 + * GNU General Public License ("GPL") as published by the Free Software
77382 + * Foundation, either version 2 of that License or (at your option) any
77383 + * later version.
77384 + *
77385 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77386 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77387 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77388 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77389 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77390 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77391 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77392 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77393 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77394 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77395 + */
77396 +
77397 +
77398 +/****************************************************************
77399 + *
77400 + * File: mm.h
77401 + *
77402 + *
77403 + * Description:
77404 + * MM (Memory Management) object definitions.
77405 + * It also includes definitions of the Free Block, Busy Block
77406 + * and Memory Block structures used by the MM object.
77407 + *
77408 + ****************************************************************/
77409 +
77410 +#ifndef __MM_H
77411 +#define __MM_H
77412 +
77413 +
77414 +#include "mm_ext.h"
77415 +
77416 +#define __ERR_MODULE__ MODULE_MM
77417 +
77418 +
77419 +#define MAKE_ALIGNED(addr, align) \
77420 + (((uint64_t)(addr) + ((align) - 1)) & (~(((uint64_t)align) - 1)))
77421 +
77422 +
77423 +/* t_MemBlock data structure defines parameters of the Memory Block */
77424 +typedef struct t_MemBlock
77425 +{
77426 + struct t_MemBlock *p_Next; /* Pointer to the next memory block */
77427 +
77428 + uint64_t base; /* Base address of the memory block */
77429 + uint64_t end; /* End address of the memory block */
77430 +} t_MemBlock;
77431 +
77432 +
77433 +/* t_FreeBlock data structure defines parameters of the Free Block */
77434 +typedef struct t_FreeBlock
77435 +{
77436 + struct t_FreeBlock *p_Next; /* Pointer to the next free block */
77437 +
77438 + uint64_t base; /* Base address of the block */
77439 + uint64_t end; /* End address of the block */
77440 +} t_FreeBlock;
77441 +
77442 +
77443 +/* t_BusyBlock data structure defines parameters of the Busy Block */
77444 +typedef struct t_BusyBlock
77445 +{
77446 + struct t_BusyBlock *p_Next; /* Pointer to the next free block */
77447 +
77448 + uint64_t base; /* Base address of the block */
77449 + uint64_t end; /* End address of the block */
77450 + char name[MM_MAX_NAME_LEN]; /* That block of memory was allocated for
77451 + something specified by the Name */
77452 +} t_BusyBlock;
77453 +
77454 +
77455 +/* t_MM data structure defines parameters of the MM object */
77456 +typedef struct t_MM
77457 +{
77458 + t_Handle h_Spinlock;
77459 +
77460 + t_MemBlock *memBlocks; /* List of memory blocks (Memory list) */
77461 + t_BusyBlock *busyBlocks; /* List of busy blocks (Busy list) */
77462 + t_FreeBlock *freeBlocks[MM_MAX_ALIGNMENT + 1];
77463 + /* Alignment lists of free blocks (Free lists) */
77464 +
77465 + uint64_t freeMemSize; /* Total size of free memory (in bytes) */
77466 +} t_MM;
77467 +
77468 +
77469 +#endif /* __MM_H */
77470 --- /dev/null
77471 +++ b/drivers/net/ethernet/freescale/sdk_fman/etc/sprint.c
77472 @@ -0,0 +1,81 @@
77473 +/*
77474 + * Copyright 2008-2012 Freescale Semiconductor Inc.
77475 + *
77476 + * Redistribution and use in source and binary forms, with or without
77477 + * modification, are permitted provided that the following conditions are met:
77478 + * * Redistributions of source code must retain the above copyright
77479 + * notice, this list of conditions and the following disclaimer.
77480 + * * Redistributions in binary form must reproduce the above copyright
77481 + * notice, this list of conditions and the following disclaimer in the
77482 + * documentation and/or other materials provided with the distribution.
77483 + * * Neither the name of Freescale Semiconductor nor the
77484 + * names of its contributors may be used to endorse or promote products
77485 + * derived from this software without specific prior written permission.
77486 + *
77487 + *
77488 + * ALTERNATIVELY, this software may be distributed under the terms of the
77489 + * GNU General Public License ("GPL") as published by the Free Software
77490 + * Foundation, either version 2 of that License or (at your option) any
77491 + * later version.
77492 + *
77493 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77494 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77495 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77496 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77497 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77498 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77499 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77500 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77501 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77502 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77503 + */
77504 +
77505 +
77506 +/*------------------------------------------------------*/
77507 +/* File: sprint.c */
77508 +/* */
77509 +/* Description: */
77510 +/* Debug routines (externals) */
77511 +/*------------------------------------------------------*/
77512 +#include "string_ext.h"
77513 +#include "stdlib_ext.h"
77514 +#include "stdarg_ext.h"
77515 +#include "sprint_ext.h"
77516 +#include "std_ext.h"
77517 +#include "xx_ext.h"
77518 +
77519 +
77520 +int Sprint(char * buf, const char *fmt, ...)
77521 +{
77522 + va_list args;
77523 + int i;
77524 +
77525 + va_start(args, fmt);
77526 + i=vsprintf(buf,fmt,args);
77527 + va_end(args);
77528 + return i;
77529 +}
77530 +
77531 +int Snprint(char * buf, uint32_t size, const char *fmt, ...)
77532 +{
77533 + va_list args;
77534 + int i;
77535 +
77536 + va_start(args, fmt);
77537 + i=vsnprintf(buf,size,fmt,args);
77538 + va_end(args);
77539 + return i;
77540 +}
77541 +
77542 +#ifndef NCSW_VXWORKS
77543 +int Sscan(const char * buf, const char * fmt, ...)
77544 +{
77545 + va_list args;
77546 + int i;
77547 +
77548 + va_start(args,fmt);
77549 + i = vsscanf(buf,fmt,args);
77550 + va_end(args);
77551 + return i;
77552 +}
77553 +#endif /* NCSW_VXWORKS */
77554 --- /dev/null
77555 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3h_dflags.h
77556 @@ -0,0 +1,57 @@
77557 +/*
77558 + * Copyright 2012 Freescale Semiconductor Inc.
77559 + *
77560 + * Redistribution and use in source and binary forms, with or without
77561 + * modification, are permitted provided that the following conditions are met:
77562 + * * Redistributions of source code must retain the above copyright
77563 + * notice, this list of conditions and the following disclaimer.
77564 + * * Redistributions in binary form must reproduce the above copyright
77565 + * notice, this list of conditions and the following disclaimer in the
77566 + * documentation and/or other materials provided with the distribution.
77567 + * * Neither the name of Freescale Semiconductor nor the
77568 + * names of its contributors may be used to endorse or promote products
77569 + * derived from this software without specific prior written permission.
77570 + *
77571 + *
77572 + * ALTERNATIVELY, this software may be distributed under the terms of the
77573 + * GNU General Public License ("GPL") as published by the Free Software
77574 + * Foundation, either version 2 of that License or (at your option) any
77575 + * later version.
77576 + *
77577 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77578 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77579 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77580 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77581 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77582 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77583 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77584 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77585 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77586 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77587 + */
77588 +
77589 +#ifndef __dflags_h
77590 +#define __dflags_h
77591 +
77592 +
77593 +#define NCSW_LINUX
77594 +
77595 +#define T4240
77596 +#define NCSW_PPC_CORE
77597 +
77598 +#define DEBUG_ERRORS 1
77599 +
77600 +#if defined(DEBUG)
77601 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
77602 +
77603 +#define DEBUG_XX_MALLOC
77604 +#define DEBUG_MEM_LEAKS
77605 +
77606 +#else
77607 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
77608 +#endif /* (DEBUG) */
77609 +
77610 +#define REPORT_EVENTS 1
77611 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
77612 +
77613 +#endif /* __dflags_h */
77614 --- /dev/null
77615 +++ b/drivers/net/ethernet/freescale/sdk_fman/fmanv3l_dflags.h
77616 @@ -0,0 +1,56 @@
77617 +/*
77618 + * Copyright 2012 Freescale Semiconductor Inc.
77619 + *
77620 + * Redistribution and use in source and binary forms, with or without
77621 + * modification, are permitted provided that the following conditions are met:
77622 + * * Redistributions of source code must retain the above copyright
77623 + * notice, this list of conditions and the following disclaimer.
77624 + * * Redistributions in binary form must reproduce the above copyright
77625 + * notice, this list of conditions and the following disclaimer in the
77626 + * documentation and/or other materials provided with the distribution.
77627 + * * Neither the name of Freescale Semiconductor nor the
77628 + * names of its contributors may be used to endorse or promote products
77629 + * derived from this software without specific prior written permission.
77630 + *
77631 + *
77632 + * ALTERNATIVELY, this software may be distributed under the terms of the
77633 + * GNU General Public License ("GPL") as published by the Free Software
77634 + * Foundation, either version 2 of that License or (at your option) any
77635 + * later version.
77636 + *
77637 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77638 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77639 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77640 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77641 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77642 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77643 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77644 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77645 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77646 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77647 + */
77648 +
77649 +#ifndef __dflags_h
77650 +#define __dflags_h
77651 +
77652 +
77653 +#define NCSW_LINUX
77654 +
77655 +#define NCSW_PPC_CORE
77656 +
77657 +#define DEBUG_ERRORS 1
77658 +
77659 +#if defined(DEBUG)
77660 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
77661 +
77662 +#define DEBUG_XX_MALLOC
77663 +#define DEBUG_MEM_LEAKS
77664 +
77665 +#else
77666 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
77667 +#endif /* (DEBUG) */
77668 +
77669 +#define REPORT_EVENTS 1
77670 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
77671 +
77672 +#endif /* __dflags_h */
77673 --- /dev/null
77674 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/crc_mac_addr_ext.h
77675 @@ -0,0 +1,364 @@
77676 +/*
77677 + * Copyright 2008-2012 Freescale Semiconductor Inc.
77678 + *
77679 + * Redistribution and use in source and binary forms, with or without
77680 + * modification, are permitted provided that the following conditions are met:
77681 + * * Redistributions of source code must retain the above copyright
77682 + * notice, this list of conditions and the following disclaimer.
77683 + * * Redistributions in binary form must reproduce the above copyright
77684 + * notice, this list of conditions and the following disclaimer in the
77685 + * documentation and/or other materials provided with the distribution.
77686 + * * Neither the name of Freescale Semiconductor nor the
77687 + * names of its contributors may be used to endorse or promote products
77688 + * derived from this software without specific prior written permission.
77689 + *
77690 + *
77691 + * ALTERNATIVELY, this software may be distributed under the terms of the
77692 + * GNU General Public License ("GPL") as published by the Free Software
77693 + * Foundation, either version 2 of that License or (at your option) any
77694 + * later version.
77695 + *
77696 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
77697 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
77698 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
77699 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
77700 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
77701 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
77702 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77703 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
77704 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
77705 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
77706 + */
77707 +
77708 +
77709 +/*------------------------------------------------------*/
77710 +/* */
77711 +/* File: crc_mac_addr_ext.h */
77712 +/* */
77713 +/* Description: */
77714 +/* Define a macro that calculate the crc value of */
77715 +/* an Ethernet MAC address (48 bitd address */
77716 +/*------------------------------------------------------*/
77717 +
77718 +#ifndef __crc_mac_addr_ext_h
77719 +#define __crc_mac_addr_ext_h
77720 +
77721 +#include "std_ext.h"
77722 +
77723 +
77724 +static uint32_t crc_table[256] =
77725 +{
77726 + 0x00000000,
77727 + 0x77073096,
77728 + 0xee0e612c,
77729 + 0x990951ba,
77730 + 0x076dc419,
77731 + 0x706af48f,
77732 + 0xe963a535,
77733 + 0x9e6495a3,
77734 + 0x0edb8832,
77735 + 0x79dcb8a4,
77736 + 0xe0d5e91e,
77737 + 0x97d2d988,
77738 + 0x09b64c2b,
77739 + 0x7eb17cbd,
77740 + 0xe7b82d07,
77741 + 0x90bf1d91,
77742 + 0x1db71064,
77743 + 0x6ab020f2,
77744 + 0xf3b97148,
77745 + 0x84be41de,
77746 + 0x1adad47d,
77747 + 0x6ddde4eb,
77748 + 0xf4d4b551,
77749 + 0x83d385c7,
77750 + 0x136c9856,
77751 + 0x646ba8c0,
77752 + 0xfd62f97a,
77753 + 0x8a65c9ec,
77754 + 0x14015c4f,
77755 + 0x63066cd9,
77756 + 0xfa0f3d63,
77757 + 0x8d080df5,
77758 + 0x3b6e20c8,
77759 + 0x4c69105e,
77760 + 0xd56041e4,
77761 + 0xa2677172,
77762 + 0x3c03e4d1,
77763 + 0x4b04d447,
77764 + 0xd20d85fd,
77765 + 0xa50ab56b,
77766 + 0x35b5a8fa,
77767 + 0x42b2986c,
77768 + 0xdbbbc9d6,
77769 + 0xacbcf940,
77770 + 0x32d86ce3,
77771 + 0x45df5c75,
77772 + 0xdcd60dcf,
77773 + 0xabd13d59,
77774 + 0x26d930ac,
77775 + 0x51de003a,
77776 + 0xc8d75180,
77777 + 0xbfd06116,
77778 + 0x21b4f4b5,
77779 + 0x56b3c423,
77780 + 0xcfba9599,
77781 + 0xb8bda50f,
77782 + 0x2802b89e,
77783 + 0x5f058808,
77784 + 0xc60cd9b2,
77785 + 0xb10be924,
77786 + 0x2f6f7c87,
77787 + 0x58684c11,
77788 + 0xc1611dab,
77789 + 0xb6662d3d,
77790 + 0x76dc4190,
77791 + 0x01db7106,
77792 + 0x98d220bc,
77793 + 0xefd5102a,
77794 + 0x71b18589,
77795 + 0x06b6b51f,
77796 + 0x9fbfe4a5,
77797 + 0xe8b8d433,
77798 + 0x7807c9a2,
77799 + 0x0f00f934,
77800 + 0x9609a88e,
77801 + 0xe10e9818,
77802 + 0x7f6a0dbb,
77803 + 0x086d3d2d,
77804 + 0x91646c97,
77805 + 0xe6635c01,
77806 + 0x6b6b51f4,
77807 + 0x1c6c6162,
77808 + 0x856530d8,
77809 + 0xf262004e,
77810 + 0x6c0695ed,
77811 + 0x1b01a57b,
77812 + 0x8208f4c1,
77813 + 0xf50fc457,
77814 + 0x65b0d9c6,
77815 + 0x12b7e950,
77816 + 0x8bbeb8ea,
77817 + 0xfcb9887c,
77818 + 0x62dd1ddf,
77819 + 0x15da2d49,
77820 + 0x8cd37cf3,
77821 + 0xfbd44c65,
77822 + 0x4db26158,
77823 + 0x3ab551ce,
77824 + 0xa3bc0074,
77825 + 0xd4bb30e2,
77826 + 0x4adfa541,
77827 + 0x3dd895d7,
77828 + 0xa4d1c46d,
77829 + 0xd3d6f4fb,
77830 + 0x4369e96a,
77831 + 0x346ed9fc,
77832 + 0xad678846,
77833 + 0xda60b8d0,
77834 + 0x44042d73,
77835 + 0x33031de5,
77836 + 0xaa0a4c5f,
77837 + 0xdd0d7cc9,
77838 + 0x5005713c,
77839 + 0x270241aa,
77840 + 0xbe0b1010,
77841 + 0xc90c2086,
77842 + 0x5768b525,
77843 + 0x206f85b3,
77844 + 0xb966d409,
77845 + 0xce61e49f,
77846 + 0x5edef90e,
77847 + 0x29d9c998,
77848 + 0xb0d09822,
77849 + 0xc7d7a8b4,
77850 + 0x59b33d17,
77851 + 0x2eb40d81,
77852 + 0xb7bd5c3b,
77853 + 0xc0ba6cad,
77854 + 0xedb88320,
77855 + 0x9abfb3b6,
77856 + 0x03b6e20c,
77857 + 0x74b1d29a,
77858 + 0xead54739,
77859 + 0x9dd277af,
77860 + 0x04db2615,
77861 + 0x73dc1683,
77862 + 0xe3630b12,
77863 + 0x94643b84,
77864 + 0x0d6d6a3e,
77865 + 0x7a6a5aa8,
77866 + 0xe40ecf0b,
77867 + 0x9309ff9d,
77868 + 0x0a00ae27,
77869 + 0x7d079eb1,
77870 + 0xf00f9344,
77871 + 0x8708a3d2,
77872 + 0x1e01f268,
77873 + 0x6906c2fe,
77874 + 0xf762575d,
77875 + 0x806567cb,
77876 + 0x196c3671,
77877 + 0x6e6b06e7,
77878 + 0xfed41b76,
77879 + 0x89d32be0,
77880 + 0x10da7a5a,
77881 + 0x67dd4acc,
77882 + 0xf9b9df6f,
77883 + 0x8ebeeff9,
77884 + 0x17b7be43,
77885 + 0x60b08ed5,
77886 + 0xd6d6a3e8,
77887 + 0xa1d1937e,
77888 + 0x38d8c2c4,
77889 + 0x4fdff252,
77890 + 0xd1bb67f1,
77891 + 0xa6bc5767,
77892 + 0x3fb506dd,
77893 + 0x48b2364b,
77894 + 0xd80d2bda,
77895 + 0xaf0a1b4c,
77896 + 0x36034af6,
77897 + 0x41047a60,
77898 + 0xdf60efc3,
77899 + 0xa867df55,
77900 + 0x316e8eef,
77901 + 0x4669be79,
77902 + 0xcb61b38c,
77903 + 0xbc66831a,
77904 + 0x256fd2a0,
77905 + 0x5268e236,
77906 + 0xcc0c7795,
77907 + 0xbb0b4703,
77908 + 0x220216b9,
77909 + 0x5505262f,
77910 + 0xc5ba3bbe,
77911 + 0xb2bd0b28,
77912 + 0x2bb45a92,
77913 + 0x5cb36a04,
77914 + 0xc2d7ffa7,
77915 + 0xb5d0cf31,
77916 + 0x2cd99e8b,
77917 + 0x5bdeae1d,
77918 + 0x9b64c2b0,
77919 + 0xec63f226,
77920 + 0x756aa39c,
77921 + 0x026d930a,
77922 + 0x9c0906a9,
77923 + 0xeb0e363f,
77924 + 0x72076785,
77925 + 0x05005713,
77926 + 0x95bf4a82,
77927 + 0xe2b87a14,
77928 + 0x7bb12bae,
77929 + 0x0cb61b38,
77930 + 0x92d28e9b,
77931 + 0xe5d5be0d,
77932 + 0x7cdcefb7,
77933 + 0x0bdbdf21,
77934 + 0x86d3d2d4,
77935 + 0xf1d4e242,
77936 + 0x68ddb3f8,
77937 + 0x1fda836e,
77938 + 0x81be16cd,
77939 + 0xf6b9265b,
77940 + 0x6fb077e1,
77941 + 0x18b74777,
77942 + 0x88085ae6,
77943 + 0xff0f6a70,
77944 + 0x66063bca,
77945 + 0x11010b5c,
77946 + 0x8f659eff,
77947 + 0xf862ae69,
77948 + 0x616bffd3,
77949 + 0x166ccf45,
77950 + 0xa00ae278,
77951 + 0xd70dd2ee,
77952 + 0x4e048354,
77953 + 0x3903b3c2,
77954 + 0xa7672661,
77955 + 0xd06016f7,
77956 + 0x4969474d,
77957 + 0x3e6e77db,
77958 + 0xaed16a4a,
77959 + 0xd9d65adc,
77960 + 0x40df0b66,
77961 + 0x37d83bf0,
77962 + 0xa9bcae53,
77963 + 0xdebb9ec5,
77964 + 0x47b2cf7f,
77965 + 0x30b5ffe9,
77966 + 0xbdbdf21c,
77967 + 0xcabac28a,
77968 + 0x53b39330,
77969 + 0x24b4a3a6,
77970 + 0xbad03605,
77971 + 0xcdd70693,
77972 + 0x54de5729,
77973 + 0x23d967bf,
77974 + 0xb3667a2e,
77975 + 0xc4614ab8,
77976 + 0x5d681b02,
77977 + 0x2a6f2b94,
77978 + 0xb40bbe37,
77979 + 0xc30c8ea1,
77980 + 0x5a05df1b,
77981 + 0x2d02ef8d
77982 +};
77983 +
77984 +
77985 +#define GET_MAC_ADDR_CRC(addr, crc) \
77986 +{ \
77987 + uint32_t i; \
77988 + uint8_t data; \
77989 + \
77990 + /* CRC calculation */ \
77991 + crc = 0xffffffff; \
77992 + for (i=0; i < 6; i++) \
77993 + { \
77994 + data = (uint8_t)(addr >> ((5-i)*8)); \
77995 + crc = crc^data; \
77996 + crc = crc_table[crc&0xff] ^ (crc>>8); \
77997 + } \
77998 +} \
77999 +
78000 +/* Define a macro for getting the mirrored value of */
78001 +/* a byte size number. (0x11010011 --> 0x11001011) */
78002 +/* Sometimes the mirrored value of the CRC is required */
78003 +static __inline__ uint8_t GetMirror(uint8_t n)
78004 +{
78005 + uint8_t mirror[16] =
78006 + {
78007 + 0x00,
78008 + 0x08,
78009 + 0x04,
78010 + 0x0c,
78011 + 0x02,
78012 + 0x0a,
78013 + 0x06,
78014 + 0x0e,
78015 + 0x01,
78016 + 0x09,
78017 + 0x05,
78018 + 0x0d,
78019 + 0x03,
78020 + 0x0b,
78021 + 0x07,
78022 + 0x0f
78023 + };
78024 + return ((uint8_t)(((mirror[n & 0x0f] << 4) | (mirror[n >> 4]))));
78025 +}
78026 +
78027 +static __inline__ uint32_t GetMirror32(uint32_t n)
78028 +{
78029 + return (((uint32_t)GetMirror((uint8_t)(n))<<24) |
78030 + ((uint32_t)GetMirror((uint8_t)(n>>8))<<16) |
78031 + ((uint32_t)GetMirror((uint8_t)(n>>16))<<8) |
78032 + ((uint32_t)GetMirror((uint8_t)(n>>24))));
78033 +}
78034 +
78035 +#define MIRROR GetMirror
78036 +#define MIRROR_32 GetMirror32
78037 +
78038 +
78039 +#endif /* __crc_mac_addr_ext_h */
78040 --- /dev/null
78041 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/dpaa_ext.h
78042 @@ -0,0 +1,210 @@
78043 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
78044 + * All rights reserved.
78045 + *
78046 + * Redistribution and use in source and binary forms, with or without
78047 + * modification, are permitted provided that the following conditions are met:
78048 + * * Redistributions of source code must retain the above copyright
78049 + * notice, this list of conditions and the following disclaimer.
78050 + * * Redistributions in binary form must reproduce the above copyright
78051 + * notice, this list of conditions and the following disclaimer in the
78052 + * documentation and/or other materials provided with the distribution.
78053 + * * Neither the name of Freescale Semiconductor nor the
78054 + * names of its contributors may be used to endorse or promote products
78055 + * derived from this software without specific prior written permission.
78056 + *
78057 + *
78058 + * ALTERNATIVELY, this software may be distributed under the terms of the
78059 + * GNU General Public License ("GPL") as published by the Free Software
78060 + * Foundation, either version 2 of that License or (at your option) any
78061 + * later version.
78062 + *
78063 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78064 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78065 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78066 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78067 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78068 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78069 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78070 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78071 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78072 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78073 + */
78074 +
78075 +
78076 +/**************************************************************************//**
78077 + @File dpaa_ext.h
78078 +
78079 + @Description DPAA Application Programming Interface.
78080 +*//***************************************************************************/
78081 +#ifndef __DPAA_EXT_H
78082 +#define __DPAA_EXT_H
78083 +
78084 +#include "std_ext.h"
78085 +#include "error_ext.h"
78086 +
78087 +
78088 +/**************************************************************************//**
78089 + @Group DPAA_grp Data Path Acceleration Architecture API
78090 +
78091 + @Description DPAA API functions, definitions and enums.
78092 +
78093 + @{
78094 +*//***************************************************************************/
78095 +
78096 +#if defined(__MWERKS__) && !defined(__GNUC__)
78097 +#pragma pack(push,1)
78098 +#endif /* defined(__MWERKS__) && ... */
78099 +
78100 +/**************************************************************************//**
78101 + @Description Frame descriptor
78102 +*//***************************************************************************/
78103 +typedef _Packed struct t_DpaaFD {
78104 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
78105 + volatile uint8_t liodn;
78106 + volatile uint8_t bpid;
78107 + volatile uint8_t elion;
78108 + volatile uint8_t addrh;
78109 + volatile uint32_t addrl;
78110 +#else
78111 + volatile uint32_t addrl;
78112 + volatile uint8_t addrh;
78113 + volatile uint8_t elion;
78114 + volatile uint8_t bpid;
78115 + volatile uint8_t liodn;
78116 + #endif
78117 + volatile uint32_t length; /**< Frame length */
78118 + volatile uint32_t status; /**< FD status */
78119 +} _PackedType t_DpaaFD;
78120 +
78121 +/**************************************************************************//**
78122 + @Description enum for defining frame format
78123 +*//***************************************************************************/
78124 +typedef enum e_DpaaFDFormatType {
78125 + e_DPAA_FD_FORMAT_TYPE_SHORT_SBSF = 0x0, /**< Simple frame Single buffer; Offset and
78126 + small length (9b OFFSET, 20b LENGTH) */
78127 + e_DPAA_FD_FORMAT_TYPE_LONG_SBSF = 0x2, /**< Simple frame, single buffer; big length
78128 + (29b LENGTH ,No OFFSET) */
78129 + e_DPAA_FD_FORMAT_TYPE_SHORT_MBSF = 0x4, /**< Simple frame, Scatter Gather table; Offset
78130 + and small length (9b OFFSET, 20b LENGTH) */
78131 + e_DPAA_FD_FORMAT_TYPE_LONG_MBSF = 0x6, /**< Simple frame, Scatter Gather table;
78132 + big length (29b LENGTH ,No OFFSET) */
78133 + e_DPAA_FD_FORMAT_TYPE_COMPOUND = 0x1, /**< Compound Frame (29b CONGESTION-WEIGHT
78134 + No LENGTH or OFFSET) */
78135 + e_DPAA_FD_FORMAT_TYPE_DUMMY
78136 +} e_DpaaFDFormatType;
78137 +
78138 +/**************************************************************************//**
78139 + @Collection Frame descriptor macros
78140 +*//***************************************************************************/
78141 +#define DPAA_FD_DD_MASK 0xc0000000 /**< FD DD field mask */
78142 +#define DPAA_FD_PID_MASK 0x3f000000 /**< FD PID field mask */
78143 +#define DPAA_FD_ELIODN_MASK 0x0000f000 /**< FD ELIODN field mask */
78144 +#define DPAA_FD_BPID_MASK 0x00ff0000 /**< FD BPID field mask */
78145 +#define DPAA_FD_ADDRH_MASK 0x000000ff /**< FD ADDRH field mask */
78146 +#define DPAA_FD_ADDRL_MASK 0xffffffff /**< FD ADDRL field mask */
78147 +#define DPAA_FD_FORMAT_MASK 0xe0000000 /**< FD FORMAT field mask */
78148 +#define DPAA_FD_OFFSET_MASK 0x1ff00000 /**< FD OFFSET field mask */
78149 +#define DPAA_FD_LENGTH_MASK 0x000fffff /**< FD LENGTH field mask */
78150 +
78151 +#define DPAA_FD_GET_ADDRH(fd) ((t_DpaaFD *)fd)->addrh /**< Macro to get FD ADDRH field */
78152 +#define DPAA_FD_GET_ADDRL(fd) ((t_DpaaFD *)fd)->addrl /**< Macro to get FD ADDRL field */
78153 +#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 */
78154 +#define DPAA_FD_GET_FORMAT(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_FORMAT_MASK) >> (31-2)) /**< Macro to get FD FORMAT field */
78155 +#define DPAA_FD_GET_OFFSET(fd) ((((t_DpaaFD *)fd)->length & DPAA_FD_OFFSET_MASK) >> (31-11)) /**< Macro to get FD OFFSET field */
78156 +#define DPAA_FD_GET_LENGTH(fd) (((t_DpaaFD *)fd)->length & DPAA_FD_LENGTH_MASK) /**< Macro to get FD LENGTH field */
78157 +#define DPAA_FD_GET_STATUS(fd) ((t_DpaaFD *)fd)->status /**< Macro to get FD STATUS field */
78158 +#define DPAA_FD_GET_ADDR(fd) XX_PhysToVirt(DPAA_FD_GET_PHYS_ADDR(fd)) /**< Macro to get FD ADDR (virtual) */
78159 +
78160 +#define DPAA_FD_SET_ADDRH(fd,val) ((t_DpaaFD *)fd)->addrh = (val) /**< Macro to set FD ADDRH field */
78161 +#define DPAA_FD_SET_ADDRL(fd,val) ((t_DpaaFD *)fd)->addrl = (val) /**< Macro to set FD ADDRL field */
78162 +#define DPAA_FD_SET_ADDR(fd,val) \
78163 +do { \
78164 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
78165 + DPAA_FD_SET_ADDRH(fd, ((uint32_t)(physAddr >> 32))); \
78166 + DPAA_FD_SET_ADDRL(fd, (uint32_t)physAddr); \
78167 +} while (0) /**< Macro to set FD ADDR field */
78168 +#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 */
78169 +#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 */
78170 +#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 */
78171 +#define DPAA_FD_SET_STATUS(fd,val) ((t_DpaaFD *)fd)->status = (val) /**< Macro to set FD STATUS field */
78172 +/* @} */
78173 +
78174 +/**************************************************************************//**
78175 + @Description Frame Scatter/Gather Table Entry
78176 +*//***************************************************************************/
78177 +typedef _Packed struct t_DpaaSGTE {
78178 + volatile uint32_t addrh; /**< Buffer Address high */
78179 + volatile uint32_t addrl; /**< Buffer Address low */
78180 + volatile uint32_t length; /**< Buffer length */
78181 + volatile uint32_t offset; /**< SGTE offset */
78182 +} _PackedType t_DpaaSGTE;
78183 +
78184 +#define DPAA_NUM_OF_SG_TABLE_ENTRY 16
78185 +
78186 +/**************************************************************************//**
78187 + @Description Frame Scatter/Gather Table
78188 +*//***************************************************************************/
78189 +typedef _Packed struct t_DpaaSGT {
78190 + t_DpaaSGTE tableEntry[DPAA_NUM_OF_SG_TABLE_ENTRY];
78191 + /**< Structure that holds information about
78192 + a single S/G entry. */
78193 +} _PackedType t_DpaaSGT;
78194 +
78195 +/**************************************************************************//**
78196 + @Description Compound Frame Table
78197 +*//***************************************************************************/
78198 +typedef _Packed struct t_DpaaCompTbl {
78199 + t_DpaaSGTE outputBuffInfo; /**< Structure that holds information about
78200 + the compound-frame output buffer;
78201 + NOTE: this may point to a S/G table */
78202 + t_DpaaSGTE inputBuffInfo; /**< Structure that holds information about
78203 + the compound-frame input buffer;
78204 + NOTE: this may point to a S/G table */
78205 +} _PackedType t_DpaaCompTbl;
78206 +
78207 +/**************************************************************************//**
78208 + @Collection Frame Scatter/Gather Table Entry macros
78209 +*//***************************************************************************/
78210 +#define DPAA_SGTE_ADDRH_MASK 0x000000ff /**< SGTE ADDRH field mask */
78211 +#define DPAA_SGTE_ADDRL_MASK 0xffffffff /**< SGTE ADDRL field mask */
78212 +#define DPAA_SGTE_E_MASK 0x80000000 /**< SGTE Extension field mask */
78213 +#define DPAA_SGTE_F_MASK 0x40000000 /**< SGTE Final field mask */
78214 +#define DPAA_SGTE_LENGTH_MASK 0x3fffffff /**< SGTE LENGTH field mask */
78215 +#define DPAA_SGTE_BPID_MASK 0x00ff0000 /**< SGTE BPID field mask */
78216 +#define DPAA_SGTE_OFFSET_MASK 0x00001fff /**< SGTE OFFSET field mask */
78217 +
78218 +#define DPAA_SGTE_GET_ADDRH(sgte) (((t_DpaaSGTE *)sgte)->addrh & DPAA_SGTE_ADDRH_MASK) /**< Macro to get SGTE ADDRH field */
78219 +#define DPAA_SGTE_GET_ADDRL(sgte) ((t_DpaaSGTE *)sgte)->addrl /**< Macro to get SGTE ADDRL field */
78220 +#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 */
78221 +#define DPAA_SGTE_GET_EXTENSION(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_E_MASK) >> (31-0)) /**< Macro to get SGTE EXTENSION field */
78222 +#define DPAA_SGTE_GET_FINAL(sgte) ((((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_F_MASK) >> (31-1)) /**< Macro to get SGTE FINAL field */
78223 +#define DPAA_SGTE_GET_LENGTH(sgte) (((t_DpaaSGTE *)sgte)->length & DPAA_SGTE_LENGTH_MASK) /**< Macro to get SGTE LENGTH field */
78224 +#define DPAA_SGTE_GET_BPID(sgte) ((((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_BPID_MASK) >> (31-15)) /**< Macro to get SGTE BPID field */
78225 +#define DPAA_SGTE_GET_OFFSET(sgte) (((t_DpaaSGTE *)sgte)->offset & DPAA_SGTE_OFFSET_MASK) /**< Macro to get SGTE OFFSET field */
78226 +#define DPAA_SGTE_GET_ADDR(sgte) XX_PhysToVirt(DPAA_SGTE_GET_PHYS_ADDR(sgte))
78227 +
78228 +#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 */
78229 +#define DPAA_SGTE_SET_ADDRL(sgte,val) ((t_DpaaSGTE *)sgte)->addrl = (val) /**< Macro to set SGTE ADDRL field */
78230 +#define DPAA_SGTE_SET_ADDR(sgte,val) \
78231 +do { \
78232 + uint64_t physAddr = (uint64_t)(XX_VirtToPhys(val)); \
78233 + DPAA_SGTE_SET_ADDRH(sgte, ((uint32_t)(physAddr >> 32))); \
78234 + DPAA_SGTE_SET_ADDRL(sgte, (uint32_t)physAddr); \
78235 +} while (0) /**< Macro to set SGTE ADDR field */
78236 +#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 */
78237 +#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 */
78238 +#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 */
78239 +#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 */
78240 +#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 */
78241 +/* @} */
78242 +
78243 +#if defined(__MWERKS__) && !defined(__GNUC__)
78244 +#pragma pack(pop)
78245 +#endif /* defined(__MWERKS__) && ... */
78246 +
78247 +#define DPAA_LIODN_DONT_OVERRIDE (-1)
78248 +
78249 +/** @} */ /* end of DPAA_grp group */
78250 +
78251 +
78252 +#endif /* __DPAA_EXT_H */
78253 --- /dev/null
78254 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_ext.h
78255 @@ -0,0 +1,1731 @@
78256 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
78257 + * All rights reserved.
78258 + *
78259 + * Redistribution and use in source and binary forms, with or without
78260 + * modification, are permitted provided that the following conditions are met:
78261 + * * Redistributions of source code must retain the above copyright
78262 + * notice, this list of conditions and the following disclaimer.
78263 + * * Redistributions in binary form must reproduce the above copyright
78264 + * notice, this list of conditions and the following disclaimer in the
78265 + * documentation and/or other materials provided with the distribution.
78266 + * * Neither the name of Freescale Semiconductor nor the
78267 + * names of its contributors may be used to endorse or promote products
78268 + * derived from this software without specific prior written permission.
78269 + *
78270 + *
78271 + * ALTERNATIVELY, this software may be distributed under the terms of the
78272 + * GNU General Public License ("GPL") as published by the Free Software
78273 + * Foundation, either version 2 of that License or (at your option) any
78274 + * later version.
78275 + *
78276 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
78277 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
78278 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
78279 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
78280 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78281 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
78282 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
78283 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
78284 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
78285 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
78286 + */
78287 +
78288 +
78289 +/**************************************************************************//**
78290 + @File fm_ext.h
78291 +
78292 + @Description FM Application Programming Interface.
78293 +*//***************************************************************************/
78294 +#ifndef __FM_EXT
78295 +#define __FM_EXT
78296 +
78297 +#include "error_ext.h"
78298 +#include "std_ext.h"
78299 +#include "dpaa_ext.h"
78300 +#include "fsl_fman_sp.h"
78301 +
78302 +/**************************************************************************//**
78303 + @Group FM_grp Frame Manager API
78304 +
78305 + @Description FM API functions, definitions and enums.
78306 +
78307 + @{
78308 +*//***************************************************************************/
78309 +
78310 +/**************************************************************************//**
78311 + @Group FM_lib_grp FM library
78312 +
78313 + @Description FM API functions, definitions and enums.
78314 +
78315 + The FM module is the main driver module and is a mandatory module
78316 + for FM driver users. This module must be initialized first prior
78317 + to any other drivers modules.
78318 + The FM is a "singleton" module. It is responsible of the common
78319 + HW modules: FPM, DMA, common QMI and common BMI initializations and
78320 + run-time control routines. This module must be initialized always
78321 + when working with any of the FM modules.
78322 + NOTE - We assume that the FM library will be initialized only by core No. 0!
78323 +
78324 + @{
78325 +*//***************************************************************************/
78326 +
78327 +/**************************************************************************//**
78328 + @Description Enum for defining port types
78329 +*//***************************************************************************/
78330 +typedef enum e_FmPortType {
78331 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
78332 + e_FM_PORT_TYPE_RX, /**< 1G Rx port */
78333 + e_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
78334 + e_FM_PORT_TYPE_TX, /**< 1G Tx port */
78335 + e_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
78336 + e_FM_PORT_TYPE_DUMMY
78337 +} e_FmPortType;
78338 +
78339 +/**************************************************************************//**
78340 + @Collection General FM defines
78341 +*//***************************************************************************/
78342 +#define FM_MAX_NUM_OF_PARTITIONS 64 /**< Maximum number of partitions */
78343 +#define FM_PHYS_ADDRESS_SIZE 6 /**< FM Physical address size */
78344 +/* @} */
78345 +
78346 +
78347 +#if defined(__MWERKS__) && !defined(__GNUC__)
78348 +#pragma pack(push,1)
78349 +#endif /* defined(__MWERKS__) && ... */
78350 +
78351 +/**************************************************************************//**
78352 + @Description FM physical Address
78353 +*//***************************************************************************/
78354 +typedef _Packed struct t_FmPhysAddr {
78355 + volatile uint8_t high; /**< High part of the physical address */
78356 + volatile uint32_t low; /**< Low part of the physical address */
78357 +} _PackedType t_FmPhysAddr;
78358 +
78359 +/**************************************************************************//**
78360 + @Description Parse results memory layout
78361 +*//***************************************************************************/
78362 +typedef _Packed struct t_FmPrsResult {
78363 + volatile uint8_t lpid; /**< Logical port id */
78364 + volatile uint8_t shimr; /**< Shim header result */
78365 + volatile uint16_t l2r; /**< Layer 2 result */
78366 + volatile uint16_t l3r; /**< Layer 3 result */
78367 + volatile uint8_t l4r; /**< Layer 4 result */
78368 + volatile uint8_t cplan; /**< Classification plan id */
78369 + volatile uint16_t nxthdr; /**< Next Header */
78370 + volatile uint16_t cksum; /**< Running-sum */
78371 + volatile uint16_t flags_frag_off; /**< Flags & fragment-offset field of the last IP-header */
78372 + volatile uint8_t route_type; /**< Routing type field of a IPv6 routing extension header */
78373 + volatile uint8_t rhp_ip_valid; /**< Routing Extension Header Present; last bit is IP valid */
78374 + volatile uint8_t shim_off[2]; /**< Shim offset */
78375 + volatile uint8_t ip_pid_off; /**< IP PID (last IP-proto) offset */
78376 + volatile uint8_t eth_off; /**< ETH offset */
78377 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
78378 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
78379 + volatile uint8_t etype_off; /**< ETYPE offset */
78380 + volatile uint8_t pppoe_off; /**< PPP offset */
78381 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
78382 + volatile uint8_t ip_off[2]; /**< IP offset */
78383 + volatile uint8_t gre_off; /**< GRE offset */
78384 + volatile uint8_t l4_off; /**< Layer 4 offset */
78385 + volatile uint8_t nxthdr_off; /**< Parser end point */
78386 +} _PackedType t_FmPrsResult;
78387 +
78388 +/**************************************************************************//**
78389 + @Collection FM Parser results
78390 +*//***************************************************************************/
78391 +#define FM_PR_L2_VLAN_STACK 0x00000100 /**< Parse Result: VLAN stack */
78392 +#define FM_PR_L2_ETHERNET 0x00008000 /**< Parse Result: Ethernet*/
78393 +#define FM_PR_L2_VLAN 0x00004000 /**< Parse Result: VLAN */
78394 +#define FM_PR_L2_LLC_SNAP 0x00002000 /**< Parse Result: LLC_SNAP */
78395 +#define FM_PR_L2_MPLS 0x00001000 /**< Parse Result: MPLS */
78396 +#define FM_PR_L2_PPPoE 0x00000800 /**< Parse Result: PPPoE */
78397 +/* @} */
78398 +
78399 +/**************************************************************************//**
78400 + @Collection FM Frame descriptor macros
78401 +*//***************************************************************************/
78402 +#define FM_FD_CMD_FCO 0x80000000 /**< Frame queue Context Override */
78403 +#define FM_FD_CMD_RPD 0x40000000 /**< Read Prepended Data */
78404 +#define FM_FD_CMD_UPD 0x20000000 /**< Update Prepended Data */
78405 +#define FM_FD_CMD_DTC 0x10000000 /**< Do L4 Checksum */
78406 +#define FM_FD_CMD_DCL4C 0x10000000 /**< Didn't calculate L4 Checksum */
78407 +#define FM_FD_CMD_CFQ 0x00ffffff /**< Confirmation Frame Queue */
78408 +
78409 +#define FM_FD_ERR_UNSUPPORTED_FORMAT 0x04000000 /**< Not for Rx-Port! Unsupported Format */
78410 +#define FM_FD_ERR_LENGTH 0x02000000 /**< Not for Rx-Port! Length Error */
78411 +#define FM_FD_ERR_DMA 0x01000000 /**< DMA Data error */
78412 +
78413 +#define FM_FD_IPR 0x00000001 /**< IPR frame (not error) */
78414 +
78415 +#define FM_FD_ERR_IPR_NCSP (0x00100000 | FM_FD_IPR) /**< IPR non-consistent-sp */
78416 +#define FM_FD_ERR_IPR (0x00200000 | FM_FD_IPR) /**< IPR error */
78417 +#define FM_FD_ERR_IPR_TO (0x00300000 | FM_FD_IPR) /**< IPR timeout */
78418 +
78419 +#ifdef FM_CAPWAP_SUPPORT
78420 +#define FM_FD_ERR_CRE 0x00200000
78421 +#define FM_FD_ERR_CHE 0x00100000
78422 +#endif /* FM_CAPWAP_SUPPORT */
78423 +
78424 +#define FM_FD_ERR_PHYSICAL 0x00080000 /**< Rx FIFO overflow, FCS error, code error, running disparity
78425 + error (SGMII and TBI modes), FIFO parity error. PHY
78426 + Sequence error, PHY error control character detected. */
78427 +#define FM_FD_ERR_SIZE 0x00040000 /**< Frame too long OR Frame size exceeds max_length_frame */
78428 +#define FM_FD_ERR_CLS_DISCARD 0x00020000 /**< classification discard */
78429 +#define FM_FD_ERR_EXTRACTION 0x00008000 /**< Extract Out of Frame */
78430 +#define FM_FD_ERR_NO_SCHEME 0x00004000 /**< No Scheme Selected */
78431 +#define FM_FD_ERR_KEYSIZE_OVERFLOW 0x00002000 /**< Keysize Overflow */
78432 +#define FM_FD_ERR_COLOR_RED 0x00000800 /**< Frame color is red */
78433 +#define FM_FD_ERR_COLOR_YELLOW 0x00000400 /**< Frame color is yellow */
78434 +#define FM_FD_ERR_ILL_PLCR 0x00000200 /**< Illegal Policer Profile selected */
78435 +#define FM_FD_ERR_PLCR_FRAME_LEN 0x00000100 /**< Policer frame length error */
78436 +#define FM_FD_ERR_PRS_TIMEOUT 0x00000080 /**< Parser Time out Exceed */
78437 +#define FM_FD_ERR_PRS_ILL_INSTRUCT 0x00000040 /**< Invalid Soft Parser instruction */
78438 +#define FM_FD_ERR_PRS_HDR_ERR 0x00000020 /**< Header error was identified during parsing */
78439 +#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED 0x00000008 /**< Frame parsed beyind 256 first bytes */
78440 +
78441 +#define FM_FD_TX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
78442 + FM_FD_ERR_LENGTH | \
78443 + FM_FD_ERR_DMA) /**< TX Error FD bits */
78444 +
78445 +#define FM_FD_RX_STATUS_ERR_MASK (FM_FD_ERR_UNSUPPORTED_FORMAT | \
78446 + FM_FD_ERR_LENGTH | \
78447 + FM_FD_ERR_DMA | \
78448 + FM_FD_ERR_IPR | \
78449 + FM_FD_ERR_IPR_TO | \
78450 + FM_FD_ERR_IPR_NCSP | \
78451 + FM_FD_ERR_PHYSICAL | \
78452 + FM_FD_ERR_SIZE | \
78453 + FM_FD_ERR_CLS_DISCARD | \
78454 + FM_FD_ERR_COLOR_RED | \
78455 + FM_FD_ERR_COLOR_YELLOW | \
78456 + FM_FD_ERR_ILL_PLCR | \
78457 + FM_FD_ERR_PLCR_FRAME_LEN | \
78458 + FM_FD_ERR_EXTRACTION | \
78459 + FM_FD_ERR_NO_SCHEME | \
78460 + FM_FD_ERR_KEYSIZE_OVERFLOW | \
78461 + FM_FD_ERR_PRS_TIMEOUT | \
78462 + FM_FD_ERR_PRS_ILL_INSTRUCT | \
78463 + FM_FD_ERR_PRS_HDR_ERR | \
78464 + FM_FD_ERR_BLOCK_LIMIT_EXCEEDED) /**< RX Error FD bits */
78465 +
78466 +#define FM_FD_RX_STATUS_ERR_NON_FM 0x00400000 /**< non Frame-Manager error */
78467 +/* @} */
78468 +
78469 +/**************************************************************************//**
78470 + @Description Context A
78471 +*//***************************************************************************/
78472 +typedef _Packed struct t_FmContextA {
78473 + volatile uint32_t command; /**< ContextA Command */
78474 + volatile uint8_t res0[4]; /**< ContextA Reserved bits */
78475 +} _PackedType t_FmContextA;
78476 +
78477 +/**************************************************************************//**
78478 + @Description Context B
78479 +*//***************************************************************************/
78480 +typedef uint32_t t_FmContextB;
78481 +
78482 +/**************************************************************************//**
78483 + @Collection Special Operation options
78484 +*//***************************************************************************/
78485 +typedef uint32_t fmSpecialOperations_t; /**< typedef for defining Special Operation options */
78486 +
78487 +#define FM_SP_OP_IPSEC 0x80000000 /**< activate features that related to IPSec (e.g fix Eth-type) */
78488 +#define FM_SP_OP_IPSEC_UPDATE_UDP_LEN 0x40000000 /**< update the UDP-Len after Encryption */
78489 +#define FM_SP_OP_IPSEC_MANIP 0x20000000 /**< handle the IPSec-manip options */
78490 +#define FM_SP_OP_RPD 0x10000000 /**< Set the RPD bit */
78491 +#define FM_SP_OP_DCL4C 0x08000000 /**< Set the DCL4C bit */
78492 +#define FM_SP_OP_CHECK_SEC_ERRORS 0x04000000 /**< Check SEC errors */
78493 +#define FM_SP_OP_CLEAR_RPD 0x02000000 /**< Clear the RPD bit */
78494 +#define FM_SP_OP_CAPWAP_DTLS_ENC 0x01000000 /**< activate features that related to CAPWAP-DTLS post Encryption */
78495 +#define FM_SP_OP_CAPWAP_DTLS_DEC 0x00800000 /**< activate features that related to CAPWAP-DTLS post Decryption */
78496 +#define FM_SP_OP_IPSEC_NO_ETH_HDR 0x00400000 /**< activate features that related to IPSec without Eth hdr */
78497 +/* @} */
78498 +
78499 +/**************************************************************************//**
78500 + @Collection Context A macros
78501 +*//***************************************************************************/
78502 +#define FM_CONTEXTA_OVERRIDE_MASK 0x80000000
78503 +#define FM_CONTEXTA_ICMD_MASK 0x40000000
78504 +#define FM_CONTEXTA_A1_VALID_MASK 0x20000000
78505 +#define FM_CONTEXTA_MACCMD_MASK 0x00ff0000
78506 +#define FM_CONTEXTA_MACCMD_VALID_MASK 0x00800000
78507 +#define FM_CONTEXTA_MACCMD_SECURED_MASK 0x00100000
78508 +#define FM_CONTEXTA_MACCMD_SC_MASK 0x000f0000
78509 +#define FM_CONTEXTA_A1_MASK 0x0000ffff
78510 +
78511 +#define FM_CONTEXTA_GET_OVERRIDE(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_OVERRIDE_MASK) >> (31-0))
78512 +#define FM_CONTEXTA_GET_ICMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_ICMD_MASK) >> (31-1))
78513 +#define FM_CONTEXTA_GET_A1_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_VALID_MASK) >> (31-2))
78514 +#define FM_CONTEXTA_GET_A1(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_A1_MASK) >> (31-31))
78515 +#define FM_CONTEXTA_GET_MACCMD(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_MASK) >> (31-15))
78516 +#define FM_CONTEXTA_GET_MACCMD_VALID(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_VALID_MASK) >> (31-8))
78517 +#define FM_CONTEXTA_GET_MACCMD_SECURED(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SECURED_MASK) >> (31-11))
78518 +#define FM_CONTEXTA_GET_MACCMD_SECURE_CHANNEL(contextA) ((((t_FmContextA *)contextA)->command & FM_CONTEXTA_MACCMD_SC_MASK) >> (31-15))
78519 +
78520 +#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) ))
78521 +#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) ))
78522 +#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) ))
78523 +#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) ))
78524 +#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) ))
78525 +#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) ))
78526 +#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) ))
78527 +#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) ))
78528 +/* @} */
78529 +
78530 +/**************************************************************************//**
78531 + @Collection Context B macros
78532 +*//***************************************************************************/
78533 +#define FM_CONTEXTB_FQID_MASK 0x00ffffff
78534 +
78535 +#define FM_CONTEXTB_GET_FQID(contextB) (*((t_FmContextB *)contextB) & FM_CONTEXTB_FQID_MASK)
78536 +#define FM_CONTEXTB_SET_FQID(contextB,val) (*((t_FmContextB *)contextB) = ((*((t_FmContextB *)contextB) & ~FM_CONTEXTB_FQID_MASK) | ((val) & FM_CONTEXTB_FQID_MASK)))
78537 +/* @} */
78538 +
78539 +#if defined(__MWERKS__) && !defined(__GNUC__)
78540 +#pragma pack(pop)
78541 +#endif /* defined(__MWERKS__) && ... */
78542 +
78543 +
78544 +/**************************************************************************//**
78545 + @Description FM Exceptions
78546 +*//***************************************************************************/
78547 +typedef enum e_FmExceptions {
78548 + e_FM_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
78549 + e_FM_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
78550 + e_FM_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
78551 + e_FM_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
78552 + e_FM_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
78553 + e_FM_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
78554 + e_FM_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
78555 + e_FM_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
78556 + e_FM_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
78557 + e_FM_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
78558 + e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
78559 + e_FM_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
78560 + e_FM_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
78561 + e_FM_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
78562 + e_FM_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
78563 + e_FM_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
78564 + e_FM_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
78565 +} e_FmExceptions;
78566 +
78567 +/**************************************************************************//**
78568 + @Description Enum for defining port DMA swap mode
78569 +*//***************************************************************************/
78570 +typedef enum e_FmDmaSwapOption {
78571 + e_FM_DMA_NO_SWP = FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
78572 + e_FM_DMA_SWP_PPC_LE = FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
78573 + in PowerPc Little Endian mode. */
78574 + e_FM_DMA_SWP_BE = FMAN_DMA_SWP_BE /**< The transferred data should be swapped
78575 + in Big Endian mode */
78576 +} e_FmDmaSwapOption;
78577 +
78578 +/**************************************************************************//**
78579 + @Description Enum for defining port DMA cache attributes
78580 +*//***************************************************************************/
78581 +typedef enum e_FmDmaCacheOption {
78582 + e_FM_DMA_NO_STASH = FMAN_DMA_NO_STASH, /**< Cacheable, no Allocate (No Stashing) */
78583 + e_FM_DMA_STASH = FMAN_DMA_STASH /**< Cacheable and Allocate (Stashing on) */
78584 +} e_FmDmaCacheOption;
78585 +
78586 +
78587 +/**************************************************************************//**
78588 + @Group FM_init_grp FM Initialization Unit
78589 +
78590 + @Description FM Initialization Unit
78591 +
78592 + Initialization Flow
78593 + Initialization of the FM Module will be carried out by the application
78594 + according to the following sequence:
78595 + - Calling the configuration routine with basic parameters.
78596 + - Calling the advance initialization routines to change driver's defaults.
78597 + - Calling the initialization routine.
78598 +
78599 + @{
78600 +*//***************************************************************************/
78601 +
78602 +/**************************************************************************//**
78603 + @Function t_FmExceptionsCallback
78604 +
78605 + @Description Exceptions user callback routine, will be called upon an
78606 + exception passing the exception identification.
78607 +
78608 + @Param[in] h_App - User's application descriptor.
78609 + @Param[in] exception - The exception.
78610 +*//***************************************************************************/
78611 +typedef void (t_FmExceptionsCallback)(t_Handle h_App,
78612 + e_FmExceptions exception);
78613 +
78614 +
78615 +/**************************************************************************//**
78616 + @Function t_FmBusErrorCallback
78617 +
78618 + @Description Bus error user callback routine, will be called upon a
78619 + bus error, passing parameters describing the errors and the owner.
78620 +
78621 + @Param[in] h_App - User's application descriptor.
78622 + @Param[in] portType - Port type (e_FmPortType)
78623 + @Param[in] portId - Port id - relative to type.
78624 + @Param[in] addr - Address that caused the error
78625 + @Param[in] tnum - Owner of error
78626 + @Param[in] liodn - Logical IO device number
78627 +*//***************************************************************************/
78628 +typedef void (t_FmBusErrorCallback) (t_Handle h_App,
78629 + e_FmPortType portType,
78630 + uint8_t portId,
78631 + uint64_t addr,
78632 + uint8_t tnum,
78633 + uint16_t liodn);
78634 +
78635 +/**************************************************************************//**
78636 + @Description A structure for defining buffer prefix area content.
78637 +*//***************************************************************************/
78638 +typedef struct t_FmBufferPrefixContent {
78639 + uint16_t privDataSize; /**< Number of bytes to be left at the beginning
78640 + of the external buffer; Note that the private-area will
78641 + start from the base of the buffer address. */
78642 + bool passPrsResult; /**< TRUE to pass the parse result to/from the FM;
78643 + User may use FM_PORT_GetBufferPrsResult() in order to
78644 + get the parser-result from a buffer. */
78645 + bool passTimeStamp; /**< TRUE to pass the timeStamp to/from the FM
78646 + User may use FM_PORT_GetBufferTimeStamp() in order to
78647 + get the parser-result from a buffer. */
78648 + bool passHashResult; /**< TRUE to pass the KG hash result to/from the FM
78649 + User may use FM_PORT_GetBufferHashResult() in order to
78650 + get the parser-result from a buffer. */
78651 + bool passAllOtherPCDInfo;/**< Add all other Internal-Context information:
78652 + AD, hash-result, key, etc. */
78653 + uint16_t dataAlign; /**< 0 to use driver's default alignment [DEFAULT_FM_SP_bufferPrefixContent_dataAlign],
78654 + other value for selecting a data alignment (must be a power of 2);
78655 + if write optimization is used, must be >= 16. */
78656 + uint8_t manipExtraSpace; /**< Maximum extra size needed (insertion-size minus removal-size);
78657 + Note that this field impacts the size of the buffer-prefix
78658 + (i.e. it pushes the data offset);
78659 + This field is irrelevant if DPAA_VERSION==10 */
78660 +} t_FmBufferPrefixContent;
78661 +
78662 +/**************************************************************************//**
78663 + @Description A structure of information about each of the external
78664 + buffer pools used by a port or storage-profile.
78665 +*//***************************************************************************/
78666 +typedef struct t_FmExtPoolParams {
78667 + uint8_t id; /**< External buffer pool id */
78668 + uint16_t size; /**< External buffer pool buffer size */
78669 +} t_FmExtPoolParams;
78670 +
78671 +/**************************************************************************//**
78672 + @Description A structure for informing the driver about the external
78673 + buffer pools allocated in the BM and used by a port or a
78674 + storage-profile.
78675 +*//***************************************************************************/
78676 +typedef struct t_FmExtPools {
78677 + uint8_t numOfPoolsUsed; /**< Number of pools use by this port */
78678 + t_FmExtPoolParams extBufPool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
78679 + /**< Parameters for each port */
78680 +} t_FmExtPools;
78681 +
78682 +/**************************************************************************//**
78683 + @Description A structure for defining backup BM Pools.
78684 +*//***************************************************************************/
78685 +typedef struct t_FmBackupBmPools {
78686 + uint8_t numOfBackupPools; /**< Number of BM backup pools -
78687 + must be smaller than the total number of
78688 + pools defined for the specified port.*/
78689 + uint8_t poolIds[FM_PORT_MAX_NUM_OF_EXT_POOLS];
78690 + /**< numOfBackupPools pool id's, specifying which
78691 + pools should be used only as backup. Pool
78692 + id's specified here must be a subset of the
78693 + pools used by the specified port.*/
78694 +} t_FmBackupBmPools;
78695 +
78696 +/**************************************************************************//**
78697 + @Description A structure for defining BM pool depletion criteria
78698 +*//***************************************************************************/
78699 +typedef struct t_FmBufPoolDepletion {
78700 + bool poolsGrpModeEnable; /**< select mode in which pause frames will be sent after
78701 + a number of pools (all together!) are depleted */
78702 + uint8_t numOfPools; /**< the number of depleted pools that will invoke
78703 + pause frames transmission. */
78704 + bool poolsToConsider[BM_MAX_NUM_OF_POOLS];
78705 + /**< For each pool, TRUE if it should be considered for
78706 + depletion (Note - this pool must be used by this port!). */
78707 + bool singlePoolModeEnable; /**< select mode in which pause frames will be sent after
78708 + a single-pool is depleted; */
78709 + bool poolsToConsiderForSingleMode[BM_MAX_NUM_OF_POOLS];
78710 + /**< For each pool, TRUE if it should be considered for
78711 + depletion (Note - this pool must be used by this port!) */
78712 +#if (DPAA_VERSION >= 11)
78713 + bool pfcPrioritiesEn[FM_MAX_NUM_OF_PFC_PRIORITIES];
78714 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame which is transmitted */
78715 +#endif /* (DPAA_VERSION >= 11) */
78716 +} t_FmBufPoolDepletion;
78717 +
78718 +/**************************************************************************//**
78719 + @Description A Structure for defining Ucode patch for loading.
78720 +*//***************************************************************************/
78721 +typedef struct t_FmFirmwareParams {
78722 + uint32_t size; /**< Size of uCode */
78723 + uint32_t *p_Code; /**< A pointer to the uCode */
78724 +} t_FmFirmwareParams;
78725 +
78726 +/**************************************************************************//**
78727 + @Description A Structure for defining FM initialization parameters
78728 +*//***************************************************************************/
78729 +typedef struct t_FmParams {
78730 + uint8_t fmId; /**< Index of the FM */
78731 + uint8_t guestId; /**< FM Partition Id */
78732 + uintptr_t baseAddr; /**< A pointer to base of memory mapped FM registers (virtual);
78733 + this field is optional when the FM runs in "guest-mode"
78734 + (i.e. guestId != NCSW_MASTER_ID); in that case, the driver will
78735 + use the memory-map instead of calling the IPC where possible;
78736 + NOTE that this should include ALL common registers of the FM including
78737 + the PCD registers area (i.e. until the VSP pages - 880KB). */
78738 + t_Handle h_FmMuram; /**< A handle of an initialized MURAM object,
78739 + to be used by the FM. */
78740 + uint16_t fmClkFreq; /**< In Mhz;
78741 + Relevant when FM not runs in "guest-mode". */
78742 + uint16_t fmMacClkRatio; /**< FM MAC Clock ratio, for backward comparability:
78743 + when fmMacClkRatio = 0, ratio is 2:1
78744 + when fmMacClkRatio = 1, ratio is 1:1 */
78745 + t_FmExceptionsCallback *f_Exception; /**< An application callback routine to handle exceptions;
78746 + Relevant when FM not runs in "guest-mode". */
78747 + t_FmBusErrorCallback *f_BusError; /**< An application callback routine to handle exceptions;
78748 + Relevant when FM not runs in "guest-mode". */
78749 + t_Handle h_App; /**< A handle to an application layer object; This handle will
78750 + be passed by the driver upon calling the above callbacks;
78751 + Relevant when FM not runs in "guest-mode". */
78752 + int irq; /**< FM interrupt source for normal events;
78753 + Relevant when FM not runs in "guest-mode". */
78754 + int errIrq; /**< FM interrupt source for errors;
78755 + Relevant when FM not runs in "guest-mode". */
78756 + t_FmFirmwareParams firmware; /**< The firmware parameters structure;
78757 + Relevant when FM not runs in "guest-mode". */
78758 +
78759 +#if (DPAA_VERSION >= 11)
78760 + uintptr_t vspBaseAddr; /**< A pointer to base of memory mapped FM VSP registers (virtual);
78761 + i.e. up to 24KB, depending on the specific chip. */
78762 + uint8_t partVSPBase; /**< The first Virtual-Storage-Profile-id dedicated to this partition.
78763 + NOTE: this parameter relevant only when working with multiple partitions. */
78764 + uint8_t partNumOfVSPs; /**< Number of VSPs dedicated to this partition.
78765 + NOTE: this parameter relevant only when working with multiple partitions. */
78766 +#endif /* (DPAA_VERSION >= 11) */
78767 +} t_FmParams;
78768 +
78769 +
78770 +/**************************************************************************//**
78771 + @Function FM_Config
78772 +
78773 + @Description Creates the FM module and returns its handle (descriptor).
78774 + This descriptor must be passed as first parameter to all other
78775 + FM function calls.
78776 +
78777 + No actual initialization or configuration of FM hardware is
78778 + done by this routine. All FM parameters get default values that
78779 + may be changed by calling one or more of the advance config routines.
78780 +
78781 + @Param[in] p_FmParams - A pointer to a data structure of mandatory FM parameters
78782 +
78783 + @Return A handle to the FM object, or NULL for Failure.
78784 +*//***************************************************************************/
78785 +t_Handle FM_Config(t_FmParams *p_FmParams);
78786 +
78787 +/**************************************************************************//**
78788 + @Function FM_Init
78789 +
78790 + @Description Initializes the FM module by defining the software structure
78791 + and configuring the hardware registers.
78792 +
78793 + @Param[in] h_Fm - FM module descriptor
78794 +
78795 + @Return E_OK on success; Error code otherwise.
78796 +*//***************************************************************************/
78797 +t_Error FM_Init(t_Handle h_Fm);
78798 +
78799 +/**************************************************************************//**
78800 + @Function FM_Free
78801 +
78802 + @Description Frees all resources that were assigned to FM module.
78803 +
78804 + Calling this routine invalidates the descriptor.
78805 +
78806 + @Param[in] h_Fm - FM module descriptor
78807 +
78808 + @Return E_OK on success; Error code otherwise.
78809 +*//***************************************************************************/
78810 +t_Error FM_Free(t_Handle h_Fm);
78811 +
78812 +
78813 +/**************************************************************************//**
78814 + @Group FM_advanced_init_grp FM Advanced Configuration Unit
78815 +
78816 + @Description Advanced configuration routines are optional routines that may
78817 + be called in order to change the default driver settings.
78818 +
78819 + Note: Advanced configuration routines are not available for guest partition.
78820 + @{
78821 +*//***************************************************************************/
78822 +
78823 +/**************************************************************************//**
78824 + @Description Enum for selecting DMA debug mode
78825 +*//***************************************************************************/
78826 +typedef enum e_FmDmaDbgCntMode {
78827 + e_FM_DMA_DBG_NO_CNT = 0, /**< No counting */
78828 + e_FM_DMA_DBG_CNT_DONE, /**< Count DONE commands */
78829 + e_FM_DMA_DBG_CNT_COMM_Q_EM, /**< count command queue emergency signals */
78830 + e_FM_DMA_DBG_CNT_INT_READ_EM, /**< Count Internal Read buffer emergency signal */
78831 + e_FM_DMA_DBG_CNT_INT_WRITE_EM, /**< Count Internal Write buffer emergency signal */
78832 + e_FM_DMA_DBG_CNT_FPM_WAIT, /**< Count FPM WAIT signal */
78833 + e_FM_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors. */
78834 + e_FM_DMA_DBG_CNT_RAW_WAR_PROT /**< Number of times there was a need for RAW & WAR protection. */
78835 +} e_FmDmaDbgCntMode;
78836 +
78837 +/**************************************************************************//**
78838 + @Description Enum for selecting DMA Cache Override
78839 +*//***************************************************************************/
78840 +typedef enum e_FmDmaCacheOverride {
78841 + e_FM_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
78842 + e_FM_DMA_NO_STASH_DATA, /**< Data should not be stashed in system level cache */
78843 + e_FM_DMA_MAY_STASH_DATA, /**< Data may be stashed in system level cache */
78844 + e_FM_DMA_STASH_DATA /**< Data should be stashed in system level cache */
78845 +} e_FmDmaCacheOverride;
78846 +
78847 +/**************************************************************************//**
78848 + @Description Enum for selecting DMA External Bus Priority
78849 +*//***************************************************************************/
78850 +typedef enum e_FmDmaExtBusPri {
78851 + e_FM_DMA_EXT_BUS_NORMAL = 0, /**< Normal priority */
78852 + e_FM_DMA_EXT_BUS_EBS, /**< AXI extended bus service priority */
78853 + e_FM_DMA_EXT_BUS_SOS, /**< AXI sos priority */
78854 + e_FM_DMA_EXT_BUS_EBS_AND_SOS /**< AXI ebs + sos priority */
78855 +} e_FmDmaExtBusPri;
78856 +
78857 +/**************************************************************************//**
78858 + @Description Enum for choosing the field that will be output on AID
78859 +*//***************************************************************************/
78860 +typedef enum e_FmDmaAidMode {
78861 + e_FM_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
78862 + e_FM_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
78863 +} e_FmDmaAidMode;
78864 +
78865 +/**************************************************************************//**
78866 + @Description Enum for selecting FPM Catastrophic error behavior
78867 +*//***************************************************************************/
78868 +typedef enum e_FmCatastrophicErr {
78869 + e_FM_CATASTROPHIC_ERR_STALL_PORT = 0, /**< Port_ID is stalled (only reset can release it) */
78870 + e_FM_CATASTROPHIC_ERR_STALL_TASK /**< Only erroneous task is stalled */
78871 +} e_FmCatastrophicErr;
78872 +
78873 +/**************************************************************************//**
78874 + @Description Enum for selecting FPM DMA Error behavior
78875 +*//***************************************************************************/
78876 +typedef enum e_FmDmaErr {
78877 + e_FM_DMA_ERR_CATASTROPHIC = 0, /**< Dma error is treated as a catastrophic
78878 + error (e_FmCatastrophicErr)*/
78879 + e_FM_DMA_ERR_REPORT /**< Dma error is just reported */
78880 +} e_FmDmaErr;
78881 +
78882 +/**************************************************************************//**
78883 + @Description Enum for selecting DMA Emergency level by BMI emergency signal
78884 +*//***************************************************************************/
78885 +typedef enum e_FmDmaEmergencyLevel {
78886 + e_FM_DMA_EM_EBS = 0, /**< EBS emergency */
78887 + e_FM_DMA_EM_SOS /**< SOS emergency */
78888 +} e_FmDmaEmergencyLevel;
78889 +
78890 +/**************************************************************************//**
78891 + @Collection Enum for selecting DMA Emergency options
78892 +*//***************************************************************************/
78893 +typedef uint32_t fmEmergencyBus_t; /**< DMA emergency options */
78894 +
78895 +#define FM_DMA_MURAM_READ_EMERGENCY 0x00800000 /**< Enable emergency for MURAM1 */
78896 +#define FM_DMA_MURAM_WRITE_EMERGENCY 0x00400000 /**< Enable emergency for MURAM2 */
78897 +#define FM_DMA_EXT_BUS_EMERGENCY 0x00100000 /**< Enable emergency for external bus */
78898 +/* @} */
78899 +
78900 +/**************************************************************************//**
78901 + @Description A structure for defining DMA emergency level
78902 +*//***************************************************************************/
78903 +typedef struct t_FmDmaEmergency {
78904 + fmEmergencyBus_t emergencyBusSelect; /**< An OR of the busses where emergency
78905 + should be enabled */
78906 + e_FmDmaEmergencyLevel emergencyLevel; /**< EBS/SOS */
78907 +} t_FmDmaEmergency;
78908 +
78909 +/**************************************************************************//*
78910 + @Description structure for defining FM threshold
78911 +*//***************************************************************************/
78912 +typedef struct t_FmThresholds {
78913 + uint8_t dispLimit; /**< The number of times a frames may
78914 + be passed in the FM before assumed to
78915 + be looping. */
78916 + uint8_t prsDispTh; /**< This is the number pf packets that may be
78917 + queued in the parser dispatch queue*/
78918 + uint8_t plcrDispTh; /**< This is the number pf packets that may be
78919 + queued in the policer dispatch queue*/
78920 + uint8_t kgDispTh; /**< This is the number pf packets that may be
78921 + queued in the keygen dispatch queue*/
78922 + uint8_t bmiDispTh; /**< This is the number pf packets that may be
78923 + queued in the BMI dispatch queue*/
78924 + uint8_t qmiEnqDispTh; /**< This is the number pf packets that may be
78925 + queued in the QMI enqueue dispatch queue*/
78926 + uint8_t qmiDeqDispTh; /**< This is the number pf packets that may be
78927 + queued in the QMI dequeue dispatch queue*/
78928 + uint8_t fmCtl1DispTh; /**< This is the number pf packets that may be
78929 + queued in fmCtl1 dispatch queue*/
78930 + uint8_t fmCtl2DispTh; /**< This is the number pf packets that may be
78931 + queued in fmCtl2 dispatch queue*/
78932 +} t_FmThresholds;
78933 +
78934 +/**************************************************************************//*
78935 + @Description structure for defining DMA thresholds
78936 +*//***************************************************************************/
78937 +typedef struct t_FmDmaThresholds {
78938 + uint8_t assertEmergency; /**< When this value is reached,
78939 + assert emergency (Threshold)*/
78940 + uint8_t clearEmergency; /**< After emergency is asserted, it is held
78941 + until this value is reached (Hystheresis) */
78942 +} t_FmDmaThresholds;
78943 +
78944 +/**************************************************************************//**
78945 + @Function t_FmResetOnInitOverrideCallback
78946 +
78947 + @Description FMan specific reset on init user callback routine,
78948 + will be used to override the standard FMan reset on init procedure
78949 +
78950 + @Param[in] h_Fm - FMan handler
78951 +*//***************************************************************************/
78952 +typedef void (t_FmResetOnInitOverrideCallback)(t_Handle h_Fm);
78953 +
78954 +/**************************************************************************//**
78955 + @Function FM_ConfigResetOnInit
78956 +
78957 + @Description Define whether to reset the FM before initialization.
78958 + Change the default configuration [DEFAULT_resetOnInit].
78959 +
78960 + @Param[in] h_Fm A handle to an FM Module.
78961 + @Param[in] enable When TRUE, FM will be reset before any initialization.
78962 +
78963 + @Return E_OK on success; Error code otherwise.
78964 +
78965 + @Cautions Allowed only following FM_Config() and before FM_Init().
78966 + This routine should NOT be called from guest-partition
78967 + (i.e. guestId != NCSW_MASTER_ID)
78968 +*//***************************************************************************/
78969 +t_Error FM_ConfigResetOnInit(t_Handle h_Fm, bool enable);
78970 +
78971 +/**************************************************************************//**
78972 + @Function FM_ConfigResetOnInitOverrideCallback
78973 +
78974 + @Description Define a special reset of FM before initialization.
78975 + Change the default configuration [DEFAULT_resetOnInitOverrideCallback].
78976 +
78977 + @Param[in] h_Fm A handle to an FM Module.
78978 + @Param[in] f_ResetOnInitOverride FM specific reset on init user callback routine.
78979 +
78980 + @Return E_OK on success; Error code otherwise.
78981 +
78982 + @Cautions Allowed only following FM_Config() and before FM_Init().
78983 + This routine should NOT be called from guest-partition
78984 + (i.e. guestId != NCSW_MASTER_ID)
78985 +*//***************************************************************************/
78986 +t_Error FM_ConfigResetOnInitOverrideCallback(t_Handle h_Fm, t_FmResetOnInitOverrideCallback *f_ResetOnInitOverride);
78987 +
78988 +/**************************************************************************//**
78989 + @Function FM_ConfigTotalFifoSize
78990 +
78991 + @Description Define Total FIFO size for the whole FM.
78992 + Calling this routine changes the total Fifo size in the internal driver
78993 + data base from its default configuration [DEFAULT_totalFifoSize]
78994 +
78995 + @Param[in] h_Fm A handle to an FM Module.
78996 + @Param[in] totalFifoSize The selected new value.
78997 +
78998 + @Return E_OK on success; Error code otherwise.
78999 +
79000 + @Cautions Allowed only following FM_Config() and before FM_Init().
79001 + This routine should NOT be called from guest-partition
79002 + (i.e. guestId != NCSW_MASTER_ID)
79003 +*//***************************************************************************/
79004 +t_Error FM_ConfigTotalFifoSize(t_Handle h_Fm, uint32_t totalFifoSize);
79005 +
79006 + /**************************************************************************//**
79007 + @Function FM_ConfigDmaCacheOverride
79008 +
79009 + @Description Define cache override mode.
79010 + Calling this routine changes the cache override mode
79011 + in the internal driver data base from its default configuration [DEFAULT_cacheOverride]
79012 +
79013 + @Param[in] h_Fm A handle to an FM Module.
79014 + @Param[in] cacheOverride The selected new value.
79015 +
79016 + @Return E_OK on success; Error code otherwise.
79017 +
79018 + @Cautions Allowed only following FM_Config() and before FM_Init().
79019 + This routine should NOT be called from guest-partition
79020 + (i.e. guestId != NCSW_MASTER_ID)
79021 +*//***************************************************************************/
79022 +t_Error FM_ConfigDmaCacheOverride(t_Handle h_Fm, e_FmDmaCacheOverride cacheOverride);
79023 +
79024 +/**************************************************************************//**
79025 + @Function FM_ConfigDmaAidOverride
79026 +
79027 + @Description Define DMA AID override mode.
79028 + Calling this routine changes the AID override mode
79029 + in the internal driver data base from its default configuration [DEFAULT_aidOverride]
79030 +
79031 + @Param[in] h_Fm A handle to an FM Module.
79032 + @Param[in] aidOverride The selected new value.
79033 +
79034 + @Return E_OK on success; Error code otherwise.
79035 +
79036 + @Cautions Allowed only following FM_Config() and before FM_Init().
79037 + This routine should NOT be called from guest-partition
79038 + (i.e. guestId != NCSW_MASTER_ID)
79039 +*//***************************************************************************/
79040 +t_Error FM_ConfigDmaAidOverride(t_Handle h_Fm, bool aidOverride);
79041 +
79042 +/**************************************************************************//**
79043 + @Function FM_ConfigDmaAidMode
79044 +
79045 + @Description Define DMA AID mode.
79046 + Calling this routine changes the AID mode in the internal
79047 + driver data base from its default configuration [DEFAULT_aidMode]
79048 +
79049 + @Param[in] h_Fm A handle to an FM Module.
79050 + @Param[in] aidMode The selected new value.
79051 +
79052 + @Return E_OK on success; Error code otherwise.
79053 +
79054 + @Cautions Allowed only following FM_Config() and before FM_Init().
79055 + This routine should NOT be called from guest-partition
79056 + (i.e. guestId != NCSW_MASTER_ID)
79057 +*//***************************************************************************/
79058 +t_Error FM_ConfigDmaAidMode(t_Handle h_Fm, e_FmDmaAidMode aidMode);
79059 +
79060 +/**************************************************************************//**
79061 + @Function FM_ConfigDmaAxiDbgNumOfBeats
79062 +
79063 + @Description Define DMA AXI number of beats.
79064 + Calling this routine changes the AXI number of beats in the internal
79065 + driver data base from its default configuration [DEFAULT_axiDbgNumOfBeats]
79066 +
79067 + @Param[in] h_Fm A handle to an FM Module.
79068 + @Param[in] axiDbgNumOfBeats The selected new value.
79069 +
79070 + @Return E_OK on success; Error code otherwise.
79071 +
79072 + @Cautions Allowed only following FM_Config() and before FM_Init().
79073 + This routine should NOT be called from guest-partition
79074 + (i.e. guestId != NCSW_MASTER_ID)
79075 +*//***************************************************************************/
79076 +t_Error FM_ConfigDmaAxiDbgNumOfBeats(t_Handle h_Fm, uint8_t axiDbgNumOfBeats);
79077 +
79078 +/**************************************************************************//**
79079 + @Function FM_ConfigDmaCamNumOfEntries
79080 +
79081 + @Description Define number of CAM entries.
79082 + Calling this routine changes the number of CAM entries in the internal
79083 + driver data base from its default configuration [DEFAULT_dmaCamNumOfEntries].
79084 +
79085 + @Param[in] h_Fm A handle to an FM Module.
79086 + @Param[in] numOfEntries The selected new value.
79087 +
79088 + @Return E_OK on success; Error code otherwise.
79089 +
79090 + @Cautions Allowed only following FM_Config() and before FM_Init().
79091 + This routine should NOT be called from guest-partition
79092 + (i.e. guestId != NCSW_MASTER_ID)
79093 +*//***************************************************************************/
79094 +t_Error FM_ConfigDmaCamNumOfEntries(t_Handle h_Fm, uint8_t numOfEntries);
79095 +
79096 +/**************************************************************************//**
79097 + @Function FM_ConfigEnableCounters
79098 +
79099 + @Description Obsolete, always return E_OK.
79100 +
79101 + @Param[in] h_Fm A handle to an FM Module.
79102 +
79103 + @Return E_OK on success; Error code otherwise.
79104 +*//***************************************************************************/
79105 +t_Error FM_ConfigEnableCounters(t_Handle h_Fm);
79106 +
79107 +/**************************************************************************//**
79108 + @Function FM_ConfigDmaDbgCounter
79109 +
79110 + @Description Define DMA debug counter.
79111 + Calling this routine changes the number of the DMA debug counter in the internal
79112 + driver data base from its default configuration [DEFAULT_dmaDbgCntMode].
79113 +
79114 + @Param[in] h_Fm A handle to an FM Module.
79115 + @Param[in] fmDmaDbgCntMode An enum selecting the debug counter mode.
79116 +
79117 + @Return E_OK on success; Error code otherwise.
79118 +
79119 + @Cautions Allowed only following FM_Config() and before FM_Init().
79120 + This routine should NOT be called from guest-partition
79121 + (i.e. guestId != NCSW_MASTER_ID)
79122 +*//***************************************************************************/
79123 +t_Error FM_ConfigDmaDbgCounter(t_Handle h_Fm, e_FmDmaDbgCntMode fmDmaDbgCntMode);
79124 +
79125 +/**************************************************************************//**
79126 + @Function FM_ConfigDmaStopOnBusErr
79127 +
79128 + @Description Define bus error behavior.
79129 + Calling this routine changes the bus error behavior definition
79130 + in the internal driver data base from its default
79131 + configuration [DEFAULT_dmaStopOnBusError].
79132 +
79133 + @Param[in] h_Fm A handle to an FM Module.
79134 + @Param[in] stop TRUE to stop on bus error, FALSE to continue.
79135 +
79136 + @Return E_OK on success; Error code otherwise.
79137 +
79138 + @Cautions Allowed only following FM_Config() and before FM_Init().
79139 + Only if bus error is enabled.
79140 + This routine should NOT be called from guest-partition
79141 + (i.e. guestId != NCSW_MASTER_ID)
79142 +*//***************************************************************************/
79143 +t_Error FM_ConfigDmaStopOnBusErr(t_Handle h_Fm, bool stop);
79144 +
79145 +/**************************************************************************//**
79146 + @Function FM_ConfigDmaEmergency
79147 +
79148 + @Description Define DMA emergency.
79149 + Calling this routine changes the DMA emergency definition
79150 + in the internal driver data base from its default
79151 + configuration where's it's disabled.
79152 +
79153 + @Param[in] h_Fm A handle to an FM Module.
79154 + @Param[in] p_Emergency An OR mask of all required options.
79155 +
79156 + @Return E_OK on success; Error code otherwise.
79157 +
79158 + @Cautions Allowed only following FM_Config() and before FM_Init().
79159 + This routine should NOT be called from guest-partition
79160 + (i.e. guestId != NCSW_MASTER_ID)
79161 +*//***************************************************************************/
79162 +t_Error FM_ConfigDmaEmergency(t_Handle h_Fm, t_FmDmaEmergency *p_Emergency);
79163 +
79164 +/**************************************************************************//**
79165 + @Function FM_ConfigDmaErr
79166 +
79167 + @Description DMA error treatment.
79168 + Calling this routine changes the DMA error treatment
79169 + in the internal driver data base from its default
79170 + configuration [DEFAULT_dmaErr].
79171 +
79172 + @Param[in] h_Fm A handle to an FM Module.
79173 + @Param[in] dmaErr The selected new choice.
79174 +
79175 + @Return E_OK on success; Error code otherwise.
79176 +
79177 + @Cautions Allowed only following FM_Config() and before FM_Init().
79178 + This routine should NOT be called from guest-partition
79179 + (i.e. guestId != NCSW_MASTER_ID)
79180 +*//***************************************************************************/
79181 +t_Error FM_ConfigDmaErr(t_Handle h_Fm, e_FmDmaErr dmaErr);
79182 +
79183 +/**************************************************************************//**
79184 + @Function FM_ConfigCatastrophicErr
79185 +
79186 + @Description Define FM behavior on catastrophic error.
79187 + Calling this routine changes the FM behavior on catastrophic
79188 + error in the internal driver data base from its default
79189 + [DEFAULT_catastrophicErr].
79190 +
79191 + @Param[in] h_Fm A handle to an FM Module.
79192 + @Param[in] catastrophicErr The selected new choice.
79193 +
79194 + @Return E_OK on success; Error code otherwise.
79195 +
79196 + @Cautions Allowed only following FM_Config() and before FM_Init().
79197 + This routine should NOT be called from guest-partition
79198 + (i.e. guestId != NCSW_MASTER_ID)
79199 +*//***************************************************************************/
79200 +t_Error FM_ConfigCatastrophicErr(t_Handle h_Fm, e_FmCatastrophicErr catastrophicErr);
79201 +
79202 +/**************************************************************************//**
79203 + @Function FM_ConfigEnableMuramTestMode
79204 +
79205 + @Description Enable MURAM test mode.
79206 + Calling this routine changes the internal driver data base
79207 + from its default selection of test mode where it's disabled.
79208 + This routine is only avaiable on old FM revisions (FMan v2).
79209 +
79210 + @Param[in] h_Fm A handle to an FM Module.
79211 +
79212 + @Return E_OK on success; Error code otherwise.
79213 +
79214 + @Cautions Allowed only following FM_Config() and before FM_Init().
79215 + This routine should NOT be called from guest-partition
79216 + (i.e. guestId != NCSW_MASTER_ID)
79217 +*//***************************************************************************/
79218 +t_Error FM_ConfigEnableMuramTestMode(t_Handle h_Fm);
79219 +
79220 +/**************************************************************************//**
79221 + @Function FM_ConfigEnableIramTestMode
79222 +
79223 + @Description Enable IRAM test mode.
79224 + Calling this routine changes the internal driver data base
79225 + from its default selection of test mode where it's disabled.
79226 + This routine is only avaiable on old FM revisions (FMan v2).
79227 +
79228 + @Param[in] h_Fm A handle to an FM Module.
79229 +
79230 + @Return E_OK on success; Error code otherwise.
79231 +
79232 + @Cautions Allowed only following FM_Config() and before FM_Init().
79233 + This routine should NOT be called from guest-partition
79234 + (i.e. guestId != NCSW_MASTER_ID)
79235 +*//***************************************************************************/
79236 +t_Error FM_ConfigEnableIramTestMode(t_Handle h_Fm);
79237 +
79238 +/**************************************************************************//**
79239 + @Function FM_ConfigHaltOnExternalActivation
79240 +
79241 + @Description Define FM behavior on external halt activation.
79242 + Calling this routine changes the FM behavior on external halt
79243 + activation in the internal driver data base from its default
79244 + [DEFAULT_haltOnExternalActivation].
79245 +
79246 + @Param[in] h_Fm A handle to an FM Module.
79247 + @Param[in] enable TRUE to enable halt on external halt
79248 + activation.
79249 +
79250 + @Return E_OK on success; Error code otherwise.
79251 +
79252 + @Cautions Allowed only following FM_Config() and before FM_Init().
79253 + This routine should NOT be called from guest-partition
79254 + (i.e. guestId != NCSW_MASTER_ID)
79255 +*//***************************************************************************/
79256 +t_Error FM_ConfigHaltOnExternalActivation(t_Handle h_Fm, bool enable);
79257 +
79258 +/**************************************************************************//**
79259 + @Function FM_ConfigHaltOnUnrecoverableEccError
79260 +
79261 + @Description Define FM behavior on external halt activation.
79262 + Calling this routine changes the FM behavior on unrecoverable
79263 + ECC error in the internal driver data base from its default
79264 + [DEFAULT_haltOnUnrecoverableEccError].
79265 + This routine is only avaiable on old FM revisions (FMan v2).
79266 +
79267 + @Param[in] h_Fm A handle to an FM Module.
79268 + @Param[in] enable TRUE to enable halt on unrecoverable Ecc error
79269 +
79270 + @Return E_OK on success; Error code otherwise.
79271 +
79272 + @Cautions Allowed only following FM_Config() and before FM_Init().
79273 + This routine should NOT be called from guest-partition
79274 + (i.e. guestId != NCSW_MASTER_ID)
79275 +*//***************************************************************************/
79276 +t_Error FM_ConfigHaltOnUnrecoverableEccError(t_Handle h_Fm, bool enable);
79277 +
79278 +/**************************************************************************//**
79279 + @Function FM_ConfigException
79280 +
79281 + @Description Define FM exceptions.
79282 + Calling this routine changes the exceptions defaults in the
79283 + internal driver data base where all exceptions are enabled.
79284 +
79285 + @Param[in] h_Fm A handle to an FM Module.
79286 + @Param[in] exception The exception to be selected.
79287 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79288 +
79289 + @Return E_OK on success; Error code otherwise.
79290 +
79291 + @Cautions Allowed only following FM_Config() and before FM_Init().
79292 + This routine should NOT be called from guest-partition
79293 + (i.e. guestId != NCSW_MASTER_ID)
79294 +*//***************************************************************************/
79295 +t_Error FM_ConfigException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
79296 +
79297 +/**************************************************************************//**
79298 + @Function FM_ConfigExternalEccRamsEnable
79299 +
79300 + @Description Select external ECC enabling.
79301 + Calling this routine changes the ECC enabling control in the internal
79302 + driver data base from its default [DEFAULT_externalEccRamsEnable].
79303 + When this option is enabled Rams ECC enabling is not effected
79304 + by FM_EnableRamsEcc/FM_DisableRamsEcc, but by a JTAG.
79305 +
79306 + @Param[in] h_Fm A handle to an FM Module.
79307 + @Param[in] enable TRUE to enable this option.
79308 +
79309 + @Return E_OK on success; Error code otherwise.
79310 +
79311 + @Cautions Allowed only following FM_Config() and before FM_Init().
79312 + This routine should NOT be called from guest-partition
79313 + (i.e. guestId != NCSW_MASTER_ID)
79314 +*//***************************************************************************/
79315 +t_Error FM_ConfigExternalEccRamsEnable(t_Handle h_Fm, bool enable);
79316 +
79317 +/**************************************************************************//**
79318 + @Function FM_ConfigTnumAgingPeriod
79319 +
79320 + @Description Define Tnum aging period.
79321 + Calling this routine changes the Tnum aging of dequeue TNUMs
79322 + in the QMI in the internal driver data base from its default
79323 + [DEFAULT_tnumAgingPeriod].
79324 +
79325 + @Param[in] h_Fm A handle to an FM Module.
79326 + @Param[in] tnumAgingPeriod Tnum Aging Period in microseconds.
79327 + Note that period is recalculated in units of
79328 + 64 FM clocks. Driver will pick the closest
79329 + possible period.
79330 +
79331 + @Return E_OK on success; Error code otherwise.
79332 +
79333 + @Cautions Allowed only following FM_Config() and before FM_Init().
79334 + This routine should NOT be called from guest-partition
79335 + (i.e. guestId != NCSW_MASTER_ID)
79336 + NOTE that if some MAC is configured for PFC, '0' value is NOT
79337 + allowed.
79338 +*//***************************************************************************/
79339 +t_Error FM_ConfigTnumAgingPeriod(t_Handle h_Fm, uint16_t tnumAgingPeriod);
79340 +
79341 +/**************************************************************************//*
79342 + @Function FM_ConfigDmaEmergencySmoother
79343 +
79344 + @Description Define DMA emergency smoother.
79345 + Calling this routine changes the definition of the minimum
79346 + amount of DATA beats transferred on the AXI READ and WRITE
79347 + ports before lowering the emergency level.
79348 + By default smoother is disabled.
79349 +
79350 + @Param[in] h_Fm A handle to an FM Module.
79351 + @Param[in] emergencyCnt emergency switching counter.
79352 +
79353 + @Return E_OK on success; Error code otherwise.
79354 +
79355 + @Cautions Allowed only following FM_Config() and before FM_Init().
79356 + This routine should NOT be called from guest-partition
79357 + (i.e. guestId != NCSW_MASTER_ID)
79358 +*//***************************************************************************/
79359 +t_Error FM_ConfigDmaEmergencySmoother(t_Handle h_Fm, uint32_t emergencyCnt);
79360 +
79361 +/**************************************************************************//*
79362 + @Function FM_ConfigThresholds
79363 +
79364 + @Description Calling this routine changes the internal driver data base
79365 + from its default FM threshold configuration:
79366 + dispLimit: [DEFAULT_dispLimit]
79367 + prsDispTh: [DEFAULT_prsDispTh]
79368 + plcrDispTh: [DEFAULT_plcrDispTh]
79369 + kgDispTh: [DEFAULT_kgDispTh]
79370 + bmiDispTh: [DEFAULT_bmiDispTh]
79371 + qmiEnqDispTh: [DEFAULT_qmiEnqDispTh]
79372 + qmiDeqDispTh: [DEFAULT_qmiDeqDispTh]
79373 + fmCtl1DispTh: [DEFAULT_fmCtl1DispTh]
79374 + fmCtl2DispTh: [DEFAULT_fmCtl2DispTh]
79375 +
79376 +
79377 + @Param[in] h_Fm A handle to an FM Module.
79378 + @Param[in] p_FmThresholds A structure of threshold parameters.
79379 +
79380 + @Return E_OK on success; Error code otherwise.
79381 +
79382 + @Cautions Allowed only following FM_Config() and before FM_Init().
79383 + This routine should NOT be called from guest-partition
79384 + (i.e. guestId != NCSW_MASTER_ID)
79385 +*//***************************************************************************/
79386 +t_Error FM_ConfigThresholds(t_Handle h_Fm, t_FmThresholds *p_FmThresholds);
79387 +
79388 +/**************************************************************************//*
79389 + @Function FM_ConfigDmaSosEmergencyThreshold
79390 +
79391 + @Description Calling this routine changes the internal driver data base
79392 + from its default dma SOS emergency configuration [DEFAULT_dmaSosEmergency]
79393 +
79394 + @Param[in] h_Fm A handle to an FM Module.
79395 + @Param[in] dmaSosEmergency The selected new value.
79396 +
79397 + @Return E_OK on success; Error code otherwise.
79398 +
79399 + @Cautions Allowed only following FM_Config() and before FM_Init().
79400 + This routine should NOT be called from guest-partition
79401 + (i.e. guestId != NCSW_MASTER_ID)
79402 +*//***************************************************************************/
79403 +t_Error FM_ConfigDmaSosEmergencyThreshold(t_Handle h_Fm, uint32_t dmaSosEmergency);
79404 +
79405 +/**************************************************************************//*
79406 + @Function FM_ConfigDmaWriteBufThresholds
79407 +
79408 + @Description Calling this routine changes the internal driver data base
79409 + from its default configuration of DMA write buffer threshold
79410 + assertEmergency: [DEFAULT_dmaWriteIntBufLow]
79411 + clearEmergency: [DEFAULT_dmaWriteIntBufHigh]
79412 + This routine is only avaiable on old FM revisions (FMan v2).
79413 +
79414 + @Param[in] h_Fm A handle to an FM Module.
79415 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
79416 + When 'assertEmergency' value is reached, emergency is asserted,
79417 + then it is held until 'clearEmergency' value is reached.
79418 +
79419 + @Return E_OK on success; Error code otherwise.
79420 +
79421 + @Cautions Allowed only following FM_Config() and before FM_Init().
79422 + This routine should NOT be called from guest-partition
79423 + (i.e. guestId != NCSW_MASTER_ID)
79424 +*//***************************************************************************/
79425 +t_Error FM_ConfigDmaWriteBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
79426 +
79427 + /**************************************************************************//*
79428 + @Function FM_ConfigDmaCommQThresholds
79429 +
79430 + @Description Calling this routine changes the internal driver data base
79431 + from its default configuration of DMA command queue threshold
79432 + assertEmergency: [DEFAULT_dmaCommQLow]
79433 + clearEmergency: [DEFAULT_dmaCommQHigh]
79434 +
79435 + @Param[in] h_Fm A handle to an FM Module.
79436 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
79437 + When 'assertEmergency' value is reached, emergency is asserted,
79438 + then it is held until 'clearEmergency' value is reached..
79439 +
79440 + @Return E_OK on success; Error code otherwise.
79441 +
79442 + @Cautions Allowed only following FM_Config() and before FM_Init().
79443 + This routine should NOT be called from guest-partition
79444 + (i.e. guestId != NCSW_MASTER_ID)
79445 +*//***************************************************************************/
79446 +t_Error FM_ConfigDmaCommQThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
79447 +
79448 +/**************************************************************************//*
79449 + @Function FM_ConfigDmaReadBufThresholds
79450 +
79451 + @Description Calling this routine changes the internal driver data base
79452 + from its default configuration of DMA read buffer threshold
79453 + assertEmergency: [DEFAULT_dmaReadIntBufLow]
79454 + clearEmergency: [DEFAULT_dmaReadIntBufHigh]
79455 + This routine is only avaiable on old FM revisions (FMan v2).
79456 +
79457 + @Param[in] h_Fm A handle to an FM Module.
79458 + @Param[in] p_FmDmaThresholds A structure of thresholds to define emergency behavior -
79459 + When 'assertEmergency' value is reached, emergency is asserted,
79460 + then it is held until 'clearEmergency' value is reached..
79461 +
79462 + @Return E_OK on success; Error code otherwise.
79463 +
79464 + @Cautions Allowed only following FM_Config() and before FM_Init().
79465 + This routine should NOT be called from guest-partition
79466 + (i.e. guestId != NCSW_MASTER_ID)
79467 +*//***************************************************************************/
79468 +t_Error FM_ConfigDmaReadBufThresholds(t_Handle h_Fm, t_FmDmaThresholds *p_FmDmaThresholds);
79469 +
79470 +/**************************************************************************//*
79471 + @Function FM_ConfigDmaWatchdog
79472 +
79473 + @Description Calling this routine changes the internal driver data base
79474 + from its default watchdog configuration, which is disabled
79475 + [DEFAULT_dmaWatchdog].
79476 +
79477 + @Param[in] h_Fm A handle to an FM Module.
79478 + @Param[in] watchDogValue The selected new value - in microseconds.
79479 +
79480 + @Return E_OK on success; Error code otherwise.
79481 +
79482 + @Cautions Allowed only following FM_Config() and before FM_Init().
79483 + This routine should NOT be called from guest-partition
79484 + (i.e. guestId != NCSW_MASTER_ID)
79485 +*//***************************************************************************/
79486 +t_Error FM_ConfigDmaWatchdog(t_Handle h_Fm, uint32_t watchDogValue);
79487 +
79488 +/** @} */ /* end of FM_advanced_init_grp group */
79489 +/** @} */ /* end of FM_init_grp group */
79490 +
79491 +
79492 +/**************************************************************************//**
79493 + @Group FM_runtime_control_grp FM Runtime Control Unit
79494 +
79495 + @Description FM Runtime control unit API functions, definitions and enums.
79496 + The FM driver provides a set of control routines.
79497 + These routines may only be called after the module was fully
79498 + initialized (both configuration and initialization routines were
79499 + called). They are typically used to get information from hardware
79500 + (status, counters/statistics, revision etc.), to modify a current
79501 + state or to force/enable a required action. Run-time control may
79502 + be called whenever necessary and as many times as needed.
79503 + @{
79504 +*//***************************************************************************/
79505 +
79506 +/**************************************************************************//**
79507 + @Collection General FM defines.
79508 +*//***************************************************************************/
79509 +#define FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
79510 + FM_MAX_NUM_OF_1G_RX_PORTS + \
79511 + FM_MAX_NUM_OF_10G_RX_PORTS + \
79512 + FM_MAX_NUM_OF_1G_TX_PORTS + \
79513 + FM_MAX_NUM_OF_10G_TX_PORTS) /**< Number of available FM ports */
79514 +/* @} */
79515 +
79516 +/**************************************************************************//*
79517 + @Description A Structure for Port bandwidth requirement. Port is identified
79518 + by type and relative id.
79519 +*//***************************************************************************/
79520 +typedef struct t_FmPortBandwidth {
79521 + e_FmPortType type; /**< FM port type */
79522 + uint8_t relativePortId; /**< Type relative port id */
79523 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
79524 +} t_FmPortBandwidth;
79525 +
79526 +/**************************************************************************//*
79527 + @Description A Structure containing an array of Port bandwidth requirements.
79528 + The user should state the ports requiring bandwidth in terms of
79529 + percentage - i.e. all port's bandwidths in the array must add
79530 + up to 100.
79531 +*//***************************************************************************/
79532 +typedef struct t_FmPortsBandwidthParams {
79533 + uint8_t numOfPorts; /**< The number of relevant ports, which is the
79534 + number of valid entries in the array below */
79535 + t_FmPortBandwidth portsBandwidths[FM_MAX_NUM_OF_VALID_PORTS];
79536 + /**< for each port, it's bandwidth (all port's
79537 + bandwidths must add up to 100.*/
79538 +} t_FmPortsBandwidthParams;
79539 +
79540 +/**************************************************************************//**
79541 + @Description DMA Emergency control on MURAM
79542 +*//***************************************************************************/
79543 +typedef enum e_FmDmaMuramPort {
79544 + e_FM_DMA_MURAM_PORT_WRITE, /**< MURAM write port */
79545 + e_FM_DMA_MURAM_PORT_READ /**< MURAM read port */
79546 +} e_FmDmaMuramPort;
79547 +
79548 +/**************************************************************************//**
79549 + @Description Enum for defining FM counters
79550 +*//***************************************************************************/
79551 +typedef enum e_FmCounters {
79552 + e_FM_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI total enqueued frames counter */
79553 + e_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
79554 + e_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
79555 + e_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
79556 + e_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
79557 + e_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
79558 + e_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
79559 + e_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
79560 + e_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
79561 + e_FM_COUNTERS_DEQ_CONFIRM /**< QMI dequeue confirm counter */
79562 +} e_FmCounters;
79563 +
79564 +/**************************************************************************//**
79565 + @Description A Structure for returning FM revision information
79566 +*//***************************************************************************/
79567 +typedef struct t_FmRevisionInfo {
79568 + uint8_t majorRev; /**< Major revision */
79569 + uint8_t minorRev; /**< Minor revision */
79570 +} t_FmRevisionInfo;
79571 +
79572 +/**************************************************************************//**
79573 + @Description A Structure for returning FM ctrl code revision information
79574 +*//***************************************************************************/
79575 +typedef struct t_FmCtrlCodeRevisionInfo {
79576 + uint16_t packageRev; /**< Package revision */
79577 + uint8_t majorRev; /**< Major revision */
79578 + uint8_t minorRev; /**< Minor revision */
79579 +} t_FmCtrlCodeRevisionInfo;
79580 +
79581 +/**************************************************************************//**
79582 + @Description A Structure for defining DMA status
79583 +*//***************************************************************************/
79584 +typedef struct t_FmDmaStatus {
79585 + bool cmqNotEmpty; /**< Command queue is not empty */
79586 + bool busError; /**< Bus error occurred */
79587 + bool readBufEccError; /**< Double ECC error on buffer Read (Valid for FM rev < 6)*/
79588 + bool writeBufEccSysError; /**< Double ECC error on buffer write from system side (Valid for FM rev < 6)*/
79589 + bool writeBufEccFmError; /**< Double ECC error on buffer write from FM side (Valid for FM rev < 6) */
79590 + bool singlePortEccError; /**< Single Port ECC error from FM side (Valid for FM rev >= 6)*/
79591 +} t_FmDmaStatus;
79592 +
79593 +/**************************************************************************//**
79594 + @Description A Structure for obtaining FM controller monitor values
79595 +*//***************************************************************************/
79596 +typedef struct t_FmCtrlMon {
79597 + uint8_t percentCnt[2]; /**< Percentage value */
79598 +} t_FmCtrlMon;
79599 +
79600 +
79601 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
79602 +/**************************************************************************//**
79603 + @Function FM_DumpRegs
79604 +
79605 + @Description Dumps all FM registers
79606 +
79607 + @Param[in] h_Fm A handle to an FM Module.
79608 +
79609 + @Return E_OK on success;
79610 +
79611 + @Cautions Allowed only following FM_Init().
79612 +*//***************************************************************************/
79613 +t_Error FM_DumpRegs(t_Handle h_Fm);
79614 +#endif /* (defined(DEBUG_ERRORS) && ... */
79615 +
79616 +/**************************************************************************//**
79617 + @Function FM_SetException
79618 +
79619 + @Description Calling this routine enables/disables the specified exception.
79620 +
79621 + @Param[in] h_Fm A handle to an FM Module.
79622 + @Param[in] exception The exception to be selected.
79623 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
79624 +
79625 + @Return E_OK on success; Error code otherwise.
79626 +
79627 + @Cautions Allowed only following FM_Init().
79628 + This routine should NOT be called from guest-partition
79629 + (i.e. guestId != NCSW_MASTER_ID)
79630 +*//***************************************************************************/
79631 +t_Error FM_SetException(t_Handle h_Fm, e_FmExceptions exception, bool enable);
79632 +
79633 +/**************************************************************************//**
79634 + @Function FM_EnableRamsEcc
79635 +
79636 + @Description Enables ECC mechanism for all the different FM RAM's; E.g. IRAM,
79637 + MURAM, Parser, Keygen, Policer, etc.
79638 + Note:
79639 + If FM_ConfigExternalEccRamsEnable was called to enable external
79640 + setting of ECC, this routine effects IRAM ECC only.
79641 + This routine is also called by the driver if an ECC exception is
79642 + enabled.
79643 +
79644 + @Param[in] h_Fm A handle to an FM Module.
79645 +
79646 + @Return E_OK on success; Error code otherwise.
79647 +
79648 + @Cautions Allowed only following FM_Config() and before FM_Init().
79649 + This routine should NOT be called from guest-partition
79650 + (i.e. guestId != NCSW_MASTER_ID)
79651 +*//***************************************************************************/
79652 +t_Error FM_EnableRamsEcc(t_Handle h_Fm);
79653 +
79654 +/**************************************************************************//**
79655 + @Function FM_DisableRamsEcc
79656 +
79657 + @Description Disables ECC mechanism for all the different FM RAM's; E.g. IRAM,
79658 + MURAM, Parser, Keygen, Policer, etc.
79659 + Note:
79660 + If FM_ConfigExternalEccRamsEnable was called to enable external
79661 + setting of ECC, this routine effects IRAM ECC only.
79662 + In opposed to FM_EnableRamsEcc, this routine must be called
79663 + explicitly to disable all Rams ECC.
79664 +
79665 + @Param[in] h_Fm A handle to an FM Module.
79666 +
79667 + @Return E_OK on success; Error code otherwise.
79668 +
79669 + @Cautions Allowed only following FM_Config() and before FM_Init().
79670 + This routine should NOT be called from guest-partition
79671 + (i.e. guestId != NCSW_MASTER_ID)
79672 +*//***************************************************************************/
79673 +t_Error FM_DisableRamsEcc(t_Handle h_Fm);
79674 +
79675 +/**************************************************************************//**
79676 + @Function FM_GetRevision
79677 +
79678 + @Description Returns the FM revision
79679 +
79680 + @Param[in] h_Fm A handle to an FM Module.
79681 + @Param[out] p_FmRevisionInfo A structure of revision information parameters.
79682 +
79683 + @Return E_OK on success; Error code otherwise.
79684 +
79685 + @Cautions Allowed only following FM_Init().
79686 +*//***************************************************************************/
79687 +t_Error FM_GetRevision(t_Handle h_Fm, t_FmRevisionInfo *p_FmRevisionInfo);
79688 +
79689 +/**************************************************************************//**
79690 + @Function FM_GetFmanCtrlCodeRevision
79691 +
79692 + @Description Returns the Fman controller code revision
79693 +
79694 + @Param[in] h_Fm A handle to an FM Module.
79695 + @Param[out] p_RevisionInfo A structure of revision information parameters.
79696 +
79697 + @Return E_OK on success; Error code otherwise.
79698 +
79699 + @Cautions Allowed only following FM_Init().
79700 +*//***************************************************************************/
79701 +t_Error FM_GetFmanCtrlCodeRevision(t_Handle h_Fm, t_FmCtrlCodeRevisionInfo *p_RevisionInfo);
79702 +
79703 +/**************************************************************************//**
79704 + @Function FM_GetCounter
79705 +
79706 + @Description Reads one of the FM counters.
79707 +
79708 + @Param[in] h_Fm A handle to an FM Module.
79709 + @Param[in] counter The requested counter.
79710 +
79711 + @Return Counter's current value.
79712 +
79713 + @Cautions Allowed only following FM_Init().
79714 + Note that it is user's responsibility to call this routine only
79715 + for enabled counters, and there will be no indication if a
79716 + disabled counter is accessed.
79717 +*//***************************************************************************/
79718 +uint32_t FM_GetCounter(t_Handle h_Fm, e_FmCounters counter);
79719 +
79720 +/**************************************************************************//**
79721 + @Function FM_ModifyCounter
79722 +
79723 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
79724 +
79725 + @Param[in] h_Fm A handle to an FM Module.
79726 + @Param[in] counter The requested counter.
79727 + @Param[in] val The requested value to be written into the counter.
79728 +
79729 + @Return E_OK on success; Error code otherwise.
79730 +
79731 + @Cautions Allowed only following FM_Init().
79732 + This routine should NOT be called from guest-partition
79733 + (i.e. guestId != NCSW_MASTER_ID)
79734 +*//***************************************************************************/
79735 +t_Error FM_ModifyCounter(t_Handle h_Fm, e_FmCounters counter, uint32_t val);
79736 +
79737 +/**************************************************************************//**
79738 + @Function FM_Resume
79739 +
79740 + @Description Release FM after halt FM command or after unrecoverable ECC error.
79741 +
79742 + @Param[in] h_Fm A handle to an FM Module.
79743 +
79744 + @Return E_OK on success; Error code otherwise.
79745 +
79746 + @Cautions Allowed only following FM_Init().
79747 + This routine should NOT be called from guest-partition
79748 + (i.e. guestId != NCSW_MASTER_ID)
79749 +*//***************************************************************************/
79750 +void FM_Resume(t_Handle h_Fm);
79751 +
79752 +/**************************************************************************//**
79753 + @Function FM_SetDmaEmergency
79754 +
79755 + @Description Manual emergency set
79756 +
79757 + @Param[in] h_Fm A handle to an FM Module.
79758 + @Param[in] muramPort MURAM direction select.
79759 + @Param[in] enable TRUE to manually enable emergency, FALSE to disable.
79760 +
79761 + @Return None.
79762 +
79763 + @Cautions Allowed only following FM_Init().
79764 + This routine should NOT be called from guest-partition
79765 + (i.e. guestId != NCSW_MASTER_ID)
79766 +*//***************************************************************************/
79767 +void FM_SetDmaEmergency(t_Handle h_Fm, e_FmDmaMuramPort muramPort, bool enable);
79768 +
79769 +/**************************************************************************//**
79770 + @Function FM_SetDmaExtBusPri
79771 +
79772 + @Description Set the DMA external bus priority
79773 +
79774 + @Param[in] h_Fm A handle to an FM Module.
79775 + @Param[in] pri External bus priority select
79776 +
79777 + @Return None.
79778 +
79779 + @Cautions Allowed only following FM_Init().
79780 + This routine should NOT be called from guest-partition
79781 + (i.e. guestId != NCSW_MASTER_ID)
79782 +*//***************************************************************************/
79783 +void FM_SetDmaExtBusPri(t_Handle h_Fm, e_FmDmaExtBusPri pri);
79784 +
79785 +/**************************************************************************//**
79786 + @Function FM_GetDmaStatus
79787 +
79788 + @Description Reads the DMA current status
79789 +
79790 + @Param[in] h_Fm A handle to an FM Module.
79791 + @Param[out] p_FmDmaStatus A structure of DMA status parameters.
79792 +
79793 + @Cautions Allowed only following FM_Init().
79794 +*//***************************************************************************/
79795 +void FM_GetDmaStatus(t_Handle h_Fm, t_FmDmaStatus *p_FmDmaStatus);
79796 +
79797 +/**************************************************************************//**
79798 + @Function FM_ErrorIsr
79799 +
79800 + @Description FM interrupt-service-routine for errors.
79801 +
79802 + @Param[in] h_Fm A handle to an FM Module.
79803 +
79804 + @Return E_OK on success; E_EMPTY if no errors found in register, other
79805 + error code otherwise.
79806 +
79807 + @Cautions Allowed only following FM_Init().
79808 + This routine should NOT be called from guest-partition
79809 + (i.e. guestId != NCSW_MASTER_ID)
79810 +*//***************************************************************************/
79811 +t_Error FM_ErrorIsr(t_Handle h_Fm);
79812 +
79813 +/**************************************************************************//**
79814 + @Function FM_EventIsr
79815 +
79816 + @Description FM interrupt-service-routine for normal events.
79817 +
79818 + @Param[in] h_Fm A handle to an FM Module.
79819 +
79820 + @Cautions Allowed only following FM_Init().
79821 + This routine should NOT be called from guest-partition
79822 + (i.e. guestId != NCSW_MASTER_ID)
79823 +*//***************************************************************************/
79824 +void FM_EventIsr(t_Handle h_Fm);
79825 +
79826 +/**************************************************************************//**
79827 + @Function FM_GetSpecialOperationCoding
79828 +
79829 + @Description Return a specific coding according to the input mask.
79830 +
79831 + @Param[in] h_Fm A handle to an FM Module.
79832 + @Param[in] spOper special operation mask.
79833 + @Param[out] p_SpOperCoding special operation code.
79834 +
79835 + @Return E_OK on success; Error code otherwise.
79836 +
79837 + @Cautions Allowed only following FM_Init().
79838 +*//***************************************************************************/
79839 +t_Error FM_GetSpecialOperationCoding(t_Handle h_Fm,
79840 + fmSpecialOperations_t spOper,
79841 + uint8_t *p_SpOperCoding);
79842 +
79843 +/**************************************************************************//**
79844 + @Function FM_CtrlMonStart
79845 +
79846 + @Description Start monitoring utilization of all available FM controllers.
79847 +
79848 + In order to obtain FM controllers utilization the following sequence
79849 + should be used:
79850 + -# FM_CtrlMonStart()
79851 + -# FM_CtrlMonStop()
79852 + -# FM_CtrlMonGetCounters() - issued for each FM controller
79853 +
79854 + @Param[in] h_Fm A handle to an FM Module.
79855 +
79856 + @Return E_OK on success; Error code otherwise.
79857 +
79858 + @Cautions Allowed only following FM_Init().
79859 + This routine should NOT be called from guest-partition
79860 + (i.e. guestId != NCSW_MASTER_ID).
79861 +*//***************************************************************************/
79862 +t_Error FM_CtrlMonStart(t_Handle h_Fm);
79863 +
79864 +/**************************************************************************//**
79865 + @Function FM_CtrlMonStop
79866 +
79867 + @Description Stop monitoring utilization of all available FM controllers.
79868 +
79869 + In order to obtain FM controllers utilization the following sequence
79870 + should be used:
79871 + -# FM_CtrlMonStart()
79872 + -# FM_CtrlMonStop()
79873 + -# FM_CtrlMonGetCounters() - issued for each FM controller
79874 +
79875 + @Param[in] h_Fm A handle to an FM Module.
79876 +
79877 + @Return E_OK on success; Error code otherwise.
79878 +
79879 + @Cautions Allowed only following FM_Init().
79880 + This routine should NOT be called from guest-partition
79881 + (i.e. guestId != NCSW_MASTER_ID).
79882 +*//***************************************************************************/
79883 +t_Error FM_CtrlMonStop(t_Handle h_Fm);
79884 +
79885 +/**************************************************************************//**
79886 + @Function FM_CtrlMonGetCounters
79887 +
79888 + @Description Obtain FM controller utilization parameters.
79889 +
79890 + In order to obtain FM controllers utilization the following sequence
79891 + should be used:
79892 + -# FM_CtrlMonStart()
79893 + -# FM_CtrlMonStop()
79894 + -# FM_CtrlMonGetCounters() - issued for each FM controller
79895 +
79896 + @Param[in] h_Fm A handle to an FM Module.
79897 + @Param[in] fmCtrlIndex FM Controller index for that utilization results
79898 + are requested.
79899 + @Param[in] p_Mon Pointer to utilization results structure.
79900 +
79901 + @Return E_OK on success; Error code otherwise.
79902 +
79903 + @Cautions Allowed only following FM_Init().
79904 + This routine should NOT be called from guest-partition
79905 + (i.e. guestId != NCSW_MASTER_ID).
79906 +*//***************************************************************************/
79907 +t_Error FM_CtrlMonGetCounters(t_Handle h_Fm, uint8_t fmCtrlIndex, t_FmCtrlMon *p_Mon);
79908 +
79909 +
79910 +/**************************************************************************//*
79911 + @Function FM_ForceIntr
79912 +
79913 + @Description Causes an interrupt event on the requested source.
79914 +
79915 + @Param[in] h_Fm A handle to an FM Module.
79916 + @Param[in] exception An exception to be forced.
79917 +
79918 + @Return E_OK on success; Error code if the exception is not enabled,
79919 + or is not able to create interrupt.
79920 +
79921 + @Cautions Allowed only following FM_Init().
79922 + This routine should NOT be called from guest-partition
79923 + (i.e. guestId != NCSW_MASTER_ID)
79924 +*//***************************************************************************/
79925 +t_Error FM_ForceIntr (t_Handle h_Fm, e_FmExceptions exception);
79926 +
79927 +/**************************************************************************//*
79928 + @Function FM_SetPortsBandwidth
79929 +
79930 + @Description Sets relative weights between ports when accessing common resources.
79931 +
79932 + @Param[in] h_Fm A handle to an FM Module.
79933 + @Param[in] p_PortsBandwidth A structure of ports bandwidths in percentage, i.e.
79934 + total must equal 100.
79935 +
79936 + @Return E_OK on success; Error code otherwise.
79937 +
79938 + @Cautions Allowed only following FM_Init().
79939 + This routine should NOT be called from guest-partition
79940 + (i.e. guestId != NCSW_MASTER_ID)
79941 +*//***************************************************************************/
79942 +t_Error FM_SetPortsBandwidth(t_Handle h_Fm, t_FmPortsBandwidthParams *p_PortsBandwidth);
79943 +
79944 +/**************************************************************************//*
79945 + @Function FM_GetMuramHandle
79946 +
79947 + @Description Gets the corresponding MURAM handle
79948 +
79949 + @Param[in] h_Fm A handle to an FM Module.
79950 +
79951 + @Return MURAM handle; NULL otherwise.
79952 +
79953 + @Cautions Allowed only following FM_Init().
79954 + This routine should NOT be called from guest-partition
79955 + (i.e. guestId != NCSW_MASTER_ID)
79956 +*//***************************************************************************/
79957 +t_Handle FM_GetMuramHandle(t_Handle h_Fm);
79958 +
79959 +/** @} */ /* end of FM_runtime_control_grp group */
79960 +/** @} */ /* end of FM_lib_grp group */
79961 +/** @} */ /* end of FM_grp group */
79962 +
79963 +
79964 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
79965 +typedef t_FmFirmwareParams t_FmPcdFirmwareParams;
79966 +typedef t_FmBufferPrefixContent t_FmPortBufferPrefixContent;
79967 +typedef t_FmExtPoolParams t_FmPortExtPoolParams;
79968 +typedef t_FmExtPools t_FmPortExtPools;
79969 +typedef t_FmBackupBmPools t_FmPortBackupBmPools;
79970 +typedef t_FmBufPoolDepletion t_FmPortBufPoolDepletion;
79971 +typedef e_FmDmaSwapOption e_FmPortDmaSwapOption;
79972 +typedef e_FmDmaCacheOption e_FmPortDmaCacheOption;
79973 +
79974 +#define FM_CONTEXTA_GET_OVVERIDE FM_CONTEXTA_GET_OVERRIDE
79975 +#define FM_CONTEXTA_SET_OVVERIDE FM_CONTEXTA_SET_OVERRIDE
79976 +
79977 +#define e_FM_EX_BMI_PIPELINE_ECC e_FM_EX_BMI_STORAGE_PROFILE_ECC
79978 +#define e_FM_PORT_DMA_NO_SWP e_FM_DMA_NO_SWP
79979 +#define e_FM_PORT_DMA_SWP_PPC_LE e_FM_DMA_SWP_PPC_LE
79980 +#define e_FM_PORT_DMA_SWP_BE e_FM_DMA_SWP_BE
79981 +#define e_FM_PORT_DMA_NO_STASH e_FM_DMA_NO_STASH
79982 +#define e_FM_PORT_DMA_STASH e_FM_DMA_STASH
79983 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
79984 +
79985 +
79986 +#endif /* __FM_EXT */
79987 --- /dev/null
79988 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_mac_ext.h
79989 @@ -0,0 +1,887 @@
79990 +/*
79991 + * Copyright 2008-2012 Freescale Semiconductor Inc.
79992 + *
79993 + * Redistribution and use in source and binary forms, with or without
79994 + * modification, are permitted provided that the following conditions are met:
79995 + * * Redistributions of source code must retain the above copyright
79996 + * notice, this list of conditions and the following disclaimer.
79997 + * * Redistributions in binary form must reproduce the above copyright
79998 + * notice, this list of conditions and the following disclaimer in the
79999 + * documentation and/or other materials provided with the distribution.
80000 + * * Neither the name of Freescale Semiconductor nor the
80001 + * names of its contributors may be used to endorse or promote products
80002 + * derived from this software without specific prior written permission.
80003 + *
80004 + *
80005 + * ALTERNATIVELY, this software may be distributed under the terms of the
80006 + * GNU General Public License ("GPL") as published by the Free Software
80007 + * Foundation, either version 2 of that License or (at your option) any
80008 + * later version.
80009 + *
80010 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80011 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80012 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80013 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80014 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80015 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80016 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80017 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80018 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80019 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80020 + */
80021 +
80022 +
80023 +/**************************************************************************//**
80024 + @File fm_mac_ext.h
80025 +
80026 + @Description FM MAC ...
80027 +*//***************************************************************************/
80028 +#ifndef __FM_MAC_EXT_H
80029 +#define __FM_MAC_EXT_H
80030 +
80031 +#include "std_ext.h"
80032 +#include "enet_ext.h"
80033 +
80034 +
80035 +/**************************************************************************//**
80036 +
80037 + @Group FM_grp Frame Manager API
80038 +
80039 + @Description FM API functions, definitions and enums
80040 +
80041 + @{
80042 +*//***************************************************************************/
80043 +
80044 +/**************************************************************************//**
80045 + @Group FM_mac_grp FM MAC
80046 +
80047 + @Description FM MAC API functions, definitions and enums
80048 +
80049 + @{
80050 +*//***************************************************************************/
80051 +
80052 +#define FM_MAC_NO_PFC 0xff
80053 +
80054 +
80055 +/**************************************************************************//**
80056 + @Description FM MAC Exceptions
80057 +*//***************************************************************************/
80058 +typedef enum e_FmMacExceptions {
80059 + e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0 /**< 10GEC MDIO scan event interrupt */
80060 + ,e_FM_MAC_EX_10G_MDIO_CMD_CMPL /**< 10GEC MDIO command completion interrupt */
80061 + ,e_FM_MAC_EX_10G_REM_FAULT /**< 10GEC, mEMAC Remote fault interrupt */
80062 + ,e_FM_MAC_EX_10G_LOC_FAULT /**< 10GEC, mEMAC Local fault interrupt */
80063 + ,e_FM_MAC_EX_10G_1TX_ECC_ER /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
80064 + ,e_FM_MAC_EX_10G_TX_FIFO_UNFL /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
80065 + ,e_FM_MAC_EX_10G_TX_FIFO_OVFL /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
80066 + ,e_FM_MAC_EX_10G_TX_ER /**< 10GEC Transmit frame error interrupt */
80067 + ,e_FM_MAC_EX_10G_RX_FIFO_OVFL /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
80068 + ,e_FM_MAC_EX_10G_RX_ECC_ER /**< 10GEC, mEMAC Receive frame ECC error interrupt */
80069 + ,e_FM_MAC_EX_10G_RX_JAB_FRM /**< 10GEC Receive jabber frame interrupt */
80070 + ,e_FM_MAC_EX_10G_RX_OVRSZ_FRM /**< 10GEC Receive oversized frame interrupt */
80071 + ,e_FM_MAC_EX_10G_RX_RUNT_FRM /**< 10GEC Receive runt frame interrupt */
80072 + ,e_FM_MAC_EX_10G_RX_FRAG_FRM /**< 10GEC Receive fragment frame interrupt */
80073 + ,e_FM_MAC_EX_10G_RX_LEN_ER /**< 10GEC Receive payload length error interrupt */
80074 + ,e_FM_MAC_EX_10G_RX_CRC_ER /**< 10GEC Receive CRC error interrupt */
80075 + ,e_FM_MAC_EX_10G_RX_ALIGN_ER /**< 10GEC Receive alignment error interrupt */
80076 + ,e_FM_MAC_EX_1G_BAB_RX /**< dTSEC Babbling receive error */
80077 + ,e_FM_MAC_EX_1G_RX_CTL /**< dTSEC Receive control (pause frame) interrupt */
80078 + ,e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET /**< dTSEC Graceful transmit stop complete */
80079 + ,e_FM_MAC_EX_1G_BAB_TX /**< dTSEC Babbling transmit error */
80080 + ,e_FM_MAC_EX_1G_TX_CTL /**< dTSEC Transmit control (pause frame) interrupt */
80081 + ,e_FM_MAC_EX_1G_TX_ERR /**< dTSEC Transmit error */
80082 + ,e_FM_MAC_EX_1G_LATE_COL /**< dTSEC Late collision */
80083 + ,e_FM_MAC_EX_1G_COL_RET_LMT /**< dTSEC Collision retry limit */
80084 + ,e_FM_MAC_EX_1G_TX_FIFO_UNDRN /**< dTSEC Transmit FIFO underrun */
80085 + ,e_FM_MAC_EX_1G_MAG_PCKT /**< dTSEC Magic Packet detection */
80086 + ,e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET /**< dTSEC MII management read completion */
80087 + ,e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET /**< dTSEC MII management write completion */
80088 + ,e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET /**< dTSEC Graceful receive stop complete */
80089 + ,e_FM_MAC_EX_1G_TX_DATA_ERR /**< dTSEC Internal data error on transmit */
80090 + ,e_FM_MAC_EX_1G_RX_DATA_ERR /**< dTSEC Internal data error on receive */
80091 + ,e_FM_MAC_EX_1G_1588_TS_RX_ERR /**< dTSEC Time-Stamp Receive Error */
80092 + ,e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL /**< dTSEC MIB counter overflow */
80093 + ,e_FM_MAC_EX_TS_FIFO_ECC_ERR /**< mEMAC Time-stamp FIFO ECC error interrupt;
80094 + not supported on T4240/B4860 rev1 chips */
80095 + ,e_FM_MAC_EX_MAGIC_PACKET_INDICATION = e_FM_MAC_EX_1G_MAG_PCKT
80096 + /**< mEMAC Magic Packet Indication Interrupt */
80097 +} e_FmMacExceptions;
80098 +
80099 +/**************************************************************************//**
80100 + @Description TM MAC statistics level
80101 +*//***************************************************************************/
80102 +typedef enum e_FmMacStatisticsLevel {
80103 + e_FM_MAC_NONE_STATISTICS = 0, /**< No statistics */
80104 + e_FM_MAC_PARTIAL_STATISTICS, /**< Only error counters are available; Optimized for performance */
80105 + e_FM_MAC_FULL_STATISTICS /**< All counters available; Not optimized for performance */
80106 +} e_FmMacStatisticsLevel;
80107 +
80108 +
80109 +#if (DPAA_VERSION >= 11)
80110 +/**************************************************************************//**
80111 + @Description Priority Flow Control Parameters
80112 +*//***************************************************************************/
80113 +typedef struct t_FmMacPfcParams {
80114 + bool pfcEnable; /**< Enable/Disable PFC */
80115 +
80116 + 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*/
80117 +
80118 + 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*/
80119 +
80120 +
80121 +} t_FmMacPfcParams;
80122 +#endif /* (DPAA_VERSION >= 11) */
80123 +
80124 +/**************************************************************************//**
80125 + @Function t_FmMacExceptionCallback
80126 +
80127 + @Description Fm Mac Exception Callback from FM MAC to the user
80128 +
80129 + @Param[in] h_App - Handle to the upper layer handler
80130 +
80131 + @Param[in] exceptions - The exception that occurred
80132 +
80133 + @Return void.
80134 +*//***************************************************************************/
80135 +typedef void (t_FmMacExceptionCallback)(t_Handle h_App, e_FmMacExceptions exceptions);
80136 +
80137 +
80138 +/**************************************************************************//**
80139 + @Description TM MAC statistics rfc3635
80140 +*//***************************************************************************/
80141 +typedef struct t_FmMacStatistics {
80142 +/* RMON */
80143 + uint64_t eStatPkts64; /**< r-10G tr-DT 64 byte frame counter */
80144 + uint64_t eStatPkts65to127; /**< r-10G 65 to 127 byte frame counter */
80145 + uint64_t eStatPkts128to255; /**< r-10G 128 to 255 byte frame counter */
80146 + uint64_t eStatPkts256to511; /**< r-10G 256 to 511 byte frame counter */
80147 + uint64_t eStatPkts512to1023; /**< r-10G 512 to 1023 byte frame counter */
80148 + uint64_t eStatPkts1024to1518; /**< r-10G 1024 to 1518 byte frame counter */
80149 + uint64_t eStatPkts1519to1522; /**< r-10G 1519 to 1522 byte good frame count */
80150 +/* */
80151 + uint64_t eStatFragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
80152 + uint64_t eStatJabbers; /**< Total number of packets longer than valid maximum length octets */
80153 + uint64_t eStatsDropEvents; /**< number of dropped packets due to internal errors of the MAC Client (during receive). */
80154 + uint64_t eStatCRCAlignErrors; /**< Incremented when frames of correct length but with CRC error are received.*/
80155 + uint64_t eStatUndersizePkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
80156 + This count does not include range length errors */
80157 + uint64_t eStatOversizePkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
80158 + a valid FCS and otherwise well formed */
80159 +/* Pause */
80160 + uint64_t teStatPause; /**< Pause MAC Control received */
80161 + uint64_t reStatPause; /**< Pause MAC Control sent */
80162 +/* MIB II */
80163 + uint64_t ifInOctets; /**< Total number of byte received. */
80164 + uint64_t ifInPkts; /**< Total number of packets received.*/
80165 + uint64_t ifInUcastPkts; /**< Total number of unicast frame received;
80166 + NOTE: this counter is not supported on dTSEC MAC */
80167 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received*/
80168 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
80169 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX. */
80170 + uint64_t ifInErrors; /**< Number of frames received with error:
80171 + - FIFO Overflow Error
80172 + - CRC Error
80173 + - Frame Too Long Error
80174 + - Alignment Error
80175 + - The dedicated Error Code (0xfe, not a code error) was received */
80176 + uint64_t ifOutOctets; /**< Total number of byte sent. */
80177 + uint64_t ifOutPkts; /**< Total number of packets sent .*/
80178 + uint64_t ifOutUcastPkts; /**< Total number of unicast frame sent;
80179 + NOTE: this counter is not supported on dTSEC MAC */
80180 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
80181 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
80182 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
80183 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
80184 + - FIFO Overflow Error
80185 + - FIFO Underflow Error
80186 + - Other */
80187 +} t_FmMacStatistics;
80188 +
80189 +/**************************************************************************//**
80190 + @Description FM MAC Frame Size Counters
80191 +*//***************************************************************************/
80192 +typedef struct t_FmMacFrameSizeCounters {
80193 +
80194 + uint64_t count_pkts_64; /**< 64 byte frame counter */
80195 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
80196 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
80197 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
80198 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
80199 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
80200 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
80201 +} t_FmMacFrameSizeCounters;
80202 +
80203 +/**************************************************************************//**
80204 + @Group FM_mac_init_grp FM MAC Initialization Unit
80205 +
80206 + @Description FM MAC Initialization Unit
80207 +
80208 + @{
80209 +*//***************************************************************************/
80210 +
80211 +/**************************************************************************//**
80212 + @Description FM MAC config input
80213 +*//***************************************************************************/
80214 +typedef struct t_FmMacParams {
80215 + uintptr_t baseAddr; /**< Base of memory mapped FM MAC registers */
80216 + t_EnetAddr addr; /**< MAC address of device; First octet is sent first */
80217 + uint8_t macId; /**< MAC ID;
80218 + numbering of dTSEC and 1G-mEMAC:
80219 + 0 - FM_MAX_NUM_OF_1G_MACS;
80220 + numbering of 10G-MAC (TGEC) and 10G-mEMAC:
80221 + 0 - FM_MAX_NUM_OF_10G_MACS */
80222 + e_EnetMode enetMode; /**< Ethernet operation mode (MAC-PHY interface and speed);
80223 + Note that the speed should indicate the maximum rate that
80224 + this MAC should support rather than the actual speed;
80225 + i.e. user should use the FM_MAC_AdjustLink() routine to
80226 + provide accurate speed;
80227 + In case of mEMAC RGMII mode, the MAC is configured to RGMII
80228 + automatic mode, where actual speed/duplex mode information
80229 + is provided by PHY automatically in-band; FM_MAC_AdjustLink()
80230 + function should be used to switch to manual RGMII speed/duplex mode
80231 + configuration if RGMII PHY doesn't support in-band status signaling;
80232 + In addition, in mEMAC, in case where user is using the higher MACs
80233 + (i.e. the MACs that should support 10G), user should pass here
80234 + speed=10000 even if the interface is not allowing that (e.g. SGMII). */
80235 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
80236 + int mdioIrq; /**< MDIO exceptions interrupt source - not valid for all
80237 + MACs; MUST be set to 'NO_IRQ' for MACs that don't have
80238 + mdio-irq, or for polling */
80239 + t_FmMacExceptionCallback *f_Event; /**< MDIO Events Callback Routine */
80240 + t_FmMacExceptionCallback *f_Exception; /**< Exception Callback Routine */
80241 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80242 + be passed by the driver upon calling the above callbacks */
80243 +} t_FmMacParams;
80244 +
80245 +
80246 +/**************************************************************************//**
80247 + @Function FM_MAC_Config
80248 +
80249 + @Description Creates descriptor for the FM MAC module.
80250 +
80251 + The routine returns a handle (descriptor) to the FM MAC object.
80252 + This descriptor must be passed as first parameter to all other
80253 + FM MAC function calls.
80254 +
80255 + No actual initialization or configuration of FM MAC hardware is
80256 + done by this routine.
80257 +
80258 + @Param[in] p_FmMacParam - Pointer to data structure of parameters
80259 +
80260 + @Retval Handle to FM MAC object, or NULL for Failure.
80261 +*//***************************************************************************/
80262 +t_Handle FM_MAC_Config(t_FmMacParams *p_FmMacParam);
80263 +
80264 +/**************************************************************************//**
80265 + @Function FM_MAC_Init
80266 +
80267 + @Description Initializes the FM MAC module
80268 +
80269 + @Param[in] h_FmMac - FM module descriptor
80270 +
80271 + @Return E_OK on success; Error code otherwise.
80272 +*//***************************************************************************/
80273 +t_Error FM_MAC_Init(t_Handle h_FmMac);
80274 +
80275 +/**************************************************************************//**
80276 + @Function FM_Free
80277 +
80278 + @Description Frees all resources that were assigned to FM MAC module.
80279 +
80280 + Calling this routine invalidates the descriptor.
80281 +
80282 + @Param[in] h_FmMac - FM module descriptor
80283 +
80284 + @Return E_OK on success; Error code otherwise.
80285 +*//***************************************************************************/
80286 +t_Error FM_MAC_Free(t_Handle h_FmMac);
80287 +
80288 +
80289 +/**************************************************************************//**
80290 + @Group FM_mac_advanced_init_grp FM MAC Advanced Configuration Unit
80291 +
80292 + @Description Configuration functions used to change default values.
80293 +
80294 + @{
80295 +*//***************************************************************************/
80296 +
80297 +/**************************************************************************//**
80298 + @Function FM_MAC_ConfigResetOnInit
80299 +
80300 + @Description Tell the driver whether to reset the FM MAC before initialization or
80301 + not. It changes the default configuration [DEFAULT_resetOnInit].
80302 +
80303 + @Param[in] h_FmMac A handle to a FM MAC Module.
80304 + @Param[in] enable When TRUE, FM will be reset before any initialization.
80305 +
80306 + @Return E_OK on success; Error code otherwise.
80307 +
80308 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80309 +*//***************************************************************************/
80310 +t_Error FM_MAC_ConfigResetOnInit(t_Handle h_FmMac, bool enable);
80311 +
80312 +/**************************************************************************//**
80313 + @Function FM_MAC_ConfigLoopback
80314 +
80315 + @Description Enable/Disable internal loopback mode
80316 +
80317 + @Param[in] h_FmMac A handle to a FM MAC Module.
80318 + @Param[in] enable TRUE to enable or FALSE to disable.
80319 +
80320 + @Return E_OK on success; Error code otherwise.
80321 +
80322 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80323 +*//***************************************************************************/
80324 +t_Error FM_MAC_ConfigLoopback(t_Handle h_FmMac, bool enable);
80325 +
80326 +/**************************************************************************//**
80327 + @Function FM_MAC_ConfigMaxFrameLength
80328 +
80329 + @Description Setup maximum Rx Frame Length (in 1G MAC, effects also Tx)
80330 +
80331 + @Param[in] h_FmMac A handle to a FM MAC Module.
80332 + @Param[in] newVal MAX Frame length
80333 +
80334 + @Return E_OK on success; Error code otherwise.
80335 +
80336 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80337 +*//***************************************************************************/
80338 +t_Error FM_MAC_ConfigMaxFrameLength(t_Handle h_FmMac, uint16_t newVal);
80339 +
80340 +/**************************************************************************//**
80341 + @Function FM_MAC_ConfigWan
80342 +
80343 + @Description ENABLE WAN mode in 10G-MAC
80344 +
80345 + @Param[in] h_FmMac A handle to a FM MAC Module.
80346 + @Param[in] enable TRUE to enable or FALSE to disable.
80347 +
80348 + @Return E_OK on success; Error code otherwise.
80349 +
80350 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80351 +*//***************************************************************************/
80352 +t_Error FM_MAC_ConfigWan(t_Handle h_FmMac, bool enable);
80353 +
80354 +/**************************************************************************//**
80355 + @Function FM_MAC_ConfigPadAndCrc
80356 +
80357 + @Description Config PAD and CRC mode
80358 +
80359 + @Param[in] h_FmMac A handle to a FM MAC Module.
80360 + @Param[in] enable TRUE to enable or FALSE to disable.
80361 +
80362 + @Return E_OK on success; Error code otherwise.
80363 +
80364 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80365 + Not supported on 10G-MAC (i.e. CRC & PAD are added automatically
80366 + by HW); on mEMAC, this routine supports only PAD (i.e. CRC is
80367 + added automatically by HW).
80368 +*//***************************************************************************/
80369 +t_Error FM_MAC_ConfigPadAndCrc(t_Handle h_FmMac, bool enable);
80370 +
80371 +/**************************************************************************//**
80372 + @Function FM_MAC_ConfigHalfDuplex
80373 +
80374 + @Description Config Half Duplex Mode
80375 +
80376 + @Param[in] h_FmMac A handle to a FM MAC Module.
80377 + @Param[in] enable TRUE to enable or FALSE to disable.
80378 +
80379 + @Return E_OK on success; Error code otherwise.
80380 +
80381 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80382 +*//***************************************************************************/
80383 +t_Error FM_MAC_ConfigHalfDuplex(t_Handle h_FmMac, bool enable);
80384 +
80385 +/**************************************************************************//**
80386 + @Function FM_MAC_ConfigTbiPhyAddr
80387 +
80388 + @Description Configures the address of internal TBI PHY.
80389 +
80390 + @Param[in] h_FmMac A handle to a FM MAC Module.
80391 + @Param[in] newVal TBI PHY address (1-31).
80392 +
80393 + @Return E_OK on success; Error code otherwise.
80394 +
80395 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80396 +*//***************************************************************************/
80397 +t_Error FM_MAC_ConfigTbiPhyAddr(t_Handle h_FmMac, uint8_t newVal);
80398 +
80399 +/**************************************************************************//**
80400 + @Function FM_MAC_ConfigLengthCheck
80401 +
80402 + @Description Configure the frame length checking.
80403 +
80404 + @Param[in] h_FmMac A handle to a FM MAC Module.
80405 + @Param[in] enable TRUE to enable or FALSE to disable.
80406 +
80407 + @Return E_OK on success; Error code otherwise.
80408 +
80409 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80410 +*//***************************************************************************/
80411 +t_Error FM_MAC_ConfigLengthCheck(t_Handle h_FmMac, bool enable);
80412 +
80413 +/**************************************************************************//**
80414 + @Function FM_MAC_ConfigException
80415 +
80416 + @Description Change Exception selection from default
80417 +
80418 + @Param[in] h_FmMac A handle to a FM MAC Module.
80419 + @Param[in] ex Type of the desired exceptions
80420 + @Param[in] enable TRUE to enable the specified exception, FALSE to disable it.
80421 +
80422 + @Return E_OK on success; Error code otherwise.
80423 +
80424 + @Cautions Allowed only following FM_MAC_Config() and before FM_MAC_Init().
80425 +*//***************************************************************************/
80426 +t_Error FM_MAC_ConfigException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
80427 +
80428 +#ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
80429 +t_Error FM_MAC_ConfigSkipFman11Workaround (t_Handle h_FmMac);
80430 +#endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
80431 +/** @} */ /* end of FM_mac_advanced_init_grp group */
80432 +/** @} */ /* end of FM_mac_init_grp group */
80433 +
80434 +
80435 +/**************************************************************************//**
80436 + @Group FM_mac_runtime_control_grp FM MAC Runtime Control Unit
80437 +
80438 + @Description FM MAC Runtime control unit API functions, definitions and enums.
80439 +
80440 + @{
80441 +*//***************************************************************************/
80442 +
80443 +/**************************************************************************//**
80444 + @Function FM_MAC_Enable
80445 +
80446 + @Description Enable the MAC
80447 +
80448 + @Param[in] h_FmMac A handle to a FM MAC Module.
80449 + @Param[in] mode Mode of operation (RX, TX, Both)
80450 +
80451 + @Return E_OK on success; Error code otherwise.
80452 +
80453 + @Cautions Allowed only following FM_MAC_Init().
80454 +*//***************************************************************************/
80455 +t_Error FM_MAC_Enable(t_Handle h_FmMac, e_CommMode mode);
80456 +
80457 +/**************************************************************************//**
80458 + @Function FM_MAC_Disable
80459 +
80460 + @Description DISABLE the MAC
80461 +
80462 + @Param[in] h_FmMac A handle to a FM MAC Module.
80463 + @Param[in] mode Define what part to Disable (RX, TX or BOTH)
80464 +
80465 + @Return E_OK on success; Error code otherwise.
80466 +
80467 + @Cautions Allowed only following FM_MAC_Init().
80468 +*//***************************************************************************/
80469 +t_Error FM_MAC_Disable(t_Handle h_FmMac, e_CommMode mode);
80470 +
80471 +/**************************************************************************//**
80472 + @Function FM_MAC_Resume
80473 +
80474 + @Description Re-init the MAC after suspend
80475 +
80476 + @Param[in] h_FmMac A handle to a FM MAC Module.
80477 +
80478 + @Return E_OK on success; Error code otherwise.
80479 +
80480 + @Cautions Allowed only following FM_MAC_Init().
80481 +*//***************************************************************************/
80482 +t_Error FM_MAC_Resume(t_Handle h_FmMac);
80483 +
80484 +/**************************************************************************//**
80485 + @Function FM_MAC_Enable1588TimeStamp
80486 +
80487 + @Description Enables the TSU operation.
80488 +
80489 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
80490 +
80491 + @Return E_OK on success; Error code otherwise.
80492 +
80493 + @Cautions Allowed only following FM_MAC_Init().
80494 +*//***************************************************************************/
80495 +t_Error FM_MAC_Enable1588TimeStamp(t_Handle h_Fm);
80496 +
80497 +/**************************************************************************//**
80498 + @Function FM_MAC_Disable1588TimeStamp
80499 +
80500 + @Description Disables the TSU operation.
80501 +
80502 + @Param[in] h_Fm - Handle to the PTP as returned from the FM_MAC_PtpConfig.
80503 +
80504 + @Return E_OK on success; Error code otherwise.
80505 +
80506 + @Cautions Allowed only following FM_MAC_Init().
80507 +*//***************************************************************************/
80508 +t_Error FM_MAC_Disable1588TimeStamp(t_Handle h_Fm);
80509 +
80510 +/**************************************************************************//**
80511 + @Function FM_MAC_SetTxAutoPauseFrames
80512 +
80513 + @Description Enable/Disable transmission of Pause-Frames.
80514 + The routine changes the default configuration [DEFAULT_TX_PAUSE_TIME].
80515 +
80516 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80517 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
80518 + Each quanta represents a 512 bit-times; Note that '0'
80519 + as an input here will be used as disabling the
80520 + transmission of the pause-frames.
80521 +
80522 + @Return E_OK on success; Error code otherwise.
80523 +
80524 + @Cautions Allowed only following FM_MAC_Init().
80525 +*//***************************************************************************/
80526 +t_Error FM_MAC_SetTxAutoPauseFrames(t_Handle h_FmMac,
80527 + uint16_t pauseTime);
80528 +
80529 + /**************************************************************************//**
80530 + @Function FM_MAC_SetTxPauseFrames
80531 +
80532 + @Description Enable/Disable transmission of Pause-Frames.
80533 + The routine changes the default configuration:
80534 + pause-time - [DEFAULT_TX_PAUSE_TIME]
80535 + threshold-time - [0]
80536 +
80537 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80538 + @Param[in] priority - the PFC class of service; use 'FM_MAC_NO_PFC'
80539 + to indicate legacy pause support (i.e. no PFC).
80540 + @Param[in] pauseTime - Pause quanta value used with transmitted pause frames.
80541 + Each quanta represents a 512 bit-times;
80542 + Note that '0' as an input here will be used as disabling the
80543 + transmission of the pause-frames.
80544 + @Param[in] threshTime - Pause Threshold equanta value used by the MAC to retransmit pause frame.
80545 + if the situation causing a pause frame to be sent didn't finish when the timer
80546 + reached the threshold quanta, the MAC will retransmit the pause frame.
80547 + Each quanta represents a 512 bit-times.
80548 +
80549 + @Return E_OK on success; Error code otherwise.
80550 +
80551 + @Cautions Allowed only following FM_MAC_Init().
80552 + In order for PFC to work properly the user must configure
80553 + TNUM-aging in the tx-port it is recommended that pre-fetch and
80554 + rate limit in the tx port should be disabled;
80555 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
80556 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
80557 + in the 'priority' field.
80558 +*//***************************************************************************/
80559 +t_Error FM_MAC_SetTxPauseFrames(t_Handle h_FmMac,
80560 + uint8_t priority,
80561 + uint16_t pauseTime,
80562 + uint16_t threshTime);
80563 +
80564 +/**************************************************************************//**
80565 + @Function FM_MAC_SetRxIgnorePauseFrames
80566 +
80567 + @Description Enable/Disable ignoring of Pause-Frames.
80568 +
80569 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80570 + @Param[in] en - boolean indicates whether to ignore the incoming pause
80571 + frames or not.
80572 +
80573 + @Return E_OK on success; Error code otherwise.
80574 +
80575 + @Cautions Allowed only following FM_MAC_Init().
80576 +*//***************************************************************************/
80577 +t_Error FM_MAC_SetRxIgnorePauseFrames(t_Handle h_FmMac, bool en);
80578 +
80579 +/**************************************************************************//**
80580 + @Function FM_MAC_SetWakeOnLan
80581 +
80582 + @Description Enable/Disable Wake On Lan support
80583 +
80584 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80585 + @Param[in] en - boolean indicates whether to enable Wake On Lan
80586 + support or not.
80587 +
80588 + @Return E_OK on success; Error code otherwise.
80589 +
80590 + @Cautions Allowed only following FM_MAC_Init().
80591 +*//***************************************************************************/
80592 +t_Error FM_MAC_SetWakeOnLan(t_Handle h_FmMac, bool en);
80593 +
80594 +/**************************************************************************//**
80595 + @Function FM_MAC_ResetCounters
80596 +
80597 + @Description reset all statistics counters
80598 +
80599 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80600 +
80601 + @Return E_OK on success; Error code otherwise.
80602 +
80603 + @Cautions Allowed only following FM_MAC_Init().
80604 +*//***************************************************************************/
80605 +t_Error FM_MAC_ResetCounters(t_Handle h_FmMac);
80606 +
80607 +/**************************************************************************//**
80608 + @Function FM_MAC_SetException
80609 +
80610 + @Description Enable/Disable a specific Exception
80611 +
80612 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80613 + @Param[in] ex - Type of the desired exceptions
80614 + @Param[in] enable - TRUE to enable the specified exception, FALSE to disable it.
80615 +
80616 +
80617 + @Return E_OK on success; Error code otherwise.
80618 +
80619 + @Cautions Allowed only following FM_MAC_Init().
80620 +*//***************************************************************************/
80621 +t_Error FM_MAC_SetException(t_Handle h_FmMac, e_FmMacExceptions ex, bool enable);
80622 +
80623 +/**************************************************************************//**
80624 + @Function FM_MAC_SetStatistics
80625 +
80626 + @Description Define Statistics level.
80627 + Where applicable, the routine also enables the MIB counters
80628 + overflow interrupt in order to keep counters accurate
80629 + and account for overflows.
80630 + This routine is relevant only for dTSEC.
80631 +
80632 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80633 + @Param[in] statisticsLevel - Full statistics level provides all standard counters but may
80634 + reduce performance. Partial statistics provides only special
80635 + event counters (errors etc.). If selected, regular counters (such as
80636 + byte/packet) will be invalid and will return -1.
80637 +
80638 + @Return E_OK on success; Error code otherwise.
80639 +
80640 + @Cautions Allowed only following FM_MAC_Init().
80641 +*//***************************************************************************/
80642 +t_Error FM_MAC_SetStatistics(t_Handle h_FmMac, e_FmMacStatisticsLevel statisticsLevel);
80643 +
80644 +/**************************************************************************//**
80645 + @Function FM_MAC_GetStatistics
80646 +
80647 + @Description get all statistics counters
80648 +
80649 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80650 + @Param[in] p_Statistics - Structure with statistics
80651 +
80652 + @Return E_OK on success; Error code otherwise.
80653 +
80654 + @Cautions Allowed only following FM_Init().
80655 +*//***************************************************************************/
80656 +t_Error FM_MAC_GetStatistics(t_Handle h_FmMac, t_FmMacStatistics *p_Statistics);
80657 +
80658 +/**************************************************************************//**
80659 + @Function FM_MAC_GetFrameSizeCounters
80660 +
80661 + @Description get MAC statistics counters for different frame size
80662 +
80663 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80664 + @Param[in] p_FrameSizeCounters - Structure with counters
80665 + @Param[in] type - Type of counters to be read
80666 +
80667 + @Return E_OK on success; Error code otherwise.
80668 +
80669 + @Cautions Allowed only following FM_Init().
80670 +*//***************************************************************************/
80671 +t_Error FM_MAC_GetFrameSizeCounters(t_Handle h_FmMac, t_FmMacFrameSizeCounters *p_FrameSizeCounters, e_CommMode type);
80672 +
80673 +/**************************************************************************//**
80674 + @Function FM_MAC_ModifyMacAddr
80675 +
80676 + @Description Replace the main MAC Address
80677 +
80678 + @Param[in] h_FmMac - A handle to a FM Module.
80679 + @Param[in] p_EnetAddr - Ethernet Mac address
80680 +
80681 + @Return E_OK on success; Error code otherwise.
80682 +
80683 + @Cautions Allowed only after FM_MAC_Init().
80684 +*//***************************************************************************/
80685 +t_Error FM_MAC_ModifyMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80686 +
80687 +/**************************************************************************//**
80688 + @Function FM_MAC_AddHashMacAddr
80689 +
80690 + @Description Add an Address to the hash table. This is for filter purpose only.
80691 +
80692 + @Param[in] h_FmMac - A handle to a FM Module.
80693 + @Param[in] p_EnetAddr - Ethernet Mac address
80694 +
80695 + @Return E_OK on success; Error code otherwise.
80696 +
80697 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
80698 + @Cautions Some address need to be filterd out in upper FM blocks.
80699 +*//***************************************************************************/
80700 +t_Error FM_MAC_AddHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80701 +
80702 +/**************************************************************************//**
80703 + @Function FM_MAC_RemoveHashMacAddr
80704 +
80705 + @Description Delete an Address to the hash table. This is for filter purpose only.
80706 +
80707 + @Param[in] h_FmMac - A handle to a FM Module.
80708 + @Param[in] p_EnetAddr - Ethernet Mac address
80709 +
80710 + @Return E_OK on success; Error code otherwise.
80711 +
80712 + @Cautions Allowed only following FM_MAC_Init().
80713 +*//***************************************************************************/
80714 +t_Error FM_MAC_RemoveHashMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80715 +
80716 +/**************************************************************************//**
80717 + @Function FM_MAC_AddExactMatchMacAddr
80718 +
80719 + @Description Add a unicast or multicast mac address for exact-match filtering
80720 + (8 on dTSEC, 2 for 10G-MAC)
80721 +
80722 + @Param[in] h_FmMac - A handle to a FM Module.
80723 + @Param[in] p_EnetAddr - MAC Address to ADD
80724 +
80725 + @Return E_OK on success; Error code otherwise.
80726 +
80727 + @Cautions Allowed only after FM_MAC_Init().
80728 +*//***************************************************************************/
80729 +t_Error FM_MAC_AddExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80730 +
80731 +/**************************************************************************//**
80732 + @Function FM_MAC_RemovelExactMatchMacAddr
80733 +
80734 + @Description Remove a uni cast or multi cast mac address.
80735 +
80736 + @Param[in] h_FmMac - A handle to a FM Module.
80737 + @Param[in] p_EnetAddr - MAC Address to remove
80738 +
80739 + @Return E_OK on success; Error code otherwise..
80740 +
80741 + @Cautions Allowed only after FM_MAC_Init().
80742 +*//***************************************************************************/
80743 +t_Error FM_MAC_RemovelExactMatchMacAddr(t_Handle h_FmMac, t_EnetAddr *p_EnetAddr);
80744 +
80745 +/**************************************************************************//**
80746 + @Function FM_MAC_SetPromiscuous
80747 +
80748 + @Description Enable/Disable MAC Promiscuous mode for ALL mac addresses.
80749 +
80750 + @Param[in] h_FmMac - A handle to a FM MAC Module.
80751 + @Param[in] enable - TRUE to enable or FALSE to disable.
80752 +
80753 + @Return E_OK on success; Error code otherwise.
80754 +
80755 + @Cautions Allowed only after FM_MAC_Init().
80756 +*//***************************************************************************/
80757 +t_Error FM_MAC_SetPromiscuous(t_Handle h_FmMac, bool enable);
80758 +
80759 +/**************************************************************************//**
80760 + @Function FM_MAC_AdjustLink
80761 +
80762 + @Description Adjusts the Ethernet link with new speed/duplex setup.
80763 + This routine is relevant for dTSEC and mEMAC.
80764 + In case of mEMAC, this routine is also used for manual
80765 + re-configuration of RGMII speed and duplex mode for
80766 + RGMII PHYs not supporting in-band status information
80767 + to MAC.
80768 +
80769 + @Param[in] h_FmMac - A handle to a FM Module.
80770 + @Param[in] speed - Ethernet speed.
80771 + @Param[in] fullDuplex - TRUE for full-duplex mode;
80772 + FALSE for half-duplex mode.
80773 +
80774 + @Return E_OK on success; Error code otherwise.
80775 +*//***************************************************************************/
80776 +t_Error FM_MAC_AdjustLink(t_Handle h_FmMac, e_EnetSpeed speed, bool fullDuplex);
80777 +
80778 +/**************************************************************************//**
80779 + @Function FM_MAC_RestartAutoneg
80780 +
80781 + @Description Restarts the auto-negotiation process.
80782 + When auto-negotiation process is invoked under traffic the
80783 + auto-negotiation process between the internal SGMII PHY and the
80784 + external PHY does not always complete successfully. Calling this
80785 + function will restart the auto-negotiation process that will end
80786 + successfully. It is recommended to call this function after issuing
80787 + auto-negotiation restart command to the Eth Phy.
80788 + This routine is relevant only for dTSEC.
80789 +
80790 + @Param[in] h_FmMac - A handle to a FM Module.
80791 +
80792 + @Return E_OK on success; Error code otherwise.
80793 +*//***************************************************************************/
80794 +t_Error FM_MAC_RestartAutoneg(t_Handle h_FmMac);
80795 +
80796 +/**************************************************************************//**
80797 + @Function FM_MAC_GetId
80798 +
80799 + @Description Return the MAC ID
80800 +
80801 + @Param[in] h_FmMac - A handle to a FM Module.
80802 + @Param[out] p_MacId - MAC ID of device
80803 +
80804 + @Return E_OK on success; Error code otherwise.
80805 +
80806 + @Cautions Allowed only after FM_MAC_Init().
80807 +*//***************************************************************************/
80808 +t_Error FM_MAC_GetId(t_Handle h_FmMac, uint32_t *p_MacId);
80809 +
80810 +/**************************************************************************//**
80811 + @Function FM_MAC_GetVesrion
80812 +
80813 + @Description Return Mac HW chip version
80814 +
80815 + @Param[in] h_FmMac - A handle to a FM Module.
80816 + @Param[out] p_MacVresion - Mac version as defined by the chip
80817 +
80818 + @Return E_OK on success; Error code otherwise.
80819 +
80820 + @Cautions Allowed only after FM_MAC_Init().
80821 +*//***************************************************************************/
80822 +t_Error FM_MAC_GetVesrion(t_Handle h_FmMac, uint32_t *p_MacVresion);
80823 +
80824 +/**************************************************************************//**
80825 + @Function FM_MAC_MII_WritePhyReg
80826 +
80827 + @Description Write data into Phy Register
80828 +
80829 + @Param[in] h_FmMac - A handle to a FM Module.
80830 + @Param[in] phyAddr - Phy Address on the MII bus
80831 + @Param[in] reg - Register Number.
80832 + @Param[in] data - Data to write.
80833 +
80834 + @Return E_OK on success; Error code otherwise.
80835 +
80836 + @Cautions Allowed only after FM_MAC_Init().
80837 +*//***************************************************************************/
80838 +t_Error FM_MAC_MII_WritePhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t data);
80839 +
80840 +/**************************************************************************//**
80841 + @Function FM_MAC_MII_ReadPhyReg
80842 +
80843 + @Description Read data from Phy Register
80844 +
80845 + @Param[in] h_FmMac - A handle to a FM Module.
80846 + @Param[in] phyAddr - Phy Address on the MII bus
80847 + @Param[in] reg - Register Number.
80848 + @Param[out] p_Data - Data from PHY.
80849 +
80850 + @Return E_OK on success; Error code otherwise.
80851 +
80852 + @Cautions Allowed only after FM_MAC_Init().
80853 +*//***************************************************************************/
80854 +t_Error FM_MAC_MII_ReadPhyReg(t_Handle h_FmMac, uint8_t phyAddr, uint8_t reg, uint16_t *p_Data);
80855 +
80856 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
80857 +/**************************************************************************//**
80858 + @Function FM_MAC_DumpRegs
80859 +
80860 + @Description Dump internal registers
80861 +
80862 + @Param[in] h_FmMac - A handle to a FM Module.
80863 +
80864 + @Return E_OK on success; Error code otherwise.
80865 +
80866 + @Cautions Allowed only after FM_MAC_Init().
80867 +*//***************************************************************************/
80868 +t_Error FM_MAC_DumpRegs(t_Handle h_FmMac);
80869 +#endif /* (defined(DEBUG_ERRORS) && ... */
80870 +
80871 +/** @} */ /* end of FM_mac_runtime_control_grp group */
80872 +/** @} */ /* end of FM_mac_grp group */
80873 +/** @} */ /* end of FM_grp group */
80874 +
80875 +
80876 +#endif /* __FM_MAC_EXT_H */
80877 --- /dev/null
80878 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_macsec_ext.h
80879 @@ -0,0 +1,1271 @@
80880 +/*
80881 + * Copyright 2008-2015 Freescale Semiconductor Inc.
80882 + *
80883 + * Redistribution and use in source and binary forms, with or without
80884 + * modification, are permitted provided that the following conditions are met:
80885 + * * Redistributions of source code must retain the above copyright
80886 + * notice, this list of conditions and the following disclaimer.
80887 + * * Redistributions in binary form must reproduce the above copyright
80888 + * notice, this list of conditions and the following disclaimer in the
80889 + * documentation and/or other materials provided with the distribution.
80890 + * * Neither the name of Freescale Semiconductor nor the
80891 + * names of its contributors may be used to endorse or promote products
80892 + * derived from this software without specific prior written permission.
80893 + *
80894 + *
80895 + * ALTERNATIVELY, this software may be distributed under the terms of the
80896 + * GNU General Public License ("GPL") as published by the Free Software
80897 + * Foundation, either version 2 of that License or (at your option) any
80898 + * later version.
80899 + *
80900 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
80901 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
80902 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
80903 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
80904 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
80905 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
80906 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
80907 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
80908 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80909 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
80910 + */
80911 +
80912 +/**************************************************************************//**
80913 + @File fm_macsec_ext.h
80914 +
80915 + @Description FM MACSEC ...
80916 +*//***************************************************************************/
80917 +#ifndef __FM_MACSEC_EXT_H
80918 +#define __FM_MACSEC_EXT_H
80919 +
80920 +#include "std_ext.h"
80921 +
80922 +
80923 +/**************************************************************************//**
80924 + @Group FM_grp Frame Manager API
80925 +
80926 + @Description FM API functions, definitions and enums
80927 +
80928 + @{
80929 +*//***************************************************************************/
80930 +
80931 +/**************************************************************************//**
80932 + @Group FM_MACSEC_grp FM MACSEC
80933 +
80934 + @Description FM MACSEC API functions, definitions and enums
80935 +
80936 + @{
80937 +*//***************************************************************************/
80938 +
80939 +/**************************************************************************//**
80940 + @Description MACSEC Exceptions
80941 +*//***************************************************************************/
80942 +typedef enum e_FmMacsecExceptions {
80943 + e_FM_MACSEC_EX_SINGLE_BIT_ECC, /**< Single bit ECC error */
80944 + e_FM_MACSEC_EX_MULTI_BIT_ECC /**< Multi bit ECC error */
80945 +} e_FmMacsecExceptions;
80946 +
80947 +
80948 +/**************************************************************************//**
80949 + @Group FM_MACSEC_init_grp FM-MACSEC Initialization Unit
80950 +
80951 + @Description FM MACSEC Initialization Unit
80952 +
80953 + @{
80954 +*//***************************************************************************/
80955 +
80956 +/**************************************************************************//**
80957 + @Function t_FmMacsecExceptionsCallback
80958 +
80959 + @Description Exceptions user callback routine, will be called upon an
80960 + exception passing the exception identification.
80961 +
80962 + @Param[in] h_App A handle to an application layer object; This handle
80963 + will be passed by the driver upon calling this callback.
80964 + @Param[in] exception The exception.
80965 +*//***************************************************************************/
80966 +typedef void (t_FmMacsecExceptionsCallback) ( t_Handle h_App,
80967 + e_FmMacsecExceptions exception);
80968 +
80969 +
80970 +/**************************************************************************//**
80971 + @Description FM MACSEC config input
80972 +*//***************************************************************************/
80973 +typedef struct t_FmMacsecParams {
80974 + t_Handle h_Fm; /**< A handle to the FM object related to */
80975 + bool guestMode; /**< Partition-id */
80976 + union {
80977 + struct {
80978 + uint8_t fmMacId; /**< FM MAC id */
80979 + } guestParams;
80980 +
80981 + struct {
80982 + uintptr_t baseAddr; /**< Base of memory mapped FM MACSEC registers */
80983 + t_Handle h_FmMac; /**< A handle to the FM MAC object related to */
80984 + t_FmMacsecExceptionsCallback *f_Exception; /**< Exception Callback Routine */
80985 + t_Handle h_App; /**< A handle to an application layer object; This handle will
80986 + be passed by the driver upon calling the above callbacks */
80987 + } nonGuestParams;
80988 + };
80989 +} t_FmMacsecParams;
80990 +
80991 +/**************************************************************************//**
80992 + @Function FM_MACSEC_Config
80993 +
80994 + @Description Creates descriptor for the FM MACSEC module;
80995 +
80996 + The routine returns a handle (descriptor) to the FM MACSEC object;
80997 + This descriptor must be passed as first parameter to all other
80998 + FM MACSEC function calls;
80999 +
81000 + No actual initialization or configuration of FM MACSEC hardware is
81001 + done by this routine.
81002 +
81003 + @Param[in] p_FmMacsecParam Pointer to data structure of parameters.
81004 +
81005 + @Retval Handle to FM MACSEC object, or NULL for Failure.
81006 +*//***************************************************************************/
81007 +t_Handle FM_MACSEC_Config(t_FmMacsecParams *p_FmMacsecParam);
81008 +
81009 +/**************************************************************************//**
81010 + @Function FM_MACSEC_Init
81011 +
81012 + @Description Initializes the FM MACSEC module.
81013 +
81014 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81015 +
81016 + @Return E_OK on success; Error code otherwise.
81017 +*//***************************************************************************/
81018 +t_Error FM_MACSEC_Init(t_Handle h_FmMacsec);
81019 +
81020 +/**************************************************************************//**
81021 + @Function FM_MACSEC_Free
81022 +
81023 + @Description Frees all resources that were assigned to FM MACSEC module;
81024 +
81025 + Calling this routine invalidates the descriptor.
81026 +
81027 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81028 +
81029 + @Return E_OK on success; Error code otherwise.
81030 +*//***************************************************************************/
81031 +t_Error FM_MACSEC_Free(t_Handle h_FmMacsec);
81032 +
81033 +
81034 +/**************************************************************************//**
81035 + @Group FM_MACSEC_advanced_init_grp FM-MACSEC Advanced Configuration Unit
81036 +
81037 + @Description Configuration functions used to change default values.
81038 +
81039 + @{
81040 +*//***************************************************************************/
81041 +
81042 +/**************************************************************************//**
81043 + @Description enum for unknown sci frame treatment
81044 +*//***************************************************************************/
81045 +typedef enum e_FmMacsecUnknownSciFrameTreatment {
81046 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH = 0, /**< Controlled port - Strict mode */
81047 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED, /**< If C bit clear deliver on controlled port, else discard
81048 + Controlled port - Check or Disable mode */
81049 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED, /**< Controlled port - Strict mode */
81050 + 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,
81051 + else discard on uncontrolled port and deliver on controlled port
81052 + Controlled port - Check or Disable mode */
81053 +} e_FmMacsecUnknownSciFrameTreatment;
81054 +
81055 +/**************************************************************************//**
81056 + @Description enum for untag frame treatment
81057 +*//***************************************************************************/
81058 +typedef enum e_FmMacsecUntagFrameTreatment {
81059 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED = 0, /**< Controlled port - Strict mode */
81060 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH, /**< Controlled port - Strict mode */
81061 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED /**< Controlled port - Strict mode */
81062 +} e_FmMacsecUntagFrameTreatment;
81063 +
81064 +/**************************************************************************//**
81065 + @Function FM_MACSEC_ConfigUnknownSciFrameTreatment
81066 +
81067 + @Description Change the treatment for received frames with unknown sci from its default
81068 + configuration [DEFAULT_unknownSciFrameTreatment].
81069 +
81070 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81071 + @Param[in] treatMode The selected mode.
81072 +
81073 + @Return E_OK on success; Error code otherwise.
81074 +
81075 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81076 +*//***************************************************************************/
81077 +t_Error FM_MACSEC_ConfigUnknownSciFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUnknownSciFrameTreatment treatMode);
81078 +
81079 +/**************************************************************************//**
81080 + @Function FM_MACSEC_ConfigInvalidTagsFrameTreatment
81081 +
81082 + @Description Change the treatment for received frames with invalid tags or
81083 + a zero value PN or an invalid ICV from its default configuration
81084 + [DEFAULT_invalidTagsFrameTreatment].
81085 +
81086 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81087 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
81088 + In both cases discard on the controlled port;
81089 + this provide Strict, Check or Disable mode.
81090 +
81091 + @Return E_OK on success; Error code otherwise.
81092 +
81093 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81094 +*//***************************************************************************/
81095 +t_Error FM_MACSEC_ConfigInvalidTagsFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
81096 +
81097 +/**************************************************************************//**
81098 + @Function FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment
81099 +
81100 + @Description Change the treatment for received frames with the Encryption bit
81101 + set and the Changed Text bit clear from its default configuration
81102 + [DEFAULT_encryptWithNoChangedTextFrameTreatment].
81103 +
81104 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81105 + @Param[in] discardUncontrolled If True discard on the uncontrolled port, else deliver;
81106 + In both cases discard on the controlled port;
81107 + this provide Strict, Check or Disable mode.
81108 +
81109 + @Return E_OK on success; Error code otherwise.
81110 +
81111 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81112 +*//***************************************************************************/
81113 +t_Error FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(t_Handle h_FmMacsec, bool discardUncontrolled);
81114 +
81115 +/**************************************************************************//**
81116 + @Function FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment
81117 +
81118 + @Description Change the treatment for received frames with the Encryption bit
81119 + clear and the Changed Text bit set from its default configuration
81120 + [DEFAULT_changedTextWithNoEncryptFrameTreatment].
81121 +
81122 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81123 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
81124 + In both cases discard on the controlled port;
81125 + this provide Strict, Check or Disable mode.
81126 +
81127 + @Return E_OK on success; Error code otherwise.
81128 +
81129 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81130 +*//***************************************************************************/
81131 +t_Error FM_MACSEC_ConfigChangedTextWithNoEncryptFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
81132 +
81133 +/**************************************************************************//**
81134 + @Function FM_MACSEC_ConfigUntagFrameTreatment
81135 +
81136 + @Description Change the treatment for received frames without the MAC security tag (SecTAG)
81137 + from its default configuration [DEFAULT_untagFrameTreatment].
81138 +
81139 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81140 + @Param[in] treatMode The selected mode.
81141 +
81142 + @Return E_OK on success; Error code otherwise.
81143 +
81144 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81145 +*//***************************************************************************/
81146 +t_Error FM_MACSEC_ConfigUntagFrameTreatment(t_Handle h_FmMacsec, e_FmMacsecUntagFrameTreatment treatMode);
81147 +
81148 +/**************************************************************************//**
81149 + @Function FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment
81150 +
81151 + @Description Change the treatment for received frames with only SCB bit set
81152 + from its default configuration [DEFAULT_onlyScbIsSetFrameTreatment].
81153 +
81154 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81155 + @Param[in] deliverUncontrolled If True deliver on the uncontrolled port, else discard;
81156 + In both cases discard on the controlled port;
81157 + this provide Strict, Check or Disable mode.
81158 +
81159 + @Return E_OK on success; Error code otherwise.
81160 +
81161 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81162 +*//***************************************************************************/
81163 +t_Error FM_MACSEC_ConfigOnlyScbIsSetFrameTreatment(t_Handle h_FmMacsec, bool deliverUncontrolled);
81164 +
81165 +/**************************************************************************//**
81166 + @Function FM_MACSEC_ConfigPnExhaustionThreshold
81167 +
81168 + @Description It's provide the ability to configure a PN exhaustion threshold;
81169 + When the NextPn crosses this value an interrupt event
81170 + is asserted to warn that the active SA should re-key.
81171 +
81172 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81173 + @Param[in] pnExhThr If the threshold is reached, an interrupt event
81174 + is asserted to re-key.
81175 +
81176 + @Return E_OK on success; Error code otherwise.
81177 +
81178 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81179 +*//***************************************************************************/
81180 +t_Error FM_MACSEC_ConfigPnExhaustionThreshold(t_Handle h_FmMacsec, uint32_t pnExhThr);
81181 +
81182 +/**************************************************************************//**
81183 + @Function FM_MACSEC_ConfigKeysUnreadable
81184 +
81185 + @Description Turn on privacy mode; All the keys and their hash values can't be read any more;
81186 + Can not be cleared unless hard reset.
81187 +
81188 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81189 +
81190 + @Return E_OK on success; Error code otherwise.
81191 +
81192 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81193 +*//***************************************************************************/
81194 +t_Error FM_MACSEC_ConfigKeysUnreadable(t_Handle h_FmMacsec);
81195 +
81196 +/**************************************************************************//**
81197 + @Function FM_MACSEC_ConfigSectagWithoutSCI
81198 +
81199 + @Description Promise that all generated Sectag will be without SCI included.
81200 +
81201 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81202 +
81203 + @Return E_OK on success; Error code otherwise.
81204 +
81205 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81206 +*//***************************************************************************/
81207 +t_Error FM_MACSEC_ConfigSectagWithoutSCI(t_Handle h_FmMacsec);
81208 +
81209 +/**************************************************************************//**
81210 + @Function FM_MACSEC_ConfigException
81211 +
81212 + @Description Calling this routine changes the internal driver data base
81213 + from its default selection of exceptions enablement;
81214 + By default all exceptions are enabled.
81215 +
81216 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81217 + @Param[in] exception The exception to be selected.
81218 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81219 +
81220 + @Return E_OK on success; Error code otherwise.
81221 +
81222 + @Cautions Allowed only following FM_MACSEC_Config() and before FM_MACSEC_Init().
81223 +*//***************************************************************************/
81224 +t_Error FM_MACSEC_ConfigException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
81225 +
81226 +/** @} */ /* end of FM_MACSEC_advanced_init_grp group */
81227 +/** @} */ /* end of FM_MACSEC_init_grp group */
81228 +
81229 +
81230 +/**************************************************************************//**
81231 + @Group FM_MACSEC_runtime_control_grp FM-MACSEC Runtime Control Data Unit
81232 +
81233 + @Description FM MACSEC runtime control data unit API functions, definitions and enums.
81234 +
81235 + @{
81236 +*//***************************************************************************/
81237 +
81238 +/**************************************************************************//**
81239 + @Function FM_MACSEC_GetRevision
81240 +
81241 + @Description Return MACSEC HW chip revision
81242 +
81243 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81244 + @Param[out] p_MacsecRevision MACSEC revision as defined by the chip.
81245 +
81246 + @Return E_OK on success; Error code otherwise.
81247 +
81248 + @Cautions Allowed only after FM_MACSEC_Init().
81249 +*//***************************************************************************/
81250 +t_Error FM_MACSEC_GetRevision(t_Handle h_FmMacsec, uint32_t *p_MacsecRevision);
81251 +
81252 +/**************************************************************************//**
81253 + @Function FM_MACSEC_Enable
81254 +
81255 + @Description This routine should be called after MACSEC is initialized for enabling all
81256 + MACSEC engines according to their existing configuration.
81257 +
81258 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81259 +
81260 + @Return E_OK on success; Error code otherwise.
81261 +
81262 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is disabled.
81263 +*//***************************************************************************/
81264 +t_Error FM_MACSEC_Enable(t_Handle h_FmMacsec);
81265 +
81266 +/**************************************************************************//**
81267 + @Function FM_MACSEC_Disable
81268 +
81269 + @Description This routine may be called when MACSEC is enabled in order to
81270 + disable all MACSEC engines; The MACSEC is working in bypass mode.
81271 +
81272 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81273 +
81274 + @Return E_OK on success; Error code otherwise.
81275 +
81276 + @Cautions Allowed only following FM_MACSEC_Init() and when MACSEC is enabled.
81277 +*//***************************************************************************/
81278 +t_Error FM_MACSEC_Disable(t_Handle h_FmMacsec);
81279 +
81280 +/**************************************************************************//**
81281 + @Function FM_MACSEC_SetException
81282 +
81283 + @Description Calling this routine enables/disables the specified exception.
81284 +
81285 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81286 + @Param[in] exception The exception to be selected.
81287 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81288 +
81289 + @Return E_OK on success; Error code otherwise.
81290 +
81291 + @Cautions Allowed only following FM_MACSEC_Init().
81292 +*//***************************************************************************/
81293 +t_Error FM_MACSEC_SetException(t_Handle h_FmMacsec, e_FmMacsecExceptions exception, bool enable);
81294 +
81295 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
81296 +/**************************************************************************//**
81297 + @Function FM_MACSEC_DumpRegs
81298 +
81299 + @Description Dump internal registers.
81300 +
81301 + @Param[in] h_FmMacsec - FM MACSEC module descriptor.
81302 +
81303 + @Return E_OK on success; Error code otherwise.
81304 +
81305 + @Cautions Allowed only after FM_MACSEC_Init().
81306 +*//***************************************************************************/
81307 +t_Error FM_MACSEC_DumpRegs(t_Handle h_FmMacsec);
81308 +#endif /* (defined(DEBUG_ERRORS) && ... */
81309 +
81310 +#ifdef VERIFICATION_SUPPORT
81311 +/********************* VERIFICATION ONLY ********************************/
81312 +/**************************************************************************//**
81313 + @Function FM_MACSEC_BackdoorSet
81314 +
81315 + @Description Set register of the MACSEC memory map
81316 +
81317 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81318 + @Param[out] offset Register offset.
81319 + @Param[out] value Value to write.
81320 +
81321 +
81322 + @Return None
81323 +
81324 + @Cautions Allowed only following FM_MACSEC_Init().
81325 +*//***************************************************************************/
81326 +t_Error FM_MACSEC_BackdoorSet(t_Handle h_FmMacsec, uint32_t offset, uint32_t value);
81327 +
81328 +/**************************************************************************//**
81329 + @Function FM_MACSEC_BackdoorGet
81330 +
81331 + @Description Read from register of the MACSEC memory map.
81332 +
81333 + @Param[in] h_FmMacsec FM MACSEC module descriptor.
81334 + @Param[out] offset Register offset.
81335 +
81336 + @Return Value read
81337 +
81338 + @Cautions Allowed only following FM_MACSEC_Init().
81339 +*//***************************************************************************/
81340 +uint32_t FM_MACSEC_BackdoorGet(t_Handle h_FmMacsec, uint32_t offset);
81341 +#endif /* VERIFICATION_SUPPORT */
81342 +
81343 +/** @} */ /* end of FM_MACSEC_runtime_control_grp group */
81344 +
81345 +
81346 +/**************************************************************************//**
81347 + @Group FM_MACSEC_SECY_grp FM-MACSEC SecY
81348 +
81349 + @Description FM-MACSEC SecY API functions, definitions and enums
81350 +
81351 + @{
81352 +*//***************************************************************************/
81353 +
81354 +typedef uint8_t macsecSAKey_t[32];
81355 +typedef uint64_t macsecSCI_t;
81356 +typedef uint8_t macsecAN_t;
81357 +
81358 +/**************************************************************************//**
81359 +@Description MACSEC SECY Cipher Suite
81360 +*//***************************************************************************/
81361 +typedef enum e_FmMacsecSecYCipherSuite {
81362 + e_FM_MACSEC_SECY_GCM_AES_128 = 0, /**< GCM-AES-128 */
81363 +#if (DPAA_VERSION >= 11)
81364 + e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
81365 +#endif /* (DPAA_VERSION >= 11) */
81366 +} e_FmMacsecSecYCipherSuite;
81367 +
81368 +/**************************************************************************//**
81369 + @Description MACSEC SECY Exceptions
81370 +*//***************************************************************************/
81371 +typedef enum e_FmMacsecSecYExceptions {
81372 + e_FM_MACSEC_SECY_EX_FRAME_DISCARDED /**< Frame Discarded */
81373 +} e_FmMacsecSecYExceptions;
81374 +
81375 +/**************************************************************************//**
81376 + @Description MACSEC SECY Events
81377 +*//***************************************************************************/
81378 +typedef enum e_FmMacsecSecYEvents {
81379 + e_FM_MACSEC_SECY_EV_NEXT_PN /**< Next Packet Number exhaustion threshold reached */
81380 +} e_FmMacsecSecYEvents;
81381 +
81382 +/**************************************************************************//**
81383 + @Collection MACSEC SECY Frame Discarded Descriptor error
81384 +*//***************************************************************************/
81385 +typedef uint8_t macsecTxScFrameDiscardedErrSelect_t; /**< typedef for defining Frame Discarded Descriptor errors */
81386 +
81387 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_NEXT_PN_ZERO 0x8000 /**< NextPn == 0 */
81388 +#define FM_MACSEC_SECY_TX_SC_FRM_DISCAR_ERR_SC_DISBALE 0x4000 /**< SC is disable */
81389 +/* @} */
81390 +
81391 +/**************************************************************************//**
81392 + @Function t_FmMacsecSecYExceptionsCallback
81393 +
81394 + @Description Exceptions user callback routine, will be called upon an
81395 + exception passing the exception identification.
81396 +
81397 + @Param[in] h_App A handle to an application layer object; This handle
81398 + will be passed by the driver upon calling this callback.
81399 + @Param[in] exception The exception.
81400 +*//***************************************************************************/
81401 +typedef void (t_FmMacsecSecYExceptionsCallback) ( t_Handle h_App,
81402 + e_FmMacsecSecYExceptions exception);
81403 +
81404 +/**************************************************************************//**
81405 + @Function t_FmMacsecSecYEventsCallback
81406 +
81407 + @Description Events user callback routine, will be called upon an
81408 + event passing the event identification.
81409 +
81410 + @Param[in] h_App A handle to an application layer object; This handle
81411 + will be passed by the driver upon calling this callback.
81412 + @Param[in] event The event.
81413 +*//***************************************************************************/
81414 +typedef void (t_FmMacsecSecYEventsCallback) ( t_Handle h_App,
81415 + e_FmMacsecSecYEvents event);
81416 +
81417 +/**************************************************************************//**
81418 + @Description RFC2863 MIB
81419 +*//***************************************************************************/
81420 +typedef struct t_MIBStatistics {
81421 + uint64_t ifInOctets; /**< Total number of byte received */
81422 + uint64_t ifInPkts; /**< Total number of packets received */
81423 + uint64_t ifInMcastPkts; /**< Total number of multicast frame received */
81424 + uint64_t ifInBcastPkts; /**< Total number of broadcast frame received */
81425 + uint64_t ifInDiscards; /**< Frames received, but discarded due to problems within the MAC RX :
81426 + - InPktsNoTag,
81427 + - InPktsLate,
81428 + - InPktsOverrun */
81429 + uint64_t ifInErrors; /**< Number of frames received with error:
81430 + - InPktsBadTag,
81431 + - InPktsNoSCI,
81432 + - InPktsNotUsingSA
81433 + - InPktsNotValid */
81434 + uint64_t ifOutOctets; /**< Total number of byte sent */
81435 + uint64_t ifOutPkts; /**< Total number of packets sent */
81436 + uint64_t ifOutMcastPkts; /**< Total number of multicast frame sent */
81437 + uint64_t ifOutBcastPkts; /**< Total number of multicast frame sent */
81438 + uint64_t ifOutDiscards; /**< Frames received, but discarded due to problems within the MAC TX N/A! */
81439 + uint64_t ifOutErrors; /**< Number of frames transmitted with error:
81440 + - FIFO Overflow Error
81441 + - FIFO Underflow Error
81442 + - Other */
81443 +} t_MIBStatistics;
81444 +
81445 +/**************************************************************************//**
81446 + @Description MACSEC SecY Rx SA Statistics
81447 +*//***************************************************************************/
81448 +typedef struct t_FmMacsecSecYRxSaStatistics {
81449 + uint32_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
81450 + frame validation frame validation with the validateFrame not set to disable */
81451 + uint32_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
81452 + validation with the validateFrame set to check */
81453 + uint32_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
81454 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
81455 + uint32_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
81456 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
81457 + uint32_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
81458 + with validateFrame not in the strict mode and the C bit is cleared */
81459 +} t_FmMacsecSecYRxSaStatistics;
81460 +
81461 +/**************************************************************************//**
81462 + @Description MACSEC SecY Tx SA Statistics
81463 +*//***************************************************************************/
81464 +typedef struct t_FmMacsecSecYTxSaStatistics {
81465 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
81466 + be transmitted, which were integrity protected */
81467 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
81468 + be transmitted, which were confidentiality protected */
81469 +} t_FmMacsecSecYTxSaStatistics;
81470 +
81471 +/**************************************************************************//**
81472 + @Description MACSEC SecY Rx SC Statistics
81473 +*//***************************************************************************/
81474 +typedef struct t_FmMacsecSecYRxScStatistics {
81475 + uint64_t inPktsUnchecked; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
81476 + that are not validated with the validateFrame set to disable */
81477 + uint64_t inPktsDelayed; /**< The number of frames with resolved SCI, delivered to the user of a controlled port,
81478 + that have their PN smaller than the lowest_PN with the validateFrame set to
81479 + disable or replayProtect disabled */
81480 + uint64_t inPktsLate; /**< The number of frames with resolved SCI, discarded on the controlled port,
81481 + that have their PN smaller than the lowest_PN with the validateFrame set to
81482 + Check or Strict and replayProtect enabled */
81483 + uint64_t inPktsOK; /**< The number of frames with resolved SCI, have passed all
81484 + frame validation frame validation with the validateFrame not set to disable */
81485 + uint64_t inPktsInvalid; /**< The number of frames with resolved SCI, that have failed frame
81486 + validation with the validateFrame set to check */
81487 + uint64_t inPktsNotValid; /**< The number of frames with resolved SCI, discarded on the controlled port,
81488 + that have failed frame validation with the validateFrame set to strict or the c bit is set */
81489 + uint64_t inPktsNotUsingSA; /**< The number of frames received with resolved SCI and discarded on disabled or
81490 + not provisioned SA with validateFrame in the strict mode or the C bit is set */
81491 + uint64_t inPktsUnusedSA; /**< The number of frames received with resolved SCI on disabled or not provisioned SA
81492 + with validateFrame not in the strict mode and the C bit is cleared */
81493 +} t_FmMacsecSecYRxScStatistics;
81494 +
81495 +/**************************************************************************//**
81496 + @Description MACSEC SecY Tx SC Statistics
81497 +*//***************************************************************************/
81498 +typedef struct t_FmMacsecSecYTxScStatistics {
81499 + uint64_t outPktsProtected; /**< The number of frames, that the user of the controlled port requested to
81500 + be transmitted, which were integrity protected */
81501 + uint64_t outPktsEncrypted; /**< The number of frames, that the user of the controlled port requested to
81502 + be transmitted, which were confidentiality protected */
81503 +} t_FmMacsecSecYTxScStatistics;
81504 +
81505 +/**************************************************************************//**
81506 + @Description MACSEC SecY Statistics
81507 +*//***************************************************************************/
81508 +typedef struct t_FmMacsecSecYStatistics {
81509 + t_MIBStatistics mibCtrlStatistics; /**< Controlled port MIB statistics */
81510 + t_MIBStatistics mibNonCtrlStatistics; /**< Uncontrolled port MIB statistics */
81511 +/* Frame verification statistics */
81512 + uint64_t inPktsUntagged; /**< The number of received packets without the MAC security tag
81513 + (SecTAG) with validateFrames which is not in the strict mode */
81514 + uint64_t inPktsNoTag; /**< The number of received packets discarded without the
81515 + MAC security tag (SecTAG) with validateFrames which is in the strict mode */
81516 + uint64_t inPktsBadTag; /**< The number of received packets discarded with an invalid
81517 + SecTAG or a zero value PN or an invalid ICV */
81518 + uint64_t inPktsUnknownSCI; /**< The number of received packets with unknown SCI with the
81519 + condition : validateFrames is not in the strict mode and the
81520 + C bit in the SecTAG is not set */
81521 + uint64_t inPktsNoSCI; /**< The number of received packets discarded with unknown SCI
81522 + information with the condition : validateFrames is in the strict mode
81523 + or the C bit in the SecTAG is set */
81524 + uint64_t inPktsOverrun; /**< The number of packets discarded because the number of
81525 + received packets exceeded the cryptographic performance capabilities */
81526 +/* Frame validation statistics */
81527 + uint64_t inOctetsValidated; /**< The number of octets of plaintext recovered from received frames with
81528 + resolved SCI that were integrity protected but not encrypted */
81529 + uint64_t inOctetsDecrypted; /**< The number of octets of plaintext recovered from received frames with
81530 + resolved SCI that were integrity protected and encrypted */
81531 +/* Frame generation statistics */
81532 + uint64_t outPktsUntagged; /**< The number of frames, that the user of the controlled port requested to
81533 + be transmitted, with protectFrame false */
81534 + uint64_t outPktsTooLong; /**< The number of frames, that the user of the controlled port requested to
81535 + be transmitted, discarded due to length being larger than Maximum Frame Length (MACSEC_MFL) */
81536 +/* Frame protection statistics */
81537 + uint64_t outOctetsProtected; /**< The number of octets of User Data in transmitted frames that were
81538 + integrity protected but not encrypted */
81539 + uint64_t outOctetsEncrypted; /**< The number of octets of User Data in transmitted frames that were
81540 + both integrity protected and encrypted */
81541 +} t_FmMacsecSecYStatistics;
81542 +
81543 +
81544 +/**************************************************************************//**
81545 + @Description MACSEC SecY SC Params
81546 +*//***************************************************************************/
81547 +typedef struct t_FmMacsecSecYSCParams {
81548 + macsecSCI_t sci; /**< The secure channel identification of the SC */
81549 + e_FmMacsecSecYCipherSuite cipherSuite; /**< Cipher suite to be used for the SC */
81550 +} t_FmMacsecSecYSCParams;
81551 +
81552 +/**************************************************************************//**
81553 + @Group FM_MACSEC_SECY_init_grp FM-MACSEC SecY Initialization Unit
81554 +
81555 + @Description FM-MACSEC SecY Initialization Unit
81556 +
81557 + @{
81558 +*//***************************************************************************/
81559 +
81560 +/**************************************************************************//**
81561 + @Description enum for validate frames
81562 +*//***************************************************************************/
81563 +typedef enum e_FmMacsecValidFrameBehavior {
81564 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE = 0, /**< disable the validation function */
81565 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK, /**< enable the validation function but only for checking
81566 + without filtering out invalid frames */
81567 + e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT /**< enable the validation function and also strictly filter
81568 + out those invalid frames */
81569 +} e_FmMacsecValidFrameBehavior;
81570 +
81571 +/**************************************************************************//**
81572 + @Description enum for sci insertion
81573 +*//***************************************************************************/
81574 +typedef enum e_FmMacsecSciInsertionMode {
81575 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG = 0, /**< explicit sci in the sectag */
81576 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA, /**< mac sa is overwritten with the sci*/
81577 + e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP /**< implicit point-to-point sci (pre-shared) */
81578 +} e_FmMacsecSciInsertionMode;
81579 +
81580 +/**************************************************************************//**
81581 + @Description FM MACSEC SecY config input
81582 +*//***************************************************************************/
81583 +typedef struct t_FmMacsecSecYParams {
81584 + t_Handle h_FmMacsec; /**< A handle to the FM MACSEC object */
81585 + t_FmMacsecSecYSCParams txScParams; /**< Tx SC Params */
81586 + uint32_t numReceiveChannels; /**< Number of receive channels dedicated to this SecY */
81587 + t_FmMacsecSecYExceptionsCallback *f_Exception; /**< Callback routine to be called by the driver upon SecY exception */
81588 + t_FmMacsecSecYEventsCallback *f_Event; /**< Callback routine to be called by the driver upon SecY event */
81589 + t_Handle h_App; /**< A handle to an application layer object; This handle will
81590 + be passed by the driver upon calling the above callbacks */
81591 +} t_FmMacsecSecYParams;
81592 +
81593 +/**************************************************************************//**
81594 + @Function FM_MACSEC_SECY_Config
81595 +
81596 + @Description Creates descriptor for the FM MACSEC SECY module;
81597 +
81598 + The routine returns a handle (descriptor) to the FM MACSEC SECY object;
81599 + This descriptor must be passed as first parameter to all other
81600 + FM MACSEC SECY function calls;
81601 + No actual initialization or configuration of FM MACSEC SecY hardware is
81602 + done by this routine.
81603 +
81604 + @Param[in] p_FmMacsecSecYParam Pointer to data structure of parameters.
81605 +
81606 + @Return Handle to FM MACSEC SECY object, or NULL for Failure.
81607 +*//***************************************************************************/
81608 +t_Handle FM_MACSEC_SECY_Config(t_FmMacsecSecYParams *p_FmMacsecSecYParam);
81609 +
81610 +/**************************************************************************//**
81611 + @Function FM_MACSEC_SECY_Init
81612 +
81613 + @Description Initializes the FM MACSEC SECY module.
81614 +
81615 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81616 +
81617 + @Return E_OK on success; Error code otherwise.
81618 +*//***************************************************************************/
81619 +t_Error FM_MACSEC_SECY_Init(t_Handle h_FmMacsecSecY);
81620 +
81621 +/**************************************************************************//**
81622 + @Function FM_MACSEC_SECY_Free
81623 +
81624 + @Description Frees all resources that were assigned to FM MACSEC SECY module.
81625 +
81626 + Calling this routine invalidates the descriptor.
81627 +
81628 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81629 +
81630 + @Return E_OK on success; Error code otherwise.
81631 +*//***************************************************************************/
81632 +t_Error FM_MACSEC_SECY_Free(t_Handle h_FmMacsecSecY);
81633 +
81634 +/**************************************************************************//**
81635 + @Group FM_MACSEC_SECY_advanced_init_grp FM-MACSEC SecY Advanced Configuration Unit
81636 +
81637 + @Description Configuration functions used to change default values.
81638 +
81639 + @{
81640 +*//***************************************************************************/
81641 +
81642 +/**************************************************************************//**
81643 + @Function FM_MACSEC_SECY_ConfigSciInsertionMode
81644 +
81645 + @Description Calling this routine changes the SCI-insertion-mode in the
81646 + internal driver data base from its default configuration
81647 + [DEFAULT_sciInsertionMode]
81648 +
81649 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81650 + @Param[in] sciInsertionMode Sci insertion mode
81651 +
81652 + @Return E_OK on success; Error code otherwise.
81653 +
81654 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81655 +
81656 +*//***************************************************************************/
81657 +t_Error FM_MACSEC_SECY_ConfigSciInsertionMode(t_Handle h_FmMacsecSecY, e_FmMacsecSciInsertionMode sciInsertionMode);
81658 +
81659 +/**************************************************************************//**
81660 + @Function FM_MACSEC_SECY_ConfigProtectFrames
81661 +
81662 + @Description Calling this routine changes the protect-frame mode in the
81663 + internal driver data base from its default configuration
81664 + [DEFAULT_protectFrames]
81665 +
81666 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81667 + @Param[in] protectFrames If FALSE, frames are transmitted without modification
81668 +
81669 + @Return E_OK on success; Error code otherwise.
81670 +
81671 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81672 +
81673 +*//***************************************************************************/
81674 +t_Error FM_MACSEC_SECY_ConfigProtectFrames(t_Handle h_FmMacsecSecY, bool protectFrames);
81675 +
81676 +/**************************************************************************//**
81677 + @Function FM_MACSEC_SECY_ConfigReplayWindow
81678 +
81679 + @Description Calling this routine changes the replay-window settings in the
81680 + internal driver data base from its default configuration
81681 + [DEFAULT_replayEnable], [DEFAULT_replayWindow]
81682 +
81683 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81684 + @Param[in] replayProtect; Replay protection function mode
81685 + @Param[in] replayWindow; The size of the replay window
81686 +
81687 + @Return E_OK on success; Error code otherwise.
81688 +
81689 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81690 +
81691 +*//***************************************************************************/
81692 +t_Error FM_MACSEC_SECY_ConfigReplayWindow(t_Handle h_FmMacsecSecY, bool replayProtect, uint32_t replayWindow);
81693 +
81694 +/**************************************************************************//**
81695 + @Function FM_MACSEC_SECY_ConfigValidationMode
81696 +
81697 + @Description Calling this routine changes the frame-validation-behavior mode
81698 + in the internal driver data base from its default configuration
81699 + [DEFAULT_validateFrames]
81700 +
81701 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81702 + @Param[in] validateFrames Validation function mode
81703 +
81704 + @Return E_OK on success; Error code otherwise.
81705 +
81706 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81707 +
81708 +*//***************************************************************************/
81709 +t_Error FM_MACSEC_SECY_ConfigValidationMode(t_Handle h_FmMacsecSecY, e_FmMacsecValidFrameBehavior validateFrames);
81710 +
81711 +/**************************************************************************//**
81712 + @Function FM_MACSEC_SECY_ConfigConfidentiality
81713 +
81714 + @Description Calling this routine changes the confidentiality settings in the
81715 + internal driver data base from its default configuration
81716 + [DEFAULT_confidentialityEnable], [DEFAULT_confidentialityOffset]
81717 +
81718 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81719 + @Param[in] confidentialityEnable TRUE - confidentiality protection and integrity protection
81720 + FALSE - no confidentiality protection, only integrity protection
81721 + @Param[in] confidentialityOffset The number of initial octets of each MSDU without confidentiality protection
81722 + common values are 0, 30, and 50
81723 +
81724 + @Return E_OK on success; Error code otherwise.
81725 +
81726 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81727 +
81728 +*//***************************************************************************/
81729 +t_Error FM_MACSEC_SECY_ConfigConfidentiality(t_Handle h_FmMacsecSecY, bool confidentialityEnable, uint16_t confidentialityOffset);
81730 +
81731 +/**************************************************************************//**
81732 + @Function FM_MACSEC_SECY_ConfigPointToPoint
81733 +
81734 + @Description configure this SecY to work in point-to-point mode, means that
81735 + it will have only one rx sc;
81736 +
81737 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81738 +
81739 + @Return E_OK on success; Error code otherwise.
81740 +
81741 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init();
81742 + Can be called only once in a system; only the first secY that will call this
81743 + routine will be able to operate in Point-To-Point mode.
81744 +*//***************************************************************************/
81745 +t_Error FM_MACSEC_SECY_ConfigPointToPoint(t_Handle h_FmMacsecSecY);
81746 +
81747 +/**************************************************************************//**
81748 + @Function FM_MACSEC_SECY_ConfigException
81749 +
81750 + @Description Calling this routine changes the internal driver data base
81751 + from its default selection of exceptions enablement;
81752 + By default all exceptions are enabled.
81753 +
81754 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81755 + @Param[in] exception The exception to be selected.
81756 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81757 +
81758 + @Return E_OK on success; Error code otherwise.
81759 +
81760 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
81761 +*//***************************************************************************/
81762 +t_Error FM_MACSEC_SECY_ConfigException(t_Handle h_FmMacsecSecY, e_FmMacsecSecYExceptions exception, bool enable);
81763 +
81764 +/**************************************************************************//**
81765 + @Function FM_MACSEC_SECY_ConfigEvent
81766 +
81767 + @Description Calling this routine changes the internal driver data base
81768 + from its default selection of events enablement;
81769 + By default all events are enabled.
81770 +
81771 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81772 + @Param[in] event The event to be selected.
81773 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
81774 +
81775 + @Return E_OK on success; Error code otherwise.
81776 +
81777 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
81778 +*//***************************************************************************/
81779 +t_Error FM_MACSEC_SECY_ConfigEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
81780 +
81781 +/** @} */ /* end of FM_MACSEC_SECY_advanced_init_grp group */
81782 +/** @} */ /* end of FM_MACSEC_SECY_init_grp group */
81783 +
81784 +
81785 +/**************************************************************************//**
81786 + @Group FM_MACSEC_SECY_runtime_control_grp FM-MACSEC SecY Runtime Control Unit
81787 +
81788 + @Description FM MACSEC SECY Runtime control unit API functions, definitions and enums.
81789 +
81790 + @{
81791 +*//***************************************************************************/
81792 +
81793 +/**************************************************************************//**
81794 + @Function FM_MACSEC_SECY_CreateRxSc
81795 +
81796 + @Description Create a receive secure channel.
81797 +
81798 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81799 + @Param[in] scParams secure channel params.
81800 +
81801 + @Return E_OK on success; Error code otherwise.
81802 +
81803 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81804 +*//***************************************************************************/
81805 +t_Handle FM_MACSEC_SECY_CreateRxSc(t_Handle h_FmMacsecSecY, t_FmMacsecSecYSCParams *p_ScParams);
81806 +
81807 +/**************************************************************************//**
81808 + @Function FM_MACSEC_SECY_DeleteRxSc
81809 +
81810 + @Description Deleting an initialized secure channel.
81811 +
81812 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81813 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81814 +
81815 + @Return E_OK on success; Error code otherwise.
81816 +
81817 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
81818 +*//***************************************************************************/
81819 +t_Error FM_MACSEC_SECY_DeleteRxSc(t_Handle h_FmMacsecSecY, t_Handle h_Sc);
81820 +
81821 +/**************************************************************************//**
81822 + @Function FM_MACSEC_SECY_CreateRxSa
81823 +
81824 + @Description Create a receive secure association for the secure channel;
81825 + the SA cannot be used to receive frames until FM_MACSEC_SECY_RxSaEnableReceive is called.
81826 +
81827 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81828 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81829 + @Param[in] an association number represent the SA.
81830 + @Param[in] lowestPn the lowest acceptable PN value for a received frame.
81831 + @Param[in] key the desired key for this SA.
81832 +
81833 + @Return E_OK on success; Error code otherwise.
81834 +
81835 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
81836 +*//***************************************************************************/
81837 +t_Error FM_MACSEC_SECY_CreateRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t lowestPn, macsecSAKey_t key);
81838 +
81839 +/**************************************************************************//**
81840 + @Function FM_MACSEC_SECY_DeleteRxSa
81841 +
81842 + @Description Deleting an initialized secure association.
81843 +
81844 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81845 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81846 + @Param[in] an association number represent the SA.
81847 +
81848 + @Return E_OK on success; Error code otherwise.
81849 +
81850 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81851 +*//***************************************************************************/
81852 +t_Error FM_MACSEC_SECY_DeleteRxSa(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
81853 +
81854 +/**************************************************************************//**
81855 + @Function FM_MACSEC_SECY_RxSaEnableReceive
81856 +
81857 + @Description Enabling the SA to receive frames.
81858 +
81859 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81860 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81861 + @Param[in] an association number represent the SA.
81862 +
81863 + @Return E_OK on success; Error code otherwise.
81864 +
81865 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81866 +*//***************************************************************************/
81867 +t_Error FM_MACSEC_SECY_RxSaEnableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
81868 +
81869 +/**************************************************************************//**
81870 + @Function FM_MACSEC_SECY_RxSaDisableReceive
81871 +
81872 + @Description Disabling the SA from receive frames.
81873 +
81874 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81875 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81876 + @Param[in] an association number represent the SA.
81877 +
81878 + @Return E_OK on success; Error code otherwise.
81879 +
81880 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81881 +*//***************************************************************************/
81882 +t_Error FM_MACSEC_SECY_RxSaDisableReceive(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an);
81883 +
81884 +/**************************************************************************//**
81885 + @Function FM_MACSEC_SECY_RxSaUpdateNextPn
81886 +
81887 + @Description Update the next packet number expected on RX;
81888 + The value of nextPN shall be set to the greater of its existing value and the
81889 + supplied of updtNextPN (802.1AE-2006 10.7.15).
81890 +
81891 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81892 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81893 + @Param[in] an association number represent the SA.
81894 + @Param[in] updtNextPN the next PN value for a received frame.
81895 +
81896 + @Return E_OK on success; Error code otherwise.
81897 +
81898 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81899 +*//***************************************************************************/
81900 +t_Error FM_MACSEC_SECY_RxSaUpdateNextPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtNextPN);
81901 +
81902 +/**************************************************************************//**
81903 + @Function FM_MACSEC_SECY_RxSaUpdateLowestPn
81904 +
81905 + @Description Update the lowest packet number expected on RX;
81906 + The value of lowestPN shall be set to the greater of its existing value and the
81907 + supplied of updtLowestPN (802.1AE-2006 10.7.15).
81908 +
81909 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81910 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81911 + @Param[in] an association number represent the SA.
81912 + @Param[in] updtLowestPN the lowest PN acceptable value for a received frame.
81913 +
81914 + @Return E_OK on success; Error code otherwise.
81915 +
81916 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81917 +*//***************************************************************************/
81918 +t_Error FM_MACSEC_SECY_RxSaUpdateLowestPn(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, uint32_t updtLowestPN);
81919 +
81920 +/**************************************************************************//**
81921 + @Function FM_MACSEC_SECY_RxSaModifyKey
81922 +
81923 + @Description Modify the current key of the SA with a new one.
81924 +
81925 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81926 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
81927 + @Param[in] an association number represent the SA.
81928 + @Param[in] key new key to replace the current key.
81929 +
81930 + @Return E_OK on success; Error code otherwise.
81931 +
81932 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSa().
81933 +*//***************************************************************************/
81934 +t_Error FM_MACSEC_SECY_RxSaModifyKey(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, macsecSAKey_t key);
81935 +
81936 +/**************************************************************************//**
81937 + @Function FM_MACSEC_SECY_CreateTxSa
81938 +
81939 + @Description Create a transmit secure association for the secure channel;
81940 + the SA cannot be used to transmit frames until FM_MACSEC_SECY_TxSaSetActivate is called;
81941 + Only one SA can be active at a time.
81942 +
81943 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81944 + @Param[in] an association number represent the SA.
81945 + @Param[in] key the desired key for this SA.
81946 +
81947 + @Return E_OK on success; Error code otherwise.
81948 +
81949 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81950 +*//***************************************************************************/
81951 +t_Error FM_MACSEC_SECY_CreateTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an, macsecSAKey_t key);
81952 +
81953 +/**************************************************************************//**
81954 + @Function FM_MACSEC_SECY_DeleteTxSa
81955 +
81956 + @Description Deleting an initialized secure association.
81957 +
81958 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81959 + @Param[in] an association number represent the SA.
81960 +
81961 + @Return E_OK on success; Error code otherwise.
81962 +
81963 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81964 +*//***************************************************************************/
81965 +t_Error FM_MACSEC_SECY_DeleteTxSa(t_Handle h_FmMacsecSecY, macsecAN_t an);
81966 +
81967 +/**************************************************************************//**
81968 + @Function FM_MACSEC_SECY_TxSaModifyKey
81969 +
81970 + @Description Modify the key of the inactive SA with a new one.
81971 +
81972 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81973 + @Param[in] nextActiveAn association number represent the next SA to be activated.
81974 + @Param[in] key new key to replace the current key.
81975 +
81976 + @Return E_OK on success; Error code otherwise.
81977 +
81978 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81979 +*//***************************************************************************/
81980 +t_Error FM_MACSEC_SECY_TxSaModifyKey(t_Handle h_FmMacsecSecY, macsecAN_t nextActiveAn, macsecSAKey_t key);
81981 +
81982 +/**************************************************************************//**
81983 + @Function FM_MACSEC_SECY_TxSaSetActive
81984 +
81985 + @Description Set this SA to the active SA to be used on TX for SC;
81986 + only one SA can be active at a time.
81987 +
81988 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
81989 + @Param[in] an association number represent the SA.
81990 +
81991 + @Return E_OK on success; Error code otherwise.
81992 +
81993 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
81994 +*//***************************************************************************/
81995 +t_Error FM_MACSEC_SECY_TxSaSetActive(t_Handle h_FmMacsecSecY, macsecAN_t an);
81996 +
81997 +/**************************************************************************//**
81998 + @Function FM_MACSEC_SECY_TxSaGetActive
81999 +
82000 + @Description Get the active SA that being used for TX.
82001 +
82002 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82003 + @Param[out] p_An the active an.
82004 +
82005 + @Return E_OK on success; Error code otherwise.
82006 +
82007 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
82008 +*//***************************************************************************/
82009 +t_Error FM_MACSEC_SECY_TxSaGetActive(t_Handle h_FmMacsecSecY, macsecAN_t *p_An);
82010 +
82011 +/**************************************************************************//**
82012 + @Function FM_MACSEC_SECY_GetStatistics
82013 +
82014 + @Description get all statistics counters.
82015 +
82016 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82017 + @Param[in] p_Statistics Structure with statistics.
82018 +
82019 + @Return E_OK on success; Error code otherwise.
82020 +
82021 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
82022 +*//***************************************************************************/
82023 +t_Error FM_MACSEC_SECY_GetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYStatistics *p_Statistics);
82024 +
82025 +/**************************************************************************//**
82026 + @Function FM_MACSEC_SECY_RxScGetStatistics
82027 +
82028 + @Description get all statistics counters.
82029 +
82030 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82031 + @Param[in] h_Sc Rx Sc handle.
82032 + @Param[in] p_Statistics Structure with statistics.
82033 +
82034 + @Return E_OK on success; Error code otherwise.
82035 +
82036 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
82037 +*//***************************************************************************/
82038 +t_Error FM_MACSEC_SECY_RxScGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, t_FmMacsecSecYRxScStatistics *p_Statistics);
82039 +
82040 +/**************************************************************************//**
82041 + @Function FM_MACSEC_SECY_RxSaGetStatistics
82042 +
82043 + @Description get all statistics counters
82044 +
82045 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82046 + @Param[in] h_Sc Rx Sc handle.
82047 + @Param[in] an association number represent the SA.
82048 + @Param[in] p_Statistics Structure with statistics.
82049 +
82050 + @Return E_OK on success; Error code otherwise.
82051 +
82052 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
82053 +*//***************************************************************************/
82054 +t_Error FM_MACSEC_SECY_RxSaGetStatistics(t_Handle h_FmMacsecSecY, t_Handle h_Sc, macsecAN_t an, t_FmMacsecSecYRxSaStatistics *p_Statistics);
82055 +
82056 +/**************************************************************************//**
82057 + @Function FM_MACSEC_SECY_TxScGetStatistics
82058 +
82059 + @Description get all statistics counters.
82060 +
82061 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82062 + @Param[in] p_Statistics Structure with statistics.
82063 +
82064 + @Return E_OK on success; Error code otherwise.
82065 +
82066 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
82067 +*//***************************************************************************/
82068 +t_Error FM_MACSEC_SECY_TxScGetStatistics(t_Handle h_FmMacsecSecY, t_FmMacsecSecYTxScStatistics *p_Statistics);
82069 +
82070 +/**************************************************************************//**
82071 + @Function FM_MACSEC_SECY_TxSaGetStatistics
82072 +
82073 + @Description get all statistics counters.
82074 +
82075 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82076 + @Param[in] an association number represent the SA.
82077 + @Param[in] p_Statistics Structure with statistics.
82078 +
82079 + @Return E_OK on success; Error code otherwise.
82080 +
82081 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
82082 +*//***************************************************************************/
82083 +t_Error FM_MACSEC_SECY_TxSaGetStatistics(t_Handle h_FmMacsecSecY, macsecAN_t an, t_FmMacsecSecYTxSaStatistics *p_Statistics);
82084 +
82085 +/**************************************************************************//**
82086 + @Function FM_MACSEC_SECY_SetException
82087 +
82088 + @Description Calling this routine enables/disables the specified exception.
82089 +
82090 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82091 + @Param[in] exception The exception to be selected.
82092 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
82093 +
82094 + @Return E_OK on success; Error code otherwise.
82095 +
82096 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
82097 +*//***************************************************************************/
82098 +t_Error FM_MACSEC_SECY_SetException(t_Handle h_FmMacsecSecY, e_FmMacsecExceptions exception, bool enable);
82099 +
82100 +/**************************************************************************//**
82101 + @Function FM_MACSEC_SECY_SetEvent
82102 +
82103 + @Description Calling this routine enables/disables the specified event.
82104 +
82105 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82106 + @Param[in] event The event to be selected.
82107 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
82108 +
82109 + @Return E_OK on success; Error code otherwise.
82110 +
82111 + @Cautions Allowed only following FM_MACSEC_SECY_Config() and before FM_MACSEC_SECY_Init().
82112 +*//***************************************************************************/
82113 +t_Error FM_MACSEC_SECY_SetEvent(t_Handle h_FmMacsecSecY, e_FmMacsecSecYEvents event, bool enable);
82114 +
82115 +/**************************************************************************//**
82116 + @Function FM_MACSEC_SECY_GetRxScPhysId
82117 +
82118 + @Description return the physical id of the Secure Channel.
82119 +
82120 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82121 + @Param[in] h_Sc SC handle as returned by FM_MACSEC_SECY_CreateRxSc.
82122 + @Param[out] p_ScPhysId the SC physical id.
82123 +
82124 + @Return E_OK on success; Error code otherwise.
82125 +
82126 + @Cautions Allowed only following FM_MACSEC_SECY_CreateRxSc().
82127 +*//***************************************************************************/
82128 +t_Error FM_MACSEC_SECY_GetRxScPhysId(t_Handle h_FmMacsecSecY, t_Handle h_Sc, uint32_t *p_ScPhysId);
82129 +
82130 +/**************************************************************************//**
82131 + @Function FM_MACSEC_SECY_GetTxScPhysId
82132 +
82133 + @Description return the physical id of the Secure Channel.
82134 +
82135 + @Param[in] h_FmMacsecSecY FM MACSEC SECY module descriptor.
82136 + @Param[out] p_ScPhysId the SC physical id.
82137 +
82138 + @Return E_OK on success; Error code otherwise.
82139 +
82140 + @Cautions Allowed only following FM_MACSEC_SECY_Init().
82141 +*//***************************************************************************/
82142 +t_Error FM_MACSEC_SECY_GetTxScPhysId(t_Handle h_FmMacsecSecY, uint32_t *p_ScPhysId);
82143 +
82144 +/** @} */ /* end of FM_MACSEC_SECY_runtime_control_grp group */
82145 +/** @} */ /* end of FM_MACSEC_SECY_grp group */
82146 +/** @} */ /* end of FM_MACSEC_grp group */
82147 +/** @} */ /* end of FM_grp group */
82148 +
82149 +
82150 +#endif /* __FM_MACSEC_EXT_H */
82151 --- /dev/null
82152 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_muram_ext.h
82153 @@ -0,0 +1,170 @@
82154 +/*
82155 + * Copyright 2008-2012 Freescale Semiconductor Inc.
82156 + *
82157 + * Redistribution and use in source and binary forms, with or without
82158 + * modification, are permitted provided that the following conditions are met:
82159 + * * Redistributions of source code must retain the above copyright
82160 + * notice, this list of conditions and the following disclaimer.
82161 + * * Redistributions in binary form must reproduce the above copyright
82162 + * notice, this list of conditions and the following disclaimer in the
82163 + * documentation and/or other materials provided with the distribution.
82164 + * * Neither the name of Freescale Semiconductor nor the
82165 + * names of its contributors may be used to endorse or promote products
82166 + * derived from this software without specific prior written permission.
82167 + *
82168 + *
82169 + * ALTERNATIVELY, this software may be distributed under the terms of the
82170 + * GNU General Public License ("GPL") as published by the Free Software
82171 + * Foundation, either version 2 of that License or (at your option) any
82172 + * later version.
82173 + *
82174 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
82175 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
82176 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
82177 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
82178 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
82179 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
82180 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
82181 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
82182 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
82183 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82184 + */
82185 +
82186 +
82187 +/**************************************************************************//**
82188 + @File fm_muram_ext.h
82189 +
82190 + @Description FM MURAM Application Programming Interface.
82191 +*//***************************************************************************/
82192 +#ifndef __FM_MURAM_EXT
82193 +#define __FM_MURAM_EXT
82194 +
82195 +#include "error_ext.h"
82196 +#include "std_ext.h"
82197 +
82198 +
82199 +/**************************************************************************//**
82200 +
82201 + @Group FM_grp Frame Manager API
82202 +
82203 + @Description FM API functions, definitions and enums
82204 +
82205 + @{
82206 +*//***************************************************************************/
82207 +
82208 +/**************************************************************************//**
82209 + @Group FM_muram_grp FM MURAM
82210 +
82211 + @Description FM MURAM API functions, definitions and enums
82212 +
82213 + @{
82214 +*//***************************************************************************/
82215 +
82216 +/**************************************************************************//**
82217 + @Group FM_muram_init_grp FM MURAM Initialization Unit
82218 +
82219 + @Description FM MURAM initialization API functions, definitions and enums
82220 +
82221 + @{
82222 +*//***************************************************************************/
82223 +
82224 +/**************************************************************************//**
82225 + @Function FM_MURAM_ConfigAndInit
82226 +
82227 + @Description Creates partition in the MURAM.
82228 +
82229 + The routine returns a handle (descriptor) to the MURAM partition.
82230 + This descriptor must be passed as first parameter to all other
82231 + FM-MURAM function calls.
82232 +
82233 + No actual initialization or configuration of FM_MURAM hardware is
82234 + done by this routine.
82235 +
82236 + @Param[in] baseAddress - Pointer to base of memory mapped FM-MURAM.
82237 + @Param[in] size - Size of the FM-MURAM partition.
82238 +
82239 + @Return Handle to FM-MURAM object, or NULL for Failure.
82240 +*//***************************************************************************/
82241 +t_Handle FM_MURAM_ConfigAndInit(uintptr_t baseAddress, uint32_t size);
82242 +
82243 +/**************************************************************************//**
82244 + @Function FM_MURAM_Free
82245 +
82246 + @Description Frees all resources that were assigned to FM-MURAM module.
82247 +
82248 + Calling this routine invalidates the descriptor.
82249 +
82250 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
82251 +
82252 + @Return E_OK on success; Error code otherwise.
82253 +*//***************************************************************************/
82254 +t_Error FM_MURAM_Free(t_Handle h_FmMuram);
82255 +
82256 +/** @} */ /* end of FM_muram_init_grp group */
82257 +
82258 +
82259 +/**************************************************************************//**
82260 + @Group FM_muram_ctrl_grp FM MURAM Control Unit
82261 +
82262 + @Description FM MURAM control API functions, definitions and enums
82263 +
82264 + @{
82265 +*//***************************************************************************/
82266 +
82267 +/**************************************************************************//**
82268 + @Function FM_MURAM_AllocMem
82269 +
82270 + @Description Allocate some memory from FM-MURAM partition.
82271 +
82272 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
82273 + @Param[in] size - size of the memory to be allocated.
82274 + @Param[in] align - Alignment of the memory.
82275 +
82276 + @Return address of the allocated memory; NULL otherwise.
82277 +*//***************************************************************************/
82278 +void * FM_MURAM_AllocMem(t_Handle h_FmMuram, uint32_t size, uint32_t align);
82279 +
82280 +/**************************************************************************//**
82281 + @Function FM_MURAM_AllocMemForce
82282 +
82283 + @Description Allocate some specific memory from FM-MURAM partition (according
82284 + to base).
82285 +
82286 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
82287 + @Param[in] base - the desired base-address to be allocated.
82288 + @Param[in] size - size of the memory to be allocated.
82289 +
82290 + @Return address of the allocated memory; NULL otherwise.
82291 +*//***************************************************************************/
82292 +void * FM_MURAM_AllocMemForce(t_Handle h_FmMuram, uint64_t base, uint32_t size);
82293 +
82294 +/**************************************************************************//**
82295 + @Function FM_MURAM_FreeMem
82296 +
82297 + @Description Free an allocated memory from FM-MURAM partition.
82298 +
82299 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
82300 + @Param[in] ptr - A pointer to an allocated memory.
82301 +
82302 + @Return E_OK on success; Error code otherwise.
82303 +*//***************************************************************************/
82304 +t_Error FM_MURAM_FreeMem(t_Handle h_FmMuram, void *ptr);
82305 +
82306 +/**************************************************************************//**
82307 + @Function FM_MURAM_GetFreeMemSize
82308 +
82309 + @Description Returns the size (in bytes) of free MURAM memory.
82310 +
82311 + @Param[in] h_FmMuram - FM-MURAM module descriptor.
82312 +
82313 + @Return Free MURAM memory size in bytes.
82314 +*//***************************************************************************/
82315 +uint64_t FM_MURAM_GetFreeMemSize(t_Handle h_FmMuram);
82316 +
82317 +/** @} */ /* end of FM_muram_ctrl_grp group */
82318 +/** @} */ /* end of FM_muram_grp group */
82319 +/** @} */ /* end of FM_grp group */
82320 +
82321 +
82322 +
82323 +#endif /* __FM_MURAM_EXT */
82324 --- /dev/null
82325 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_pcd_ext.h
82326 @@ -0,0 +1,3974 @@
82327 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
82328 + * All rights reserved.
82329 + *
82330 + * Redistribution and use in source and binary forms, with or without
82331 + * modification, are permitted provided that the following conditions are met:
82332 + * * Redistributions of source code must retain the above copyright
82333 + * notice, this list of conditions and the following disclaimer.
82334 + * * Redistributions in binary form must reproduce the above copyright
82335 + * notice, this list of conditions and the following disclaimer in the
82336 + * documentation and/or other materials provided with the distribution.
82337 + * * Neither the name of Freescale Semiconductor nor the
82338 + * names of its contributors may be used to endorse or promote products
82339 + * derived from this software without specific prior written permission.
82340 + *
82341 + *
82342 + * ALTERNATIVELY, this software may be distributed under the terms of the
82343 + * GNU General Public License ("GPL") as published by the Free Software
82344 + * Foundation, either version 2 of that License or (at your option) any
82345 + * later version.
82346 + *
82347 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
82348 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
82349 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
82350 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
82351 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
82352 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
82353 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
82354 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
82355 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
82356 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
82357 + */
82358 +
82359 +
82360 +/**************************************************************************//**
82361 + @File fm_pcd_ext.h
82362 +
82363 + @Description FM PCD API definitions
82364 +*//***************************************************************************/
82365 +#ifndef __FM_PCD_EXT
82366 +#define __FM_PCD_EXT
82367 +
82368 +#include "std_ext.h"
82369 +#include "net_ext.h"
82370 +#include "list_ext.h"
82371 +#include "fm_ext.h"
82372 +#include "fsl_fman_kg.h"
82373 +
82374 +
82375 +/**************************************************************************//**
82376 + @Group FM_grp Frame Manager API
82377 +
82378 + @Description Frame Manager Application Programming Interface
82379 +
82380 + @{
82381 +*//***************************************************************************/
82382 +
82383 +/**************************************************************************//**
82384 + @Group FM_PCD_grp FM PCD
82385 +
82386 + @Description Frame Manager PCD (Parse-Classify-Distribute) API.
82387 +
82388 + The FM PCD module is responsible for the initialization of all
82389 + global classifying FM modules. This includes the parser general and
82390 + common registers, the key generator global and common registers,
82391 + and the policer global and common registers.
82392 + In addition, the FM PCD SW module will initialize all required
82393 + key generator schemes, coarse classification flows, and policer
82394 + profiles. When FM module is configured to work with one of these
82395 + entities, it will register to it using the FM PORT API. The PCD
82396 + module will manage the PCD resources - i.e. resource management of
82397 + KeyGen schemes, etc.
82398 +
82399 + @{
82400 +*//***************************************************************************/
82401 +
82402 +/**************************************************************************//**
82403 + @Collection General PCD defines
82404 +*//***************************************************************************/
82405 +#define FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
82406 +
82407 +#define FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
82408 +#define FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
82409 + /**< Number of distinction units is limited by
82410 + register size (32 bits) minus reserved bits
82411 + for private headers. */
82412 +#define FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
82413 + in a distinction unit */
82414 +#define FM_PCD_KG_NUM_OF_GENERIC_REGS FM_KG_NUM_OF_GENERIC_REGS /**< Total number of generic KeyGen registers */
82415 +#define FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
82416 + For HW implementation reasons, in most
82417 + cases less than this will be allowed; The
82418 + driver will return an initialization error
82419 + if resource is unavailable. */
82420 +#define FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
82421 +#define FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
82422 +
82423 +#define FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
82424 +#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)
82425 + /**< Maximum size of SW parser code */
82426 +
82427 +#define FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
82428 + insert manipulation */
82429 +
82430 +#if (DPAA_VERSION >= 11)
82431 +#define FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
82432 +#endif /* (DPAA_VERSION >= 11) */
82433 +/* @} */
82434 +
82435 +
82436 +/**************************************************************************//**
82437 + @Group FM_PCD_init_grp FM PCD Initialization Unit
82438 +
82439 + @Description Frame Manager PCD Initialization Unit API
82440 +
82441 + @{
82442 +*//***************************************************************************/
82443 +
82444 +/**************************************************************************//**
82445 + @Description PCD counters
82446 +*//***************************************************************************/
82447 +typedef enum e_FmPcdCounters {
82448 + e_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
82449 + e_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
82450 + e_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
82451 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
82452 + This is a subset of e_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
82453 + e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
82454 + This is a subset of e_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
82455 + e_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
82456 + e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
82457 + e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
82458 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
82459 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
82460 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
82461 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
82462 + 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. */
82463 + 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. */
82464 + 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. */
82465 + 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. */
82466 + e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
82467 + 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. */
82468 + 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). */
82469 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
82470 + e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
82471 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
82472 + e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
82473 + e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
82474 +} e_FmPcdCounters;
82475 +
82476 +/**************************************************************************//**
82477 + @Description PCD interrupts
82478 +*//***************************************************************************/
82479 +typedef enum e_FmPcdExceptions {
82480 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
82481 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
82482 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
82483 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
82484 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
82485 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
82486 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
82487 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
82488 +} e_FmPcdExceptions;
82489 +
82490 +
82491 +/**************************************************************************//**
82492 + @Description Exceptions user callback routine, will be called upon an
82493 + exception passing the exception identification.
82494 +
82495 + @Param[in] h_App - User's application descriptor.
82496 + @Param[in] exception - The exception.
82497 + *//***************************************************************************/
82498 +typedef void (t_FmPcdExceptionCallback) (t_Handle h_App, e_FmPcdExceptions exception);
82499 +
82500 +/**************************************************************************//**
82501 + @Description Exceptions user callback routine, will be called upon an exception
82502 + passing the exception identification.
82503 +
82504 + @Param[in] h_App - User's application descriptor.
82505 + @Param[in] exception - The exception.
82506 + @Param[in] index - id of the relevant source (may be scheme or profile id).
82507 + *//***************************************************************************/
82508 +typedef void (t_FmPcdIdExceptionCallback) ( t_Handle h_App,
82509 + e_FmPcdExceptions exception,
82510 + uint16_t index);
82511 +
82512 +/**************************************************************************//**
82513 + @Description A callback for enqueuing frame onto a QM queue.
82514 +
82515 + @Param[in] h_QmArg - Application's handle passed to QM module on enqueue.
82516 + @Param[in] p_Fd - Frame descriptor for the frame.
82517 +
82518 + @Return E_OK on success; Error code otherwise.
82519 + *//***************************************************************************/
82520 +typedef t_Error (t_FmPcdQmEnqueueCallback) (t_Handle h_QmArg, void *p_Fd);
82521 +
82522 +/**************************************************************************//**
82523 + @Description Host-Command parameters structure.
82524 +
82525 + When using Host command for PCD functionalities, a dedicated port
82526 + must be used. If this routine is called for a PCD in a single partition
82527 + environment, or it is the Master partition in a Multi-partition
82528 + environment, The port will be initialized by the PCD driver
82529 + initialization routine.
82530 + *//***************************************************************************/
82531 +typedef struct t_FmPcdHcParams {
82532 + uintptr_t portBaseAddr; /**< Virtual Address of Host-Command Port memory mapped registers.*/
82533 + uint8_t portId; /**< Port Id (0-6 relative to Host-Command/Offline-Parsing ports);
82534 + NOTE: When configuring Host Command port for
82535 + FMANv3 devices (DPAA_VERSION 11 and higher),
82536 + portId=0 MUST be used. */
82537 + uint16_t liodnBase; /**< LIODN base for this port, to be used together with LIODN offset
82538 + (irrelevant for P4080 revision 1.0) */
82539 + uint32_t errFqid; /**< Host-Command Port error queue Id. */
82540 + uint32_t confFqid; /**< Host-Command Port confirmation queue Id. */
82541 + uint32_t qmChannel; /**< QM channel dedicated to this Host-Command port;
82542 + will be used by the FM for dequeue. */
82543 + t_FmPcdQmEnqueueCallback *f_QmEnqueue; /**< Callback routine for enqueuing a frame to the QM */
82544 + t_Handle h_QmArg; /**< Application's handle passed to QM module on enqueue */
82545 +} t_FmPcdHcParams;
82546 +
82547 +/**************************************************************************//**
82548 + @Description The main structure for PCD initialization
82549 + *//***************************************************************************/
82550 +typedef struct t_FmPcdParams {
82551 + bool prsSupport; /**< TRUE if Parser will be used for any of the FM ports. */
82552 + bool ccSupport; /**< TRUE if Coarse Classification will be used for any
82553 + of the FM ports. */
82554 + bool kgSupport; /**< TRUE if KeyGen will be used for any of the FM ports. */
82555 + bool plcrSupport; /**< TRUE if Policer will be used for any of the FM ports. */
82556 + t_Handle h_Fm; /**< A handle to the FM module. */
82557 + uint8_t numOfSchemes; /**< Number of schemes dedicated to this partition.
82558 + this parameter is relevant if 'kgSupport'=TRUE. */
82559 + bool useHostCommand; /**< Optional for single partition, Mandatory for Multi partition */
82560 + t_FmPcdHcParams hc; /**< Host Command parameters, relevant only if 'useHostCommand'=TRUE;
82561 + Relevant when FM not runs in "guest-mode". */
82562 +
82563 + t_FmPcdExceptionCallback *f_Exception; /**< Callback routine for general PCD exceptions;
82564 + Relevant when FM not runs in "guest-mode". */
82565 + t_FmPcdIdExceptionCallback *f_ExceptionId; /**< Callback routine for specific KeyGen scheme or
82566 + Policer profile exceptions;
82567 + Relevant when FM not runs in "guest-mode". */
82568 + t_Handle h_App; /**< A handle to an application layer object; This handle will
82569 + be passed by the driver upon calling the above callbacks;
82570 + Relevant when FM not runs in "guest-mode". */
82571 + uint8_t partPlcrProfilesBase; /**< The first policer-profile-id dedicated to this partition.
82572 + this parameter is relevant if 'plcrSupport'=TRUE.
82573 + NOTE: this parameter relevant only when working with multiple partitions. */
82574 + uint16_t partNumOfPlcrProfiles; /**< Number of policer-profiles dedicated to this partition.
82575 + this parameter is relevant if 'plcrSupport'=TRUE.
82576 + NOTE: this parameter relevant only when working with multiple partitions. */
82577 +} t_FmPcdParams;
82578 +
82579 +
82580 +/**************************************************************************//**
82581 + @Function FM_PCD_Config
82582 +
82583 + @Description Basic configuration of the PCD module.
82584 + Creates descriptor for the FM PCD module.
82585 +
82586 + @Param[in] p_FmPcdParams A structure of parameters for the initialization of PCD.
82587 +
82588 + @Return A handle to the initialized module.
82589 +*//***************************************************************************/
82590 +t_Handle FM_PCD_Config(t_FmPcdParams *p_FmPcdParams);
82591 +
82592 +/**************************************************************************//**
82593 + @Function FM_PCD_Init
82594 +
82595 + @Description Initialization of the PCD module.
82596 +
82597 + @Param[in] h_FmPcd - FM PCD module descriptor.
82598 +
82599 + @Return E_OK on success; Error code otherwise.
82600 +*//***************************************************************************/
82601 +t_Error FM_PCD_Init(t_Handle h_FmPcd);
82602 +
82603 +/**************************************************************************//**
82604 + @Function FM_PCD_Free
82605 +
82606 + @Description Frees all resources that were assigned to FM module.
82607 +
82608 + Calling this routine invalidates the descriptor.
82609 +
82610 + @Param[in] h_FmPcd - FM PCD module descriptor.
82611 +
82612 + @Return E_OK on success; Error code otherwise.
82613 +*//***************************************************************************/
82614 +t_Error FM_PCD_Free(t_Handle h_FmPcd);
82615 +
82616 +/**************************************************************************//**
82617 + @Group FM_PCD_advanced_cfg_grp FM PCD Advanced Configuration Unit
82618 +
82619 + @Description Frame Manager PCD Advanced Configuration API.
82620 +
82621 + @{
82622 +*//***************************************************************************/
82623 +
82624 +/**************************************************************************//**
82625 + @Function FM_PCD_ConfigException
82626 +
82627 + @Description Calling this routine changes the internal driver data base
82628 + from its default selection of exceptions enabling.
82629 + [DEFAULT_numOfSharedPlcrProfiles].
82630 +
82631 + @Param[in] h_FmPcd FM PCD module descriptor.
82632 + @Param[in] exception The exception to be selected.
82633 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
82634 +
82635 + @Return E_OK on success; Error code otherwise.
82636 +
82637 + @Cautions This routine should NOT be called from guest-partition
82638 + (i.e. guestId != NCSW_MASTER_ID)
82639 +*//***************************************************************************/
82640 +t_Error FM_PCD_ConfigException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
82641 +
82642 +/**************************************************************************//**
82643 + @Function FM_PCD_ConfigHcFramesDataMemory
82644 +
82645 + @Description Configures memory-partition-id for FMan-Controller Host-Command
82646 + frames. Calling this routine changes the internal driver data
82647 + base from its default configuration [0].
82648 +
82649 + @Param[in] h_FmPcd FM PCD module descriptor.
82650 + @Param[in] memId Memory partition ID.
82651 +
82652 + @Return E_OK on success; Error code otherwise.
82653 +
82654 + @Cautions This routine may be called only if 'useHostCommand' was TRUE
82655 + when FM_PCD_Config() routine was called.
82656 +*//***************************************************************************/
82657 +t_Error FM_PCD_ConfigHcFramesDataMemory(t_Handle h_FmPcd, uint8_t memId);
82658 +
82659 +/**************************************************************************//**
82660 + @Function FM_PCD_ConfigPlcrNumOfSharedProfiles
82661 +
82662 + @Description Calling this routine changes the internal driver data base
82663 + from its default selection of exceptions enablement.
82664 + [DEFAULT_numOfSharedPlcrProfiles].
82665 +
82666 + @Param[in] h_FmPcd FM PCD module descriptor.
82667 + @Param[in] numOfSharedPlcrProfiles Number of profiles to
82668 + be shared between ports on this partition
82669 +
82670 + @Return E_OK on success; Error code otherwise.
82671 +*//***************************************************************************/
82672 +t_Error FM_PCD_ConfigPlcrNumOfSharedProfiles(t_Handle h_FmPcd, uint16_t numOfSharedPlcrProfiles);
82673 +
82674 +/**************************************************************************//**
82675 + @Function FM_PCD_ConfigPlcrAutoRefreshMode
82676 +
82677 + @Description Calling this routine changes the internal driver data base
82678 + from its default selection of exceptions enablement.
82679 + By default auto-refresh is [DEFAULT_plcrAutoRefresh].
82680 +
82681 + @Param[in] h_FmPcd FM PCD module descriptor.
82682 + @Param[in] enable TRUE to enable, FALSE to disable
82683 +
82684 + @Return E_OK on success; Error code otherwise.
82685 +
82686 + @Cautions This routine should NOT be called from guest-partition
82687 + (i.e. guestId != NCSW_MASTER_ID)
82688 +*//***************************************************************************/
82689 +t_Error FM_PCD_ConfigPlcrAutoRefreshMode(t_Handle h_FmPcd, bool enable);
82690 +
82691 +/**************************************************************************//**
82692 + @Function FM_PCD_ConfigPrsMaxCycleLimit
82693 +
82694 + @Description Calling this routine changes the internal data structure for
82695 + the maximum parsing time from its default value
82696 + [DEFAULT_MAX_PRS_CYC_LIM].
82697 +
82698 + @Param[in] h_FmPcd FM PCD module descriptor.
82699 + @Param[in] value 0 to disable the mechanism, or new
82700 + maximum parsing time.
82701 +
82702 + @Return E_OK on success; Error code otherwise.
82703 +
82704 + @Cautions This routine should NOT be called from guest-partition
82705 + (i.e. guestId != NCSW_MASTER_ID)
82706 +*//***************************************************************************/
82707 +t_Error FM_PCD_ConfigPrsMaxCycleLimit(t_Handle h_FmPcd,uint16_t value);
82708 +
82709 +/** @} */ /* end of FM_PCD_advanced_cfg_grp group */
82710 +/** @} */ /* end of FM_PCD_init_grp group */
82711 +
82712 +
82713 +/**************************************************************************//**
82714 + @Group FM_PCD_Runtime_grp FM PCD Runtime Unit
82715 +
82716 + @Description Frame Manager PCD Runtime Unit API
82717 +
82718 + The runtime control allows creation of PCD infrastructure modules
82719 + such as Network Environment Characteristics, Classification Plan
82720 + Groups and Coarse Classification Trees.
82721 + It also allows on-the-fly initialization, modification and removal
82722 + of PCD modules such as KeyGen schemes, coarse classification nodes
82723 + and Policer profiles.
82724 +
82725 + In order to explain the programming model of the PCD driver interface
82726 + a few terms should be explained, and will be used below.
82727 + - Distinction Header - One of the 16 protocols supported by the FM parser,
82728 + or one of the SHIM headers (1 or 2). May be a header with a special
82729 + option (see below).
82730 + - Interchangeable Headers Group - This is a group of Headers recognized
82731 + by either one of them. For example, if in a specific context the user
82732 + chooses to treat IPv4 and IPV6 in the same way, they may create an
82733 + interchangeable Headers Unit consisting of these 2 headers.
82734 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
82735 + Group.
82736 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
82737 + IPv6, includes multicast, broadcast and other protocol specific options.
82738 + In terms of hardware it relates to the options available in the classification
82739 + plan.
82740 + - Network Environment Characteristics - a set of Distinction Units that define
82741 + the total recognizable header selection for a certain environment. This is
82742 + NOT the list of all headers that will ever appear in a flow, but rather
82743 + everything that needs distinction in a flow, where distinction is made by KeyGen
82744 + schemes and coarse classification action descriptors.
82745 +
82746 + The PCD runtime modules initialization is done in stages. The first stage after
82747 + initializing the PCD module itself is to establish a Network Flows Environment
82748 + Definition. The application may choose to establish one or more such environments.
82749 + Later, when needed, the application will have to state, for some of its modules,
82750 + to which single environment it belongs.
82751 +
82752 + @{
82753 +*//***************************************************************************/
82754 +
82755 +/**************************************************************************//**
82756 + @Description A structure for SW parser labels
82757 + *//***************************************************************************/
82758 +typedef struct t_FmPcdPrsLabelParams {
82759 + uint32_t instructionOffset; /**< SW parser label instruction offset (2 bytes
82760 + resolution), relative to Parser RAM. */
82761 + e_NetHeaderType hdr; /**< The existence of this header will invoke
82762 + the SW parser code; Use HEADER_TYPE_NONE
82763 + to indicate that sw parser is to run
82764 + independent of the existence of any protocol
82765 + (run before HW parser). */
82766 + uint8_t indexPerHdr; /**< Normally 0, if more than one SW parser
82767 + attachments for the same header, use this
82768 + index to distinguish between them. */
82769 +} t_FmPcdPrsLabelParams;
82770 +
82771 +/**************************************************************************//**
82772 + @Description A structure for SW parser
82773 + *//***************************************************************************/
82774 +typedef struct t_FmPcdPrsSwParams {
82775 + bool override; /**< FALSE to invoke a check that nothing else
82776 + was loaded to this address, including
82777 + internal patches.
82778 + TRUE to override any existing code.*/
82779 + uint32_t size; /**< SW parser code size */
82780 + uint16_t base; /**< SW parser base (in instruction counts!
82781 + must be larger than 0x20)*/
82782 + uint8_t *p_Code; /**< SW parser code */
82783 + uint32_t swPrsDataParams[FM_PCD_PRS_NUM_OF_HDRS];
82784 + /**< SW parser data (parameters) */
82785 + uint8_t numOfLabels; /**< Number of labels for SW parser. */
82786 + t_FmPcdPrsLabelParams labelsTable[FM_PCD_PRS_NUM_OF_LABELS];
82787 + /**< SW parser labels table, containing
82788 + numOfLabels entries */
82789 +} t_FmPcdPrsSwParams;
82790 +
82791 +
82792 +/**************************************************************************//**
82793 + @Function FM_PCD_Enable
82794 +
82795 + @Description This routine should be called after PCD is initialized for enabling all
82796 + PCD engines according to their existing configuration.
82797 +
82798 + @Param[in] h_FmPcd FM PCD module descriptor.
82799 +
82800 + @Return E_OK on success; Error code otherwise.
82801 +
82802 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82803 +*//***************************************************************************/
82804 +t_Error FM_PCD_Enable(t_Handle h_FmPcd);
82805 +
82806 +/**************************************************************************//**
82807 + @Function FM_PCD_Disable
82808 +
82809 + @Description This routine may be called when PCD is enabled in order to
82810 + disable all PCD engines. It may be called
82811 + only when none of the ports in the system are using the PCD.
82812 +
82813 + @Param[in] h_FmPcd FM PCD module descriptor.
82814 +
82815 + @Return E_OK on success; Error code otherwise.
82816 +
82817 + @Cautions Allowed only following FM_PCD_Init() and when PCD is enabled.
82818 +*//***************************************************************************/
82819 +t_Error FM_PCD_Disable(t_Handle h_FmPcd);
82820 +
82821 +/**************************************************************************//**
82822 + @Function FM_PCD_GetCounter
82823 +
82824 + @Description Reads one of the FM PCD counters.
82825 +
82826 + @Param[in] h_FmPcd FM PCD module descriptor.
82827 + @Param[in] counter The requested counter.
82828 +
82829 + @Return Counter's current value.
82830 +
82831 + @Cautions Allowed only following FM_PCD_Init().
82832 + Note that it is user's responsibility to call this routine only
82833 + for enabled counters, and there will be no indication if a
82834 + disabled counter is accessed.
82835 +*//***************************************************************************/
82836 +uint32_t FM_PCD_GetCounter(t_Handle h_FmPcd, e_FmPcdCounters counter);
82837 +
82838 +/**************************************************************************//**
82839 +@Function FM_PCD_PrsLoadSw
82840 +
82841 +@Description This routine may be called in order to load software parsing code.
82842 +
82843 +
82844 +@Param[in] h_FmPcd FM PCD module descriptor.
82845 +@Param[in] p_SwPrs A pointer to a structure of software
82846 + parser parameters, including the software
82847 + parser image.
82848 +
82849 +@Return E_OK on success; Error code otherwise.
82850 +
82851 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82852 + This routine should NOT be called from guest-partition
82853 + (i.e. guestId != NCSW_MASTER_ID)
82854 +*//***************************************************************************/
82855 +t_Error FM_PCD_PrsLoadSw(t_Handle h_FmPcd, t_FmPcdPrsSwParams *p_SwPrs);
82856 +
82857 +/**************************************************************************//**
82858 +@Function FM_PCD_SetAdvancedOffloadSupport
82859 +
82860 +@Description This routine must be called in order to support the following features:
82861 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
82862 +
82863 +@Param[in] h_FmPcd FM PCD module descriptor.
82864 +
82865 +@Return E_OK on success; Error code otherwise.
82866 +
82867 +@Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82868 + This routine should NOT be called from guest-partition
82869 + (i.e. guestId != NCSW_MASTER_ID)
82870 +*//***************************************************************************/
82871 +t_Error FM_PCD_SetAdvancedOffloadSupport(t_Handle h_FmPcd);
82872 +
82873 +/**************************************************************************//**
82874 + @Function FM_PCD_KgSetDfltValue
82875 +
82876 + @Description Calling this routine sets a global default value to be used
82877 + by the KeyGen when parser does not recognize a required
82878 + field/header.
82879 + By default default values are 0.
82880 +
82881 + @Param[in] h_FmPcd FM PCD module descriptor.
82882 + @Param[in] valueId 0,1 - one of 2 global default values.
82883 + @Param[in] value The requested default value.
82884 +
82885 + @Return E_OK on success; Error code otherwise.
82886 +
82887 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82888 + This routine should NOT be called from guest-partition
82889 + (i.e. guestId != NCSW_MASTER_ID)
82890 +*//***************************************************************************/
82891 +t_Error FM_PCD_KgSetDfltValue(t_Handle h_FmPcd, uint8_t valueId, uint32_t value);
82892 +
82893 +/**************************************************************************//**
82894 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
82895 +
82896 + @Description Calling this routine allows the KeyGen to access data past
82897 + the parser finishing point.
82898 +
82899 + @Param[in] h_FmPcd FM PCD module descriptor.
82900 + @Param[in] payloadOffset the number of bytes beyond the parser location.
82901 +
82902 + @Return E_OK on success; Error code otherwise.
82903 +
82904 + @Cautions Allowed only following FM_PCD_Init() and when PCD is disabled.
82905 + This routine should NOT be called from guest-partition
82906 + (i.e. guestId != NCSW_MASTER_ID)
82907 +*//***************************************************************************/
82908 +t_Error FM_PCD_KgSetAdditionalDataAfterParsing(t_Handle h_FmPcd, uint8_t payloadOffset);
82909 +
82910 +/**************************************************************************//**
82911 + @Function FM_PCD_SetException
82912 +
82913 + @Description Calling this routine enables/disables PCD interrupts.
82914 +
82915 + @Param[in] h_FmPcd FM PCD module descriptor.
82916 + @Param[in] exception The exception to be selected.
82917 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
82918 +
82919 + @Return E_OK on success; Error code otherwise.
82920 +
82921 + @Cautions Allowed only following FM_PCD_Init().
82922 + This routine should NOT be called from guest-partition
82923 + (i.e. guestId != NCSW_MASTER_ID)
82924 +*//***************************************************************************/
82925 +t_Error FM_PCD_SetException(t_Handle h_FmPcd, e_FmPcdExceptions exception, bool enable);
82926 +
82927 +/**************************************************************************//**
82928 + @Function FM_PCD_ModifyCounter
82929 +
82930 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
82931 +
82932 + @Param[in] h_FmPcd FM PCD module descriptor.
82933 + @Param[in] counter The requested counter.
82934 + @Param[in] value The requested value to be written into the counter.
82935 +
82936 + @Return E_OK on success; Error code otherwise.
82937 +
82938 + @Cautions Allowed only following FM_PCD_Init().
82939 + This routine should NOT be called from guest-partition
82940 + (i.e. guestId != NCSW_MASTER_ID)
82941 +*//***************************************************************************/
82942 +t_Error FM_PCD_ModifyCounter(t_Handle h_FmPcd, e_FmPcdCounters counter, uint32_t value);
82943 +
82944 +/**************************************************************************//**
82945 + @Function FM_PCD_SetPlcrStatistics
82946 +
82947 + @Description This routine may be used to enable/disable policer statistics
82948 + counter. By default the statistics is enabled.
82949 +
82950 + @Param[in] h_FmPcd FM PCD module descriptor
82951 + @Param[in] enable TRUE to enable, FALSE to disable.
82952 +
82953 + @Return E_OK on success; Error code otherwise.
82954 +
82955 + @Cautions Allowed only following FM_PCD_Init().
82956 + This routine should NOT be called from guest-partition
82957 + (i.e. guestId != NCSW_MASTER_ID)
82958 +*//***************************************************************************/
82959 +t_Error FM_PCD_SetPlcrStatistics(t_Handle h_FmPcd, bool enable);
82960 +
82961 +/**************************************************************************//**
82962 + @Function FM_PCD_SetPrsStatistics
82963 +
82964 + @Description Defines whether to gather parser statistics including all ports.
82965 +
82966 + @Param[in] h_FmPcd FM PCD module descriptor.
82967 + @Param[in] enable TRUE to enable, FALSE to disable.
82968 +
82969 + @Return None
82970 +
82971 + @Cautions Allowed only following FM_PCD_Init().
82972 + This routine should NOT be called from guest-partition
82973 + (i.e. guestId != NCSW_MASTER_ID)
82974 +*//***************************************************************************/
82975 +void FM_PCD_SetPrsStatistics(t_Handle h_FmPcd, bool enable);
82976 +
82977 +/**************************************************************************//**
82978 + @Function FM_PCD_HcTxConf
82979 +
82980 + @Description This routine should be called to confirm frames that were
82981 + received on the HC confirmation queue.
82982 +
82983 + @Param[in] h_FmPcd A handle to an FM PCD Module.
82984 + @Param[in] p_Fd Frame descriptor of the received frame.
82985 +
82986 + @Cautions Allowed only following FM_PCD_Init(). Allowed only if 'useHostCommand'
82987 + option was selected in the initialization.
82988 +*//***************************************************************************/
82989 +void FM_PCD_HcTxConf(t_Handle h_FmPcd, t_DpaaFD *p_Fd);
82990 +
82991 +/**************************************************************************//*
82992 + @Function FM_PCD_ForceIntr
82993 +
82994 + @Description Causes an interrupt event on the requested source.
82995 +
82996 + @Param[in] h_FmPcd FM PCD module descriptor.
82997 + @Param[in] exception An exception to be forced.
82998 +
82999 + @Return E_OK on success; Error code if the exception is not enabled,
83000 + or is not able to create interrupt.
83001 +
83002 + @Cautions Allowed only following FM_PCD_Init().
83003 + This routine should NOT be called from guest-partition
83004 + (i.e. guestId != NCSW_MASTER_ID)
83005 +*//***************************************************************************/
83006 +t_Error FM_PCD_ForceIntr (t_Handle h_FmPcd, e_FmPcdExceptions exception);
83007 +
83008 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
83009 +/**************************************************************************//**
83010 + @Function FM_PCD_DumpRegs
83011 +
83012 + @Description Dumps all PCD registers
83013 +
83014 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83015 +
83016 + @Return E_OK on success; Error code otherwise.
83017 +
83018 + @Cautions Allowed only following FM_PCD_Init().
83019 + NOTE: this routine may be called only for FM in master mode
83020 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
83021 + are mapped.
83022 +*//***************************************************************************/
83023 +t_Error FM_PCD_DumpRegs(t_Handle h_FmPcd);
83024 +
83025 +/**************************************************************************//**
83026 + @Function FM_PCD_KgDumpRegs
83027 +
83028 + @Description Dumps all PCD KG registers
83029 +
83030 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83031 +
83032 + @Return E_OK on success; Error code otherwise.
83033 +
83034 + @Cautions Allowed only following FM_PCD_Init().
83035 + NOTE: this routine may be called only for FM in master mode
83036 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
83037 + are mapped.
83038 +*//***************************************************************************/
83039 +t_Error FM_PCD_KgDumpRegs(t_Handle h_FmPcd);
83040 +
83041 +/**************************************************************************//**
83042 + @Function FM_PCD_PlcrDumpRegs
83043 +
83044 + @Description Dumps all PCD Policer registers
83045 +
83046 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83047 +
83048 + @Return E_OK on success; Error code otherwise.
83049 +
83050 + @Cautions Allowed only following FM_PCD_Init().
83051 + NOTE: this routine may be called only for FM in master mode
83052 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
83053 + are mapped.
83054 +*//***************************************************************************/
83055 +t_Error FM_PCD_PlcrDumpRegs(t_Handle h_FmPcd);
83056 +
83057 +/**************************************************************************//**
83058 + @Function FM_PCD_PlcrProfileDumpRegs
83059 +
83060 + @Description Dumps all PCD Policer profile registers
83061 +
83062 + @Param[in] h_Profile A handle to a Policer profile.
83063 +
83064 + @Return E_OK on success; Error code otherwise.
83065 +
83066 + @Cautions Allowed only following FM_PCD_Init().
83067 + NOTE: this routine may be called only for FM in master mode
83068 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
83069 + are mapped.
83070 +*//***************************************************************************/
83071 +t_Error FM_PCD_PlcrProfileDumpRegs(t_Handle h_Profile);
83072 +
83073 +/**************************************************************************//**
83074 + @Function FM_PCD_PrsDumpRegs
83075 +
83076 + @Description Dumps all PCD Parser registers
83077 +
83078 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83079 +
83080 + @Return E_OK on success; Error code otherwise.
83081 +
83082 + @Cautions Allowed only following FM_PCD_Init().
83083 + NOTE: this routine may be called only for FM in master mode
83084 + (i.e. 'guestId'=NCSW_MASTER_ID) or in a case that the registers
83085 + are mapped.
83086 +*//***************************************************************************/
83087 +t_Error FM_PCD_PrsDumpRegs(t_Handle h_FmPcd);
83088 +
83089 +/**************************************************************************//**
83090 + @Function FM_PCD_HcDumpRegs
83091 +
83092 + @Description Dumps HC Port registers
83093 +
83094 + @Param[in] h_FmPcd A handle to an FM PCD Module.
83095 +
83096 + @Return E_OK on success; Error code otherwise.
83097 +
83098 + @Cautions Allowed only following FM_PCD_Init().
83099 + NOTE: this routine may be called only for FM in master mode
83100 + (i.e. 'guestId'=NCSW_MASTER_ID).
83101 +*//***************************************************************************/
83102 +t_Error FM_PCD_HcDumpRegs(t_Handle h_FmPcd);
83103 +#endif /* (defined(DEBUG_ERRORS) && ... */
83104 +
83105 +
83106 +
83107 +/**************************************************************************//**
83108 + KeyGen FM_PCD_Runtime_build_grp FM PCD Runtime Building Unit
83109 +
83110 + @Description Frame Manager PCD Runtime Building API
83111 +
83112 + This group contains routines for setting, deleting and modifying
83113 + PCD resources, for defining the total PCD tree.
83114 + @{
83115 +*//***************************************************************************/
83116 +
83117 +/**************************************************************************//**
83118 + @Collection Definitions of coarse classification
83119 + parameters as required by KeyGen (when coarse classification
83120 + is the next engine after this scheme).
83121 +*//***************************************************************************/
83122 +#define FM_PCD_MAX_NUM_OF_CC_TREES 8
83123 +#define FM_PCD_MAX_NUM_OF_CC_GROUPS 16
83124 +#define FM_PCD_MAX_NUM_OF_CC_UNITS 4
83125 +#define FM_PCD_MAX_NUM_OF_KEYS 256
83126 +#define FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
83127 +#define FM_PCD_MAX_SIZE_OF_KEY 56
83128 +#define FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
83129 +#define FM_PCD_LAST_KEY_INDEX 0xffff
83130 +
83131 +#define FM_PCD_MAX_NUM_OF_CC_NODES 255 /* Obsolete, not used - will be removed in the future */
83132 +/* @} */
83133 +
83134 +/**************************************************************************//**
83135 + @Collection A set of definitions to allow protocol
83136 + special option description.
83137 +*//***************************************************************************/
83138 +typedef uint32_t protocolOpt_t; /**< A general type to define a protocol option. */
83139 +
83140 +typedef protocolOpt_t ethProtocolOpt_t; /**< Ethernet protocol options. */
83141 +#define ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
83142 +#define ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
83143 +
83144 +typedef protocolOpt_t vlanProtocolOpt_t; /**< VLAN protocol options. */
83145 +#define VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
83146 +
83147 +typedef protocolOpt_t mplsProtocolOpt_t; /**< MPLS protocol options. */
83148 +#define MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
83149 +
83150 +typedef protocolOpt_t ipv4ProtocolOpt_t; /**< IPv4 protocol options. */
83151 +#define IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
83152 +#define IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
83153 +#define IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
83154 +#define IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
83155 +
83156 +#define IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
83157 + IPV4 Reassembly manipulation requires network
83158 + environment with IPV4 header and IPV4_FRAG_1 option */
83159 +
83160 +typedef protocolOpt_t ipv6ProtocolOpt_t; /**< IPv6 protocol options. */
83161 +#define IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
83162 +#define IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
83163 +#define IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
83164 +
83165 +#define IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
83166 + IPV6 Reassembly manipulation requires network
83167 + environment with IPV6 header and IPV6_FRAG_1 option;
83168 + in case where fragment found, the fragment-extension offset
83169 + may be found at 'shim2' (in parser-result). */
83170 +#if (DPAA_VERSION >= 11)
83171 +typedef protocolOpt_t capwapProtocolOpt_t; /**< CAPWAP protocol options. */
83172 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
83173 + CAPWAP Reassembly manipulation requires network
83174 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
83175 + in case where fragment found, the fragment-extension offset
83176 + may be found at 'shim2' (in parser-result). */
83177 +#endif /* (DPAA_VERSION >= 11) */
83178 +
83179 +
83180 +/* @} */
83181 +
83182 +#define FM_PCD_MANIP_MAX_HDR_SIZE 256
83183 +#define FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
83184 +
83185 +/**************************************************************************//**
83186 + @Collection A set of definitions to support Header Manipulation selection.
83187 +*//***************************************************************************/
83188 +typedef uint32_t hdrManipFlags_t; /**< A general type to define a HMan update command flags. */
83189 +
83190 +typedef hdrManipFlags_t ipv4HdrManipUpdateFlags_t; /**< IPv4 protocol HMan update command flags. */
83191 +
83192 +#define HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
83193 + of t_FmPcdManipHdrFieldUpdateIpv4) */
83194 +#define HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
83195 + of t_FmPcdManipHdrFieldUpdateIpv4) */
83196 +#define HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
83197 +#define HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
83198 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv4) */
83199 +#define HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
83200 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv4) */
83201 +
83202 +typedef hdrManipFlags_t ipv6HdrManipUpdateFlags_t; /**< IPv6 protocol HMan update command flags. */
83203 +
83204 +#define HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
83205 + ('trafficClass' field of t_FmPcdManipHdrFieldUpdateIpv6) */
83206 +#define HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
83207 +#define HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
83208 + ('src' field of t_FmPcdManipHdrFieldUpdateIpv6) */
83209 +#define HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
83210 + ('dst' field of t_FmPcdManipHdrFieldUpdateIpv6) */
83211 +
83212 +typedef hdrManipFlags_t tcpUdpHdrManipUpdateFlags_t;/**< TCP/UDP protocol HMan update command flags. */
83213 +
83214 +#define HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
83215 + ('src' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
83216 +#define HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
83217 + ('dst' field of t_FmPcdManipHdrFieldUpdateTcpUdp) */
83218 +#define HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
83219 +
83220 +/* @} */
83221 +
83222 +/**************************************************************************//**
83223 + @Description A type used for returning the order of the key extraction.
83224 + each value in this array represents the index of the extraction
83225 + command as defined by the user in the initialization extraction array.
83226 + The valid size of this array is the user define number of extractions
83227 + required (also marked by the second '0' in this array).
83228 +*//***************************************************************************/
83229 +typedef uint8_t t_FmPcdKgKeyOrder [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
83230 +
83231 +/**************************************************************************//**
83232 + @Description All PCD engines
83233 +*//***************************************************************************/
83234 +typedef enum e_FmPcdEngine {
83235 + e_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
83236 + e_FM_PCD_DONE, /**< No PCD Engine indicated */
83237 + e_FM_PCD_KG, /**< KeyGen */
83238 + e_FM_PCD_CC, /**< Coarse classifier */
83239 + e_FM_PCD_PLCR, /**< Policer */
83240 + e_FM_PCD_PRS, /**< Parser */
83241 +#if (DPAA_VERSION >= 11)
83242 + e_FM_PCD_FR, /**< Frame-Replicator */
83243 +#endif /* (DPAA_VERSION >= 11) */
83244 + e_FM_PCD_HASH /**< Hash table */
83245 +} e_FmPcdEngine;
83246 +
83247 +/**************************************************************************//**
83248 + @Description Enumeration type for selecting extraction by header types
83249 +*//***************************************************************************/
83250 +typedef enum e_FmPcdExtractByHdrType {
83251 + e_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
83252 + e_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
83253 + e_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
83254 +} e_FmPcdExtractByHdrType;
83255 +
83256 +/**************************************************************************//**
83257 + @Description Enumeration type for selecting extraction source
83258 + (when it is not the header)
83259 +*//***************************************************************************/
83260 +typedef enum e_FmPcdExtractFrom {
83261 + e_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
83262 + e_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
83263 + e_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG & CC: Extract from the point where parsing had finished */
83264 + e_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
83265 + e_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
83266 + e_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG only: Extract from the parser result */
83267 + e_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
83268 + e_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
83269 +} e_FmPcdExtractFrom;
83270 +
83271 +/**************************************************************************//**
83272 + @Description Enumeration type for selecting extraction type
83273 +*//***************************************************************************/
83274 +typedef enum e_FmPcdExtractType {
83275 + e_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
83276 + e_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
83277 + e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
83278 +} e_FmPcdExtractType;
83279 +
83280 +/**************************************************************************//**
83281 + @Description Enumeration type for selecting default extraction value
83282 +*//***************************************************************************/
83283 +typedef enum e_FmPcdKgExtractDfltSelect {
83284 + e_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
83285 + e_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
83286 + e_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
83287 + e_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
83288 + e_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
83289 +} e_FmPcdKgExtractDfltSelect;
83290 +
83291 +/**************************************************************************//**
83292 + @Description Enumeration type defining all default groups - each group shares
83293 + a default value, one of four user-initialized values.
83294 +*//***************************************************************************/
83295 +typedef enum e_FmPcdKgKnownFieldsDfltTypes {
83296 + e_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
83297 + e_FM_PCD_KG_TCI, /**< TCI field */
83298 + e_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
83299 + e_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
83300 + e_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
83301 + e_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
83302 + e_FM_PCD_KG_IP_ADDR, /**< IP address */
83303 + e_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
83304 + e_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
83305 + e_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
83306 + e_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
83307 + e_FM_PCD_KG_L4_PORT, /**< L4 Port */
83308 + e_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
83309 + e_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
83310 + any data extraction that is not the full
83311 + field described above */
83312 + e_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
83313 + any data extraction without validation */
83314 + e_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
83315 + extraction from parser result or
83316 + direct use of default value */
83317 +} e_FmPcdKgKnownFieldsDfltTypes;
83318 +
83319 +/**************************************************************************//**
83320 + @Description Enumeration type for defining header index for scenarios with
83321 + multiple (tunneled) headers
83322 +*//***************************************************************************/
83323 +typedef enum e_FmPcdHdrIndex {
83324 + e_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
83325 + to specify regular IP (not tunneled). */
83326 + e_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
83327 + e_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
83328 + e_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
83329 + e_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
83330 +} e_FmPcdHdrIndex;
83331 +
83332 +/**************************************************************************//**
83333 + @Description Enumeration type for selecting the policer profile functional type
83334 +*//***************************************************************************/
83335 +typedef enum e_FmPcdProfileTypeSelection {
83336 + e_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
83337 + e_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
83338 +} e_FmPcdProfileTypeSelection;
83339 +
83340 +/**************************************************************************//**
83341 + @Description Enumeration type for selecting the policer profile algorithm
83342 +*//***************************************************************************/
83343 +typedef enum e_FmPcdPlcrAlgorithmSelection {
83344 + e_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
83345 + e_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
83346 + e_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
83347 +} e_FmPcdPlcrAlgorithmSelection;
83348 +
83349 +/**************************************************************************//**
83350 + @Description Enumeration type for selecting a policer profile color mode
83351 +*//***************************************************************************/
83352 +typedef enum e_FmPcdPlcrColorMode {
83353 + e_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
83354 + e_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
83355 +} e_FmPcdPlcrColorMode;
83356 +
83357 +/**************************************************************************//**
83358 + @Description Enumeration type for selecting a policer profile color
83359 +*//***************************************************************************/
83360 +typedef enum e_FmPcdPlcrColor {
83361 + e_FM_PCD_PLCR_GREEN, /**< Green color code */
83362 + e_FM_PCD_PLCR_YELLOW, /**< Yellow color code */
83363 + e_FM_PCD_PLCR_RED, /**< Red color code */
83364 + e_FM_PCD_PLCR_OVERRIDE /**< Color override code */
83365 +} e_FmPcdPlcrColor;
83366 +
83367 +/**************************************************************************//**
83368 + @Description Enumeration type for selecting the policer profile packet frame length selector
83369 +*//***************************************************************************/
83370 +typedef enum e_FmPcdPlcrFrameLengthSelect {
83371 + e_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
83372 + e_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
83373 + e_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
83374 + e_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
83375 +} e_FmPcdPlcrFrameLengthSelect;
83376 +
83377 +/**************************************************************************//**
83378 + @Description Enumeration type for selecting roll-back frame
83379 +*//***************************************************************************/
83380 +typedef enum e_FmPcdPlcrRollBackFrameSelect {
83381 + e_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Roll-back L2 frame length */
83382 + e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Roll-back Full frame length */
83383 +} e_FmPcdPlcrRollBackFrameSelect;
83384 +
83385 +/**************************************************************************//**
83386 + @Description Enumeration type for selecting the policer profile packet or byte mode
83387 +*//***************************************************************************/
83388 +typedef enum e_FmPcdPlcrRateMode {
83389 + e_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
83390 + e_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
83391 +} e_FmPcdPlcrRateMode;
83392 +
83393 +/**************************************************************************//**
83394 + @Description Enumeration type for defining action of frame
83395 +*//***************************************************************************/
83396 +typedef enum e_FmPcdDoneAction {
83397 + e_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
83398 + e_FM_PCD_DROP_FRAME /**< Mark this frame as error frame and continue
83399 + to error flow; 'FM_PORT_FRM_ERR_CLS_DISCARD'
83400 + flag will be set for this frame. */
83401 +} e_FmPcdDoneAction;
83402 +
83403 +/**************************************************************************//**
83404 + @Description Enumeration type for selecting the policer counter
83405 +*//***************************************************************************/
83406 +typedef enum e_FmPcdPlcrProfileCounters {
83407 + e_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
83408 + e_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
83409 + e_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
83410 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
83411 + e_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
83412 +} e_FmPcdPlcrProfileCounters;
83413 +
83414 +/**************************************************************************//**
83415 + @Description Enumeration type for selecting the PCD action after extraction
83416 +*//***************************************************************************/
83417 +typedef enum e_FmPcdAction {
83418 + e_FM_PCD_ACTION_NONE, /**< NONE */
83419 + e_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction */
83420 + e_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction */
83421 +} e_FmPcdAction;
83422 +
83423 +/**************************************************************************//**
83424 + @Description Enumeration type for selecting type of insert manipulation
83425 +*//***************************************************************************/
83426 +typedef enum e_FmPcdManipHdrInsrtType {
83427 + e_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
83428 + e_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
83429 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83430 + e_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
83431 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83432 +} e_FmPcdManipHdrInsrtType;
83433 +
83434 +/**************************************************************************//**
83435 + @Description Enumeration type for selecting type of remove manipulation
83436 +*//***************************************************************************/
83437 +typedef enum e_FmPcdManipHdrRmvType {
83438 + e_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
83439 + e_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
83440 +} e_FmPcdManipHdrRmvType;
83441 +
83442 +/**************************************************************************//**
83443 + @Description Enumeration type for selecting specific L2 fields removal
83444 +*//***************************************************************************/
83445 +typedef enum e_FmPcdManipHdrRmvSpecificL2 {
83446 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
83447 + e_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
83448 + e_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
83449 + the header which follows the MPLS header */
83450 + e_FM_PCD_MANIP_HDR_RMV_MPLS, /**< Remove MPLS header (Unlimited MPLS labels) */
83451 + e_FM_PCD_MANIP_HDR_RMV_PPPOE /**< Remove the PPPoE header and PPP protocol field. */
83452 +} e_FmPcdManipHdrRmvSpecificL2;
83453 +
83454 +/**************************************************************************//**
83455 + @Description Enumeration type for selecting specific fields updates
83456 +*//***************************************************************************/
83457 +typedef enum e_FmPcdManipHdrFieldUpdateType {
83458 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
83459 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
83460 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
83461 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
83462 +} e_FmPcdManipHdrFieldUpdateType;
83463 +
83464 +/**************************************************************************//**
83465 + @Description Enumeration type for selecting VLAN updates
83466 +*//***************************************************************************/
83467 +typedef enum e_FmPcdManipHdrFieldUpdateVlan {
83468 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
83469 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
83470 +} e_FmPcdManipHdrFieldUpdateVlan;
83471 +
83472 +/**************************************************************************//**
83473 + @Description Enumeration type for selecting specific L2 header insertion
83474 +*//***************************************************************************/
83475 +typedef enum e_FmPcdManipHdrInsrtSpecificL2 {
83476 + e_FM_PCD_MANIP_HDR_INSRT_MPLS, /**< Insert MPLS header (Unlimited MPLS labels) */
83477 + e_FM_PCD_MANIP_HDR_INSRT_PPPOE /**< Insert PPPOE */
83478 +} e_FmPcdManipHdrInsrtSpecificL2;
83479 +
83480 +#if (DPAA_VERSION >= 11)
83481 +/**************************************************************************//**
83482 + @Description Enumeration type for selecting QoS mapping mode
83483 +
83484 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
83485 + User should instruct the port to read the hash-result
83486 +*//***************************************************************************/
83487 +typedef enum e_FmPcdManipHdrQosMappingMode {
83488 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
83489 + e_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the hash-result. */
83490 +} e_FmPcdManipHdrQosMappingMode;
83491 +
83492 +/**************************************************************************//**
83493 + @Description Enumeration type for selecting QoS source
83494 +
83495 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
83496 + User should left room for the hash-result on input/output buffer
83497 + and instruct the port to read/write the hash-result to the buffer (RPD should be set)
83498 +*//***************************************************************************/
83499 +typedef enum e_FmPcdManipHdrQosSrc {
83500 + e_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
83501 + e_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the hash-result. */
83502 +} e_FmPcdManipHdrQosSrc;
83503 +#endif /* (DPAA_VERSION >= 11) */
83504 +
83505 +/**************************************************************************//**
83506 + @Description Enumeration type for selecting type of header insertion
83507 +*//***************************************************************************/
83508 +typedef enum e_FmPcdManipHdrInsrtByHdrType {
83509 + e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
83510 +#if (DPAA_VERSION >= 11)
83511 + e_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
83512 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
83513 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
83514 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
83515 +#endif /* (DPAA_VERSION >= 11) */
83516 +} e_FmPcdManipHdrInsrtByHdrType;
83517 +
83518 +/**************************************************************************//**
83519 + @Description Enumeration type for selecting specific customCommand
83520 +*//***************************************************************************/
83521 +typedef enum e_FmPcdManipHdrCustomType {
83522 + e_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
83523 + e_FM_PCD_MANIP_HDR_CUSTOM_GEN_FIELD_REPLACE, /**< Replace IPv4/IPv6 */
83524 +} e_FmPcdManipHdrCustomType;
83525 +
83526 +/**************************************************************************//**
83527 + @Description Enumeration type for selecting specific customCommand
83528 +*//***************************************************************************/
83529 +typedef enum e_FmPcdManipHdrCustomIpReplace {
83530 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
83531 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
83532 +} e_FmPcdManipHdrCustomIpReplace;
83533 +
83534 +/**************************************************************************//**
83535 + @Description Enumeration type for selecting type of header removal
83536 +*//***************************************************************************/
83537 +typedef enum e_FmPcdManipHdrRmvByHdrType {
83538 + e_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
83539 +#if (DPAA_VERSION >= 11)
83540 + e_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
83541 +#endif /* (DPAA_VERSION >= 11) */
83542 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83543 + e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
83544 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83545 +} e_FmPcdManipHdrRmvByHdrType;
83546 +
83547 +/**************************************************************************//**
83548 + @Description Enumeration type for selecting type of timeout mode
83549 +*//***************************************************************************/
83550 +typedef enum e_FmPcdManipReassemTimeOutMode {
83551 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
83552 + from the first fragment to the last */
83553 + e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
83554 +} e_FmPcdManipReassemTimeOutMode;
83555 +
83556 +/**************************************************************************//**
83557 + @Description Enumeration type for selecting type of WaysNumber mode
83558 +*//***************************************************************************/
83559 +typedef enum e_FmPcdManipReassemWaysNumber {
83560 + e_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
83561 + e_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
83562 + e_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
83563 + e_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
83564 + e_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
83565 + e_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
83566 + e_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
83567 + e_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
83568 +} e_FmPcdManipReassemWaysNumber;
83569 +
83570 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
83571 +/**************************************************************************//**
83572 + @Description Enumeration type for selecting type of statistics mode
83573 +*//***************************************************************************/
83574 +typedef enum e_FmPcdStatsType {
83575 + e_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
83576 +} e_FmPcdStatsType;
83577 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
83578 +
83579 +/**************************************************************************//**
83580 + @Description Enumeration type for selecting manipulation type
83581 +*//***************************************************************************/
83582 +typedef enum e_FmPcdManipType {
83583 + e_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
83584 + e_FM_PCD_MANIP_REASSEM, /**< Reassembly */
83585 + e_FM_PCD_MANIP_FRAG, /**< Fragmentation */
83586 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
83587 +} e_FmPcdManipType;
83588 +
83589 +/**************************************************************************//**
83590 + @Description Enumeration type for selecting type of statistics mode
83591 +*//***************************************************************************/
83592 +typedef enum e_FmPcdCcStatsMode {
83593 + e_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
83594 + e_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
83595 + e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
83596 +#if (DPAA_VERSION >= 11)
83597 + e_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics;
83598 + This mode is supported only on B4860 device */
83599 +#endif /* (DPAA_VERSION >= 11) */
83600 +} e_FmPcdCcStatsMode;
83601 +
83602 +/**************************************************************************//**
83603 + @Description Enumeration type for determining the action in case an IP packet
83604 + is larger than MTU but its DF (Don't Fragment) bit is set.
83605 +*//***************************************************************************/
83606 +typedef enum e_FmPcdManipDontFragAction {
83607 + e_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
83608 + e_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_FM_PCD_MANIP_DISCARD_PACKET,
83609 + /**< Obsolete, cannot enqueue to error queue;
83610 + In practice, selects to discard packets;
83611 + Will be removed in the future */
83612 + e_FM_PCD_MANIP_FRAGMENT_PACKET, /**< Fragment packet and continue normal processing */
83613 + e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
83614 +} e_FmPcdManipDontFragAction;
83615 +
83616 +/**************************************************************************//**
83617 + @Description Enumeration type for selecting type of special offload manipulation
83618 +*//***************************************************************************/
83619 +typedef enum e_FmPcdManipSpecialOffloadType {
83620 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
83621 +#if (DPAA_VERSION >= 11)
83622 + e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
83623 +#endif /* (DPAA_VERSION >= 11) */
83624 +} e_FmPcdManipSpecialOffloadType;
83625 +
83626 +
83627 +/**************************************************************************//**
83628 + @Description A Union of protocol dependent special options
83629 +*//***************************************************************************/
83630 +typedef union u_FmPcdHdrProtocolOpt {
83631 + ethProtocolOpt_t ethOpt; /**< Ethernet options */
83632 + vlanProtocolOpt_t vlanOpt; /**< VLAN options */
83633 + mplsProtocolOpt_t mplsOpt; /**< MPLS options */
83634 + ipv4ProtocolOpt_t ipv4Opt; /**< IPv4 options */
83635 + ipv6ProtocolOpt_t ipv6Opt; /**< IPv6 options */
83636 +#if (DPAA_VERSION >= 11)
83637 + capwapProtocolOpt_t capwapOpt; /**< CAPWAP options */
83638 +#endif /* (DPAA_VERSION >= 11) */
83639 +} u_FmPcdHdrProtocolOpt;
83640 +
83641 +/**************************************************************************//**
83642 + @Description A union holding protocol fields
83643 +
83644 +
83645 + Fields supported as "full fields":
83646 + HEADER_TYPE_ETH:
83647 + NET_HEADER_FIELD_ETH_DA
83648 + NET_HEADER_FIELD_ETH_SA
83649 + NET_HEADER_FIELD_ETH_TYPE
83650 +
83651 + HEADER_TYPE_LLC_SNAP:
83652 + NET_HEADER_FIELD_LLC_SNAP_TYPE
83653 +
83654 + HEADER_TYPE_VLAN:
83655 + NET_HEADER_FIELD_VLAN_TCI
83656 + (index may apply:
83657 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83658 + e_FM_PCD_HDR_INDEX_LAST)
83659 +
83660 + HEADER_TYPE_MPLS:
83661 + NET_HEADER_FIELD_MPLS_LABEL_STACK
83662 + (index may apply:
83663 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83664 + e_FM_PCD_HDR_INDEX_2,
83665 + e_FM_PCD_HDR_INDEX_LAST)
83666 +
83667 + HEADER_TYPE_IPv4:
83668 + NET_HEADER_FIELD_IPv4_SRC_IP
83669 + NET_HEADER_FIELD_IPv4_DST_IP
83670 + NET_HEADER_FIELD_IPv4_PROTO
83671 + NET_HEADER_FIELD_IPv4_TOS
83672 + (index may apply:
83673 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83674 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
83675 +
83676 + HEADER_TYPE_IPv6:
83677 + NET_HEADER_FIELD_IPv6_SRC_IP
83678 + NET_HEADER_FIELD_IPv6_DST_IP
83679 + NET_HEADER_FIELD_IPv6_NEXT_HDR
83680 + NET_HEADER_FIELD_IPv6_VER | NET_HEADER_FIELD_IPv6_FL | NET_HEADER_FIELD_IPv6_TC (must come together!)
83681 + (index may apply:
83682 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83683 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
83684 +
83685 + (Note that starting from DPAA 1-1, NET_HEADER_FIELD_IPv6_NEXT_HDR applies to
83686 + the last next header indication, meaning the next L4, which may be
83687 + present at the Ipv6 last extension. On earlier revisions this field
83688 + applies to the Next-Header field of the main IPv6 header)
83689 +
83690 + HEADER_TYPE_IP:
83691 + NET_HEADER_FIELD_IP_PROTO
83692 + (index may apply:
83693 + e_FM_PCD_HDR_INDEX_LAST)
83694 + NET_HEADER_FIELD_IP_DSCP
83695 + (index may apply:
83696 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1)
83697 + HEADER_TYPE_GRE:
83698 + NET_HEADER_FIELD_GRE_TYPE
83699 +
83700 + HEADER_TYPE_MINENCAP
83701 + NET_HEADER_FIELD_MINENCAP_SRC_IP
83702 + NET_HEADER_FIELD_MINENCAP_DST_IP
83703 + NET_HEADER_FIELD_MINENCAP_TYPE
83704 +
83705 + HEADER_TYPE_TCP:
83706 + NET_HEADER_FIELD_TCP_PORT_SRC
83707 + NET_HEADER_FIELD_TCP_PORT_DST
83708 + NET_HEADER_FIELD_TCP_FLAGS
83709 +
83710 + HEADER_TYPE_UDP:
83711 + NET_HEADER_FIELD_UDP_PORT_SRC
83712 + NET_HEADER_FIELD_UDP_PORT_DST
83713 +
83714 + HEADER_TYPE_UDP_LITE:
83715 + NET_HEADER_FIELD_UDP_LITE_PORT_SRC
83716 + NET_HEADER_FIELD_UDP_LITE_PORT_DST
83717 +
83718 + HEADER_TYPE_IPSEC_AH:
83719 + NET_HEADER_FIELD_IPSEC_AH_SPI
83720 + NET_HEADER_FIELD_IPSEC_AH_NH
83721 +
83722 + HEADER_TYPE_IPSEC_ESP:
83723 + NET_HEADER_FIELD_IPSEC_ESP_SPI
83724 +
83725 + HEADER_TYPE_SCTP:
83726 + NET_HEADER_FIELD_SCTP_PORT_SRC
83727 + NET_HEADER_FIELD_SCTP_PORT_DST
83728 +
83729 + HEADER_TYPE_DCCP:
83730 + NET_HEADER_FIELD_DCCP_PORT_SRC
83731 + NET_HEADER_FIELD_DCCP_PORT_DST
83732 +
83733 + HEADER_TYPE_PPPoE:
83734 + NET_HEADER_FIELD_PPPoE_PID
83735 + NET_HEADER_FIELD_PPPoE_SID
83736 +
83737 + *****************************************************************
83738 + Fields supported as "from fields":
83739 + HEADER_TYPE_ETH (with or without validation):
83740 + NET_HEADER_FIELD_ETH_TYPE
83741 +
83742 + HEADER_TYPE_VLAN (with or without validation):
83743 + NET_HEADER_FIELD_VLAN_TCI
83744 + (index may apply:
83745 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83746 + e_FM_PCD_HDR_INDEX_LAST)
83747 +
83748 + HEADER_TYPE_IPv4 (without validation):
83749 + NET_HEADER_FIELD_IPv4_PROTO
83750 + (index may apply:
83751 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83752 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
83753 +
83754 + HEADER_TYPE_IPv6 (without validation):
83755 + NET_HEADER_FIELD_IPv6_NEXT_HDR
83756 + (index may apply:
83757 + e_FM_PCD_HDR_INDEX_NONE/e_FM_PCD_HDR_INDEX_1,
83758 + e_FM_PCD_HDR_INDEX_2/e_FM_PCD_HDR_INDEX_LAST)
83759 +
83760 +*//***************************************************************************/
83761 +typedef union t_FmPcdFields {
83762 + headerFieldEth_t eth; /**< Ethernet */
83763 + headerFieldVlan_t vlan; /**< VLAN */
83764 + headerFieldLlcSnap_t llcSnap; /**< LLC SNAP */
83765 + headerFieldPppoe_t pppoe; /**< PPPoE */
83766 + headerFieldMpls_t mpls; /**< MPLS */
83767 + headerFieldIp_t ip; /**< IP */
83768 + headerFieldIpv4_t ipv4; /**< IPv4 */
83769 + headerFieldIpv6_t ipv6; /**< IPv6 */
83770 + headerFieldUdp_t udp; /**< UDP */
83771 + headerFieldUdpLite_t udpLite; /**< UDP Lite */
83772 + headerFieldTcp_t tcp; /**< TCP */
83773 + headerFieldSctp_t sctp; /**< SCTP */
83774 + headerFieldDccp_t dccp; /**< DCCP */
83775 + headerFieldGre_t gre; /**< GRE */
83776 + headerFieldMinencap_t minencap; /**< Minimal Encapsulation */
83777 + headerFieldIpsecAh_t ipsecAh; /**< IPSec AH */
83778 + headerFieldIpsecEsp_t ipsecEsp; /**< IPSec ESP */
83779 + headerFieldUdpEncapEsp_t udpEncapEsp; /**< UDP Encapsulation ESP */
83780 +} t_FmPcdFields;
83781 +
83782 +/**************************************************************************//**
83783 + @Description Parameters for defining header extraction for key generation
83784 +*//***************************************************************************/
83785 +typedef struct t_FmPcdFromHdr {
83786 + uint8_t size; /**< Size in byte */
83787 + uint8_t offset; /**< Byte offset */
83788 +} t_FmPcdFromHdr;
83789 +
83790 +/**************************************************************************//**
83791 + @Description Parameters for defining field extraction for key generation
83792 +*//***************************************************************************/
83793 +typedef struct t_FmPcdFromField {
83794 + t_FmPcdFields field; /**< Field selection */
83795 + uint8_t size; /**< Size in byte */
83796 + uint8_t offset; /**< Byte offset */
83797 +} t_FmPcdFromField;
83798 +
83799 +/**************************************************************************//**
83800 + @Description Parameters for defining a single network environment unit
83801 +
83802 + A distinction unit should be defined if it will later be used
83803 + by one or more PCD engines to distinguish between flows.
83804 +*//***************************************************************************/
83805 +typedef struct t_FmPcdDistinctionUnit {
83806 + struct {
83807 + e_NetHeaderType hdr; /**< One of the headers supported by the FM */
83808 + u_FmPcdHdrProtocolOpt opt; /**< Select only one option ! */
83809 + } hdrs[FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
83810 +} t_FmPcdDistinctionUnit;
83811 +
83812 +/**************************************************************************//**
83813 + @Description Parameters for defining all different distinction units supported
83814 + by a specific PCD Network Environment Characteristics module.
83815 +
83816 + Each unit represent a protocol or a group of protocols that may
83817 + be used later by the different PCD engines to distinguish
83818 + between flows.
83819 +*//***************************************************************************/
83820 +typedef struct t_FmPcdNetEnvParams {
83821 + uint8_t numOfDistinctionUnits; /**< Number of different units to be identified */
83822 + t_FmPcdDistinctionUnit units[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /**< An array of numOfDistinctionUnits of the
83823 + different units to be identified */
83824 +} t_FmPcdNetEnvParams;
83825 +
83826 +/**************************************************************************//**
83827 + @Description Parameters for defining a single extraction action when
83828 + creating a key
83829 +*//***************************************************************************/
83830 +typedef struct t_FmPcdExtractEntry {
83831 + e_FmPcdExtractType type; /**< Extraction type select */
83832 + union {
83833 + struct {
83834 + e_NetHeaderType hdr; /**< Header selection */
83835 + bool ignoreProtocolValidation;
83836 + /**< Ignore protocol validation */
83837 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
83838 + IP. Otherwise should be cleared. */
83839 + e_FmPcdExtractByHdrType type; /**< Header extraction type select */
83840 + union {
83841 + t_FmPcdFromHdr fromHdr; /**< Extract bytes from header parameters */
83842 + t_FmPcdFromField fromField; /**< Extract bytes from field parameters */
83843 + t_FmPcdFields fullField; /**< Extract full filed parameters */
83844 + } extractByHdrType;
83845 + } extractByHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
83846 + struct {
83847 + e_FmPcdExtractFrom src; /**< Non-header extraction source */
83848 + e_FmPcdAction action; /**< Relevant for CC Only */
83849 + uint16_t icIndxMask; /**< Relevant only for CC when
83850 + action = e_FM_PCD_ACTION_INDEXED_LOOKUP;
83851 + Note that the number of bits that are set within
83852 + this mask must be log2 of the CC-node 'numOfKeys'.
83853 + Note that the mask cannot be set on the lower bits. */
83854 + uint8_t offset; /**< Byte offset */
83855 + uint8_t size; /**< Size in byte */
83856 + } extractNonHdr; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
83857 + };
83858 +} t_FmPcdExtractEntry;
83859 +
83860 +/**************************************************************************//**
83861 + @Description Parameters for defining masks for each extracted field in the key.
83862 +*//***************************************************************************/
83863 +typedef struct t_FmPcdKgExtractMask {
83864 + uint8_t extractArrayIndex; /**< Index in the extraction array, as initialized by user */
83865 + uint8_t offset; /**< Byte offset */
83866 + uint8_t mask; /**< A byte mask (selected bits will be used) */
83867 +} t_FmPcdKgExtractMask;
83868 +
83869 +/**************************************************************************//**
83870 + @Description Parameters for defining default selection per groups of fields
83871 +*//***************************************************************************/
83872 +typedef struct t_FmPcdKgExtractDflt {
83873 + e_FmPcdKgKnownFieldsDfltTypes type; /**< Default type select */
83874 + e_FmPcdKgExtractDfltSelect dfltSelect; /**< Default register select */
83875 +} t_FmPcdKgExtractDflt;
83876 +
83877 +/**************************************************************************//**
83878 + @Description Parameters for defining key extraction and hashing
83879 +*//***************************************************************************/
83880 +typedef struct t_FmPcdKgKeyExtractAndHashParams {
83881 + uint32_t privateDflt0; /**< Scheme default register 0 */
83882 + uint32_t privateDflt1; /**< Scheme default register 1 */
83883 + uint8_t numOfUsedExtracts; /**< defines the valid size of the following array */
83884 + t_FmPcdExtractEntry extractArray [FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY]; /**< An array of extractions definition. */
83885 + uint8_t numOfUsedDflts; /**< defines the valid size of the following array */
83886 + t_FmPcdKgExtractDflt dflts[FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
83887 + /**< For each extraction used in this scheme, specify the required
83888 + default register to be used when header is not found.
83889 + types not specified in this array will get undefined value. */
83890 + uint8_t numOfUsedMasks; /**< defines the valid size of the following array */
83891 + t_FmPcdKgExtractMask masks[FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
83892 + uint8_t hashShift; /**< hash result right shift. Select the 24 bits out of the 64 hash
83893 + result. 0 means using the 24 LSB's, otherwise use the
83894 + 24 LSB's after shifting right.*/
83895 + uint32_t hashDistributionNumOfFqids; /**< must be > 1 and a power of 2. Represents the range
83896 + of queues for the key and hash functionality */
83897 + uint8_t hashDistributionFqidsShift; /**< selects the FQID bits that will be effected by the hash */
83898 + bool symmetricHash; /**< TRUE to generate the same hash for frames with swapped source and
83899 + destination fields on all layers; If TRUE, driver will check that for
83900 + all layers, if SRC extraction is selected, DST extraction must also be
83901 + selected, and vice versa. */
83902 +} t_FmPcdKgKeyExtractAndHashParams;
83903 +
83904 +/**************************************************************************//**
83905 + @Description Parameters for defining a single FQID mask (extracted OR).
83906 +*//***************************************************************************/
83907 +typedef struct t_FmPcdKgExtractedOrParams {
83908 + e_FmPcdExtractType type; /**< Extraction type select */
83909 + union {
83910 + struct { /**< used when type = e_FM_PCD_KG_EXTRACT_BY_HDR */
83911 + e_NetHeaderType hdr;
83912 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled
83913 + IP. Otherwise should be cleared.*/
83914 + bool ignoreProtocolValidation;
83915 + /**< continue extraction even if protocol is not recognized */
83916 + } extractByHdr; /**< Header to extract by */
83917 + e_FmPcdExtractFrom src; /**< used when type = e_FM_PCD_KG_EXTRACT_NON_HDR */
83918 + };
83919 + uint8_t extractionOffset; /**< Offset for extraction (in bytes). */
83920 + e_FmPcdKgExtractDfltSelect dfltValue; /**< Select register from which extraction is taken if
83921 + field not found */
83922 + uint8_t mask; /**< Extraction mask (specified bits are used) */
83923 + uint8_t bitOffsetInFqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
83924 + the extracted byte; Assume byte is placed as the 8 MSB's in
83925 + a 32 bit word where the lower bits
83926 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
83927 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
83928 + extracted byte will effect the 8 LSB's of the FQID,
83929 + if bitOffsetInFqid=31 than the byte's MSB will effect
83930 + the FQID's LSB; 0 means - no effect on FQID;
83931 + Note that one, and only one of
83932 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
83933 + extracted byte must effect either FQID or Policer profile).*/
83934 + uint8_t bitOffsetInPlcrProfile;
83935 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
83936 + effect using the extracted byte; Assume byte is placed
83937 + as the 8 MSB's in a 16 bit word where the lower bits
83938 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
83939 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
83940 + than the extracted byte will effect the whole policer profile id,
83941 + if bitOffsetInFqid=15 than the byte's MSB will effect
83942 + the Policer Profile id's LSB;
83943 + 0 means - no effect on policer profile; Note that one, and only one of
83944 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
83945 + extracted byte must effect either FQID or Policer profile).*/
83946 +} t_FmPcdKgExtractedOrParams;
83947 +
83948 +/**************************************************************************//**
83949 + @Description Parameters for configuring a scheme counter
83950 +*//***************************************************************************/
83951 +typedef struct t_FmPcdKgSchemeCounter {
83952 + bool update; /**< FALSE to keep the current counter state
83953 + and continue from that point, TRUE to update/reset
83954 + the counter when the scheme is written. */
83955 + uint32_t value; /**< If update=TRUE, this value will be written into the
83956 + counter. clear this field to reset the counter. */
83957 +} t_FmPcdKgSchemeCounter;
83958 +
83959 +/**************************************************************************//**
83960 + @Description Parameters for configuring a policer profile for a KeyGen scheme
83961 + (when policer is the next engine after this scheme).
83962 +*//***************************************************************************/
83963 +typedef struct t_FmPcdKgPlcrProfile {
83964 + bool sharedProfile; /**< TRUE if this profile is shared between ports
83965 + (managed by master partition); Must not be TRUE
83966 + if profile is after Coarse Classification*/
83967 + bool direct; /**< if TRUE, directRelativeProfileId only selects the profile
83968 + id, if FALSE fqidOffsetRelativeProfileIdBase is used
83969 + together with fqidOffsetShift and numOfProfiles
83970 + parameters, to define a range of profiles from
83971 + which the KeyGen result will determine the
83972 + destination policer profile. */
83973 + union {
83974 + uint16_t directRelativeProfileId; /**< Used if 'direct' is TRUE, to select policer profile.
83975 + should indicate the policer profile offset within the
83976 + port's policer profiles or shared window. */
83977 + struct {
83978 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
83979 + final FQID - without the FQID base). */
83980 + uint8_t fqidOffsetRelativeProfileIdBase;
83981 + /**< The base of the FMan Port's relative Storage-Profile ID;
83982 + this value will be "OR'ed" with the KeyGen create FQID
83983 + offset (i.e. not the final FQID - without the FQID base);
83984 + the final result should indicate the Storage-Profile offset
83985 + within the FMan Port's relative Storage-Profiles window/
83986 + (or the SHARED window depends on 'sharedProfile'). */
83987 + uint8_t numOfProfiles; /**< Range of profiles starting at base */
83988 + } indirectProfile; /**< Indirect profile parameters */
83989 + } profileSelect; /**< Direct/indirect profile selection and parameters */
83990 +} t_FmPcdKgPlcrProfile;
83991 +
83992 +#if (DPAA_VERSION >= 11)
83993 +/**************************************************************************//**
83994 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
83995 +*//***************************************************************************/
83996 +typedef struct t_FmPcdKgStorageProfile {
83997 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
83998 + profile id;
83999 + If FALSE, fqidOffsetRelativeProfileIdBase is used
84000 + together with fqidOffsetShift and numOfProfiles
84001 + parameters to define a range of profiles from which
84002 + the KeyGen result will determine the destination
84003 + storage profile. */
84004 + union {
84005 + uint16_t directRelativeProfileId; /**< Used when 'direct' is TRUE, to select a storage profile;
84006 + should indicate the storage profile offset within the
84007 + port's storage profiles window. */
84008 + struct {
84009 + uint8_t fqidOffsetShift; /**< Shift on the KeyGen create FQID offset (i.e. not the
84010 + final FQID - without the FQID base). */
84011 + uint8_t fqidOffsetRelativeProfileIdBase;
84012 + /**< The base of the FMan Port's relative Storage-Profile ID;
84013 + this value will be "OR'ed" with the KeyGen create FQID
84014 + offset (i.e. not the final FQID - without the FQID base);
84015 + the final result should indicate the Storage-Profile offset
84016 + within the FMan Port's relative Storage-Profiles window. */
84017 + uint8_t numOfProfiles; /**< Range of profiles starting at base. */
84018 + } indirectProfile; /**< Indirect profile parameters. */
84019 + } profileSelect; /**< Direct/indirect profile selection and parameters. */
84020 +} t_FmPcdKgStorageProfile;
84021 +#endif /* (DPAA_VERSION >= 11) */
84022 +
84023 +/**************************************************************************//**
84024 + @Description Parameters for defining CC as the next engine after KeyGen
84025 +*//***************************************************************************/
84026 +typedef struct t_FmPcdKgCc {
84027 + t_Handle h_CcTree; /**< A handle to a CC Tree */
84028 + uint8_t grpId; /**< CC group id within the CC tree */
84029 + bool plcrNext; /**< TRUE if after CC, in case of data frame,
84030 + policing is required. */
84031 + bool bypassPlcrProfileGeneration; /**< TRUE to bypass KeyGen policer profile generation;
84032 + selected profile is the one set at port initialization. */
84033 + t_FmPcdKgPlcrProfile plcrProfile; /**< Valid only if plcrNext = TRUE and
84034 + bypassPlcrProfileGeneration = FALSE */
84035 +} t_FmPcdKgCc;
84036 +
84037 +/**************************************************************************//**
84038 + @Description Parameters for defining initializing a KeyGen scheme
84039 +*//***************************************************************************/
84040 +typedef struct t_FmPcdKgSchemeParams {
84041 + bool modify; /**< TRUE to change an existing scheme */
84042 + union
84043 + {
84044 + uint8_t relativeSchemeId; /**< if modify=FALSE:Partition relative scheme id */
84045 + t_Handle h_Scheme; /**< if modify=TRUE: a handle of the existing scheme */
84046 + } id;
84047 + bool alwaysDirect; /**< This scheme is reached only directly, i.e. no need
84048 + for match vector; KeyGen will ignore it when matching */
84049 + struct { /**< HL Relevant only if alwaysDirect = FALSE */
84050 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
84051 + by FM_PCD_NetEnvCharacteristicsSet() */
84052 + uint8_t numOfDistinctionUnits; /**< Number of NetEnv units listed in unitIds array */
84053 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
84054 + /**< Indexes as passed to SetNetEnvCharacteristics array*/
84055 + } netEnvParams;
84056 + bool useHash; /**< use the KeyGen Hash functionality */
84057 + t_FmPcdKgKeyExtractAndHashParams keyExtractAndHashParams;
84058 + /**< used only if useHash = TRUE */
84059 + bool bypassFqidGeneration; /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
84060 + In such a case FQID after KeyGen will be the default FQID
84061 + defined for the relevant port, or the FQID defined by CC
84062 + in cases where CC was the previous engine. */
84063 + uint32_t baseFqid; /**< Base FQID; Relevant only if bypassFqidGeneration = FALSE;
84064 + If hash is used and an even distribution is expected
84065 + according to hashDistributionNumOfFqids, baseFqid must be aligned to
84066 + hashDistributionNumOfFqids. */
84067 + uint8_t numOfUsedExtractedOrs; /**< Number of FQID masks listed in extractedOrs array */
84068 + t_FmPcdKgExtractedOrParams extractedOrs[FM_PCD_KG_NUM_OF_GENERIC_REGS];
84069 + /**< FM_PCD_KG_NUM_OF_GENERIC_REGS
84070 + registers are shared between qidMasks
84071 + functionality and some of the extraction
84072 + actions; Normally only some will be used
84073 + for qidMask. Driver will return error if
84074 + resource is full at initialization time. */
84075 +
84076 +#if (DPAA_VERSION >= 11)
84077 + bool overrideStorageProfile; /**< TRUE if KeyGen override previously decided storage profile */
84078 + t_FmPcdKgStorageProfile storageProfile; /**< Used when overrideStorageProfile TRUE */
84079 +#endif /* (DPAA_VERSION >= 11) */
84080 +
84081 + e_FmPcdEngine nextEngine; /**< may be BMI, PLCR or CC */
84082 + union { /**< depends on nextEngine */
84083 + e_FmPcdDoneAction doneAction; /**< Used when next engine is BMI (done) */
84084 + t_FmPcdKgPlcrProfile plcrProfile; /**< Used when next engine is PLCR */
84085 + t_FmPcdKgCc cc; /**< Used when next engine is CC */
84086 + } kgNextEngineParams;
84087 + t_FmPcdKgSchemeCounter schemeCounter; /**< A structure of parameters for updating
84088 + the scheme counter */
84089 +} t_FmPcdKgSchemeParams;
84090 +
84091 +/**************************************************************************//**
84092 + @Collection Definitions for CC statistics
84093 +*//***************************************************************************/
84094 +#if (DPAA_VERSION >= 11)
84095 +#define FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
84096 +#define FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
84097 +#endif /* (DPAA_VERSION >= 11) */
84098 +#define FM_PCD_CC_STATS_COUNTER_SIZE 4 /* Size in bytes of a frame length range counter */
84099 +/* @} */
84100 +
84101 +/**************************************************************************//**
84102 + @Description Parameters for defining CC as the next engine after a CC node.
84103 +*//***************************************************************************/
84104 +typedef struct t_FmPcdCcNextCcParams {
84105 + t_Handle h_CcNode; /**< A handle of the next CC node */
84106 +} t_FmPcdCcNextCcParams;
84107 +
84108 +#if (DPAA_VERSION >= 11)
84109 +/**************************************************************************//**
84110 + @Description Parameters for defining Frame replicator as the next engine after a CC node.
84111 +*//***************************************************************************/
84112 +typedef struct t_FmPcdCcNextFrParams {
84113 + t_Handle h_FrmReplic; /**< A handle of the next frame replicator group */
84114 +} t_FmPcdCcNextFrParams;
84115 +#endif /* (DPAA_VERSION >= 11) */
84116 +
84117 +/**************************************************************************//**
84118 + @Description Parameters for defining Policer as the next engine after a CC node.
84119 +*//***************************************************************************/
84120 +typedef struct t_FmPcdCcNextPlcrParams {
84121 + bool overrideParams; /**< TRUE if CC override previously decided parameters*/
84122 + bool sharedProfile; /**< Relevant only if overrideParams=TRUE:
84123 + TRUE if this profile is shared between ports */
84124 + uint16_t newRelativeProfileId; /**< Relevant only if overrideParams=TRUE:
84125 + (otherwise profile id is taken from KeyGen);
84126 + This parameter should indicate the policer
84127 + profile offset within the port's
84128 + policer profiles or from SHARED window.*/
84129 + uint32_t newFqid; /**< Relevant only if overrideParams=TRUE:
84130 + FQID for enqueuing the frame;
84131 + In earlier chips if policer next engine is KEYGEN,
84132 + this parameter can be 0, because the KEYGEN
84133 + always decides the enqueue FQID.*/
84134 +#if (DPAA_VERSION >= 11)
84135 + uint8_t newRelativeStorageProfileId;
84136 + /**< Indicates the relative storage profile offset within
84137 + the port's storage profiles window;
84138 + Relevant only if the port was configured with VSP. */
84139 +#endif /* (DPAA_VERSION >= 11) */
84140 +} t_FmPcdCcNextPlcrParams;
84141 +
84142 +/**************************************************************************//**
84143 + @Description Parameters for defining enqueue as the next action after a CC node.
84144 +*//***************************************************************************/
84145 +typedef struct t_FmPcdCcNextEnqueueParams {
84146 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
84147 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
84148 + relevant if action = e_FM_PCD_ENQ_FRAME */
84149 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
84150 + (otherwise FQID is taken from KeyGen),
84151 + relevant if action = e_FM_PCD_ENQ_FRAME */
84152 +#if (DPAA_VERSION >= 11)
84153 + uint8_t newRelativeStorageProfileId;
84154 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
84155 + storage profile offset within the port's storage profiles
84156 + window; Relevant only if the port was configured with VSP. */
84157 +#endif /* (DPAA_VERSION >= 11) */
84158 +} t_FmPcdCcNextEnqueueParams;
84159 +
84160 +/**************************************************************************//**
84161 + @Description Parameters for defining KeyGen as the next engine after a CC node.
84162 +*//***************************************************************************/
84163 +typedef struct t_FmPcdCcNextKgParams {
84164 + bool overrideFqid; /**< TRUE if CC override previously decided fqid and vspid,
84165 + Note - this parameters irrelevant for earlier chips */
84166 + uint32_t newFqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
84167 + (otherwise FQID is taken from KeyGen),
84168 + Note - this parameters irrelevant for earlier chips */
84169 +#if (DPAA_VERSION >= 11)
84170 + uint8_t newRelativeStorageProfileId;
84171 + /**< Valid if overrideFqid=TRUE, Indicates the relative virtual
84172 + storage profile offset within the port's storage profiles
84173 + window; Relevant only if the port was configured with VSP. */
84174 +#endif /* (DPAA_VERSION >= 11) */
84175 +
84176 + t_Handle h_DirectScheme; /**< Direct scheme handle to go to. */
84177 +} t_FmPcdCcNextKgParams;
84178 +
84179 +/**************************************************************************//**
84180 + @Description Parameters for defining the next engine after a CC node.
84181 +*//***************************************************************************/
84182 +typedef struct t_FmPcdCcNextEngineParams {
84183 + e_FmPcdEngine nextEngine; /**< User has to initialize parameters
84184 + according to nextEngine definition */
84185 + union {
84186 + t_FmPcdCcNextCcParams ccParams; /**< Parameters in case next engine is CC */
84187 + t_FmPcdCcNextPlcrParams plcrParams; /**< Parameters in case next engine is PLCR */
84188 + t_FmPcdCcNextEnqueueParams enqueueParams; /**< Parameters in case next engine is BMI */
84189 + t_FmPcdCcNextKgParams kgParams; /**< Parameters in case next engine is KG */
84190 +#if (DPAA_VERSION >= 11)
84191 + t_FmPcdCcNextFrParams frParams; /**< Parameters in case next engine is FR */
84192 +#endif /* (DPAA_VERSION >= 11) */
84193 + } params; /**< union used for all the next-engine parameters options */
84194 +
84195 + t_Handle h_Manip; /**< Handle to Manipulation object.
84196 + Relevant if next engine is of type result
84197 + (e_FM_PCD_PLCR, e_FM_PCD_KG, e_FM_PCD_DONE) */
84198 +
84199 + bool statisticsEn; /**< If TRUE, statistics counters are incremented
84200 + for each frame passing through this
84201 + Coarse Classification entry. */
84202 +} t_FmPcdCcNextEngineParams;
84203 +
84204 +/**************************************************************************//**
84205 + @Description Parameters for defining a single CC key
84206 +*//***************************************************************************/
84207 +typedef struct t_FmPcdCcKeyParams {
84208 + uint8_t *p_Key; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
84209 + pointer to the key of the size defined in keySize */
84210 + uint8_t *p_Mask; /**< Relevant only if 'action' = e_FM_PCD_ACTION_EXACT_MATCH;
84211 + pointer to the Mask per key of the size defined
84212 + in keySize. p_Key and p_Mask (if defined) has to be
84213 + of the same size defined in the keySize;
84214 + NOTE that if this value is equal for all entries whithin
84215 + this table, the driver will automatically use global-mask
84216 + (i.e. one common mask for all entries) instead of private
84217 + one; that is done in order to spare some memory and for
84218 + better performance. */
84219 + t_FmPcdCcNextEngineParams ccNextEngineParams;
84220 + /**< parameters for the next for the defined Key in
84221 + the p_Key */
84222 +} t_FmPcdCcKeyParams;
84223 +
84224 +/**************************************************************************//**
84225 + @Description Parameters for defining CC keys parameters
84226 + The driver supports two methods for CC node allocation: dynamic and static.
84227 + Static mode was created in order to prevent runtime alloc/free
84228 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
84229 + the driver automatically allocates the memory according to
84230 + 'maxNumOfKeys' parameter. The driver calculates the maximal memory
84231 + size that may be used for this CC-Node taking into consideration
84232 + 'maskSupport' and 'statisticsMode' parameters.
84233 + When 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
84234 + parameters of this node, 'maxNumOfKeys' must be equal to 'numOfKeys'.
84235 + In dynamic mode, 'maxNumOfKeys' must be zero. At initialization,
84236 + all required structures are allocated according to 'numOfKeys'
84237 + parameter. During runtime modification, these structures are
84238 + re-allocated according to the updated number of keys.
84239 +
84240 + Please note that 'action' and 'icIndxMask' mentioned in the
84241 + specific parameter explanations are passed in the extraction
84242 + parameters of the node (fields of extractCcParams.extractNonHdr).
84243 +*//***************************************************************************/
84244 +typedef struct t_KeysParams {
84245 + uint16_t maxNumOfKeys; /**< Maximum number of keys that will (ever) be used in this CC-Node;
84246 + A value of zero may be used for dynamic memory allocation. */
84247 + bool maskSupport; /**< This parameter is relevant only if a node is initialized with
84248 + 'action' = e_FM_PCD_ACTION_EXACT_MATCH and maxNumOfKeys > 0;
84249 + Should be TRUE to reserve table memory for key masks, even if
84250 + initial keys do not contain masks, or if the node was initialized
84251 + as 'empty' (without keys); this will allow user to add keys with
84252 + masks at runtime.
84253 + NOTE that if user want to use only global-masks (i.e. one common mask
84254 + for all the entries within this table, this parameter should set to 'FALSE'. */
84255 + e_FmPcdCcStatsMode statisticsMode; /**< Determines the supported statistics mode for all node's keys.
84256 + To enable statistics gathering, statistics should be enabled per
84257 + every key, using 'statisticsEn' in next engine parameters structure
84258 + of that key;
84259 + If 'maxNumOfKeys' is set, all required structures will be
84260 + preallocated for all keys. */
84261 +#if (DPAA_VERSION >= 11)
84262 + uint16_t frameLengthRanges[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
84263 + /**< Relevant only for 'RMON' statistics mode
84264 + (this feature is supported only on B4860 device);
84265 + Holds a list of programmable thresholds - for each received frame,
84266 + its length in bytes is examined against these range thresholds and
84267 + the appropriate counter is incremented by 1 - for example, to belong
84268 + to range i, the following should hold:
84269 + range i-1 threshold < frame length <= range i threshold
84270 + Each range threshold must be larger then its preceding range
84271 + threshold, and last range threshold must be 0xFFFF. */
84272 +#endif /* (DPAA_VERSION >= 11) */
84273 + uint16_t numOfKeys; /**< Number of initial keys;
84274 + Note that in case of 'action' = e_FM_PCD_ACTION_INDEXED_LOOKUP,
84275 + this field should be power-of-2 of the number of bits that are
84276 + set in 'icIndxMask'. */
84277 + uint8_t keySize; /**< Size of key - for extraction of type FULL_FIELD, 'keySize' has
84278 + to be the standard size of the selected key; For other extraction
84279 + types, 'keySize' has to be as size of extraction; When 'action' =
84280 + e_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
84281 + t_FmPcdCcKeyParams keyParams[FM_PCD_MAX_NUM_OF_KEYS];
84282 + /**< An array with 'numOfKeys' entries, each entry specifies the
84283 + corresponding key parameters;
84284 + When 'action' = e_FM_PCD_ACTION_EXACT_MATCH, this value must not
84285 + exceed 255 (FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
84286 + for the 'miss' entry. */
84287 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss;
84288 + /**< Parameters for defining the next engine when a key is not matched;
84289 + Not relevant if action = e_FM_PCD_ACTION_INDEXED_LOOKUP. */
84290 +} t_KeysParams;
84291 +
84292 +
84293 +/**************************************************************************//**
84294 + @Description Parameters for defining a CC node
84295 +*//***************************************************************************/
84296 +typedef struct t_FmPcdCcNodeParams {
84297 + t_FmPcdExtractEntry extractCcParams; /**< Extraction parameters */
84298 + t_KeysParams keysParams; /**< Keys definition matching the selected extraction */
84299 +} t_FmPcdCcNodeParams;
84300 +
84301 +/**************************************************************************//**
84302 + @Description Parameters for defining a hash table
84303 +*//***************************************************************************/
84304 +typedef struct t_FmPcdHashTableParams {
84305 + uint16_t maxNumOfKeys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
84306 + e_FmPcdCcStatsMode statisticsMode; /**< If not e_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
84307 + requested statistics mode will be allocated according to maxNumOfKeys. */
84308 + uint8_t kgHashShift; /**< KG-Hash-shift as it was configured in the KG-scheme
84309 + that leads to this hash-table. */
84310 + uint16_t hashResMask; /**< Mask that will be used on the hash-result;
84311 + The number-of-sets for this hash will be calculated
84312 + as (2^(number of bits set in 'hashResMask'));
84313 + The 4 lower bits must be cleared. */
84314 + uint8_t hashShift; /**< Byte offset from the beginning of the KeyGen hash result to the
84315 + 2-bytes to be used as hash index. */
84316 + uint8_t matchKeySize; /**< Size of the exact match keys held by the hash buckets */
84317 +
84318 + t_FmPcdCcNextEngineParams ccNextEngineParamsForMiss; /**< Parameters for defining the next engine when a key is not matched */
84319 +
84320 +} t_FmPcdHashTableParams;
84321 +
84322 +/**************************************************************************//**
84323 + @Description Parameters for defining a CC tree group.
84324 +
84325 + This structure defines a CC group in terms of NetEnv units
84326 + and the action to be taken in each case. The unitIds list must
84327 + be given in order from low to high indices.
84328 +
84329 + t_FmPcdCcNextEngineParams is a list of 2^numOfDistinctionUnits
84330 + structures where each defines the next action to be taken for
84331 + each units combination. for example:
84332 + numOfDistinctionUnits = 2
84333 + unitIds = {1,3}
84334 + p_NextEnginePerEntriesInGrp[0] = t_FmPcdCcNextEngineParams for the case that
84335 + unit 1 - not found; unit 3 - not found;
84336 + p_NextEnginePerEntriesInGrp[1] = t_FmPcdCcNextEngineParams for the case that
84337 + unit 1 - not found; unit 3 - found;
84338 + p_NextEnginePerEntriesInGrp[2] = t_FmPcdCcNextEngineParams for the case that
84339 + unit 1 - found; unit 3 - not found;
84340 + p_NextEnginePerEntriesInGrp[3] = t_FmPcdCcNextEngineParams for the case that
84341 + unit 1 - found; unit 3 - found;
84342 +*//***************************************************************************/
84343 +typedef struct t_FmPcdCcGrpParams {
84344 + uint8_t numOfDistinctionUnits; /**< Up to 4 */
84345 + uint8_t unitIds[FM_PCD_MAX_NUM_OF_CC_UNITS];
84346 + /**< Indices of the units as defined in
84347 + FM_PCD_NetEnvCharacteristicsSet() */
84348 + t_FmPcdCcNextEngineParams nextEnginePerEntriesInGrp[FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
84349 + /**< Maximum entries per group is 16 */
84350 +} t_FmPcdCcGrpParams;
84351 +
84352 +/**************************************************************************//**
84353 + @Description Parameters for defining CC tree groups
84354 +*//***************************************************************************/
84355 +typedef struct t_FmPcdCcTreeParams {
84356 + t_Handle h_NetEnv; /**< A handle to the Network environment as returned
84357 + by FM_PCD_NetEnvCharacteristicsSet() */
84358 + uint8_t numOfGrps; /**< Number of CC groups within the CC tree */
84359 + t_FmPcdCcGrpParams ccGrpParams[FM_PCD_MAX_NUM_OF_CC_GROUPS];
84360 + /**< Parameters for each group. */
84361 +} t_FmPcdCcTreeParams;
84362 +
84363 +
84364 +/**************************************************************************//**
84365 + @Description CC key statistics structure
84366 +*//***************************************************************************/
84367 +typedef struct t_FmPcdCcKeyStatistics {
84368 + uint32_t byteCount; /**< This counter reflects byte count of frames that
84369 + were matched by this key. */
84370 + uint32_t frameCount; /**< This counter reflects count of frames that
84371 + were matched by this key. */
84372 +#if (DPAA_VERSION >= 11)
84373 + uint32_t frameLengthRangeCount[FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
84374 + /**< These counters reflect how many frames matched
84375 + this key in 'RMON' statistics mode:
84376 + Each counter holds the number of frames of a
84377 + specific frames length range, according to the
84378 + ranges provided at initialization. */
84379 +#endif /* (DPAA_VERSION >= 11) */
84380 +} t_FmPcdCcKeyStatistics;
84381 +
84382 +/**************************************************************************//**
84383 + @Description Parameters for defining policer byte rate
84384 +*//***************************************************************************/
84385 +typedef struct t_FmPcdPlcrByteRateModeParams {
84386 + e_FmPcdPlcrFrameLengthSelect frameLengthSelection; /**< Frame length selection */
84387 + e_FmPcdPlcrRollBackFrameSelect rollBackFrameSelection; /**< relevant option only e_FM_PCD_PLCR_L2_FRM_LEN,
84388 + e_FM_PCD_PLCR_FULL_FRM_LEN */
84389 +} t_FmPcdPlcrByteRateModeParams;
84390 +
84391 +/**************************************************************************//**
84392 + @Description Parameters for defining the policer profile (based on
84393 + RFC-2698 or RFC-4115 attributes).
84394 +*//***************************************************************************/
84395 +typedef struct t_FmPcdPlcrNonPassthroughAlgParams {
84396 + e_FmPcdPlcrRateMode rateMode; /**< Byte mode or Packet mode */
84397 + t_FmPcdPlcrByteRateModeParams byteModeParams; /**< Valid for Byte NULL for Packet */
84398 + uint32_t committedInfoRate; /**< KBits/Second or Packets/Second */
84399 + uint32_t committedBurstSize; /**< Bytes/Packets */
84400 + uint32_t peakOrExcessInfoRate; /**< KBits/Second or Packets/Second */
84401 + uint32_t peakOrExcessBurstSize; /**< Bytes/Packets */
84402 +} t_FmPcdPlcrNonPassthroughAlgParams;
84403 +
84404 +/**************************************************************************//**
84405 + @Description Parameters for defining the next engine after policer
84406 +*//***************************************************************************/
84407 +typedef union u_FmPcdPlcrNextEngineParams {
84408 + e_FmPcdDoneAction action; /**< Action - when next engine is BMI (done) */
84409 + t_Handle h_Profile; /**< Policer profile handle - used when next engine
84410 + is Policer, must be a SHARED profile */
84411 + t_Handle h_DirectScheme; /**< Direct scheme select - when next engine is KeyGen */
84412 +} u_FmPcdPlcrNextEngineParams;
84413 +
84414 +/**************************************************************************//**
84415 + @Description Parameters for defining the policer profile entry
84416 +*//***************************************************************************/
84417 +typedef struct t_FmPcdPlcrProfileParams {
84418 + bool modify; /**< TRUE to change an existing profile */
84419 + union {
84420 + struct {
84421 + e_FmPcdProfileTypeSelection profileType; /**< Type of policer profile */
84422 + t_Handle h_FmPort; /**< Relevant for per-port profiles only */
84423 + uint16_t relativeProfileId; /**< Profile id - relative to shared group or to port */
84424 + } newParams; /**< use it when modify = FALSE */
84425 + t_Handle h_Profile; /**< A handle to a profile - use it when modify=TRUE */
84426 + } id;
84427 + e_FmPcdPlcrAlgorithmSelection algSelection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
84428 + e_FmPcdPlcrColorMode colorMode; /**< COLOR_BLIND, COLOR_AWARE */
84429 +
84430 + union {
84431 + e_FmPcdPlcrColor dfltColor; /**< For Color-Blind Pass-Through mode; the policer will re-color
84432 + any incoming packet with the default value. */
84433 + e_FmPcdPlcrColor override; /**< For Color-Aware modes; the profile response to a
84434 + pre-color value of 2'b11. */
84435 + } color;
84436 +
84437 + t_FmPcdPlcrNonPassthroughAlgParams nonPassthroughAlgParams; /**< RFC2698 or RFC4115 parameters */
84438 +
84439 + e_FmPcdEngine nextEngineOnGreen; /**< Next engine for green-colored frames */
84440 + u_FmPcdPlcrNextEngineParams paramsOnGreen; /**< Next engine parameters for green-colored frames */
84441 +
84442 + e_FmPcdEngine nextEngineOnYellow; /**< Next engine for yellow-colored frames */
84443 + u_FmPcdPlcrNextEngineParams paramsOnYellow; /**< Next engine parameters for yellow-colored frames */
84444 +
84445 + e_FmPcdEngine nextEngineOnRed; /**< Next engine for red-colored frames */
84446 + u_FmPcdPlcrNextEngineParams paramsOnRed; /**< Next engine parameters for red-colored frames */
84447 +
84448 + bool trapProfileOnFlowA; /**< Obsolete - do not use */
84449 + bool trapProfileOnFlowB; /**< Obsolete - do not use */
84450 + bool trapProfileOnFlowC; /**< Obsolete - do not use */
84451 +} t_FmPcdPlcrProfileParams;
84452 +
84453 +/**************************************************************************//**
84454 + @Description Parameters for selecting a location for requested manipulation
84455 +*//***************************************************************************/
84456 +typedef struct t_FmManipHdrInfo {
84457 + e_NetHeaderType hdr; /**< Header selection */
84458 + e_FmPcdHdrIndex hdrIndex; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
84459 + bool byField; /**< TRUE if the location of manipulation is according to some field in the specific header*/
84460 + t_FmPcdFields fullField; /**< Relevant only when byField = TRUE: Extract field */
84461 +} t_FmManipHdrInfo;
84462 +
84463 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84464 +/**************************************************************************//**
84465 + @Description Parameters for defining an insertion manipulation
84466 + of type e_FM_PCD_MANIP_INSRT_TO_START_OF_FRAME_TEMPLATE
84467 +*//***************************************************************************/
84468 +typedef struct t_FmPcdManipHdrInsrtByTemplateParams {
84469 + uint8_t size; /**< Size of insert template to the start of the frame. */
84470 + uint8_t hdrTemplate[FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE];
84471 + /**< Array of the insertion template. */
84472 +
84473 + bool modifyOuterIp; /**< TRUE if user want to modify some fields in outer IP. */
84474 + struct {
84475 + uint16_t ipOuterOffset; /**< Offset of outer IP in the insert template, relevant if modifyOuterIp = TRUE.*/
84476 + uint16_t dscpEcn; /**< value of dscpEcn in IP outer, relevant if modifyOuterIp = TRUE.
84477 + in IPV4 dscpEcn only byte - it has to be adjusted to the right*/
84478 + bool udpPresent; /**< TRUE if UDP is present in the insert template, relevant if modifyOuterIp = TRUE.*/
84479 + uint8_t udpOffset; /**< Offset in the insert template of UDP, relevant if modifyOuterIp = TRUE and udpPresent=TRUE.*/
84480 + uint8_t ipIdentGenId; /**< Used by FMan-CTRL to calculate IP-identification field,relevant if modifyOuterIp = TRUE.*/
84481 + 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.*/
84482 + struct {
84483 + uint8_t blockSize; /**< The CAAM block-size; Used by FMan-CTRL to calculate the IP Total Length field.*/
84484 + uint8_t extraBytesAddedAlignedToBlockSize; /**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length*/
84485 + uint8_t extraBytesAddedNotAlignedToBlockSize;/**< Used by FMan-CTRL to calculate the IP Total Length field and UDP length.*/
84486 + } recalculateLengthParams; /**< Recalculate length parameters - relevant if modifyOuterIp = TRUE and recalculateLength = TRUE */
84487 + } modifyOuterIpParams; /**< Outer IP modification parameters - ignored if modifyOuterIp is FALSE */
84488 +
84489 + bool modifyOuterVlan; /**< TRUE if user wants to modify VPri field in the outer VLAN header*/
84490 + struct {
84491 + uint8_t vpri; /**< Value of VPri, relevant if modifyOuterVlan = TRUE
84492 + VPri only 3 bits, it has to be adjusted to the right*/
84493 + } modifyOuterVlanParams;
84494 +} t_FmPcdManipHdrInsrtByTemplateParams;
84495 +
84496 +/**************************************************************************//**
84497 + @Description Parameters for defining CAPWAP fragmentation
84498 +*//***************************************************************************/
84499 +typedef struct t_CapwapFragmentationParams {
84500 + uint16_t sizeForFragmentation; /**< if length of the frame is greater than this value, CAPWAP fragmentation will be executed.*/
84501 + bool headerOptionsCompr; /**< TRUE - first fragment include the CAPWAP header options field,
84502 + and all other fragments exclude the CAPWAP options field,
84503 + FALSE - all fragments include CAPWAP header options field. */
84504 +} t_CapwapFragmentationParams;
84505 +
84506 +/**************************************************************************//**
84507 + @Description Parameters for defining CAPWAP reassembly
84508 +*//***************************************************************************/
84509 +typedef struct t_CapwapReassemblyParams {
84510 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be reassembled concurrently; must be power of 2.
84511 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
84512 + maxNumFramesInProcess has to be in the range of 4 - 512,
84513 + In case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
84514 + maxNumFramesInProcess has to be in the range of 8 - 2048 */
84515 + bool haltOnDuplicationFrag; /**< If TRUE, reassembly process will be halted due to duplicated fragment,
84516 + and all processed fragments will be enqueued with error indication;
84517 + If FALSE, only duplicated fragments will be enqueued with error indication. */
84518 +
84519 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by the reassembly process */
84520 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process */
84521 + uint32_t timeoutRoutineRequestTime;
84522 + /**< Represents the time interval in microseconds between consecutive
84523 + timeout routine requests It has to be power of 2. */
84524 + uint32_t timeoutThresholdForReassmProcess;
84525 + /**< Time interval (microseconds) for marking frames in process as too old;
84526 + Frames in process are those for which at least one fragment was received
84527 + but not all fragments. */
84528 +
84529 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;/**< Number of frames per hash entry (needed for the reassembly process) */
84530 +} t_CapwapReassemblyParams;
84531 +
84532 +/**************************************************************************//**
84533 + @Description Parameters for defining fragmentation/reassembly manipulation
84534 +*//***************************************************************************/
84535 +typedef struct t_FmPcdManipFragOrReasmParams {
84536 + bool frag; /**< TRUE if using the structure for fragmentation,
84537 + otherwise this structure is used for reassembly */
84538 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
84539 + Same LIODN number is used for these buffers as for
84540 + the received frames buffers, so buffers of this pool
84541 + need to be allocated in the same memory area as the
84542 + received buffers. If the received buffers arrive
84543 + from different sources, the Scatter/Gather BP id
84544 + should be mutual to all these sources. */
84545 + e_NetHeaderType hdr; /**< Header selection */
84546 + union {
84547 + t_CapwapFragmentationParams capwapFragParams; /**< Structure for CAPWAP fragmentation,
84548 + relevant if 'frag' = TRUE, 'hdr' = HEADER_TYPE_CAPWAP */
84549 + t_CapwapReassemblyParams capwapReasmParams; /**< Structure for CAPWAP reassembly,
84550 + relevant if 'frag' = FALSE, 'hdr' = HEADER_TYPE_CAPWAP */
84551 + } u;
84552 +} t_FmPcdManipFragOrReasmParams;
84553 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
84554 +
84555 +
84556 +/**************************************************************************//**
84557 + @Description Parameters for defining header removal by header type
84558 +*//***************************************************************************/
84559 +typedef struct t_FmPcdManipHdrRmvByHdrParams {
84560 + e_FmPcdManipHdrRmvByHdrType type; /**< Selection of header removal location */
84561 + union {
84562 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
84563 + struct {
84564 + bool include; /**< If FALSE, remove until the specified header (not including the header);
84565 + If TRUE, remove also the specified header. */
84566 + t_FmManipHdrInfo hdrInfo;
84567 + } fromStartByHdr; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
84568 +#endif /* (DPAA_VERSION >= 11) || ... */
84569 +#if (DPAA_VERSION >= 11)
84570 + t_FmManipHdrInfo hdrInfo; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
84571 +#endif /* (DPAA_VERSION >= 11) */
84572 + e_FmPcdManipHdrRmvSpecificL2 specificL2; /**< Relevant when type = e_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
84573 + Defines which L2 headers to remove. */
84574 + } u;
84575 +} t_FmPcdManipHdrRmvByHdrParams;
84576 +
84577 +/**************************************************************************//**
84578 + @Description Parameters for configuring IP fragmentation manipulation
84579 +
84580 + Restrictions:
84581 + - IP Fragmentation output fragments must not be forwarded to application directly.
84582 + - Maximum number of fragments per frame is 16.
84583 + - Fragmentation of IP fragments is not supported.
84584 + - IPv4 packets containing header Option fields are fragmented by copying all option
84585 + fields to each fragment, regardless of the copy bit value.
84586 + - Transmit confirmation is not supported.
84587 + - Fragmentation after SEC can't handle S/G frames.
84588 + - Fragmentation nodes must be set as the last PCD action (i.e. the
84589 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
84590 + - Only BMan buffers shall be used for frames to be fragmented.
84591 + - IPF does not support VSP. Therefore, on the same port where we have IPF
84592 + we cannot support VSP.
84593 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
84594 + does not support VSP. Therefore, on the same port where we have IPF we
84595 + cannot support VSP.
84596 +*//***************************************************************************/
84597 +typedef struct t_FmPcdManipFragIpParams {
84598 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
84599 + IP fragmentation will be executed.*/
84600 +#if (DPAA_VERSION == 10)
84601 + uint8_t scratchBpid; /**< Absolute buffer pool id according to BM configuration.*/
84602 +#endif /* (DPAA_VERSION == 10) */
84603 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
84604 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
84605 + received frame's buffer. */
84606 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
84607 + This parameters is relevant when 'sgBpidEn=TRUE';
84608 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
84609 + of this pool need to be allocated in the same memory area as the received buffers.
84610 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
84611 + mutual to all these sources. */
84612 + e_FmPcdManipDontFragAction dontFragAction; /**< Don't Fragment Action - If an IP packet is larger
84613 + than MTU and its DF bit is set, then this field will
84614 + determine the action to be taken.*/
84615 +} t_FmPcdManipFragIpParams;
84616 +
84617 +/**************************************************************************//**
84618 + @Description Parameters for configuring IP reassembly manipulation.
84619 +
84620 + This is a common structure for both IPv4 and IPv6 reassembly
84621 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
84622 + set the 'hdr' field in t_FmPcdManipReassemParams to HEADER_TYPE_IPv6.
84623 +
84624 + Restrictions:
84625 + - Application must define at least one scheme to catch the reassembled frames.
84626 + - Maximum number of fragments per frame is 16.
84627 + - Reassembly of IPv4 fragments containing Option fields is supported.
84628 +
84629 +*//***************************************************************************/
84630 +typedef struct t_FmPcdManipReassemIpParams {
84631 + uint8_t relativeSchemeId[2]; /**< Partition relative scheme id:
84632 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
84633 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
84634 + NOTE: The following comment is relevant only for FMAN v2 devices:
84635 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
84636 + the user schemes id to ensure that the reassembly schemes will be first match;
84637 + Rest schemes, if defined, should have higher relative scheme ID. */
84638 +#if (DPAA_VERSION >= 11)
84639 + uint32_t nonConsistentSpFqid; /**< In case that other fragments of the frame corresponds to different storage
84640 + profile than the opening fragment (Non-Consistent-SP state)
84641 + then one of two possible scenarios occurs:
84642 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
84643 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
84644 +#else
84645 + uint8_t sgBpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
84646 +#endif /* (DPAA_VERSION >= 11) */
84647 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
84648 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
84649 + uint16_t minFragSize[2]; /**< Minimum fragment size:
84650 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
84651 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry[2];
84652 + /**< Number of frames per hash entry needed for reassembly process:
84653 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
84654 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_FM_PCD_MANIP_SIX_WAYS_HASH). */
84655 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by Reassembly in the same time;
84656 + Must be power of 2;
84657 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
84658 + maxNumFramesInProcess has to be in the range of 4 - 512;
84659 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
84660 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
84661 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
84662 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
84663 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
84664 + uint32_t timeoutThresholdForReassmProcess;
84665 + /**< Represents the time interval in microseconds which defines
84666 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
84667 +} t_FmPcdManipReassemIpParams;
84668 +
84669 +/**************************************************************************//**
84670 + @Description structure for defining IPSEC manipulation
84671 +*//***************************************************************************/
84672 +typedef struct t_FmPcdManipSpecialOffloadIPSecParams {
84673 + bool decryption; /**< TRUE if being used in decryption direction;
84674 + FALSE if being used in encryption direction. */
84675 + bool ecnCopy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
84676 + (direction depends on the 'decryption' field). */
84677 + bool dscpCopy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
84678 + (direction depends on the 'decryption' field). */
84679 + bool variableIpHdrLen; /**< TRUE for supporting variable IP header length in decryption. */
84680 + bool variableIpVersion; /**< TRUE for supporting both IP version on the same SA in encryption */
84681 + uint8_t outerIPHdrLen; /**< if 'variableIpVersion == TRUE' then this field must be set to non-zero value;
84682 + It is specifies the length of the outer IP header that was configured in the
84683 + corresponding SA. */
84684 + uint16_t arwSize; /**< if <> '0' then will perform ARW check for this SA;
84685 + The value must be a multiplication of 16 */
84686 + uintptr_t arwAddr; /**< if arwSize <> '0' then this field must be set to non-zero value;
84687 + MUST be allocated from FMAN's MURAM that the post-sec op-port belongs to;
84688 + Must be 4B aligned. Required MURAM size is 'NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
84689 +} t_FmPcdManipSpecialOffloadIPSecParams;
84690 +
84691 +#if (DPAA_VERSION >= 11)
84692 +/**************************************************************************//**
84693 + @Description Parameters for configuring CAPWAP fragmentation manipulation
84694 +
84695 + Restrictions:
84696 + - Maximum number of fragments per frame is 16.
84697 + - Transmit confirmation is not supported.
84698 + - Fragmentation nodes must be set as the last PCD action (i.e. the
84699 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
84700 + - Only BMan buffers shall be used for frames to be fragmented.
84701 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
84702 + does not support VSP. Therefore, on the same port where we have IPF we
84703 + cannot support VSP.
84704 +*//***************************************************************************/
84705 +typedef struct t_FmPcdManipFragCapwapParams {
84706 + uint16_t sizeForFragmentation; /**< If length of the frame is greater than this value,
84707 + CAPWAP fragmentation will be executed.*/
84708 + bool sgBpidEn; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
84709 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
84710 + received frame's buffer. */
84711 + uint8_t sgBpid; /**< Scatter/Gather buffer pool id;
84712 + This parameters is relevant when 'sgBpidEn=TRUE';
84713 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
84714 + of this pool need to be allocated in the same memory area as the received buffers.
84715 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
84716 + mutual to all these sources. */
84717 + bool compressModeEn; /**< CAPWAP Header Options Compress Enable mode;
84718 + When this mode is enabled then only the first fragment include the CAPWAP header options
84719 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
84720 + options field (CAPWAP header is updated accordingly).*/
84721 +} t_FmPcdManipFragCapwapParams;
84722 +
84723 +/**************************************************************************//**
84724 + @Description Parameters for configuring CAPWAP reassembly manipulation.
84725 +
84726 + Restrictions:
84727 + - Application must define one scheme to catch the reassembled frames.
84728 + - Maximum number of fragments per frame is 16.
84729 +
84730 +*//***************************************************************************/
84731 +typedef struct t_FmPcdManipReassemCapwapParams {
84732 + uint8_t relativeSchemeId; /**< Partition relative scheme id;
84733 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
84734 + Rest schemes, if defined, should have higher relative scheme ID. */
84735 + uint8_t dataMemId; /**< Memory partition ID for the IPR's external tables structure */
84736 + uint16_t dataLiodnOffset; /**< LIODN offset for access the IPR's external tables structure. */
84737 + uint16_t maxReassembledFrameLength;/**< The maximum CAPWAP reassembled frame length in bytes;
84738 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
84739 + considered as a valid length;
84740 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
84741 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
84742 + e_FmPcdManipReassemWaysNumber numOfFramesPerHashEntry;
84743 + /**< Number of frames per hash entry needed for reassembly process */
84744 + uint16_t maxNumFramesInProcess; /**< Number of frames which can be processed by reassembly in the same time;
84745 + Must be power of 2;
84746 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
84747 + maxNumFramesInProcess has to be in the range of 4 - 512;
84748 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
84749 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
84750 + e_FmPcdManipReassemTimeOutMode timeOutMode; /**< Expiration delay initialized by Reassembly process */
84751 + uint32_t fqidForTimeOutFrames; /**< FQID in which time out frames will enqueue during Time Out Process;
84752 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
84753 + uint32_t timeoutThresholdForReassmProcess;
84754 + /**< Represents the time interval in microseconds which defines
84755 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
84756 +} t_FmPcdManipReassemCapwapParams;
84757 +
84758 +/**************************************************************************//**
84759 + @Description structure for defining CAPWAP manipulation
84760 +*//***************************************************************************/
84761 +typedef struct t_FmPcdManipSpecialOffloadCapwapParams {
84762 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
84763 + e_FmPcdManipHdrQosSrc qosSrc; /**< TODO */
84764 +} t_FmPcdManipSpecialOffloadCapwapParams;
84765 +
84766 +#endif /* (DPAA_VERSION >= 11) */
84767 +
84768 +
84769 +/**************************************************************************//**
84770 + @Description Parameters for defining special offload manipulation
84771 +*//***************************************************************************/
84772 +typedef struct t_FmPcdManipSpecialOffloadParams {
84773 + e_FmPcdManipSpecialOffloadType type; /**< Type of special offload manipulation */
84774 + union
84775 + {
84776 + t_FmPcdManipSpecialOffloadIPSecParams ipsec; /**< Parameters for IPSec; Relevant when
84777 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
84778 +#if (DPAA_VERSION >= 11)
84779 + t_FmPcdManipSpecialOffloadCapwapParams capwap; /**< Parameters for CAPWAP; Relevant when
84780 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
84781 +#endif /* (DPAA_VERSION >= 11) */
84782 + } u;
84783 +} t_FmPcdManipSpecialOffloadParams;
84784 +
84785 +/**************************************************************************//**
84786 + @Description Parameters for defining insertion manipulation
84787 +*//***************************************************************************/
84788 +typedef struct t_FmPcdManipHdrInsrt {
84789 + uint8_t size; /**< size of inserted section */
84790 + uint8_t *p_Data; /**< data to be inserted */
84791 +} t_FmPcdManipHdrInsrt;
84792 +
84793 +
84794 +/**************************************************************************//**
84795 + @Description Parameters for defining generic removal manipulation
84796 +*//***************************************************************************/
84797 +typedef struct t_FmPcdManipHdrRmvGenericParams {
84798 + uint8_t offset; /**< Offset from beginning of header to the start
84799 + location of the removal */
84800 + uint8_t size; /**< Size of removed section */
84801 +} t_FmPcdManipHdrRmvGenericParams;
84802 +
84803 +/**************************************************************************//**
84804 + @Description Parameters for defining generic insertion manipulation
84805 +*//***************************************************************************/
84806 +typedef struct t_FmPcdManipHdrInsrtGenericParams {
84807 + uint8_t offset; /**< Offset from beginning of header to the start
84808 + location of the insertion */
84809 + uint8_t size; /**< Size of inserted section */
84810 + bool replace; /**< TRUE to override (replace) existing data at
84811 + 'offset', FALSE to insert */
84812 + uint8_t *p_Data; /**< Pointer to data to be inserted */
84813 +} t_FmPcdManipHdrInsrtGenericParams;
84814 +
84815 +/**************************************************************************//**
84816 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
84817 +*//***************************************************************************/
84818 +typedef struct t_FmPcdManipHdrFieldUpdateVlanDscpToVpri {
84819 + uint8_t dscpToVpriTable[FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
84820 + /**< A table of VPri values for each DSCP value;
84821 + The index is the DSCP value (0-0x3F) and the
84822 + value is the corresponding VPRI (0-15). */
84823 + uint8_t vpriDefVal; /**< 0-7, Relevant only if if updateType =
84824 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
84825 + this field is the Q Tag default value if the
84826 + IP header is not found. */
84827 +} t_FmPcdManipHdrFieldUpdateVlanDscpToVpri;
84828 +
84829 +/**************************************************************************//**
84830 + @Description Parameters for defining header manipulation VLAN fields updates
84831 +*//***************************************************************************/
84832 +typedef struct t_FmPcdManipHdrFieldUpdateVlan {
84833 + e_FmPcdManipHdrFieldUpdateVlan updateType; /**< Selects VLAN update type */
84834 + union {
84835 + uint8_t vpri; /**< 0-7, Relevant only if If updateType =
84836 + e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
84837 + is the new VLAN pri. */
84838 + t_FmPcdManipHdrFieldUpdateVlanDscpToVpri dscpToVpri; /**< Parameters structure, Relevant only if updateType
84839 + = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
84840 + } u;
84841 +} t_FmPcdManipHdrFieldUpdateVlan;
84842 +
84843 +/**************************************************************************//**
84844 + @Description Parameters for defining header manipulation IPV4 fields updates
84845 +*//***************************************************************************/
84846 +typedef struct t_FmPcdManipHdrFieldUpdateIpv4 {
84847 + ipv4HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
84848 + uint8_t tos; /**< 8 bit New TOS; Relevant if validUpdates contains
84849 + HDR_MANIP_IPV4_TOS */
84850 + uint16_t id; /**< 16 bit New IP ID; Relevant only if validUpdates
84851 + contains HDR_MANIP_IPV4_ID */
84852 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if validUpdates
84853 + contains HDR_MANIP_IPV4_SRC */
84854 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if validUpdates
84855 + contains HDR_MANIP_IPV4_DST */
84856 +} t_FmPcdManipHdrFieldUpdateIpv4;
84857 +
84858 +/**************************************************************************//**
84859 + @Description Parameters for defining header manipulation IPV6 fields updates
84860 +*//***************************************************************************/
84861 +typedef struct t_FmPcdManipHdrFieldUpdateIpv6 {
84862 + ipv6HdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
84863 + uint8_t trafficClass; /**< 8 bit New Traffic Class; Relevant if validUpdates contains
84864 + HDR_MANIP_IPV6_TC */
84865 + uint8_t src[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
84866 + /**< 16 byte new IP SRC; Relevant only if validUpdates
84867 + contains HDR_MANIP_IPV6_SRC */
84868 + uint8_t dst[NET_HEADER_FIELD_IPv6_ADDR_SIZE];
84869 + /**< 16 byte new IP DST; Relevant only if validUpdates
84870 + contains HDR_MANIP_IPV6_DST */
84871 +} t_FmPcdManipHdrFieldUpdateIpv6;
84872 +
84873 +/**************************************************************************//**
84874 + @Description Parameters for defining header manipulation TCP/UDP fields updates
84875 +*//***************************************************************************/
84876 +typedef struct t_FmPcdManipHdrFieldUpdateTcpUdp {
84877 + tcpUdpHdrManipUpdateFlags_t validUpdates; /**< ORed flag, selecting the required updates */
84878 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if validUpdates
84879 + contains HDR_MANIP_TCP_UDP_SRC */
84880 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if validUpdates
84881 + contains HDR_MANIP_TCP_UDP_DST */
84882 +} t_FmPcdManipHdrFieldUpdateTcpUdp;
84883 +
84884 +/**************************************************************************//**
84885 + @Description Parameters for defining header manipulation fields updates
84886 +*//***************************************************************************/
84887 +typedef struct t_FmPcdManipHdrFieldUpdateParams {
84888 + e_FmPcdManipHdrFieldUpdateType type; /**< Type of header field update manipulation */
84889 + union {
84890 + t_FmPcdManipHdrFieldUpdateVlan vlan; /**< Parameters for VLAN update. Relevant when
84891 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
84892 + t_FmPcdManipHdrFieldUpdateIpv4 ipv4; /**< Parameters for IPv4 update. Relevant when
84893 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
84894 + t_FmPcdManipHdrFieldUpdateIpv6 ipv6; /**< Parameters for IPv6 update. Relevant when
84895 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
84896 + t_FmPcdManipHdrFieldUpdateTcpUdp tcpUdp; /**< Parameters for TCP/UDP update. Relevant when
84897 + type = e_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
84898 + } u;
84899 +} t_FmPcdManipHdrFieldUpdateParams;
84900 +
84901 +
84902 +
84903 +/**************************************************************************//**
84904 + @Description Parameters for defining custom header manipulation for generic field replacement
84905 +*//***************************************************************************/
84906 +typedef struct t_FmPcdManipHdrCustomGenFieldReplace {
84907 + uint8_t srcOffset; /**< Location of new data - Offset from
84908 + Parse Result (>= 16, srcOffset+size <= 32, ) */
84909 + uint8_t dstOffset; /**< Location of data to be overwritten - Offset from
84910 + start of frame (dstOffset + size <= 256). */
84911 + uint8_t size; /**< The number of bytes (<=16) to be replaced */
84912 + uint8_t mask; /**< Optional 1 byte mask. Set to select bits for
84913 + replacement (1 - bit will be replaced);
84914 + Clear to use field as is. */
84915 + uint8_t maskOffset; /**< Relevant if mask != 0;
84916 + Mask offset within the replaces "size" */
84917 +} t_FmPcdManipHdrCustomGenFieldReplace;
84918 +
84919 +/**************************************************************************//**
84920 + @Description Parameters for defining custom header manipulation for IP replacement
84921 +*//***************************************************************************/
84922 +typedef struct t_FmPcdManipHdrCustomIpHdrReplace {
84923 + e_FmPcdManipHdrCustomIpReplace replaceType; /**< Selects replace update type */
84924 + bool decTtlHl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
84925 + bool updateIpv4Id; /**< Relevant when replaceType =
84926 + e_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
84927 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
84928 + updateIpv4Id = TRUE */
84929 + uint8_t hdrSize; /**< The size of the new IP header */
84930 + uint8_t hdr[FM_PCD_MANIP_MAX_HDR_SIZE];
84931 + /**< The new IP header */
84932 +} t_FmPcdManipHdrCustomIpHdrReplace;
84933 +
84934 +/**************************************************************************//**
84935 + @Description Parameters for defining custom header manipulation
84936 +*//***************************************************************************/
84937 +typedef struct t_FmPcdManipHdrCustomParams {
84938 + e_FmPcdManipHdrCustomType type; /**< Type of header field update manipulation */
84939 + union {
84940 + t_FmPcdManipHdrCustomIpHdrReplace ipHdrReplace; /**< Parameters IP header replacement */
84941 + t_FmPcdManipHdrCustomGenFieldReplace genFieldReplace; /**< Parameters IP header replacement */
84942 + } u;
84943 +} t_FmPcdManipHdrCustomParams;
84944 +
84945 +/**************************************************************************//**
84946 + @Description Parameters for defining specific L2 insertion manipulation
84947 +*//***************************************************************************/
84948 +typedef struct t_FmPcdManipHdrInsrtSpecificL2Params {
84949 + e_FmPcdManipHdrInsrtSpecificL2 specificL2; /**< Selects which L2 headers to insert */
84950 + bool update; /**< TRUE to update MPLS header */
84951 + uint8_t size; /**< size of inserted section */
84952 + uint8_t *p_Data; /**< data to be inserted */
84953 +} t_FmPcdManipHdrInsrtSpecificL2Params;
84954 +
84955 +#if (DPAA_VERSION >= 11)
84956 +/**************************************************************************//**
84957 + @Description Parameters for defining IP insertion manipulation
84958 +*//***************************************************************************/
84959 +typedef struct t_FmPcdManipHdrInsrtIpParams {
84960 + bool calcL4Checksum; /**< Calculate L4 checksum. */
84961 + e_FmPcdManipHdrQosMappingMode mappingMode; /**< TODO */
84962 + uint8_t lastPidOffset; /**< the offset of the last Protocol within
84963 + the inserted header */
84964 + uint16_t id; /**< 16 bit New IP ID */
84965 + bool dontFragOverwrite;
84966 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
84967 + * This byte is configured to be overwritten when RPD is set. */
84968 + uint8_t lastDstOffset;
84969 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
84970 + * in order to calculate UDP checksum pseudo header;
84971 + * Otherwise set it to '0'. */
84972 + t_FmPcdManipHdrInsrt insrt; /**< size and data to be inserted. */
84973 +} t_FmPcdManipHdrInsrtIpParams;
84974 +#endif /* (DPAA_VERSION >= 11) */
84975 +
84976 +/**************************************************************************//**
84977 + @Description Parameters for defining header insertion manipulation by header type
84978 +*//***************************************************************************/
84979 +typedef struct t_FmPcdManipHdrInsrtByHdrParams {
84980 + e_FmPcdManipHdrInsrtByHdrType type; /**< Selects manipulation type */
84981 + union {
84982 +
84983 + t_FmPcdManipHdrInsrtSpecificL2Params specificL2Params;
84984 + /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
84985 + Selects which L2 headers to insert */
84986 +#if (DPAA_VERSION >= 11)
84987 + t_FmPcdManipHdrInsrtIpParams ipParams; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
84988 + t_FmPcdManipHdrInsrt insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
84989 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
84990 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
84991 +#endif /* (DPAA_VERSION >= 11) */
84992 + } u;
84993 +} t_FmPcdManipHdrInsrtByHdrParams;
84994 +
84995 +/**************************************************************************//**
84996 + @Description Parameters for defining header insertion manipulation
84997 +*//***************************************************************************/
84998 +typedef struct t_FmPcdManipHdrInsrtParams {
84999 + e_FmPcdManipHdrInsrtType type; /**< Type of insertion manipulation */
85000 + union {
85001 + t_FmPcdManipHdrInsrtByHdrParams byHdr; /**< Parameters for defining header insertion manipulation by header type,
85002 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_HDR */
85003 + t_FmPcdManipHdrInsrtGenericParams generic; /**< Parameters for defining generic header insertion manipulation,
85004 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_GENERIC */
85005 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
85006 + t_FmPcdManipHdrInsrtByTemplateParams byTemplate; /**< Parameters for defining header insertion manipulation by template,
85007 + relevant if 'type' = e_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
85008 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
85009 + } u;
85010 +} t_FmPcdManipHdrInsrtParams;
85011 +
85012 +/**************************************************************************//**
85013 + @Description Parameters for defining header removal manipulation
85014 +*//***************************************************************************/
85015 +typedef struct t_FmPcdManipHdrRmvParams {
85016 + e_FmPcdManipHdrRmvType type; /**< Type of header removal manipulation */
85017 + union {
85018 + t_FmPcdManipHdrRmvByHdrParams byHdr; /**< Parameters for defining header removal manipulation by header type,
85019 + relevant if type = e_FM_PCD_MANIP_RMV_BY_HDR */
85020 + t_FmPcdManipHdrRmvGenericParams generic; /**< Parameters for defining generic header removal manipulation,
85021 + relevant if type = e_FM_PCD_MANIP_RMV_GENERIC */
85022 + } u;
85023 +} t_FmPcdManipHdrRmvParams;
85024 +
85025 +/**************************************************************************//**
85026 + @Description Parameters for defining header manipulation node
85027 +*//***************************************************************************/
85028 +typedef struct t_FmPcdManipHdrParams {
85029 + bool rmv; /**< TRUE, to define removal manipulation */
85030 + t_FmPcdManipHdrRmvParams rmvParams; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
85031 +
85032 + bool insrt; /**< TRUE, to define insertion manipulation */
85033 + t_FmPcdManipHdrInsrtParams insrtParams; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
85034 +
85035 + bool fieldUpdate; /**< TRUE, to define field update manipulation */
85036 + t_FmPcdManipHdrFieldUpdateParams fieldUpdateParams; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
85037 +
85038 + bool custom; /**< TRUE, to define custom manipulation */
85039 + t_FmPcdManipHdrCustomParams customParams; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
85040 +
85041 + bool dontParseAfterManip;/**< TRUE to de-activate the parser after the manipulation defined in this node.
85042 + Restrictions:
85043 + 1. MUST be set if the next engine after the CC is not another CC node
85044 + (but rather Policer or Keygen), and this is the last (no h_NextManip) in a chain
85045 + of manipulation nodes. This includes single nodes (i.e. no h_NextManip and
85046 + also never pointed as h_NextManip of other manipulation nodes)
85047 + 2. MUST be set if the next engine after the CC is another CC node, and
85048 + this is NOT the last manipulation node (i.e. it has h_NextManip).*/
85049 +} t_FmPcdManipHdrParams;
85050 +
85051 +/**************************************************************************//**
85052 + @Description Parameters for defining fragmentation manipulation
85053 +*//***************************************************************************/
85054 +typedef struct t_FmPcdManipFragParams {
85055 + e_NetHeaderType hdr; /**< Header selection */
85056 + union {
85057 +#if (DPAA_VERSION >= 11)
85058 + t_FmPcdManipFragCapwapParams capwapFrag; /**< Parameters for defining CAPWAP fragmentation,
85059 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
85060 +#endif /* (DPAA_VERSION >= 11) */
85061 + t_FmPcdManipFragIpParams ipFrag; /**< Parameters for defining IP fragmentation,
85062 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
85063 + } u;
85064 +} t_FmPcdManipFragParams;
85065 +
85066 +/**************************************************************************//**
85067 + @Description Parameters for defining reassembly manipulation
85068 +*//***************************************************************************/
85069 +typedef struct t_FmPcdManipReassemParams {
85070 + e_NetHeaderType hdr; /**< Header selection */
85071 + union {
85072 +#if (DPAA_VERSION >= 11)
85073 + t_FmPcdManipReassemCapwapParams capwapReassem; /**< Parameters for defining CAPWAP reassembly,
85074 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
85075 +#endif /* (DPAA_VERSION >= 11) */
85076 +
85077 + t_FmPcdManipReassemIpParams ipReassem; /**< Parameters for defining IP reassembly,
85078 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
85079 + } u;
85080 +} t_FmPcdManipReassemParams;
85081 +
85082 +/**************************************************************************//**
85083 + @Description Parameters for defining a manipulation node
85084 +*//***************************************************************************/
85085 +typedef struct t_FmPcdManipParams {
85086 + e_FmPcdManipType type; /**< Selects type of manipulation node */
85087 + union{
85088 + t_FmPcdManipHdrParams hdr; /**< Parameters for defining header manipulation node */
85089 + t_FmPcdManipReassemParams reassem; /**< Parameters for defining reassembly manipulation node */
85090 + t_FmPcdManipFragParams frag; /**< Parameters for defining fragmentation manipulation node */
85091 + t_FmPcdManipSpecialOffloadParams specialOffload; /**< Parameters for defining special offload manipulation node */
85092 + } u;
85093 +
85094 + t_Handle h_NextManip; /**< Supported for Header Manipulation only;
85095 + Handle to another (previously defined) manipulation node;
85096 + Allows concatenation of manipulation actions;
85097 + This parameter is optional and may be NULL. */
85098 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
85099 + bool fragOrReasm; /**< TRUE, if defined fragmentation/reassembly manipulation */
85100 + t_FmPcdManipFragOrReasmParams fragOrReasmParams; /**< Parameters for fragmentation/reassembly manipulation,
85101 + relevant if fragOrReasm = TRUE */
85102 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
85103 +} t_FmPcdManipParams;
85104 +
85105 +/**************************************************************************//**
85106 + @Description Structure for retrieving IP reassembly statistics
85107 +*//***************************************************************************/
85108 +typedef struct t_FmPcdManipReassemIpStats {
85109 + /* common counters for both IPv4 and IPv6 */
85110 + uint32_t timeout; /**< Counts the number of timeout occurrences */
85111 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
85112 + a Reassembly Frame Descriptor */
85113 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
85114 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
85115 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
85116 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
85117 +#if (DPAA_VERSION >= 11)
85118 + uint32_t nonConsistentSp; /**< Counts the number of Non Consistent Storage Profile events for
85119 + successfully reassembled frames */
85120 +#endif /* (DPAA_VERSION >= 11) */
85121 + struct {
85122 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
85123 + uint32_t validFragments; /**< Counts the total number of valid fragments that
85124 + have been processed for all frames */
85125 + uint32_t processedFragments; /**< Counts the number of processed fragments
85126 + (valid and error fragments) for all frames */
85127 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
85128 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
85129 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
85130 + to access an IP-Reassembly Automatic Learning Hash set */
85131 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
85132 + exceeds 16 */
85133 + } specificHdrStatistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
85134 +} t_FmPcdManipReassemIpStats;
85135 +
85136 +/**************************************************************************//**
85137 + @Description Structure for retrieving IP fragmentation statistics
85138 +*//***************************************************************************/
85139 +typedef struct t_FmPcdManipFragIpStats {
85140 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
85141 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
85142 + uint32_t generatedFragments; /**< Number of fragments that were generated */
85143 +} t_FmPcdManipFragIpStats;
85144 +
85145 +#if (DPAA_VERSION >= 11)
85146 +/**************************************************************************//**
85147 + @Description Structure for retrieving CAPWAP reassembly statistics
85148 +*//***************************************************************************/
85149 +typedef struct t_FmPcdManipReassemCapwapStats {
85150 + uint32_t timeout; /**< Counts the number of timeout occurrences */
85151 + uint32_t rfdPoolBusy; /**< Counts the number of failed attempts to allocate
85152 + a Reassembly Frame Descriptor */
85153 + uint32_t internalBufferBusy; /**< Counts the number of times an internal buffer busy occurred */
85154 + uint32_t externalBufferBusy; /**< Counts the number of times external buffer busy occurred */
85155 + uint32_t sgFragments; /**< Counts the number of Scatter/Gather fragments */
85156 + uint32_t dmaSemaphoreDepletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
85157 + uint32_t successfullyReassembled; /**< Counts the number of successfully reassembled frames */
85158 + uint32_t validFragments; /**< Counts the total number of valid fragments that
85159 + have been processed for all frames */
85160 + uint32_t processedFragments; /**< Counts the number of processed fragments
85161 + (valid and error fragments) for all frames */
85162 + uint32_t malformedFragments; /**< Counts the number of malformed fragments processed for all frames */
85163 + uint32_t autoLearnBusy; /**< Counts the number of times a busy condition occurs when attempting
85164 + to access an Reassembly Automatic Learning Hash set */
85165 + uint32_t discardedFragments; /**< Counts the number of fragments discarded by the reassembly process */
85166 + uint32_t moreThan16Fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
85167 + exceeds 16 */
85168 + uint32_t exceedMaxReassemblyFrameLen;/**< ounts the number of times that a successful reassembled frame
85169 + length exceeds MaxReassembledFrameLength value */
85170 +} t_FmPcdManipReassemCapwapStats;
85171 +
85172 +/**************************************************************************//**
85173 + @Description Structure for retrieving CAPWAP fragmentation statistics
85174 +*//***************************************************************************/
85175 +typedef struct t_FmPcdManipFragCapwapStats {
85176 + uint32_t totalFrames; /**< Number of frames that passed through the manipulation node */
85177 + uint32_t fragmentedFrames; /**< Number of frames that were fragmented */
85178 + uint32_t generatedFragments; /**< Number of fragments that were generated */
85179 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
85180 + uint8_t sgAllocationFailure; /**< Number of allocation failure of s/g buffers */
85181 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
85182 +} t_FmPcdManipFragCapwapStats;
85183 +#endif /* (DPAA_VERSION >= 11) */
85184 +
85185 +/**************************************************************************//**
85186 + @Description Structure for retrieving reassembly statistics
85187 +*//***************************************************************************/
85188 +typedef struct t_FmPcdManipReassemStats {
85189 + union {
85190 + t_FmPcdManipReassemIpStats ipReassem; /**< Structure for IP reassembly statistics */
85191 +#if (DPAA_VERSION >= 11)
85192 + t_FmPcdManipReassemCapwapStats capwapReassem; /**< Structure for CAPWAP reassembly statistics */
85193 +#endif /* (DPAA_VERSION >= 11) */
85194 + } u;
85195 +} t_FmPcdManipReassemStats;
85196 +
85197 +/**************************************************************************//**
85198 + @Description Structure for retrieving fragmentation statistics
85199 +*//***************************************************************************/
85200 +typedef struct t_FmPcdManipFragStats {
85201 + union {
85202 + t_FmPcdManipFragIpStats ipFrag; /**< Structure for IP fragmentation statistics */
85203 +#if (DPAA_VERSION >= 11)
85204 + t_FmPcdManipFragCapwapStats capwapFrag; /**< Structure for CAPWAP fragmentation statistics */
85205 +#endif /* (DPAA_VERSION >= 11) */
85206 + } u;
85207 +} t_FmPcdManipFragStats;
85208 +
85209 +/**************************************************************************//**
85210 + @Description Structure for selecting manipulation statistics
85211 +*//***************************************************************************/
85212 +typedef struct t_FmPcdManipStats {
85213 + union {
85214 + t_FmPcdManipReassemStats reassem; /**< Structure for reassembly statistics */
85215 + t_FmPcdManipFragStats frag; /**< Structure for fragmentation statistics */
85216 + } u;
85217 +} t_FmPcdManipStats;
85218 +
85219 +#if (DPAA_VERSION >= 11)
85220 +/**************************************************************************//**
85221 + @Description Parameters for defining frame replicator group and its members
85222 +*//***************************************************************************/
85223 +typedef struct t_FmPcdFrmReplicGroupParams {
85224 + uint8_t maxNumOfEntries; /**< Maximal number of members in the group;
85225 + Must be at least 2. */
85226 + uint8_t numOfEntries; /**< Number of members in the group;
85227 + Must be at least 1. */
85228 + t_FmPcdCcNextEngineParams nextEngineParams[FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
85229 + /**< Array of members' parameters */
85230 +} t_FmPcdFrmReplicGroupParams;
85231 +#endif /* (DPAA_VERSION >= 11) */
85232 +
85233 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
85234 +/**************************************************************************//**
85235 + @Description structure for defining statistics node
85236 +*//***************************************************************************/
85237 +typedef struct t_FmPcdStatsParams {
85238 + e_FmPcdStatsType type; /**< type of statistics node */
85239 +} t_FmPcdStatsParams;
85240 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
85241 +
85242 +/**************************************************************************//**
85243 + @Function FM_PCD_NetEnvCharacteristicsSet
85244 +
85245 + @Description Define a set of Network Environment Characteristics.
85246 +
85247 + When setting an environment it is important to understand its
85248 + application. It is not meant to describe the flows that will run
85249 + on the ports using this environment, but what the user means TO DO
85250 + with the PCD mechanisms in order to parse-classify-distribute those
85251 + frames.
85252 + By specifying a distinction unit, the user means it would use that option
85253 + for distinction between frames at either a KeyGen scheme or a coarse
85254 + classification action descriptor. Using interchangeable headers to define a
85255 + unit means that the user is indifferent to which of the interchangeable
85256 + headers is present in the frame, and wants the distinction to be based
85257 + on the presence of either one of them.
85258 +
85259 + Depending on context, there are limitations to the use of environments. A
85260 + port using the PCD functionality is bound to an environment. Some or even
85261 + all ports may share an environment but also an environment per port is
85262 + possible. When initializing a scheme, a classification plan group (see below),
85263 + or a coarse classification tree, one of the initialized environments must be
85264 + stated and related to. When a port is bound to a scheme, a classification
85265 + plan group, or a coarse classification tree, it MUST be bound to the same
85266 + environment.
85267 +
85268 + The different PCD modules, may relate (for flows definition) ONLY on
85269 + distinction units as defined by their environment. When initializing a
85270 + scheme for example, it may not choose to select IPV4 as a match for
85271 + recognizing flows unless it was defined in the relating environment. In
85272 + fact, to guide the user through the configuration of the PCD, each module's
85273 + characterization in terms of flows is not done using protocol names, but using
85274 + environment indexes.
85275 +
85276 + In terms of HW implementation, the list of distinction units sets the LCV vectors
85277 + and later used for match vector, classification plan vectors and coarse classification
85278 + indexing.
85279 +
85280 + @Param[in] h_FmPcd FM PCD module descriptor.
85281 + @Param[in] p_NetEnvParams A structure of parameters for the initialization of
85282 + the network environment.
85283 +
85284 + @Return A handle to the initialized object on success; NULL code otherwise.
85285 +
85286 + @Cautions Allowed only following FM_PCD_Init().
85287 +*//***************************************************************************/
85288 +t_Handle FM_PCD_NetEnvCharacteristicsSet(t_Handle h_FmPcd, t_FmPcdNetEnvParams *p_NetEnvParams);
85289 +
85290 +/**************************************************************************//**
85291 + @Function FM_PCD_NetEnvCharacteristicsDelete
85292 +
85293 + @Description Deletes a set of Network Environment Characteristics.
85294 +
85295 + @Param[in] h_NetEnv A handle to the Network environment.
85296 +
85297 + @Return E_OK on success; Error code otherwise.
85298 +*//***************************************************************************/
85299 +t_Error FM_PCD_NetEnvCharacteristicsDelete(t_Handle h_NetEnv);
85300 +
85301 +/**************************************************************************//**
85302 + @Function FM_PCD_KgSchemeSet
85303 +
85304 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
85305 + This routine should be called for adding or modifying a scheme.
85306 + When a scheme needs modifying, the API requires that it will be
85307 + rewritten. In such a case 'modify' should be TRUE. If the
85308 + routine is called for a valid scheme and 'modify' is FALSE,
85309 + it will return error.
85310 +
85311 + @Param[in] h_FmPcd If this is a new scheme - A handle to an FM PCD Module.
85312 + Otherwise NULL (ignored by driver).
85313 + @Param[in,out] p_SchemeParams A structure of parameters for defining the scheme
85314 +
85315 + @Return A handle to the initialized scheme on success; NULL code otherwise.
85316 + When used as "modify" (rather than for setting a new scheme),
85317 + p_SchemeParams->id.h_Scheme will return NULL if action fails due to scheme
85318 + BUSY state.
85319 +
85320 + @Cautions Allowed only following FM_PCD_Init().
85321 +*//***************************************************************************/
85322 +t_Handle FM_PCD_KgSchemeSet(t_Handle h_FmPcd,
85323 + t_FmPcdKgSchemeParams *p_SchemeParams);
85324 +
85325 +/**************************************************************************//**
85326 + @Function FM_PCD_KgSchemeDelete
85327 +
85328 + @Description Deleting an initialized scheme.
85329 +
85330 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet()
85331 +
85332 + @Return E_OK on success; Error code otherwise.
85333 +
85334 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
85335 +*//***************************************************************************/
85336 +t_Error FM_PCD_KgSchemeDelete(t_Handle h_Scheme);
85337 +
85338 +/**************************************************************************//**
85339 + @Function FM_PCD_KgSchemeGetCounter
85340 +
85341 + @Description Reads scheme packet counter.
85342 +
85343 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
85344 +
85345 + @Return Counter's current value.
85346 +
85347 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
85348 +*//***************************************************************************/
85349 +uint32_t FM_PCD_KgSchemeGetCounter(t_Handle h_Scheme);
85350 +
85351 +/**************************************************************************//**
85352 + @Function FM_PCD_KgSchemeSetCounter
85353 +
85354 + @Description Writes scheme packet counter.
85355 +
85356 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
85357 + @Param[in] value New scheme counter value - typically '0' for
85358 + resetting the counter.
85359 +
85360 + @Return E_OK on success; Error code otherwise.
85361 +
85362 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
85363 +*//***************************************************************************/
85364 +t_Error FM_PCD_KgSchemeSetCounter(t_Handle h_Scheme, uint32_t value);
85365 +
85366 +/**************************************************************************//**
85367 + @Function FM_PCD_PlcrProfileSet
85368 +
85369 + @Description Sets a profile entry in the policer profile table.
85370 + The routine overrides any existing value.
85371 +
85372 + @Param[in] h_FmPcd A handle to an FM PCD Module.
85373 + @Param[in] p_Profile A structure of parameters for defining a
85374 + policer profile entry.
85375 +
85376 + @Return A handle to the initialized object on success; NULL code otherwise.
85377 + When used as "modify" (rather than for setting a new profile),
85378 + p_Profile->id.h_Profile will return NULL if action fails due to profile
85379 + BUSY state.
85380 + @Cautions Allowed only following FM_PCD_Init().
85381 +*//***************************************************************************/
85382 +t_Handle FM_PCD_PlcrProfileSet(t_Handle h_FmPcd,
85383 + t_FmPcdPlcrProfileParams *p_Profile);
85384 +
85385 +/**************************************************************************//**
85386 + @Function FM_PCD_PlcrProfileDelete
85387 +
85388 + @Description Delete a profile entry in the policer profile table.
85389 + The routine set entry to invalid.
85390 +
85391 + @Param[in] h_Profile A handle to the profile.
85392 +
85393 + @Return E_OK on success; Error code otherwise.
85394 +
85395 + @Cautions Allowed only following FM_PCD_Init().
85396 +*//***************************************************************************/
85397 +t_Error FM_PCD_PlcrProfileDelete(t_Handle h_Profile);
85398 +
85399 +/**************************************************************************//**
85400 + @Function FM_PCD_PlcrProfileGetCounter
85401 +
85402 + @Description Sets an entry in the classification plan.
85403 + The routine overrides any existing value.
85404 +
85405 + @Param[in] h_Profile A handle to the profile.
85406 + @Param[in] counter Counter selector.
85407 +
85408 + @Return specific counter value.
85409 +
85410 + @Cautions Allowed only following FM_PCD_Init().
85411 +*//***************************************************************************/
85412 +uint32_t FM_PCD_PlcrProfileGetCounter(t_Handle h_Profile,
85413 + e_FmPcdPlcrProfileCounters counter);
85414 +
85415 +/**************************************************************************//**
85416 + @Function FM_PCD_PlcrProfileSetCounter
85417 +
85418 + @Description Sets an entry in the classification plan.
85419 + The routine overrides any existing value.
85420 +
85421 + @Param[in] h_Profile A handle to the profile.
85422 + @Param[in] counter Counter selector.
85423 + @Param[in] value value to set counter with.
85424 +
85425 + @Return E_OK on success; Error code otherwise.
85426 +
85427 + @Cautions Allowed only following FM_PCD_Init().
85428 +*//***************************************************************************/
85429 +t_Error FM_PCD_PlcrProfileSetCounter(t_Handle h_Profile,
85430 + e_FmPcdPlcrProfileCounters counter,
85431 + uint32_t value);
85432 +
85433 +/**************************************************************************//**
85434 + @Function FM_PCD_CcRootBuild
85435 +
85436 + @Description This routine must be called to define a complete coarse
85437 + classification tree. This is the way to define coarse
85438 + classification to a certain flow - the KeyGen schemes
85439 + may point only to trees defined in this way.
85440 +
85441 + @Param[in] h_FmPcd FM PCD module descriptor.
85442 + @Param[in] p_Params A structure of parameters to define the tree.
85443 +
85444 + @Return A handle to the initialized object on success; NULL code otherwise.
85445 +
85446 + @Cautions Allowed only following FM_PCD_Init().
85447 +*//***************************************************************************/
85448 +t_Handle FM_PCD_CcRootBuild (t_Handle h_FmPcd,
85449 + t_FmPcdCcTreeParams *p_Params);
85450 +
85451 +/**************************************************************************//**
85452 + @Function FM_PCD_CcRootDelete
85453 +
85454 + @Description Deleting an built tree.
85455 +
85456 + @Param[in] h_CcTree A handle to a CC tree.
85457 +
85458 + @Return E_OK on success; Error code otherwise.
85459 +
85460 + @Cautions Allowed only following FM_PCD_Init().
85461 +*//***************************************************************************/
85462 +t_Error FM_PCD_CcRootDelete(t_Handle h_CcTree);
85463 +
85464 +/**************************************************************************//**
85465 + @Function FM_PCD_CcRootModifyNextEngine
85466 +
85467 + @Description Modify the Next Engine Parameters in the entry of the tree.
85468 +
85469 + @Param[in] h_CcTree A handle to the tree
85470 + @Param[in] grpId A Group index in the tree
85471 + @Param[in] index Entry index in the group defined by grpId
85472 + @Param[in] p_FmPcdCcNextEngineParams Pointer to new next engine parameters
85473 +
85474 + @Return E_OK on success; Error code otherwise.
85475 +
85476 + @Cautions Allowed only following FM_PCD_CcBuildTree().
85477 +*//***************************************************************************/
85478 +t_Error FM_PCD_CcRootModifyNextEngine(t_Handle h_CcTree,
85479 + uint8_t grpId,
85480 + uint8_t index,
85481 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85482 +
85483 +/**************************************************************************//**
85484 + @Function FM_PCD_MatchTableSet
85485 +
85486 + @Description This routine should be called for each CC (coarse classification)
85487 + node. The whole CC tree should be built bottom up so that each
85488 + node points to already defined nodes.
85489 +
85490 + @Param[in] h_FmPcd FM PCD module descriptor.
85491 + @Param[in] p_Param A structure of parameters defining the CC node
85492 +
85493 + @Return A handle to the initialized object on success; NULL code otherwise.
85494 +
85495 + @Cautions Allowed only following FM_PCD_Init().
85496 +*//***************************************************************************/
85497 +t_Handle FM_PCD_MatchTableSet(t_Handle h_FmPcd, t_FmPcdCcNodeParams *p_Param);
85498 +
85499 +/**************************************************************************//**
85500 + @Function FM_PCD_MatchTableDelete
85501 +
85502 + @Description Deleting an built node.
85503 +
85504 + @Param[in] h_CcNode A handle to a CC node.
85505 +
85506 + @Return E_OK on success; Error code otherwise.
85507 +
85508 + @Cautions Allowed only following FM_PCD_Init().
85509 +*//***************************************************************************/
85510 +t_Error FM_PCD_MatchTableDelete(t_Handle h_CcNode);
85511 +
85512 +/**************************************************************************//**
85513 + @Function FM_PCD_MatchTableModifyMissNextEngine
85514 +
85515 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
85516 +
85517 + @Param[in] h_CcNode A handle to the node
85518 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
85519 +
85520 + @Return E_OK on success; Error code otherwise.
85521 +
85522 + @Cautions Allowed only following FM_PCD_MatchTableSet();
85523 + Not relevant in the case the node is of type 'INDEXED_LOOKUP'.
85524 + When configuring nextEngine = e_FM_PCD_CC, note that
85525 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85526 + from the currently changed table.
85527 +
85528 +*//***************************************************************************/
85529 +t_Error FM_PCD_MatchTableModifyMissNextEngine(t_Handle h_CcNode,
85530 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85531 +
85532 +/**************************************************************************//**
85533 + @Function FM_PCD_MatchTableRemoveKey
85534 +
85535 + @Description Remove the key (including next engine parameters of this key)
85536 + defined by the index of the relevant node.
85537 +
85538 + @Param[in] h_CcNode A handle to the node
85539 + @Param[in] keyIndex Key index for removing
85540 +
85541 + @Return E_OK on success; Error code otherwise.
85542 +
85543 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85544 + node and the nodes that lead to it.
85545 +*//***************************************************************************/
85546 +t_Error FM_PCD_MatchTableRemoveKey(t_Handle h_CcNode, uint16_t keyIndex);
85547 +
85548 +/**************************************************************************//**
85549 + @Function FM_PCD_MatchTableAddKey
85550 +
85551 + @Description Add the key (including next engine parameters of this key in the
85552 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
85553 + may be used by user that don't care about the position of the
85554 + key in the table - in that case, the key will be automatically
85555 + added by the driver in the last available entry.
85556 +
85557 + @Param[in] h_CcNode A handle to the node
85558 + @Param[in] keyIndex Key index for adding.
85559 + @Param[in] keySize Key size of added key
85560 + @Param[in] p_KeyParams A pointer to the parameters includes
85561 + new key with Next Engine Parameters
85562 +
85563 + @Return E_OK on success; Error code otherwise.
85564 +
85565 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85566 + node and the nodes that lead to it.
85567 +*//***************************************************************************/
85568 +t_Error FM_PCD_MatchTableAddKey(t_Handle h_CcNode,
85569 + uint16_t keyIndex,
85570 + uint8_t keySize,
85571 + t_FmPcdCcKeyParams *p_KeyParams);
85572 +
85573 +/**************************************************************************//**
85574 + @Function FM_PCD_MatchTableModifyNextEngine
85575 +
85576 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
85577 +
85578 + @Param[in] h_CcNode A handle to the node
85579 + @Param[in] keyIndex Key index for Next Engine modifications
85580 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
85581 +
85582 + @Return E_OK on success; Error code otherwise.
85583 +
85584 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85585 + When configuring nextEngine = e_FM_PCD_CC, note that
85586 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85587 + from the currently changed table.
85588 +
85589 +*//***************************************************************************/
85590 +t_Error FM_PCD_MatchTableModifyNextEngine(t_Handle h_CcNode,
85591 + uint16_t keyIndex,
85592 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85593 +
85594 +/**************************************************************************//**
85595 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
85596 +
85597 + @Description Modify the key and Next Engine Parameters of this key in the
85598 + index defined by the keyIndex.
85599 +
85600 + @Param[in] h_CcNode A handle to the node
85601 + @Param[in] keyIndex Key index for adding
85602 + @Param[in] keySize Key size of added key
85603 + @Param[in] p_KeyParams A pointer to the parameters includes
85604 + modified key and modified Next Engine Parameters
85605 +
85606 + @Return E_OK on success; Error code otherwise.
85607 +
85608 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85609 + node and the nodes that lead to it.
85610 + When configuring nextEngine = e_FM_PCD_CC, note that
85611 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85612 + from the currently changed table.
85613 +*//***************************************************************************/
85614 +t_Error FM_PCD_MatchTableModifyKeyAndNextEngine(t_Handle h_CcNode,
85615 + uint16_t keyIndex,
85616 + uint8_t keySize,
85617 + t_FmPcdCcKeyParams *p_KeyParams);
85618 +
85619 +/**************************************************************************//**
85620 + @Function FM_PCD_MatchTableModifyKey
85621 +
85622 + @Description Modify the key in the index defined by the keyIndex.
85623 +
85624 + @Param[in] h_CcNode A handle to the node
85625 + @Param[in] keyIndex Key index for adding
85626 + @Param[in] keySize Key size of added key
85627 + @Param[in] p_Key A pointer to the new key
85628 + @Param[in] p_Mask A pointer to the new mask if relevant,
85629 + otherwise pointer to NULL
85630 +
85631 + @Return E_OK on success; Error code otherwise.
85632 +
85633 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85634 + node and the nodes that lead to it.
85635 +*//***************************************************************************/
85636 +t_Error FM_PCD_MatchTableModifyKey(t_Handle h_CcNode,
85637 + uint16_t keyIndex,
85638 + uint8_t keySize,
85639 + uint8_t *p_Key,
85640 + uint8_t *p_Mask);
85641 +
85642 +/**************************************************************************//**
85643 + @Function FM_PCD_MatchTableFindNRemoveKey
85644 +
85645 + @Description Remove the key (including next engine parameters of this key)
85646 + defined by the key and mask. Note that this routine will search
85647 + the node to locate the index of the required key (& mask) to remove.
85648 +
85649 + @Param[in] h_CcNode A handle to the node
85650 + @Param[in] keySize Key size of the one to remove.
85651 + @Param[in] p_Key A pointer to the requested key to remove.
85652 + @Param[in] p_Mask A pointer to the mask if relevant,
85653 + otherwise pointer to NULL
85654 +
85655 + @Return E_OK on success; Error code otherwise.
85656 +
85657 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85658 + node and the nodes that lead to it.
85659 +*//***************************************************************************/
85660 +t_Error FM_PCD_MatchTableFindNRemoveKey(t_Handle h_CcNode,
85661 + uint8_t keySize,
85662 + uint8_t *p_Key,
85663 + uint8_t *p_Mask);
85664 +
85665 +/**************************************************************************//**
85666 + @Function FM_PCD_MatchTableFindNModifyNextEngine
85667 +
85668 + @Description Modify the Next Engine Parameters in the relevant key entry of
85669 + the node. Note that this routine will search the node to locate
85670 + the index of the required key (& mask) to modify.
85671 +
85672 + @Param[in] h_CcNode A handle to the node
85673 + @Param[in] keySize Key size of the one to modify.
85674 + @Param[in] p_Key A pointer to the requested key to modify.
85675 + @Param[in] p_Mask A pointer to the mask if relevant,
85676 + otherwise pointer to NULL
85677 + @Param[in] p_FmPcdCcNextEngineParams Parameters for defining next engine
85678 +
85679 + @Return E_OK on success; Error code otherwise.
85680 +
85681 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85682 + When configuring nextEngine = e_FM_PCD_CC, note that
85683 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85684 + from the currently changed table.
85685 +*//***************************************************************************/
85686 +t_Error FM_PCD_MatchTableFindNModifyNextEngine(t_Handle h_CcNode,
85687 + uint8_t keySize,
85688 + uint8_t *p_Key,
85689 + uint8_t *p_Mask,
85690 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85691 +
85692 +/**************************************************************************//**
85693 + @Function FM_PCD_MatchTableFindNModifyKeyAndNextEngine
85694 +
85695 + @Description Modify the key and Next Engine Parameters of this key in the
85696 + index defined by the keyIndex. Note that this routine will search
85697 + the node to locate the index of the required key (& mask) to modify.
85698 +
85699 + @Param[in] h_CcNode A handle to the node
85700 + @Param[in] keySize Key size of the one to modify.
85701 + @Param[in] p_Key A pointer to the requested key to modify.
85702 + @Param[in] p_Mask A pointer to the mask if relevant,
85703 + otherwise pointer to NULL
85704 + @Param[in] p_KeyParams A pointer to the parameters includes
85705 + modified key and modified Next Engine Parameters
85706 +
85707 + @Return E_OK on success; Error code otherwise.
85708 +
85709 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85710 + node and the nodes that lead to it.
85711 + When configuring nextEngine = e_FM_PCD_CC, note that
85712 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85713 + from the currently changed table.
85714 +*//***************************************************************************/
85715 +t_Error FM_PCD_MatchTableFindNModifyKeyAndNextEngine(t_Handle h_CcNode,
85716 + uint8_t keySize,
85717 + uint8_t *p_Key,
85718 + uint8_t *p_Mask,
85719 + t_FmPcdCcKeyParams *p_KeyParams);
85720 +
85721 +/**************************************************************************//**
85722 + @Function FM_PCD_MatchTableFindNModifyKey
85723 +
85724 + @Description Modify the key in the index defined by the keyIndex. Note that
85725 + this routine will search the node to locate the index of the
85726 + required key (& mask) to modify.
85727 +
85728 + @Param[in] h_CcNode A handle to the node
85729 + @Param[in] keySize Key size of the one to modify.
85730 + @Param[in] p_Key A pointer to the requested key to modify.
85731 + @Param[in] p_Mask A pointer to the mask if relevant,
85732 + otherwise pointer to NULL
85733 + @Param[in] p_NewKey A pointer to the new key
85734 + @Param[in] p_NewMask A pointer to the new mask if relevant,
85735 + otherwise pointer to NULL
85736 +
85737 + @Return E_OK on success; Error code otherwise.
85738 +
85739 + @Cautions Allowed only following FM_PCD_MatchTableSet() was called for this
85740 + node and the nodes that lead to it.
85741 +*//***************************************************************************/
85742 +t_Error FM_PCD_MatchTableFindNModifyKey(t_Handle h_CcNode,
85743 + uint8_t keySize,
85744 + uint8_t *p_Key,
85745 + uint8_t *p_Mask,
85746 + uint8_t *p_NewKey,
85747 + uint8_t *p_NewMask);
85748 +
85749 +/**************************************************************************//**
85750 + @Function FM_PCD_MatchTableGetKeyCounter
85751 +
85752 + @Description This routine may be used to get a counter of specific key in a CC
85753 + Node; This counter reflects how many frames passed that were matched
85754 + this key.
85755 +
85756 + @Param[in] h_CcNode A handle to the node
85757 + @Param[in] keyIndex Key index for adding
85758 +
85759 + @Return The specific key counter.
85760 +
85761 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85762 +*//***************************************************************************/
85763 +uint32_t FM_PCD_MatchTableGetKeyCounter(t_Handle h_CcNode, uint16_t keyIndex);
85764 +
85765 +/**************************************************************************//**
85766 + @Function FM_PCD_MatchTableGetKeyStatistics
85767 +
85768 + @Description This routine may be used to get statistics counters of specific key
85769 + in a CC Node.
85770 +
85771 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
85772 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
85773 + these counters reflect how many frames passed that were matched
85774 + this key; The total frames count will be returned in the counter
85775 + of the first range (as only one frame length range was defined).
85776 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
85777 + frame count will be separated to frame length counters, based on
85778 + provided frame length ranges.
85779 +
85780 + @Param[in] h_CcNode A handle to the node
85781 + @Param[in] keyIndex Key index for adding
85782 + @Param[out] p_KeyStatistics Key statistics counters
85783 +
85784 + @Return The specific key statistics.
85785 +
85786 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85787 +*//***************************************************************************/
85788 +t_Error FM_PCD_MatchTableGetKeyStatistics(t_Handle h_CcNode,
85789 + uint16_t keyIndex,
85790 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
85791 +
85792 +/**************************************************************************//**
85793 + @Function FM_PCD_MatchTableGetMissStatistics
85794 +
85795 + @Description This routine may be used to get statistics counters of miss entry
85796 + in a CC Node.
85797 +
85798 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
85799 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
85800 + these counters reflect how many frames were not matched to any
85801 + existing key and therefore passed through the miss entry; The
85802 + total frames count will be returned in the counter of the
85803 + first range (as only one frame length range was defined).
85804 +
85805 + @Param[in] h_CcNode A handle to the node
85806 + @Param[out] p_MissStatistics Statistics counters for 'miss'
85807 +
85808 + @Return The statistics for 'miss'.
85809 +
85810 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85811 +*//***************************************************************************/
85812 +t_Error FM_PCD_MatchTableGetMissStatistics(t_Handle h_CcNode,
85813 + t_FmPcdCcKeyStatistics *p_MissStatistics);
85814 +
85815 +/**************************************************************************//**
85816 + @Function FM_PCD_MatchTableFindNGetKeyStatistics
85817 +
85818 + @Description This routine may be used to get statistics counters of specific key
85819 + in a CC Node.
85820 +
85821 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
85822 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
85823 + these counters reflect how many frames passed that were matched
85824 + this key; The total frames count will be returned in the counter
85825 + of the first range (as only one frame length range was defined).
85826 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
85827 + frame count will be separated to frame length counters, based on
85828 + provided frame length ranges.
85829 + Note that this routine will search the node to locate the index
85830 + of the required key based on received key parameters.
85831 +
85832 + @Param[in] h_CcNode A handle to the node
85833 + @Param[in] keySize Size of the requested key
85834 + @Param[in] p_Key A pointer to the requested key
85835 + @Param[in] p_Mask A pointer to the mask if relevant,
85836 + otherwise pointer to NULL
85837 + @Param[out] p_KeyStatistics Key statistics counters
85838 +
85839 + @Return The specific key statistics.
85840 +
85841 + @Cautions Allowed only following FM_PCD_MatchTableSet().
85842 +*//***************************************************************************/
85843 +t_Error FM_PCD_MatchTableFindNGetKeyStatistics(t_Handle h_CcNode,
85844 + uint8_t keySize,
85845 + uint8_t *p_Key,
85846 + uint8_t *p_Mask,
85847 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
85848 +
85849 +/**************************************************************************//*
85850 + @Function FM_PCD_MatchTableGetNextEngine
85851 +
85852 + @Description Gets NextEngine of the relevant keyIndex.
85853 +
85854 + @Param[in] h_CcNode A handle to the node.
85855 + @Param[in] keyIndex keyIndex in the relevant node.
85856 + @Param[out] p_FmPcdCcNextEngineParams here updated nextEngine parameters for
85857 + the relevant keyIndex of the CC Node
85858 + received as parameter to this function
85859 +
85860 + @Return E_OK on success; Error code otherwise.
85861 +
85862 + @Cautions Allowed only following FM_PCD_Init().
85863 +*//***************************************************************************/
85864 +t_Error FM_PCD_MatchTableGetNextEngine(t_Handle h_CcNode,
85865 + uint16_t keyIndex,
85866 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
85867 +
85868 +/**************************************************************************//*
85869 + @Function FM_PCD_MatchTableGetIndexedHashBucket
85870 +
85871 + @Description This routine simulates KeyGen operation on the provided key and
85872 + calculates to which hash bucket it will be mapped.
85873 +
85874 + @Param[in] h_CcNode A handle to the node.
85875 + @Param[in] kgKeySize Key size as it was configured in the KG
85876 + scheme that leads to this hash.
85877 + @Param[in] p_KgKey Pointer to the key; must be like the key
85878 + that the KG is generated, i.e. the same
85879 + extraction and with mask if exist.
85880 + @Param[in] kgHashShift Hash-shift as it was configured in the KG
85881 + scheme that leads to this hash.
85882 + @Param[out] p_CcNodeBucketHandle Pointer to the bucket of the provided key.
85883 + @Param[out] p_BucketIndex Index to the bucket of the provided key
85884 + @Param[out] p_LastIndex Pointer to last index in the bucket of the
85885 + provided key.
85886 +
85887 + @Return E_OK on success; Error code otherwise.
85888 +
85889 + @Cautions Allowed only following FM_PCD_HashTableSet()
85890 +*//***************************************************************************/
85891 +t_Error FM_PCD_MatchTableGetIndexedHashBucket(t_Handle h_CcNode,
85892 + uint8_t kgKeySize,
85893 + uint8_t *p_KgKey,
85894 + uint8_t kgHashShift,
85895 + t_Handle *p_CcNodeBucketHandle,
85896 + uint8_t *p_BucketIndex,
85897 + uint16_t *p_LastIndex);
85898 +
85899 +/**************************************************************************//**
85900 + @Function FM_PCD_HashTableSet
85901 +
85902 + @Description This routine initializes a hash table structure.
85903 + KeyGen hash result determines the hash bucket.
85904 + Next, KeyGen key is compared against all keys of this
85905 + bucket (exact match).
85906 + Number of sets (number of buckets) of the hash equals to the
85907 + number of 1-s in 'hashResMask' in the provided parameters.
85908 + Number of hash table ways is then calculated by dividing
85909 + 'maxNumOfKeys' equally between the hash sets. This is the maximal
85910 + number of keys that a hash bucket may hold.
85911 + The hash table is initialized empty and keys may be
85912 + added to it following the initialization. Keys masks are not
85913 + supported in current hash table implementation.
85914 + The initialized hash table can be integrated as a node in a
85915 + CC tree.
85916 +
85917 + @Param[in] h_FmPcd FM PCD module descriptor.
85918 + @Param[in] p_Param A structure of parameters defining the hash table
85919 +
85920 + @Return A handle to the initialized object on success; NULL code otherwise.
85921 +
85922 + @Cautions Allowed only following FM_PCD_Init().
85923 +*//***************************************************************************/
85924 +t_Handle FM_PCD_HashTableSet(t_Handle h_FmPcd, t_FmPcdHashTableParams *p_Param);
85925 +
85926 +/**************************************************************************//**
85927 + @Function FM_PCD_HashTableDelete
85928 +
85929 + @Description This routine deletes the provided hash table and released all
85930 + its allocated resources.
85931 +
85932 + @Param[in] h_HashTbl A handle to a hash table
85933 +
85934 + @Return E_OK on success; Error code otherwise.
85935 +
85936 + @Cautions Allowed only following FM_PCD_HashTableSet().
85937 +*//***************************************************************************/
85938 +t_Error FM_PCD_HashTableDelete(t_Handle h_HashTbl);
85939 +
85940 +/**************************************************************************//**
85941 + @Function FM_PCD_HashTableAddKey
85942 +
85943 + @Description This routine adds the provided key (including next engine
85944 + parameters of this key) to the hash table.
85945 + The key is added as the last key of the bucket that it is
85946 + mapped to.
85947 +
85948 + @Param[in] h_HashTbl A handle to a hash table
85949 + @Param[in] keySize Key size of added key
85950 + @Param[in] p_KeyParams A pointer to the parameters includes
85951 + new key with next engine parameters; The pointer
85952 + to the key mask must be NULL, as masks are not
85953 + supported in hash table implementation.
85954 +
85955 + @Return E_OK on success; Error code otherwise.
85956 +
85957 + @Cautions Allowed only following FM_PCD_HashTableSet().
85958 +*//***************************************************************************/
85959 +t_Error FM_PCD_HashTableAddKey(t_Handle h_HashTbl,
85960 + uint8_t keySize,
85961 + t_FmPcdCcKeyParams *p_KeyParams);
85962 +
85963 +/**************************************************************************//**
85964 + @Function FM_PCD_HashTableRemoveKey
85965 +
85966 + @Description This routine removes the requested key (including next engine
85967 + parameters of this key) from the hash table.
85968 +
85969 + @Param[in] h_HashTbl A handle to a hash table
85970 + @Param[in] keySize Key size of the one to remove.
85971 + @Param[in] p_Key A pointer to the requested key to remove.
85972 +
85973 + @Return E_OK on success; Error code otherwise.
85974 +
85975 + @Cautions Allowed only following FM_PCD_HashTableSet().
85976 +*//***************************************************************************/
85977 +t_Error FM_PCD_HashTableRemoveKey(t_Handle h_HashTbl,
85978 + uint8_t keySize,
85979 + uint8_t *p_Key);
85980 +
85981 +/**************************************************************************//**
85982 + @Function FM_PCD_HashTableModifyNextEngine
85983 +
85984 + @Description This routine modifies the next engine for the provided key. The
85985 + key should be previously added to the hash table.
85986 +
85987 + @Param[in] h_HashTbl A handle to a hash table
85988 + @Param[in] keySize Key size of the key to modify.
85989 + @Param[in] p_Key A pointer to the requested key to modify.
85990 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
85991 + parameters.
85992 +
85993 + @Return E_OK on success; Error code otherwise.
85994 +
85995 + @Cautions Allowed only following FM_PCD_HashTableSet().
85996 + When configuring nextEngine = e_FM_PCD_CC, note that
85997 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
85998 + from the currently changed table.
85999 +*//***************************************************************************/
86000 +t_Error FM_PCD_HashTableModifyNextEngine(t_Handle h_HashTbl,
86001 + uint8_t keySize,
86002 + uint8_t *p_Key,
86003 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
86004 +
86005 +/**************************************************************************//**
86006 + @Function FM_PCD_HashTableModifyMissNextEngine
86007 +
86008 + @Description This routine modifies the next engine on key match miss.
86009 +
86010 + @Param[in] h_HashTbl A handle to a hash table
86011 + @Param[in] p_FmPcdCcNextEngineParams A structure for defining new next engine
86012 + parameters.
86013 +
86014 + @Return E_OK on success; Error code otherwise.
86015 +
86016 + @Cautions Allowed only following FM_PCD_HashTableSet().
86017 + When configuring nextEngine = e_FM_PCD_CC, note that
86018 + p_FmPcdCcNextEngineParams->ccParams.h_CcNode must be different
86019 + from the currently changed table.
86020 +*//***************************************************************************/
86021 +t_Error FM_PCD_HashTableModifyMissNextEngine(t_Handle h_HashTbl,
86022 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
86023 +
86024 +/**************************************************************************//*
86025 + @Function FM_PCD_HashTableGetMissNextEngine
86026 +
86027 + @Description Gets NextEngine in case of key match miss.
86028 +
86029 + @Param[in] h_HashTbl A handle to a hash table
86030 + @Param[out] p_FmPcdCcNextEngineParams Next engine parameters for the specified
86031 + hash table.
86032 +
86033 + @Return E_OK on success; Error code otherwise.
86034 +
86035 + @Cautions Allowed only following FM_PCD_HashTableSet().
86036 +*//***************************************************************************/
86037 +t_Error FM_PCD_HashTableGetMissNextEngine(t_Handle h_HashTbl,
86038 + t_FmPcdCcNextEngineParams *p_FmPcdCcNextEngineParams);
86039 +
86040 +/**************************************************************************//**
86041 + @Function FM_PCD_HashTableFindNGetKeyStatistics
86042 +
86043 + @Description This routine may be used to get statistics counters of specific key
86044 + in a hash table.
86045 +
86046 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
86047 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
86048 + these counters reflect how many frames passed that were matched
86049 + this key; The total frames count will be returned in the counter
86050 + of the first range (as only one frame length range was defined).
86051 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
86052 + frame count will be separated to frame length counters, based on
86053 + provided frame length ranges.
86054 + Note that this routine will identify the bucket of this key in
86055 + the hash table and will search the bucket to locate the index
86056 + of the required key based on received key parameters.
86057 +
86058 + @Param[in] h_HashTbl A handle to a hash table
86059 + @Param[in] keySize Size of the requested key
86060 + @Param[in] p_Key A pointer to the requested key
86061 + @Param[out] p_KeyStatistics Key statistics counters
86062 +
86063 + @Return The specific key statistics.
86064 +
86065 + @Cautions Allowed only following FM_PCD_HashTableSet().
86066 +*//***************************************************************************/
86067 +t_Error FM_PCD_HashTableFindNGetKeyStatistics(t_Handle h_HashTbl,
86068 + uint8_t keySize,
86069 + uint8_t *p_Key,
86070 + t_FmPcdCcKeyStatistics *p_KeyStatistics);
86071 +
86072 +/**************************************************************************//**
86073 + @Function FM_PCD_HashTableGetMissStatistics
86074 +
86075 + @Description This routine may be used to get statistics counters of 'miss'
86076 + entry of the a hash table.
86077 +
86078 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
86079 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
86080 + these counters reflect how many frames were not matched to any
86081 + existing key and therefore passed through the miss entry;
86082 +
86083 + @Param[in] h_HashTbl A handle to a hash table
86084 + @Param[out] p_MissStatistics Statistics counters for 'miss'
86085 +
86086 + @Return The statistics for 'miss'.
86087 +
86088 + @Cautions Allowed only following FM_PCD_HashTableSet().
86089 +*//***************************************************************************/
86090 +t_Error FM_PCD_HashTableGetMissStatistics(t_Handle h_HashTbl,
86091 + t_FmPcdCcKeyStatistics *p_MissStatistics);
86092 +
86093 +/**************************************************************************//**
86094 + @Function FM_PCD_ManipNodeSet
86095 +
86096 + @Description This routine should be called for defining a manipulation
86097 + node. A manipulation node must be defined before the CC node
86098 + that precedes it.
86099 +
86100 + @Param[in] h_FmPcd FM PCD module descriptor.
86101 + @Param[in] p_FmPcdManipParams A structure of parameters defining the manipulation
86102 +
86103 + @Return A handle to the initialized object on success; NULL code otherwise.
86104 +
86105 + @Cautions Allowed only following FM_PCD_Init().
86106 +*//***************************************************************************/
86107 +t_Handle FM_PCD_ManipNodeSet(t_Handle h_FmPcd, t_FmPcdManipParams *p_FmPcdManipParams);
86108 +
86109 +/**************************************************************************//**
86110 + @Function FM_PCD_ManipNodeDelete
86111 +
86112 + @Description Delete an existing manipulation node.
86113 +
86114 + @Param[in] h_ManipNode A handle to a manipulation node.
86115 +
86116 + @Return E_OK on success; Error code otherwise.
86117 +
86118 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
86119 +*//***************************************************************************/
86120 +t_Error FM_PCD_ManipNodeDelete(t_Handle h_ManipNode);
86121 +
86122 +/**************************************************************************//**
86123 + @Function FM_PCD_ManipGetStatistics
86124 +
86125 + @Description Retrieve the manipulation statistics.
86126 +
86127 + @Param[in] h_ManipNode A handle to a manipulation node.
86128 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
86129 +
86130 + @Return E_OK on success; Error code otherwise.
86131 +
86132 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
86133 +*//***************************************************************************/
86134 +t_Error FM_PCD_ManipGetStatistics(t_Handle h_ManipNode, t_FmPcdManipStats *p_FmPcdManipStats);
86135 +
86136 +/**************************************************************************//**
86137 + @Function FM_PCD_ManipNodeReplace
86138 +
86139 + @Description Change existing manipulation node to be according to new requirement.
86140 +
86141 + @Param[in] h_ManipNode A handle to a manipulation node.
86142 + @Param[out] p_ManipParams A structure of parameters defining the change requirement
86143 +
86144 + @Return E_OK on success; Error code otherwise.
86145 +
86146 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
86147 +*//***************************************************************************/
86148 +t_Error FM_PCD_ManipNodeReplace(t_Handle h_ManipNode, t_FmPcdManipParams *p_ManipParams);
86149 +
86150 +#if (DPAA_VERSION >= 11)
86151 +/**************************************************************************//**
86152 + @Function FM_PCD_FrmReplicSetGroup
86153 +
86154 + @Description Initialize a Frame Replicator group.
86155 +
86156 + @Param[in] h_FmPcd FM PCD module descriptor.
86157 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
86158 + the frame replicator group.
86159 +
86160 + @Return A handle to the initialized object on success; NULL code otherwise.
86161 +
86162 + @Cautions Allowed only following FM_PCD_Init().
86163 +*//***************************************************************************/
86164 +t_Handle FM_PCD_FrmReplicSetGroup(t_Handle h_FmPcd, t_FmPcdFrmReplicGroupParams *p_FrmReplicGroupParam);
86165 +
86166 +/**************************************************************************//**
86167 + @Function FM_PCD_FrmReplicDeleteGroup
86168 +
86169 + @Description Delete a Frame Replicator group.
86170 +
86171 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
86172 +
86173 + @Return E_OK on success; Error code otherwise.
86174 +
86175 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
86176 +*//***************************************************************************/
86177 +t_Error FM_PCD_FrmReplicDeleteGroup(t_Handle h_FrmReplicGroup);
86178 +
86179 +/**************************************************************************//**
86180 + @Function FM_PCD_FrmReplicAddMember
86181 +
86182 + @Description Add the member in the index defined by the memberIndex.
86183 +
86184 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
86185 + @Param[in] memberIndex member index for adding.
86186 + @Param[in] p_MemberParams A pointer to the new member parameters.
86187 +
86188 + @Return E_OK on success; Error code otherwise.
86189 +
86190 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
86191 +*//***************************************************************************/
86192 +t_Error FM_PCD_FrmReplicAddMember(t_Handle h_FrmReplicGroup,
86193 + uint16_t memberIndex,
86194 + t_FmPcdCcNextEngineParams *p_MemberParams);
86195 +
86196 +/**************************************************************************//**
86197 + @Function FM_PCD_FrmReplicRemoveMember
86198 +
86199 + @Description Remove the member defined by the index from the relevant group.
86200 +
86201 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
86202 + @Param[in] memberIndex member index for removing.
86203 +
86204 + @Return E_OK on success; Error code otherwise.
86205 +
86206 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
86207 +*//***************************************************************************/
86208 +t_Error FM_PCD_FrmReplicRemoveMember(t_Handle h_FrmReplicGroup,
86209 + uint16_t memberIndex);
86210 +#endif /* (DPAA_VERSION >= 11) */
86211 +
86212 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
86213 +/**************************************************************************//**
86214 + @Function FM_PCD_StatisticsSetNode
86215 +
86216 + @Description This routine should be called for defining a statistics node.
86217 +
86218 + @Param[in] h_FmPcd FM PCD module descriptor.
86219 + @Param[in] p_FmPcdstatsParams A structure of parameters defining the statistics
86220 +
86221 + @Return A handle to the initialized object on success; NULL code otherwise.
86222 +
86223 + @Cautions Allowed only following FM_PCD_Init().
86224 +*//***************************************************************************/
86225 +t_Handle FM_PCD_StatisticsSetNode(t_Handle h_FmPcd, t_FmPcdStatsParams *p_FmPcdstatsParams);
86226 +#endif /* ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
86227 +
86228 +/** @} */ /* end of FM_PCD_Runtime_build_grp group */
86229 +/** @} */ /* end of FM_PCD_Runtime_grp group */
86230 +/** @} */ /* end of FM_PCD_grp group */
86231 +/** @} */ /* end of FM_grp group */
86232 +
86233 +
86234 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
86235 +#define FM_PCD_MAX_NUM_OF_INTERCHANGABLE_HDRS FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS
86236 +#define e_FM_PCD_MANIP_ONE_WAYS_HASH e_FM_PCD_MANIP_ONE_WAY_HASH
86237 +#define e_FM_PCD_MANIP_TOW_WAYS_HASH e_FM_PCD_MANIP_TWO_WAYS_HASH
86238 +
86239 +#define e_FM_PCD_MANIP_FRAGMENT_PACKECT e_FM_PCD_MANIP_FRAGMENT_PACKET /* Feb13 */
86240 +
86241 +#define FM_PCD_SetNetEnvCharacteristics(_pcd, _params) \
86242 + FM_PCD_NetEnvCharacteristicsSet(_pcd, _params)
86243 +#define FM_PCD_KgSetScheme(_pcd, _params) FM_PCD_KgSchemeSet(_pcd, _params)
86244 +#define FM_PCD_CcBuildTree(_pcd, _params) FM_PCD_CcRootBuild(_pcd, _params)
86245 +#define FM_PCD_CcSetNode(_pcd, _params) FM_PCD_MatchTableSet(_pcd, _params)
86246 +#define FM_PCD_PlcrSetProfile(_pcd, _params) FM_PCD_PlcrProfileSet(_pcd, _params)
86247 +#define FM_PCD_ManipSetNode(_pcd, _params) FM_PCD_ManipNodeSet(_pcd, _params)
86248 +
86249 +#define FM_PCD_DeleteNetEnvCharacteristics(_pcd, ...) \
86250 + FM_PCD_NetEnvCharacteristicsDelete(__VA_ARGS__)
86251 +#define FM_PCD_KgDeleteScheme(_pcd, ...) \
86252 + FM_PCD_KgSchemeDelete(__VA_ARGS__)
86253 +#define FM_PCD_KgGetSchemeCounter(_pcd, ...) \
86254 + FM_PCD_KgSchemeGetCounter(__VA_ARGS__)
86255 +#define FM_PCD_KgSetSchemeCounter(_pcd, ...) \
86256 + FM_PCD_KgSchemeSetCounter(__VA_ARGS__)
86257 +#define FM_PCD_PlcrDeleteProfile(_pcd, ...) \
86258 + FM_PCD_PlcrProfileDelete(__VA_ARGS__)
86259 +#define FM_PCD_PlcrGetProfileCounter(_pcd, ...) \
86260 + FM_PCD_PlcrProfileGetCounter(__VA_ARGS__)
86261 +#define FM_PCD_PlcrSetProfileCounter(_pcd, ...) \
86262 + FM_PCD_PlcrProfileSetCounter(__VA_ARGS__)
86263 +#define FM_PCD_CcDeleteTree(_pcd, ...) \
86264 + FM_PCD_CcRootDelete(__VA_ARGS__)
86265 +#define FM_PCD_CcTreeModifyNextEngine(_pcd, ...) \
86266 + FM_PCD_CcRootModifyNextEngine(__VA_ARGS__)
86267 +#define FM_PCD_CcDeleteNode(_pcd, ...) \
86268 + FM_PCD_MatchTableDelete(__VA_ARGS__)
86269 +#define FM_PCD_CcNodeModifyMissNextEngine(_pcd, ...) \
86270 + FM_PCD_MatchTableModifyMissNextEngine(__VA_ARGS__)
86271 +#define FM_PCD_CcNodeRemoveKey(_pcd, ...) \
86272 + FM_PCD_MatchTableRemoveKey(__VA_ARGS__)
86273 +#define FM_PCD_CcNodeAddKey(_pcd, ...) \
86274 + FM_PCD_MatchTableAddKey(__VA_ARGS__)
86275 +#define FM_PCD_CcNodeModifyNextEngine(_pcd, ...) \
86276 + FM_PCD_MatchTableModifyNextEngine(__VA_ARGS__)
86277 +#define FM_PCD_CcNodeModifyKeyAndNextEngine(_pcd, ...) \
86278 + FM_PCD_MatchTableModifyKeyAndNextEngine(__VA_ARGS__)
86279 +#define FM_PCD_CcNodeModifyKey(_pcd, ...) \
86280 + FM_PCD_MatchTableModifyKey(__VA_ARGS__)
86281 +#define FM_PCD_CcNodeFindNRemoveKey(_pcd, ...) \
86282 + FM_PCD_MatchTableFindNRemoveKey(__VA_ARGS__)
86283 +#define FM_PCD_CcNodeFindNModifyNextEngine(_pcd, ...) \
86284 + FM_PCD_MatchTableFindNModifyNextEngine(__VA_ARGS__)
86285 +#define FM_PCD_CcNodeFindNModifyKeyAndNextEngine(_pcd, ...) \
86286 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine(__VA_ARGS__)
86287 +#define FM_PCD_CcNodeFindNModifyKey(_pcd, ...) \
86288 + FM_PCD_MatchTableFindNModifyKey(__VA_ARGS__)
86289 +#define FM_PCD_CcIndexedHashNodeGetBucket(_pcd, ...) \
86290 + FM_PCD_MatchTableGetIndexedHashBucket(__VA_ARGS__)
86291 +#define FM_PCD_CcNodeGetNextEngine(_pcd, ...) \
86292 + FM_PCD_MatchTableGetNextEngine(__VA_ARGS__)
86293 +#define FM_PCD_CcNodeGetKeyCounter(_pcd, ...) \
86294 + FM_PCD_MatchTableGetKeyCounter(__VA_ARGS__)
86295 +#define FM_PCD_ManipDeleteNode(_pcd, ...) \
86296 + FM_PCD_ManipNodeDelete(__VA_ARGS__)
86297 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
86298 +
86299 +
86300 +#endif /* __FM_PCD_EXT */
86301 --- /dev/null
86302 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_port_ext.h
86303 @@ -0,0 +1,2608 @@
86304 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
86305 + * All rights reserved.
86306 + *
86307 + * Redistribution and use in source and binary forms, with or without
86308 + * modification, are permitted provided that the following conditions are met:
86309 + * * Redistributions of source code must retain the above copyright
86310 + * notice, this list of conditions and the following disclaimer.
86311 + * * Redistributions in binary form must reproduce the above copyright
86312 + * notice, this list of conditions and the following disclaimer in the
86313 + * documentation and/or other materials provided with the distribution.
86314 + * * Neither the name of Freescale Semiconductor nor the
86315 + * names of its contributors may be used to endorse or promote products
86316 + * derived from this software without specific prior written permission.
86317 + *
86318 + *
86319 + * ALTERNATIVELY, this software may be distributed under the terms of the
86320 + * GNU General Public License ("GPL") as published by the Free Software
86321 + * Foundation, either version 2 of that License or (at your option) any
86322 + * later version.
86323 + *
86324 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
86325 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
86326 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
86327 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
86328 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
86329 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
86330 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
86331 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
86332 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
86333 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
86334 + */
86335 +
86336 +
86337 +/**************************************************************************//**
86338 + @File fm_port_ext.h
86339 +
86340 + @Description FM-Port Application Programming Interface.
86341 +*//***************************************************************************/
86342 +#ifndef __FM_PORT_EXT
86343 +#define __FM_PORT_EXT
86344 +
86345 +#include "error_ext.h"
86346 +#include "std_ext.h"
86347 +#include "fm_pcd_ext.h"
86348 +#include "fm_ext.h"
86349 +#include "net_ext.h"
86350 +
86351 +
86352 +/**************************************************************************//**
86353 +
86354 + @Group FM_grp Frame Manager API
86355 +
86356 + @Description FM API functions, definitions and enums
86357 +
86358 + @{
86359 +*//***************************************************************************/
86360 +
86361 +/**************************************************************************//**
86362 + @Group FM_PORT_grp FM Port
86363 +
86364 + @Description FM Port API
86365 +
86366 + The FM uses a general module called "port" to represent a Tx port
86367 + (MAC), an Rx port (MAC) or Offline Parsing port.
86368 + The number of ports in an FM varies between SOCs.
86369 + The SW driver manages these ports as sub-modules of the FM, i.e.
86370 + after an FM is initialized, its ports may be initialized and
86371 + operated upon.
86372 +
86373 + The port is initialized aware of its type, but other functions on
86374 + a port may be indifferent to its type. When necessary, the driver
86375 + verifies coherence and returns error if applicable.
86376 +
86377 + On initialization, user specifies the port type and it's index
86378 + (relative to the port's type) - always starting at 0.
86379 +
86380 + @{
86381 +*//***************************************************************************/
86382 +
86383 +/**************************************************************************//**
86384 + @Description An enum for defining port PCD modes.
86385 + This enum defines the superset of PCD engines support - i.e. not
86386 + all engines have to be used, but all have to be enabled. The real
86387 + flow of a specific frame depends on the PCD configuration and the
86388 + frame headers and payload.
86389 + Note: the first engine and the first engine after the parser (if
86390 + exists) should be in order, the order is important as it will
86391 + define the flow of the port. However, as for the rest engines
86392 + (the ones that follows), the order is not important anymore as
86393 + it is defined by the PCD graph itself.
86394 +*//***************************************************************************/
86395 +typedef enum e_FmPortPcdSupport {
86396 + e_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
86397 + , e_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
86398 + , e_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
86399 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
86400 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
86401 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
86402 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
86403 + /**< Use all PCD engines */
86404 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
86405 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
86406 + , e_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
86407 + , e_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
86408 +#ifdef FM_CAPWAP_SUPPORT
86409 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
86410 + , e_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
86411 +#endif /* FM_CAPWAP_SUPPORT */
86412 +} e_FmPortPcdSupport;
86413 +
86414 +/**************************************************************************//**
86415 + @Description Port interrupts
86416 +*//***************************************************************************/
86417 +typedef enum e_FmPortExceptions {
86418 + e_FM_PORT_EXCEPTION_IM_BUSY /**< Independent-Mode Rx-BUSY */
86419 +} e_FmPortExceptions;
86420 +
86421 +
86422 +/**************************************************************************//**
86423 + @Collection General FM Port defines
86424 +*//***************************************************************************/
86425 +#define FM_PORT_PRS_RESULT_NUM_OF_WORDS 8 /**< Number of 4 bytes words in parser result */
86426 +/* @} */
86427 +
86428 +/**************************************************************************//**
86429 + @Collection FM Frame error
86430 +*//***************************************************************************/
86431 +typedef uint32_t fmPortFrameErrSelect_t; /**< typedef for defining Frame Descriptor errors */
86432 +
86433 +#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT FM_FD_ERR_UNSUPPORTED_FORMAT /**< Not for Rx-Port! Unsupported Format */
86434 +#define FM_PORT_FRM_ERR_LENGTH FM_FD_ERR_LENGTH /**< Not for Rx-Port! Length Error */
86435 +#define FM_PORT_FRM_ERR_DMA FM_FD_ERR_DMA /**< DMA Data error */
86436 +#define FM_PORT_FRM_ERR_NON_FM FM_FD_RX_STATUS_ERR_NON_FM /**< non Frame-Manager error; probably come from SEC that
86437 + was chained to FM */
86438 +
86439 +#define FM_PORT_FRM_ERR_IPRE (FM_FD_ERR_IPR & ~FM_FD_IPR) /**< IPR error */
86440 +#define FM_PORT_FRM_ERR_IPR_NCSP (FM_FD_ERR_IPR_NCSP & ~FM_FD_IPR) /**< IPR non-consistent-sp */
86441 +
86442 +#define FM_PORT_FRM_ERR_IPFE 0 /**< Obsolete; will be removed in the future */
86443 +
86444 +#ifdef FM_CAPWAP_SUPPORT
86445 +#define FM_PORT_FRM_ERR_CRE FM_FD_ERR_CRE
86446 +#define FM_PORT_FRM_ERR_CHE FM_FD_ERR_CHE
86447 +#endif /* FM_CAPWAP_SUPPORT */
86448 +
86449 +#define FM_PORT_FRM_ERR_PHYSICAL FM_FD_ERR_PHYSICAL /**< Rx FIFO overflow, FCS error, code error, running disparity
86450 + error (SGMII and TBI modes), FIFO parity error. PHY
86451 + Sequence error, PHY error control character detected. */
86452 +#define FM_PORT_FRM_ERR_SIZE FM_FD_ERR_SIZE /**< Frame too long OR Frame size exceeds max_length_frame */
86453 +#define FM_PORT_FRM_ERR_CLS_DISCARD FM_FD_ERR_CLS_DISCARD /**< indicates a classifier "drop" operation */
86454 +#define FM_PORT_FRM_ERR_EXTRACTION FM_FD_ERR_EXTRACTION /**< Extract Out of Frame */
86455 +#define FM_PORT_FRM_ERR_NO_SCHEME FM_FD_ERR_NO_SCHEME /**< No Scheme Selected */
86456 +#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW FM_FD_ERR_KEYSIZE_OVERFLOW /**< Keysize Overflow */
86457 +#define FM_PORT_FRM_ERR_COLOR_RED FM_FD_ERR_COLOR_RED /**< Frame color is red */
86458 +#define FM_PORT_FRM_ERR_COLOR_YELLOW FM_FD_ERR_COLOR_YELLOW /**< Frame color is yellow */
86459 +#define FM_PORT_FRM_ERR_ILL_PLCR FM_FD_ERR_ILL_PLCR /**< Illegal Policer Profile selected */
86460 +#define FM_PORT_FRM_ERR_PLCR_FRAME_LEN FM_FD_ERR_PLCR_FRAME_LEN /**< Policer frame length error */
86461 +#define FM_PORT_FRM_ERR_PRS_TIMEOUT FM_FD_ERR_PRS_TIMEOUT /**< Parser Time out Exceed */
86462 +#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT FM_FD_ERR_PRS_ILL_INSTRUCT /**< Invalid Soft Parser instruction */
86463 +#define FM_PORT_FRM_ERR_PRS_HDR_ERR FM_FD_ERR_PRS_HDR_ERR /**< Header error was identified during parsing */
86464 +#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED FM_FD_ERR_BLOCK_LIMIT_EXCEEDED /**< Frame parsed beyind 256 first bytes */
86465 +#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT 0x00000001 /**< FPM Frame Processing Timeout Exceeded */
86466 +/* @} */
86467 +
86468 +
86469 +
86470 +/**************************************************************************//**
86471 + @Group FM_PORT_init_grp FM Port Initialization Unit
86472 +
86473 + @Description FM Port Initialization Unit
86474 +
86475 + @{
86476 +*//***************************************************************************/
86477 +
86478 +/**************************************************************************//**
86479 + @Description Exceptions user callback routine, will be called upon an
86480 + exception passing the exception identification.
86481 +
86482 + @Param[in] h_App - User's application descriptor.
86483 + @Param[in] exception - The exception.
86484 + *//***************************************************************************/
86485 +typedef void (t_FmPortExceptionCallback) (t_Handle h_App, e_FmPortExceptions exception);
86486 +
86487 +/**************************************************************************//**
86488 + @Description User callback function called by driver with received data.
86489 +
86490 + User provides this function. Driver invokes it.
86491 +
86492 + @Param[in] h_App Application's handle originally specified to
86493 + the API Config function
86494 + @Param[in] p_Data A pointer to data received
86495 + @Param[in] length length of received data
86496 + @Param[in] status receive status and errors
86497 + @Param[in] position position of buffer in frame
86498 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
86499 +
86500 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
86501 + operation for all ready data.
86502 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
86503 +*//***************************************************************************/
86504 +typedef e_RxStoreResponse (t_FmPortImRxStoreCallback) (t_Handle h_App,
86505 + uint8_t *p_Data,
86506 + uint16_t length,
86507 + uint16_t status,
86508 + uint8_t position,
86509 + t_Handle h_BufContext);
86510 +
86511 +/**************************************************************************//**
86512 + @Description User callback function called by driver when transmit completed.
86513 +
86514 + User provides this function. Driver invokes it.
86515 +
86516 + @Param[in] h_App Application's handle originally specified to
86517 + the API Config function
86518 + @Param[in] p_Data A pointer to data received
86519 + @Param[in] status transmit status and errors
86520 + @Param[in] lastBuffer is last buffer in frame
86521 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
86522 + *//***************************************************************************/
86523 +typedef void (t_FmPortImTxConfCallback) (t_Handle h_App,
86524 + uint8_t *p_Data,
86525 + uint16_t status,
86526 + t_Handle h_BufContext);
86527 +
86528 +/**************************************************************************//**
86529 + @Description A structure for additional Rx port parameters
86530 +*//***************************************************************************/
86531 +typedef struct t_FmPortRxParams {
86532 + uint32_t errFqid; /**< Error Queue Id. */
86533 + uint32_t dfltFqid; /**< Default Queue Id. */
86534 + uint16_t liodnOffset; /**< Port's LIODN offset. */
86535 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
86536 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes. */
86537 +} t_FmPortRxParams;
86538 +
86539 +/**************************************************************************//**
86540 + @Description A structure for additional non-Rx port parameters
86541 +*//***************************************************************************/
86542 +typedef struct t_FmPortNonRxParams {
86543 + uint32_t errFqid; /**< Error Queue Id. */
86544 + uint32_t dfltFqid; /**< For Tx - Default Confirmation queue,
86545 + 0 means no Tx confirmation for processed
86546 + frames. For OP port - default Rx queue. */
86547 + uint32_t qmChannel; /**< QM-channel dedicated to this port; will be used
86548 + by the FM for dequeue. */
86549 +} t_FmPortNonRxParams;
86550 +
86551 +/**************************************************************************//**
86552 + @Description A structure for additional Rx port parameters
86553 +*//***************************************************************************/
86554 +typedef struct t_FmPortImRxTxParams {
86555 + t_Handle h_FmMuram; /**< A handle of the FM-MURAM partition */
86556 + uint16_t liodnOffset; /**< For Rx ports only. Port's LIODN Offset. */
86557 + uint8_t dataMemId; /**< Memory partition ID for data buffers */
86558 + uint32_t dataMemAttributes; /**< Memory attributes for data buffers */
86559 + t_BufferPoolInfo rxPoolParams; /**< For Rx ports only. */
86560 + t_FmPortImRxStoreCallback *f_RxStore; /**< For Rx ports only. */
86561 + t_FmPortImTxConfCallback *f_TxConf; /**< For Tx ports only. */
86562 +} t_FmPortImRxTxParams;
86563 +
86564 +/**************************************************************************//**
86565 + @Description A union for additional parameters depending on port type
86566 +*//***************************************************************************/
86567 +typedef union u_FmPortSpecificParams {
86568 + t_FmPortImRxTxParams imRxTxParams; /**< Rx/Tx Independent-Mode port parameter structure */
86569 + t_FmPortRxParams rxParams; /**< Rx port parameters structure */
86570 + t_FmPortNonRxParams nonRxParams; /**< Non-Rx port parameters structure */
86571 +} u_FmPortSpecificParams;
86572 +
86573 +/**************************************************************************//**
86574 + @Description A structure representing FM initialization parameters
86575 +*//***************************************************************************/
86576 +typedef struct t_FmPortParams {
86577 + uintptr_t baseAddr; /**< Virtual Address of memory mapped FM Port registers.*/
86578 + t_Handle h_Fm; /**< A handle to the FM object this port related to */
86579 + e_FmPortType portType; /**< Port type */
86580 + uint8_t portId; /**< Port Id - relative to type;
86581 + NOTE: When configuring Offline Parsing port for
86582 + FMANv3 devices (DPAA_VERSION 11 and higher),
86583 + it is highly recommended NOT to use portId=0 due to lack
86584 + of HW resources on portId=0. */
86585 + bool independentModeEnable;
86586 + /**< This port is Independent-Mode - Used for Rx/Tx ports only! */
86587 + uint16_t liodnBase; /**< Irrelevant for P4080 rev 1. LIODN base for this port, to be
86588 + used together with LIODN offset. */
86589 + u_FmPortSpecificParams specificParams; /**< Additional parameters depending on port
86590 + type. */
86591 +
86592 + t_FmPortExceptionCallback *f_Exception; /**< Relevant for IM only Callback routine to be called on BUSY exception */
86593 + t_Handle h_App; /**< A handle to an application layer object; This handle will
86594 + be passed by the driver upon calling the above callbacks */
86595 +} t_FmPortParams;
86596 +
86597 +
86598 +/**************************************************************************//**
86599 + @Function FM_PORT_Config
86600 +
86601 + @Description Creates a descriptor for the FM PORT module.
86602 +
86603 + The routine returns a handle (descriptor) to the FM PORT object.
86604 + This descriptor must be passed as first parameter to all other
86605 + FM PORT function calls.
86606 +
86607 + No actual initialization or configuration of FM hardware is
86608 + done by this routine.
86609 +
86610 + @Param[in] p_FmPortParams - Pointer to data structure of parameters
86611 +
86612 + @Retval Handle to FM object, or NULL for Failure.
86613 +*//***************************************************************************/
86614 +t_Handle FM_PORT_Config(t_FmPortParams *p_FmPortParams);
86615 +
86616 +/**************************************************************************//**
86617 + @Function FM_PORT_Init
86618 +
86619 + @Description Initializes the FM PORT module by defining the software structure
86620 + and configuring the hardware registers.
86621 +
86622 + @Param[in] h_FmPort - FM PORT module descriptor
86623 +
86624 + @Return E_OK on success; Error code otherwise.
86625 +*//***************************************************************************/
86626 +t_Error FM_PORT_Init(t_Handle h_FmPort);
86627 +
86628 +/**************************************************************************//**
86629 + @Function FM_PORT_Free
86630 +
86631 + @Description Frees all resources that were assigned to FM PORT module.
86632 +
86633 + Calling this routine invalidates the descriptor.
86634 +
86635 + @Param[in] h_FmPort - FM PORT module descriptor
86636 +
86637 + @Return E_OK on success; Error code otherwise.
86638 +*//***************************************************************************/
86639 +t_Error FM_PORT_Free(t_Handle h_FmPort);
86640 +
86641 +
86642 +/**************************************************************************//**
86643 + @Group FM_PORT_advanced_init_grp FM Port Advanced Configuration Unit
86644 +
86645 + @Description Configuration functions used to change default values.
86646 +
86647 + @{
86648 +*//***************************************************************************/
86649 +
86650 +/**************************************************************************//**
86651 + @Description enum for defining QM frame dequeue
86652 +*//***************************************************************************/
86653 +typedef enum e_FmPortDeqType {
86654 + e_FM_PORT_DEQ_TYPE1, /**< Dequeue from the SP channel - with priority precedence,
86655 + and Intra-Class Scheduling respected. */
86656 + e_FM_PORT_DEQ_TYPE2, /**< Dequeue from the SP channel - with active FQ precedence,
86657 + and Intra-Class Scheduling respected. */
86658 + e_FM_PORT_DEQ_TYPE3 /**< Dequeue from the SP channel - with active FQ precedence,
86659 + and override Intra-Class Scheduling */
86660 +} e_FmPortDeqType;
86661 +
86662 +/**************************************************************************//**
86663 + @Description enum for defining QM frame dequeue
86664 +*//***************************************************************************/
86665 +typedef enum e_FmPortDeqPrefetchOption {
86666 + e_FM_PORT_DEQ_NO_PREFETCH, /**< QMI preforms a dequeue action for a single frame
86667 + only when a dedicated portID Tnum is waiting. */
86668 + e_FM_PORT_DEQ_PARTIAL_PREFETCH, /**< QMI preforms a dequeue action for 3 frames when
86669 + one dedicated portId tnum is waiting. */
86670 + e_FM_PORT_DEQ_FULL_PREFETCH /**< QMI preforms a dequeue action for 3 frames when
86671 + no dedicated portId tnums are waiting. */
86672 +
86673 +} e_FmPortDeqPrefetchOption;
86674 +
86675 +/**************************************************************************//**
86676 + @Description enum for defining port default color
86677 +*//***************************************************************************/
86678 +typedef enum e_FmPortColor {
86679 + e_FM_PORT_COLOR_GREEN, /**< Default port color is green */
86680 + e_FM_PORT_COLOR_YELLOW, /**< Default port color is yellow */
86681 + e_FM_PORT_COLOR_RED, /**< Default port color is red */
86682 + e_FM_PORT_COLOR_OVERRIDE /**< Ignore color */
86683 +} e_FmPortColor;
86684 +
86685 +/**************************************************************************//**
86686 + @Description A structure for defining Dual Tx rate limiting scale
86687 +*//***************************************************************************/
86688 +typedef enum e_FmPortDualRateLimiterScaleDown {
86689 + e_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
86690 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
86691 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
86692 + e_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
86693 +} e_FmPortDualRateLimiterScaleDown;
86694 +
86695 +
86696 +/**************************************************************************//**
86697 + @Description A structure for defining FM port resources
86698 +*//***************************************************************************/
86699 +typedef struct t_FmPortRsrc {
86700 + uint32_t num; /**< Committed required resource */
86701 + uint32_t extra; /**< Extra (not committed) required resource */
86702 +} t_FmPortRsrc;
86703 +
86704 +/**************************************************************************//**
86705 + @Description A structure for defining observed pool depletion
86706 +*//***************************************************************************/
86707 +typedef struct t_FmPortObservedBufPoolDepletion {
86708 + t_FmBufPoolDepletion poolDepletionParams;/**< parameters to define pool depletion */
86709 + t_FmExtPools poolsParams; /**< Which external buffer pools are observed
86710 + (up to FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS),
86711 + and their sizes. */
86712 +} t_FmPortObservedBufPoolDepletion;
86713 +
86714 +/**************************************************************************//**
86715 + @Description A structure for defining Tx rate limiting
86716 +*//***************************************************************************/
86717 +typedef struct t_FmPortRateLimit {
86718 + uint16_t maxBurstSize; /**< in KBytes for Tx ports, in frames
86719 + for OP ports. (note that
86720 + for early chips burst size is
86721 + rounded up to a multiply of 1000 frames).*/
86722 + uint32_t rateLimit; /**< in Kb/sec for Tx ports, in frame/sec for
86723 + OP ports. Rate limit refers to
86724 + data rate (rather than line rate). */
86725 + e_FmPortDualRateLimiterScaleDown rateLimitDivider; /**< For OP ports only. Not-valid
86726 + for some earlier chip revisions */
86727 +} t_FmPortRateLimit;
86728 +
86729 +/**************************************************************************//**
86730 + @Description A structure for defining the parameters of
86731 + the Rx port performance counters
86732 +*//***************************************************************************/
86733 +typedef struct t_FmPortPerformanceCnt {
86734 + uint8_t taskCompVal; /**< Task compare value */
86735 + uint8_t queueCompVal; /**< Rx queue/Tx confirm queue compare
86736 + value (unused for H/O) */
86737 + uint8_t dmaCompVal; /**< Dma compare value */
86738 + uint32_t fifoCompVal; /**< Fifo compare value (in bytes) */
86739 +} t_FmPortPerformanceCnt;
86740 +
86741 +
86742 +/**************************************************************************//**
86743 + @Description A structure for defining the sizes of the Deep Sleep
86744 + the Auto Response tables
86745 +*//***************************************************************************/
86746 +typedef struct t_FmPortDsarTablesSizes
86747 +{
86748 + uint16_t maxNumOfArpEntries;
86749 + uint16_t maxNumOfEchoIpv4Entries;
86750 + uint16_t maxNumOfNdpEntries;
86751 + uint16_t maxNumOfEchoIpv6Entries;
86752 + uint16_t maxNumOfSnmpIPV4Entries;
86753 + uint16_t maxNumOfSnmpIPV6Entries;
86754 + uint16_t maxNumOfSnmpOidEntries;
86755 + uint16_t maxNumOfSnmpOidChar; /* total amount of character needed for the snmp table */
86756 +
86757 + uint16_t maxNumOfIpProtFiltering;
86758 + uint16_t maxNumOfTcpPortFiltering;
86759 + uint16_t maxNumOfUdpPortFiltering;
86760 +} t_FmPortDsarTablesSizes;
86761 +
86762 +
86763 +/**************************************************************************//**
86764 + @Function FM_PORT_ConfigDsarSupport
86765 +
86766 + @Description This function will allocate the amount of MURAM needed for
86767 + this max number of entries for Deep Sleep Auto Response.
86768 + it will calculate all needed MURAM for autoresponse including
86769 + necesary common stuff.
86770 +
86771 +
86772 + @Param[in] h_FmPort A handle to a FM Port module.
86773 + @Param[in] params A pointer to a structure containing the maximum
86774 + sizes of the auto response tables
86775 +
86776 + @Return E_OK on success; Error code otherwise.
86777 +
86778 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86779 +*//***************************************************************************/
86780 +t_Error FM_PORT_ConfigDsarSupport(t_Handle h_FmPortRx, t_FmPortDsarTablesSizes *params);
86781 +
86782 +/**************************************************************************//**
86783 + @Function FM_PORT_ConfigNumOfOpenDmas
86784 +
86785 + @Description Calling this routine changes the max number of open DMA's
86786 + available for this port. It changes this parameter in the
86787 + internal driver data base from its default configuration
86788 + [OP: 1]
86789 + [1G-RX, 1G-TX: 1 (+1)]
86790 + [10G-RX, 10G-TX: 8 (+8)]
86791 +
86792 + @Param[in] h_FmPort A handle to a FM Port module.
86793 + @Param[in] p_OpenDmas A pointer to a structure of parameters defining
86794 + the open DMA allocation.
86795 +
86796 + @Return E_OK on success; Error code otherwise.
86797 +
86798 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86799 +*//***************************************************************************/
86800 +t_Error FM_PORT_ConfigNumOfOpenDmas(t_Handle h_FmPort, t_FmPortRsrc *p_OpenDmas);
86801 +
86802 +/**************************************************************************//**
86803 + @Function FM_PORT_ConfigNumOfTasks
86804 +
86805 + @Description Calling this routine changes the max number of tasks
86806 + available for this port. It changes this parameter in the
86807 + internal driver data base from its default configuration
86808 + [OP: 1]
86809 + [1G-RX, 1G-TX: 3 (+2)]
86810 + [10G-RX, 10G-TX: 16 (+8)]
86811 +
86812 + @Param[in] h_FmPort A handle to a FM Port module.
86813 + @Param[in] p_NumOfTasks A pointer to a structure of parameters defining
86814 + the tasks allocation.
86815 +
86816 + @Return E_OK on success; Error code otherwise.
86817 +
86818 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86819 +*//***************************************************************************/
86820 +t_Error FM_PORT_ConfigNumOfTasks(t_Handle h_FmPort, t_FmPortRsrc *p_NumOfTasks);
86821 +
86822 +/**************************************************************************//**
86823 + @Function FM_PORT_ConfigSizeOfFifo
86824 +
86825 + @Description Calling this routine changes the max FIFO size configured for this port.
86826 +
86827 + This function changes the internal driver data base from its
86828 + default configuration. Please refer to the driver's User Guide for
86829 + information on default FIFO sizes in the various devices.
86830 + [OP: 2KB]
86831 + [1G-RX, 1G-TX: 11KB]
86832 + [10G-RX, 10G-TX: 12KB]
86833 +
86834 + @Param[in] h_FmPort A handle to a FM Port module.
86835 + @Param[in] p_SizeOfFifo A pointer to a structure of parameters defining
86836 + the FIFO allocation.
86837 +
86838 + @Return E_OK on success; Error code otherwise.
86839 +
86840 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86841 +*//***************************************************************************/
86842 +t_Error FM_PORT_ConfigSizeOfFifo(t_Handle h_FmPort, t_FmPortRsrc *p_SizeOfFifo);
86843 +
86844 +/**************************************************************************//**
86845 + @Function FM_PORT_ConfigDeqHighPriority
86846 +
86847 + @Description Calling this routine changes the dequeue priority in the
86848 + internal driver data base from its default configuration
86849 + 1G: [DEFAULT_PORT_deqHighPriority_1G]
86850 + 10G: [DEFAULT_PORT_deqHighPriority_10G]
86851 +
86852 + May be used for Non-Rx ports only
86853 +
86854 + @Param[in] h_FmPort A handle to a FM Port module.
86855 + @Param[in] highPri TRUE to select high priority, FALSE for normal operation.
86856 +
86857 + @Return E_OK on success; Error code otherwise.
86858 +
86859 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86860 +*//***************************************************************************/
86861 +t_Error FM_PORT_ConfigDeqHighPriority(t_Handle h_FmPort, bool highPri);
86862 +
86863 +/**************************************************************************//**
86864 + @Function FM_PORT_ConfigDeqType
86865 +
86866 + @Description Calling this routine changes the dequeue type parameter in the
86867 + internal driver data base from its default configuration
86868 + [DEFAULT_PORT_deqType].
86869 +
86870 + May be used for Non-Rx ports only
86871 +
86872 + @Param[in] h_FmPort A handle to a FM Port module.
86873 + @Param[in] deqType According to QM definition.
86874 +
86875 + @Return E_OK on success; Error code otherwise.
86876 +
86877 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86878 +*//***************************************************************************/
86879 +t_Error FM_PORT_ConfigDeqType(t_Handle h_FmPort, e_FmPortDeqType deqType);
86880 +
86881 +/**************************************************************************//**
86882 + @Function FM_PORT_ConfigDeqPrefetchOption
86883 +
86884 + @Description Calling this routine changes the dequeue prefetch option parameter in the
86885 + internal driver data base from its default configuration
86886 + [DEFAULT_PORT_deqPrefetchOption]
86887 + Note: Available for some chips only
86888 +
86889 + May be used for Non-Rx ports only
86890 +
86891 + @Param[in] h_FmPort A handle to a FM Port module.
86892 + @Param[in] deqPrefetchOption New option
86893 +
86894 + @Return E_OK on success; Error code otherwise.
86895 +
86896 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86897 +*//***************************************************************************/
86898 +t_Error FM_PORT_ConfigDeqPrefetchOption(t_Handle h_FmPort, e_FmPortDeqPrefetchOption deqPrefetchOption);
86899 +
86900 +/**************************************************************************//**
86901 + @Function FM_PORT_ConfigDeqByteCnt
86902 +
86903 + @Description Calling this routine changes the dequeue byte count parameter in
86904 + the internal driver data base from its default configuration
86905 + 1G:[DEFAULT_PORT_deqByteCnt_1G].
86906 + 10G:[DEFAULT_PORT_deqByteCnt_10G].
86907 +
86908 + May be used for Non-Rx ports only
86909 +
86910 + @Param[in] h_FmPort A handle to a FM Port module.
86911 + @Param[in] deqByteCnt New byte count
86912 +
86913 + @Return E_OK on success; Error code otherwise.
86914 +
86915 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86916 +*//***************************************************************************/
86917 +t_Error FM_PORT_ConfigDeqByteCnt(t_Handle h_FmPort, uint16_t deqByteCnt);
86918 +
86919 +/**************************************************************************//**
86920 + @Function FM_PORT_ConfigBufferPrefixContent
86921 +
86922 + @Description Defines the structure, size and content of the application buffer.
86923 + The prefix will
86924 + In Tx ports, if 'passPrsResult', the application
86925 + should set a value to their offsets in the prefix of
86926 + the FM will save the first 'privDataSize', than,
86927 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
86928 + and timeStamp, and the packet itself (in this order), to the
86929 + application buffer, and to offset.
86930 + Calling this routine changes the buffer margins definitions
86931 + in the internal driver data base from its default
86932 + configuration: Data size: [DEFAULT_PORT_bufferPrefixContent_privDataSize]
86933 + Pass Parser result: [DEFAULT_PORT_bufferPrefixContent_passPrsResult].
86934 + Pass timestamp: [DEFAULT_PORT_bufferPrefixContent_passTimeStamp].
86935 +
86936 + May be used for all ports
86937 +
86938 + @Param[in] h_FmPort A handle to a FM Port module.
86939 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
86940 + structure of the buffer.
86941 + Out parameter: Start margin - offset
86942 + of data from start of external buffer.
86943 +
86944 + @Return E_OK on success; Error code otherwise.
86945 +
86946 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86947 +*//***************************************************************************/
86948 +t_Error FM_PORT_ConfigBufferPrefixContent(t_Handle h_FmPort,
86949 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
86950 +
86951 +/**************************************************************************//**
86952 + @Function FM_PORT_ConfigCheksumLastBytesIgnore
86953 +
86954 + @Description Calling this routine changes the number of checksum bytes to ignore
86955 + parameter in the internal driver data base from its default configuration
86956 + [DEFAULT_PORT_cheksumLastBytesIgnore]
86957 +
86958 + May be used by Tx & Rx ports only
86959 +
86960 + @Param[in] h_FmPort A handle to a FM Port module.
86961 + @Param[in] cheksumLastBytesIgnore New value
86962 +
86963 + @Return E_OK on success; Error code otherwise.
86964 +
86965 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86966 +*//***************************************************************************/
86967 +t_Error FM_PORT_ConfigCheksumLastBytesIgnore(t_Handle h_FmPort, uint8_t cheksumLastBytesIgnore);
86968 +
86969 +/**************************************************************************//**
86970 + @Function FM_PORT_ConfigCutBytesFromEnd
86971 +
86972 + @Description Calling this routine changes the number of bytes to cut from a
86973 + frame's end parameter in the internal driver data base
86974 + from its default configuration [DEFAULT_PORT_cutBytesFromEnd]
86975 + Note that if the result of (frame length before chop - cutBytesFromEnd) is
86976 + less than 14 bytes, the chop operation is not executed.
86977 +
86978 + May be used for Rx ports only
86979 +
86980 + @Param[in] h_FmPort A handle to a FM Port module.
86981 + @Param[in] cutBytesFromEnd New value
86982 +
86983 + @Return E_OK on success; Error code otherwise.
86984 +
86985 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
86986 +*//***************************************************************************/
86987 +t_Error FM_PORT_ConfigCutBytesFromEnd(t_Handle h_FmPort, uint8_t cutBytesFromEnd);
86988 +
86989 +/**************************************************************************//**
86990 + @Function FM_PORT_ConfigPoolDepletion
86991 +
86992 + @Description Calling this routine enables pause frame generation depending on the
86993 + depletion status of BM pools. It also defines the conditions to activate
86994 + this functionality. By default, this functionality is disabled.
86995 +
86996 + May be used for Rx ports only
86997 +
86998 + @Param[in] h_FmPort A handle to a FM Port module.
86999 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
87000 +
87001 + @Return E_OK on success; Error code otherwise.
87002 +
87003 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87004 +*//***************************************************************************/
87005 +t_Error FM_PORT_ConfigPoolDepletion(t_Handle h_FmPort, t_FmBufPoolDepletion *p_BufPoolDepletion);
87006 +
87007 +/**************************************************************************//**
87008 + @Function FM_PORT_ConfigObservedPoolDepletion
87009 +
87010 + @Description Calling this routine enables a mechanism to stop port enqueue
87011 + depending on the depletion status of selected BM pools.
87012 + It also defines the conditions to activate
87013 + this functionality. By default, this functionality is disabled.
87014 +
87015 + Note: Available for some chips only
87016 +
87017 + May be used for OP ports only
87018 +
87019 + @Param[in] h_FmPort A handle to a FM Port module.
87020 + @Param[in] p_FmPortObservedBufPoolDepletion A structure of parameters for pool depletion.
87021 +
87022 + @Return E_OK on success; Error code otherwise.
87023 +
87024 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87025 +*//***************************************************************************/
87026 +t_Error FM_PORT_ConfigObservedPoolDepletion(t_Handle h_FmPort,
87027 + t_FmPortObservedBufPoolDepletion *p_FmPortObservedBufPoolDepletion);
87028 +
87029 +/**************************************************************************//**
87030 + @Function FM_PORT_ConfigExtBufPools
87031 +
87032 + @Description This routine should be called for OP ports
87033 + that internally use BM buffer pools. In such cases, e.g. for fragmentation and
87034 + re-assembly, the FM needs new BM buffers. By calling this routine the user
87035 + specifies the BM buffer pools that should be used.
87036 +
87037 + Note: Available for some chips only
87038 +
87039 + May be used for OP ports only
87040 +
87041 + @Param[in] h_FmPort A handle to a FM Port module.
87042 + @Param[in] p_FmExtPools A structure of parameters for the external pools.
87043 +
87044 + @Return E_OK on success; Error code otherwise.
87045 +
87046 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87047 +*//***************************************************************************/
87048 +t_Error FM_PORT_ConfigExtBufPools(t_Handle h_FmPort, t_FmExtPools *p_FmExtPools);
87049 +
87050 +/**************************************************************************//**
87051 + @Function FM_PORT_ConfigBackupPools
87052 +
87053 + @Description Calling this routine allows the configuration of some of the BM pools
87054 + defined for this port as backup pools.
87055 + A pool configured to be a backup pool will be used only if all other
87056 + enabled non-backup pools are depleted.
87057 +
87058 + May be used for Rx ports only
87059 +
87060 + @Param[in] h_FmPort A handle to a FM Port module.
87061 + @Param[in] p_FmPortBackupBmPools An array of pool id's. All pools specified here will
87062 + be defined as backup pools.
87063 +
87064 + @Return E_OK on success; Error code otherwise.
87065 +
87066 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87067 +*//***************************************************************************/
87068 +t_Error FM_PORT_ConfigBackupPools(t_Handle h_FmPort, t_FmBackupBmPools *p_FmPortBackupBmPools);
87069 +
87070 +/**************************************************************************//**
87071 + @Function FM_PORT_ConfigFrmDiscardOverride
87072 +
87073 + @Description Calling this routine changes the error frames destination parameter
87074 + in the internal driver data base from its default configuration:
87075 + override = [DEFAULT_PORT_frmDiscardOverride]
87076 +
87077 + May be used for Rx and OP ports only
87078 +
87079 + @Param[in] h_FmPort A handle to a FM Port module.
87080 + @Param[in] override TRUE to override discarding of error frames and
87081 + enqueueing them to error queue.
87082 +
87083 + @Return E_OK on success; Error code otherwise.
87084 +
87085 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87086 +*//***************************************************************************/
87087 +t_Error FM_PORT_ConfigFrmDiscardOverride(t_Handle h_FmPort, bool override);
87088 +
87089 +/**************************************************************************//**
87090 + @Function FM_PORT_ConfigErrorsToDiscard
87091 +
87092 + @Description Calling this routine changes the behaviour on error parameter
87093 + in the internal driver data base from its default configuration:
87094 + [DEFAULT_PORT_errorsToDiscard].
87095 + If a requested error was previously defined as "ErrorsToEnqueue" it's
87096 + definition will change and the frame will be discarded.
87097 + Errors that were not defined either as "ErrorsToEnqueue" nor as
87098 + "ErrorsToDiscard", will be forwarded to CPU.
87099 +
87100 + May be used for Rx and OP ports only
87101 +
87102 + @Param[in] h_FmPort A handle to a FM Port module.
87103 + @Param[in] errs A list of errors to discard
87104 +
87105 + @Return E_OK on success; Error code otherwise.
87106 +
87107 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87108 +*//***************************************************************************/
87109 +t_Error FM_PORT_ConfigErrorsToDiscard(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
87110 +
87111 +/**************************************************************************//**
87112 + @Function FM_PORT_ConfigDmaSwapData
87113 +
87114 + @Description Calling this routine changes the DMA swap data aparameter
87115 + in the internal driver data base from its default
87116 + configuration [DEFAULT_PORT_dmaSwapData]
87117 +
87118 + May be used for all port types
87119 +
87120 + @Param[in] h_FmPort A handle to a FM Port module.
87121 + @Param[in] swapData New selection
87122 +
87123 + @Return E_OK on success; Error code otherwise.
87124 +
87125 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87126 +*//***************************************************************************/
87127 +t_Error FM_PORT_ConfigDmaSwapData(t_Handle h_FmPort, e_FmDmaSwapOption swapData);
87128 +
87129 +/**************************************************************************//**
87130 + @Function FM_PORT_ConfigDmaIcCacheAttr
87131 +
87132 + @Description Calling this routine changes the internal context cache
87133 + attribute parameter in the internal driver data base
87134 + from its default configuration [DEFAULT_PORT_dmaIntContextCacheAttr]
87135 +
87136 + May be used for all port types
87137 +
87138 + @Param[in] h_FmPort A handle to a FM Port module.
87139 + @Param[in] intContextCacheAttr New selection
87140 +
87141 + @Return E_OK on success; Error code otherwise.
87142 +
87143 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87144 +*//***************************************************************************/
87145 +t_Error FM_PORT_ConfigDmaIcCacheAttr(t_Handle h_FmPort, e_FmDmaCacheOption intContextCacheAttr);
87146 +
87147 +/**************************************************************************//**
87148 + @Function FM_PORT_ConfigDmaHdrAttr
87149 +
87150 + @Description Calling this routine changes the header cache
87151 + attribute parameter in the internal driver data base
87152 + from its default configuration [DEFAULT_PORT_dmaHeaderCacheAttr]
87153 +
87154 + May be used for all port types
87155 +
87156 + @Param[in] h_FmPort A handle to a FM Port module.
87157 + @Param[in] headerCacheAttr New selection
87158 +
87159 + @Return E_OK on success; Error code otherwise.
87160 +
87161 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87162 +*//***************************************************************************/
87163 +t_Error FM_PORT_ConfigDmaHdrAttr(t_Handle h_FmPort, e_FmDmaCacheOption headerCacheAttr);
87164 +
87165 +/**************************************************************************//**
87166 + @Function FM_PORT_ConfigDmaScatterGatherAttr
87167 +
87168 + @Description Calling this routine changes the scatter gather cache
87169 + attribute parameter in the internal driver data base
87170 + from its default configuration [DEFAULT_PORT_dmaScatterGatherCacheAttr]
87171 +
87172 + May be used for all port types
87173 +
87174 + @Param[in] h_FmPort A handle to a FM Port module.
87175 + @Param[in] scatterGatherCacheAttr New selection
87176 +
87177 + @Return E_OK on success; Error code otherwise.
87178 +
87179 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87180 +*//***************************************************************************/
87181 +t_Error FM_PORT_ConfigDmaScatterGatherAttr(t_Handle h_FmPort, e_FmDmaCacheOption scatterGatherCacheAttr);
87182 +
87183 +/**************************************************************************//**
87184 + @Function FM_PORT_ConfigDmaWriteOptimize
87185 +
87186 + @Description Calling this routine changes the write optimization
87187 + parameter in the internal driver data base
87188 + from its default configuration: By default optimize = [DEFAULT_PORT_dmaWriteOptimize].
87189 + Note:
87190 +
87191 + 1. For head optimization, data alignment must be >= 16 (supported by default).
87192 +
87193 + 3. For tail optimization, note that the optimization is performed by extending the write transaction
87194 + of the frame payload at the tail as needed to achieve optimal bus transfers, so that the last write
87195 + is extended to be on 16/64 bytes aligned block (chip dependent).
87196 +
87197 + Relevant for non-Tx port types
87198 +
87199 + @Param[in] h_FmPort A handle to a FM Port module.
87200 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
87201 +
87202 + @Return E_OK on success; Error code otherwise.
87203 +
87204 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87205 +*//***************************************************************************/
87206 +t_Error FM_PORT_ConfigDmaWriteOptimize(t_Handle h_FmPort, bool optimize);
87207 +
87208 +/**************************************************************************//**
87209 + @Function FM_PORT_ConfigNoScatherGather
87210 +
87211 + @Description Calling this routine changes the noScatherGather parameter in internal driver data base
87212 + from its default configuration.
87213 +
87214 + @Param[in] h_FmPort A handle to a FM Port module.
87215 + @Param[in] noScatherGather (TRUE - frame is discarded if can not be stored in single buffer,
87216 + FALSE - frame can be stored in scatter gather (S/G) format).
87217 +
87218 + @Return E_OK on success; Error code otherwise.
87219 +
87220 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87221 +*//***************************************************************************/
87222 +t_Error FM_PORT_ConfigNoScatherGather(t_Handle h_FmPort, bool noScatherGather);
87223 +
87224 +/**************************************************************************//**
87225 + @Function FM_PORT_ConfigDfltColor
87226 +
87227 + @Description Calling this routine changes the internal default color parameter
87228 + in the internal driver data base
87229 + from its default configuration [DEFAULT_PORT_color]
87230 +
87231 + May be used for all port types
87232 +
87233 + @Param[in] h_FmPort A handle to a FM Port module.
87234 + @Param[in] color New selection
87235 +
87236 + @Return E_OK on success; Error code otherwise.
87237 +
87238 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87239 +*//***************************************************************************/
87240 +t_Error FM_PORT_ConfigDfltColor(t_Handle h_FmPort, e_FmPortColor color);
87241 +
87242 +/**************************************************************************//**
87243 + @Function FM_PORT_ConfigSyncReq
87244 +
87245 + @Description Calling this routine changes the synchronization attribute parameter
87246 + in the internal driver data base from its default configuration:
87247 + syncReq = [DEFAULT_PORT_syncReq]
87248 +
87249 + May be used for all port types
87250 +
87251 + @Param[in] h_FmPort A handle to a FM Port module.
87252 + @Param[in] syncReq TRUE to request synchronization, FALSE otherwize.
87253 +
87254 + @Return E_OK on success; Error code otherwise.
87255 +
87256 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87257 +*//***************************************************************************/
87258 +t_Error FM_PORT_ConfigSyncReq(t_Handle h_FmPort, bool syncReq);
87259 +
87260 +/**************************************************************************//**
87261 + @Function FM_PORT_ConfigForwardReuseIntContext
87262 +
87263 + @Description This routine is relevant for Rx ports that are routed to OP port.
87264 + It changes the internal context reuse option in the internal
87265 + driver data base from its default configuration:
87266 + reuse = [DEFAULT_PORT_forwardIntContextReuse]
87267 +
87268 + May be used for Rx ports only
87269 +
87270 + @Param[in] h_FmPort A handle to a FM Port module.
87271 + @Param[in] reuse TRUE to reuse internal context on frames
87272 + forwarded to OP port.
87273 +
87274 + @Return E_OK on success; Error code otherwise.
87275 +
87276 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87277 +*//***************************************************************************/
87278 +t_Error FM_PORT_ConfigForwardReuseIntContext(t_Handle h_FmPort, bool reuse);
87279 +
87280 +/**************************************************************************//**
87281 + @Function FM_PORT_ConfigDontReleaseTxBufToBM
87282 +
87283 + @Description This routine should be called if no Tx confirmation
87284 + is done, and yet buffers should not be released to the BM.
87285 + Normally, buffers are returned using the Tx confirmation
87286 + process. When Tx confirmation is not used (defFqid=0),
87287 + buffers are typically released to the BM. This routine
87288 + may be called to avoid this behavior and not release the
87289 + buffers.
87290 +
87291 + May be used for Tx ports only
87292 +
87293 + @Param[in] h_FmPort A handle to a FM Port module.
87294 +
87295 + @Return E_OK on success; Error code otherwise.
87296 +
87297 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87298 +*//***************************************************************************/
87299 +t_Error FM_PORT_ConfigDontReleaseTxBufToBM(t_Handle h_FmPort);
87300 +
87301 +/**************************************************************************//**
87302 + @Function FM_PORT_ConfigIMMaxRxBufLength
87303 +
87304 + @Description Changes the maximum receive buffer length from its default
87305 + configuration: Closest rounded down power of 2 value of the
87306 + data buffer size.
87307 +
87308 + The maximum receive buffer length directly affects the structure
87309 + of received frames (single- or multi-buffered) and the performance
87310 + of both the FM and the driver.
87311 +
87312 + The selection between single- or multi-buffered frames should be
87313 + done according to the characteristics of the specific application.
87314 + The recommended mode is to use a single data buffer per packet,
87315 + as this mode provides the best performance. However, the user can
87316 + select to use multiple data buffers per packet.
87317 +
87318 + @Param[in] h_FmPort A handle to a FM Port module.
87319 + @Param[in] newVal Maximum receive buffer length (in bytes).
87320 +
87321 + @Return E_OK on success; Error code otherwise.
87322 +
87323 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87324 + This routine is to be used only if Independent-Mode is enabled.
87325 +*//***************************************************************************/
87326 +t_Error FM_PORT_ConfigIMMaxRxBufLength(t_Handle h_FmPort, uint16_t newVal);
87327 +
87328 +/**************************************************************************//**
87329 + @Function FM_PORT_ConfigIMRxBdRingLength
87330 +
87331 + @Description Changes the receive BD ring length from its default
87332 + configuration:[DEFAULT_PORT_rxBdRingLength]
87333 +
87334 + @Param[in] h_FmPort A handle to a FM Port module.
87335 + @Param[in] newVal The desired BD ring length.
87336 +
87337 + @Return E_OK on success; Error code otherwise.
87338 +
87339 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87340 + This routine is to be used only if Independent-Mode is enabled.
87341 +*//***************************************************************************/
87342 +t_Error FM_PORT_ConfigIMRxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
87343 +
87344 +/**************************************************************************//**
87345 + @Function FM_PORT_ConfigIMTxBdRingLength
87346 +
87347 + @Description Changes the transmit BD ring length from its default
87348 + configuration:[DEFAULT_PORT_txBdRingLength]
87349 +
87350 + @Param[in] h_FmPort A handle to a FM Port module.
87351 + @Param[in] newVal The desired BD ring length.
87352 +
87353 + @Return E_OK on success; Error code otherwise.
87354 +
87355 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87356 + This routine is to be used only if Independent-Mode is enabled.
87357 +*//***************************************************************************/
87358 +t_Error FM_PORT_ConfigIMTxBdRingLength(t_Handle h_FmPort, uint16_t newVal);
87359 +
87360 +/**************************************************************************//**
87361 + @Function FM_PORT_ConfigIMFmanCtrlExternalStructsMemory
87362 +
87363 + @Description Configures memory partition and attributes for FMan-Controller
87364 + data structures (e.g. BD rings).
87365 + Calling this routine changes the internal driver data base
87366 + from its default configuration
87367 + [DEFAULT_PORT_ImfwExtStructsMemId, DEFAULT_PORT_ImfwExtStructsMemAttr].
87368 +
87369 + @Param[in] h_FmPort A handle to a FM Port module.
87370 + @Param[in] memId Memory partition ID.
87371 + @Param[in] memAttributes Memory attributes mask (a combination of MEMORY_ATTR_x flags).
87372 +
87373 + @Return E_OK on success; Error code otherwise.
87374 +*//***************************************************************************/
87375 +t_Error FM_PORT_ConfigIMFmanCtrlExternalStructsMemory(t_Handle h_FmPort,
87376 + uint8_t memId,
87377 + uint32_t memAttributes);
87378 +
87379 +/**************************************************************************//**
87380 + @Function FM_PORT_ConfigIMPolling
87381 +
87382 + @Description Changes the Rx flow from interrupt driven (default) to polling.
87383 +
87384 + @Param[in] h_FmPort A handle to a FM Port module.
87385 +
87386 + @Return E_OK on success; Error code otherwise.
87387 +
87388 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87389 + This routine is to be used only if Independent-Mode is enabled.
87390 +*//***************************************************************************/
87391 +t_Error FM_PORT_ConfigIMPolling(t_Handle h_FmPort);
87392 +
87393 +/**************************************************************************//**
87394 + @Function FM_PORT_ConfigMaxFrameLength
87395 +
87396 + @Description Changes the definition of the max size of frame that should be
87397 + transmitted/received on this port from its default value [DEFAULT_PORT_maxFrameLength].
87398 + This parameter is used for confirmation of the minimum Fifo
87399 + size calculations and only for Tx ports or ports working in
87400 + independent mode. This should be larger than the maximum possible
87401 + MTU that will be used for this port (i.e. its MAC).
87402 +
87403 + @Param[in] h_FmPort A handle to a FM Port module.
87404 + @Param[in] length Max size of frame
87405 +
87406 + @Return E_OK on success; Error code otherwise.
87407 +
87408 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87409 + This routine is to be used only if Independent-Mode is enabled.
87410 +*//***************************************************************************/
87411 +t_Error FM_PORT_ConfigMaxFrameLength(t_Handle h_FmPort, uint16_t length);
87412 +
87413 +/**************************************************************************//*
87414 + @Function FM_PORT_ConfigTxFifoMinFillLevel
87415 +
87416 + @Description Calling this routine changes the fifo minimum
87417 + fill level parameter in the internal driver data base
87418 + from its default configuration [DEFAULT_PORT_txFifoMinFillLevel]
87419 +
87420 + May be used for Tx ports only
87421 +
87422 + @Param[in] h_FmPort A handle to a FM Port module.
87423 + @Param[in] minFillLevel New value
87424 +
87425 + @Return E_OK on success; Error code otherwise.
87426 +
87427 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87428 +*//***************************************************************************/
87429 +t_Error FM_PORT_ConfigTxFifoMinFillLevel(t_Handle h_FmPort, uint32_t minFillLevel);
87430 +
87431 +/**************************************************************************//*
87432 + @Function FM_PORT_ConfigFifoDeqPipelineDepth
87433 +
87434 + @Description Calling this routine changes the fifo dequeue
87435 + pipeline depth parameter in the internal driver data base
87436 +
87437 + from its default configuration: 1G ports: [DEFAULT_PORT_fifoDeqPipelineDepth_1G],
87438 + 10G port: [DEFAULT_PORT_fifoDeqPipelineDepth_10G],
87439 + OP port: [DEFAULT_PORT_fifoDeqPipelineDepth_OH]
87440 +
87441 + May be used for Tx/OP ports only
87442 +
87443 + @Param[in] h_FmPort A handle to a FM Port module.
87444 + @Param[in] deqPipelineDepth New value
87445 +
87446 + @Return E_OK on success; Error code otherwise.
87447 +
87448 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87449 +*//***************************************************************************/
87450 +t_Error FM_PORT_ConfigFifoDeqPipelineDepth(t_Handle h_FmPort, uint8_t deqPipelineDepth);
87451 +
87452 +/**************************************************************************//*
87453 + @Function FM_PORT_ConfigTxFifoLowComfLevel
87454 +
87455 + @Description Calling this routine changes the fifo low comfort level
87456 + parameter in internal driver data base
87457 + from its default configuration [DEFAULT_PORT_txFifoLowComfLevel]
87458 +
87459 + May be used for Tx ports only
87460 +
87461 + @Param[in] h_FmPort A handle to a FM Port module.
87462 + @Param[in] fifoLowComfLevel New value
87463 +
87464 + @Return E_OK on success; Error code otherwise.
87465 +
87466 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87467 +*//***************************************************************************/
87468 +t_Error FM_PORT_ConfigTxFifoLowComfLevel(t_Handle h_FmPort, uint32_t fifoLowComfLevel);
87469 +
87470 +/**************************************************************************//*
87471 + @Function FM_PORT_ConfigRxFifoThreshold
87472 +
87473 + @Description Calling this routine changes the threshold of the FIFO
87474 + fill level parameter in the internal driver data base
87475 + from its default configuration [DEFAULT_PORT_rxFifoThreshold]
87476 +
87477 + If the total number of buffers which are
87478 + currently in use and associated with the
87479 + specific RX port exceed this threshold, the
87480 + BMI will signal the MAC to send a pause frame
87481 + over the link.
87482 +
87483 + May be used for Rx ports only
87484 +
87485 + @Param[in] h_FmPort A handle to a FM Port module.
87486 + @Param[in] fifoThreshold New value
87487 +
87488 + @Return E_OK on success; Error code otherwise.
87489 +
87490 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87491 +*//***************************************************************************/
87492 +t_Error FM_PORT_ConfigRxFifoThreshold(t_Handle h_FmPort, uint32_t fifoThreshold);
87493 +
87494 +/**************************************************************************//*
87495 + @Function FM_PORT_ConfigRxFifoPriElevationLevel
87496 +
87497 + @Description Calling this routine changes the priority elevation level
87498 + parameter in the internal driver data base from its default
87499 + configuration [DEFAULT_PORT_rxFifoPriElevationLevel]
87500 +
87501 + If the total number of buffers which are currently in use and
87502 + associated with the specific RX port exceed the amount specified
87503 + in priElevationLevel, BMI will signal the main FM's DMA to
87504 + elevate the FM priority on the system bus.
87505 +
87506 + May be used for Rx ports only
87507 +
87508 + @Param[in] h_FmPort A handle to a FM Port module.
87509 + @Param[in] priElevationLevel New value
87510 +
87511 + @Return E_OK on success; Error code otherwise.
87512 +
87513 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87514 +*//***************************************************************************/
87515 +t_Error FM_PORT_ConfigRxFifoPriElevationLevel(t_Handle h_FmPort, uint32_t priElevationLevel);
87516 +
87517 +#ifdef FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
87518 +/**************************************************************************//*
87519 + @Function FM_PORT_ConfigBCBWorkaround
87520 +
87521 + @Description Configures BCB errata workaround.
87522 +
87523 + When BCB errata is applicable, the workaround is always
87524 + performed by FM Controller. Thus, this functions doesn't
87525 + actually enable errata workaround but rather allows driver
87526 + to perform adjustments required due to errata workaround
87527 + execution in FM controller.
87528 +
87529 + Applying BCB workaround also configures FM_PORT_FRM_ERR_PHYSICAL
87530 + errors to be discarded. Thus FM_PORT_FRM_ERR_PHYSICAL can't be
87531 + set by FM_PORT_SetErrorsRoute() function.
87532 +
87533 + @Param[in] h_FmPort A handle to a FM Port module.
87534 +
87535 + @Return E_OK on success; Error code otherwise.
87536 +
87537 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87538 +*//***************************************************************************/
87539 +t_Error FM_PORT_ConfigBCBWorkaround(t_Handle h_FmPort);
87540 +#endif /* FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669 */
87541 +
87542 +#if (DPAA_VERSION >= 11)
87543 +/**************************************************************************//*
87544 + @Function FM_PORT_ConfigInternalBuffOffset
87545 +
87546 + @Description Configures internal buffer offset.
87547 +
87548 + May be used for Rx and OP ports only
87549 +
87550 + @Param[in] h_FmPort A handle to a FM Port module.
87551 + @Param[in] val New value
87552 +
87553 + @Return E_OK on success; Error code otherwise.
87554 +
87555 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
87556 +*//***************************************************************************/
87557 +t_Error FM_PORT_ConfigInternalBuffOffset(t_Handle h_FmPort, uint8_t val);
87558 +#endif /* (DPAA_VERSION >= 11) */
87559 +
87560 +/** @} */ /* end of FM_PORT_advanced_init_grp group */
87561 +/** @} */ /* end of FM_PORT_init_grp group */
87562 +
87563 +
87564 +/**************************************************************************//**
87565 + @Group FM_PORT_runtime_control_grp FM Port Runtime Control Unit
87566 +
87567 + @Description FM Port Runtime control unit API functions, definitions and enums.
87568 +
87569 + @{
87570 +*//***************************************************************************/
87571 +
87572 +/**************************************************************************//**
87573 + @Description enum for defining FM Port counters
87574 +*//***************************************************************************/
87575 +typedef enum e_FmPortCounters {
87576 + e_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
87577 + e_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
87578 + e_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
87579 + e_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
87580 + e_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
87581 + e_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
87582 + e_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
87583 + e_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
87584 + e_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
87585 + e_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
87586 + e_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
87587 + e_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
87588 + e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
87589 + e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
87590 + e_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
87591 + e_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
87592 + e_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
87593 + e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
87594 + e_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
87595 + e_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
87596 + e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
87597 + e_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
87598 +} e_FmPortCounters;
87599 +
87600 +typedef struct t_FmPortBmiStats {
87601 + uint32_t cntCycle;
87602 + uint32_t cntTaskUtil;
87603 + uint32_t cntQueueUtil;
87604 + uint32_t cntDmaUtil;
87605 + uint32_t cntFifoUtil;
87606 + uint32_t cntRxPauseActivation;
87607 + uint32_t cntFrame;
87608 + uint32_t cntDiscardFrame;
87609 + uint32_t cntDeallocBuf;
87610 + uint32_t cntRxBadFrame;
87611 + uint32_t cntRxLargeFrame;
87612 + uint32_t cntRxFilterFrame;
87613 + uint32_t cntRxListDmaErr;
87614 + uint32_t cntRxOutOfBuffersDiscard;
87615 + uint32_t cntWredDiscard;
87616 + uint32_t cntLengthErr;
87617 + uint32_t cntUnsupportedFormat;
87618 +} t_FmPortBmiStats;
87619 +
87620 +/**************************************************************************//**
87621 + @Description Structure for Port id parameters.
87622 + Fields commented 'IN' are passed by the port module to be used
87623 + by the FM module.
87624 + Fields commented 'OUT' will be filled by FM before returning to port.
87625 +*//***************************************************************************/
87626 +typedef struct t_FmPortCongestionGrps {
87627 + uint16_t numOfCongestionGrpsToConsider; /**< The number of required CGs
87628 + to define the size of the following array */
87629 + uint8_t congestionGrpsToConsider[FM_PORT_NUM_OF_CONGESTION_GRPS];
87630 + /**< An array of CG indexes;
87631 + Note that the size of the array should be
87632 + 'numOfCongestionGrpsToConsider'. */
87633 +#if (DPAA_VERSION >= 11)
87634 + bool pfcPrioritiesEn[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
87635 + /**< a matrix that represents the map between the CG ids
87636 + defined in 'congestionGrpsToConsider' to the priorties
87637 + mapping array. */
87638 +#endif /* (DPAA_VERSION >= 11) */
87639 +} t_FmPortCongestionGrps;
87640 +
87641 +/**************************************************************************//**
87642 + @Description Structure for Deep Sleep Auto Response ARP Entry
87643 +*//***************************************************************************/
87644 +typedef struct t_FmPortDsarArpEntry
87645 +{
87646 + uint32_t ipAddress;
87647 + uint8_t mac[6];
87648 + bool isVlan;
87649 + uint16_t vid;
87650 +} t_FmPortDsarArpEntry;
87651 +
87652 +/**************************************************************************//**
87653 + @Description Structure for Deep Sleep Auto Response ARP info
87654 +*//***************************************************************************/
87655 +typedef struct t_FmPortDsarArpInfo
87656 +{
87657 + uint8_t tableSize;
87658 + t_FmPortDsarArpEntry *p_AutoResTable;
87659 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
87660 +} t_FmPortDsarArpInfo;
87661 +
87662 +/**************************************************************************//**
87663 + @Description Structure for Deep Sleep Auto Response NDP Entry
87664 +*//***************************************************************************/
87665 +typedef struct t_FmPortDsarNdpEntry
87666 +{
87667 + uint32_t ipAddress[4];
87668 + uint8_t mac[6];
87669 + bool isVlan;
87670 + uint16_t vid;
87671 +} t_FmPortDsarNdpEntry;
87672 +
87673 +/**************************************************************************//**
87674 + @Description Structure for Deep Sleep Auto Response NDP info
87675 +*//***************************************************************************/
87676 +typedef struct t_FmPortDsarNdpInfo
87677 +{
87678 + uint32_t multicastGroup;
87679 +
87680 + uint8_t tableSizeAssigned;
87681 + t_FmPortDsarNdpEntry *p_AutoResTableAssigned; /* This list refer to solicitation IP addresses.
87682 + Note that all IP adresses must be from the same multicast group.
87683 + This will be checked and if not operation will fail. */
87684 + uint8_t tableSizeTmp;
87685 + t_FmPortDsarNdpEntry *p_AutoResTableTmp; /* This list refer to temp IP addresses.
87686 + Note that all temp IP adresses must be from the same multicast group.
87687 + This will be checked and if not operation will fail. */
87688 +
87689 + bool enableConflictDetection; /* when TRUE Conflict Detection will be checked and wake the host if needed */
87690 +
87691 +} t_FmPortDsarNdpInfo;
87692 +
87693 +/**************************************************************************//**
87694 + @Description Structure for Deep Sleep Auto Response ICMPV4 info
87695 +*//***************************************************************************/
87696 +typedef struct t_FmPortDsarEchoIpv4Info
87697 +{
87698 + uint8_t tableSize;
87699 + t_FmPortDsarArpEntry *p_AutoResTable;
87700 +} t_FmPortDsarEchoIpv4Info;
87701 +
87702 +/**************************************************************************//**
87703 + @Description Structure for Deep Sleep Auto Response ICMPV6 info
87704 +*//***************************************************************************/
87705 +typedef struct t_FmPortDsarEchoIpv6Info
87706 +{
87707 + uint8_t tableSize;
87708 + t_FmPortDsarNdpEntry *p_AutoResTable;
87709 +} t_FmPortDsarEchoIpv6Info;
87710 +
87711 +/**************************************************************************//**
87712 +@Description Deep Sleep Auto Response SNMP OIDs table entry
87713 +
87714 +*//***************************************************************************/
87715 +typedef struct {
87716 + uint16_t oidSize;
87717 + uint8_t *oidVal; /* only the oid string */
87718 + uint16_t resSize;
87719 + uint8_t *resVal; /* resVal will be the entire reply,
87720 + i.e. "Type|Length|Value" */
87721 +} t_FmPortDsarOidsEntry;
87722 +
87723 +/**************************************************************************//**
87724 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
87725 + Refer to the FMan Controller spec for more details.
87726 +*//***************************************************************************/
87727 +typedef struct
87728 +{
87729 + uint32_t ipv4Addr; /*!< 32 bit IPv4 Address. */
87730 + bool isVlan;
87731 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
87732 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
87733 +} t_FmPortDsarSnmpIpv4AddrTblEntry;
87734 +
87735 +/**************************************************************************//**
87736 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
87737 + Refer to the FMan Controller spec for more details.
87738 +*//***************************************************************************/
87739 +typedef struct
87740 +{
87741 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
87742 + bool isVlan;
87743 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
87744 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
87745 +} t_FmPortDsarSnmpIpv6AddrTblEntry;
87746 +
87747 +/**************************************************************************//**
87748 + @Description Deep Sleep Auto Response SNMP Descriptor
87749 +
87750 +*//***************************************************************************/
87751 +typedef struct
87752 +{
87753 + uint16_t control; /**< Control bits [0-15]. */
87754 + uint16_t maxSnmpMsgLength; /**< Maximal allowed SNMP message length. */
87755 + uint16_t numOfIpv4Addresses; /**< Number of entries in IPv4 addresses table. */
87756 + uint16_t numOfIpv6Addresses; /**< Number of entries in IPv6 addresses table. */
87757 + t_FmPortDsarSnmpIpv4AddrTblEntry *p_Ipv4AddrTbl; /**< Pointer to IPv4 addresses table. */
87758 + t_FmPortDsarSnmpIpv6AddrTblEntry *p_Ipv6AddrTbl; /**< Pointer to IPv6 addresses table. */
87759 + uint8_t *p_RdOnlyCommunityStr; /**< Pointer to the Read Only Community String. */
87760 + uint8_t *p_RdWrCommunityStr; /**< Pointer to the Read Write Community String. */
87761 + t_FmPortDsarOidsEntry *p_OidsTbl; /**< Pointer to OIDs table. */
87762 + uint32_t oidsTblSize; /**< Number of entries in OIDs table. */
87763 +} t_FmPortDsarSnmpInfo;
87764 +
87765 +/**************************************************************************//**
87766 + @Description Structure for Deep Sleep Auto Response filtering Entry
87767 +*//***************************************************************************/
87768 +typedef struct t_FmPortDsarFilteringEntry
87769 +{
87770 + uint16_t srcPort;
87771 + uint16_t dstPort;
87772 + uint16_t srcPortMask;
87773 + uint16_t dstPortMask;
87774 +} t_FmPortDsarFilteringEntry;
87775 +
87776 +/**************************************************************************//**
87777 + @Description Structure for Deep Sleep Auto Response filtering info
87778 +*//***************************************************************************/
87779 +typedef struct t_FmPortDsarFilteringInfo
87780 +{
87781 + /* IP protocol filtering parameters */
87782 + uint8_t ipProtTableSize;
87783 + uint8_t *p_IpProtTablePtr;
87784 + bool ipProtPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
87785 + hit will pass the packet to UDP/TCP filters if needed and if not
87786 + to the classification tree. If the classification tree will pass
87787 + the packet to a queue it will cause a wake interupt.
87788 + When FALSE it the other way around. */
87789 + /* UDP port filtering parameters */
87790 + uint8_t udpPortsTableSize;
87791 + t_FmPortDsarFilteringEntry *p_UdpPortsTablePtr;
87792 + bool udpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
87793 + hit will pass the packet to classification tree.
87794 + If the classification tree will pass the packet to a queue it
87795 + will cause a wake interupt.
87796 + When FALSE it the other way around. */
87797 + /* TCP port filtering parameters */
87798 + uint16_t tcpFlagsMask;
87799 + uint8_t tcpPortsTableSize;
87800 + t_FmPortDsarFilteringEntry *p_TcpPortsTablePtr;
87801 + bool tcpPortPassOnHit; /* when TRUE, miss in the table will cause the packet to be droped,
87802 + hit will pass the packet to classification tree.
87803 + If the classification tree will pass the packet to a queue it
87804 + will cause a wake interupt.
87805 + When FALSE it the other way around. */
87806 +} t_FmPortDsarFilteringInfo;
87807 +
87808 +/**************************************************************************//**
87809 + @Description Structure for Deep Sleep Auto Response parameters
87810 +*//***************************************************************************/
87811 +typedef struct t_FmPortDsarParams
87812 +{
87813 + t_Handle h_FmPortTx;
87814 + t_FmPortDsarArpInfo *p_AutoResArpInfo;
87815 + t_FmPortDsarEchoIpv4Info *p_AutoResEchoIpv4Info;
87816 + t_FmPortDsarNdpInfo *p_AutoResNdpInfo;
87817 + t_FmPortDsarEchoIpv6Info *p_AutoResEchoIpv6Info;
87818 + t_FmPortDsarSnmpInfo *p_AutoResSnmpInfo;
87819 + t_FmPortDsarFilteringInfo *p_AutoResFilteringInfo;
87820 +} t_FmPortDsarParams;
87821 +
87822 +/**************************************************************************//**
87823 + @Function FM_PORT_EnterDsar
87824 +
87825 + @Description Enter Deep Sleep Auto Response mode.
87826 + This function write the apropriate values to in the relevant
87827 + tables in the MURAM.
87828 +
87829 + @Param[in] h_FmPortRx - FM PORT module descriptor
87830 + @Param[in] params - Auto Response parameters
87831 +
87832 + @Return E_OK on success; Error code otherwise.
87833 +
87834 + @Cautions Allowed only following FM_PORT_Init().
87835 +*//***************************************************************************/
87836 +t_Error FM_PORT_EnterDsar(t_Handle h_FmPortRx, t_FmPortDsarParams *params);
87837 +
87838 +/**************************************************************************//**
87839 + @Function FM_PORT_EnterDsarFinal
87840 +
87841 + @Description Enter Deep Sleep Auto Response mode.
87842 + This function sets the Tx port in independent mode as needed
87843 + and redirect the receive flow to go through the
87844 + Dsar Fman-ctrl code
87845 +
87846 + @Param[in] h_DsarRxPort - FM Rx PORT module descriptor
87847 + @Param[in] h_DsarTxPort - FM Tx PORT module descriptor
87848 +
87849 + @Return E_OK on success; Error code otherwise.
87850 +
87851 + @Cautions Allowed only following FM_PORT_Init().
87852 +*//***************************************************************************/
87853 +t_Error FM_PORT_EnterDsarFinal(t_Handle h_DsarRxPort, t_Handle h_DsarTxPort);
87854 +
87855 +/**************************************************************************//**
87856 + @Function FM_PORT_ExitDsar
87857 +
87858 + @Description Exit Deep Sleep Auto Response mode.
87859 + This function reverse the AR mode and put the ports back into
87860 + their original wake mode
87861 +
87862 + @Param[in] h_FmPortRx - FM PORT Rx module descriptor
87863 + @Param[in] h_FmPortTx - FM PORT Tx module descriptor
87864 +
87865 + @Return E_OK on success; Error code otherwise.
87866 +
87867 + @Cautions Allowed only following FM_PORT_EnterDsar().
87868 +*//***************************************************************************/
87869 +void FM_PORT_ExitDsar(t_Handle h_FmPortRx, t_Handle h_FmPortTx);
87870 +
87871 +/**************************************************************************//**
87872 + @Function FM_PORT_IsInDsar
87873 +
87874 + @Description This function returns TRUE if the port was set as Auto Response
87875 + and FALSE if not. Once Exit AR mode it will return FALSE as well
87876 + until re-enabled once more.
87877 +
87878 + @Param[in] h_FmPort - FM PORT module descriptor
87879 +
87880 + @Return E_OK on success; Error code otherwise.
87881 +*//***************************************************************************/
87882 +bool FM_PORT_IsInDsar(t_Handle h_FmPort);
87883 +
87884 +typedef struct t_FmPortDsarStats
87885 +{
87886 + uint32_t arpArCnt;
87887 + uint32_t echoIcmpv4ArCnt;
87888 + uint32_t ndpArCnt;
87889 + uint32_t echoIcmpv6ArCnt;
87890 + uint32_t snmpGetCnt;
87891 + uint32_t snmpGetNextCnt;
87892 +} t_FmPortDsarStats;
87893 +
87894 +/**************************************************************************//**
87895 + @Function FM_PORT_GetDsarStats
87896 +
87897 + @Description Return statistics for Deep Sleep Auto Response
87898 +
87899 + @Param[in] h_FmPortRx - FM PORT module descriptor
87900 + @Param[out] stats - structure containing the statistics counters
87901 +
87902 + @Return E_OK on success; Error code otherwise.
87903 +*//***************************************************************************/
87904 +t_Error FM_PORT_GetDsarStats(t_Handle h_FmPortRx, t_FmPortDsarStats *stats);
87905 +
87906 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
87907 +/**************************************************************************//**
87908 + @Function FM_PORT_DumpRegs
87909 +
87910 + @Description Dump all regs.
87911 +
87912 + Calling this routine invalidates the descriptor.
87913 +
87914 + @Param[in] h_FmPort - FM PORT module descriptor
87915 +
87916 + @Return E_OK on success; Error code otherwise.
87917 +
87918 + @Cautions Allowed only following FM_PORT_Init().
87919 +*//***************************************************************************/
87920 +t_Error FM_PORT_DumpRegs(t_Handle h_FmPort);
87921 +#endif /* (defined(DEBUG_ERRORS) && ... */
87922 +
87923 +/**************************************************************************//**
87924 + @Function FM_PORT_GetBufferDataOffset
87925 +
87926 + @Description Relevant for Rx ports.
87927 + Returns the data offset from the beginning of the data buffer
87928 +
87929 + @Param[in] h_FmPort - FM PORT module descriptor
87930 +
87931 + @Return data offset.
87932 +
87933 + @Cautions Allowed only following FM_PORT_Init().
87934 +*//***************************************************************************/
87935 +uint32_t FM_PORT_GetBufferDataOffset(t_Handle h_FmPort);
87936 +
87937 +/**************************************************************************//**
87938 + @Function FM_PORT_GetBufferICInfo
87939 +
87940 + @Description Returns the Internal Context offset from the beginning of the data buffer
87941 +
87942 + @Param[in] h_FmPort - FM PORT module descriptor
87943 + @Param[in] p_Data - A pointer to the data buffer.
87944 +
87945 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
87946 + configured for this port.
87947 +
87948 + @Cautions Allowed only following FM_PORT_Init().
87949 +*//***************************************************************************/
87950 +uint8_t * FM_PORT_GetBufferICInfo(t_Handle h_FmPort, char *p_Data);
87951 +
87952 +/**************************************************************************//**
87953 + @Function FM_PORT_GetBufferPrsResult
87954 +
87955 + @Description Returns the pointer to the parse result in the data buffer.
87956 + In Rx ports this is relevant after reception, if parse
87957 + result is configured to be part of the data passed to the
87958 + application. For non Rx ports it may be used to get the pointer
87959 + of the area in the buffer where parse result should be
87960 + initialized - if so configured.
87961 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
87962 + configuration.
87963 +
87964 + @Param[in] h_FmPort - FM PORT module descriptor
87965 + @Param[in] p_Data - A pointer to the data buffer.
87966 +
87967 + @Return Parse result pointer on success, NULL if parse result was not
87968 + configured for this port.
87969 +
87970 + @Cautions Allowed only following FM_PORT_Init().
87971 +*//***************************************************************************/
87972 +t_FmPrsResult * FM_PORT_GetBufferPrsResult(t_Handle h_FmPort, char *p_Data);
87973 +
87974 +/**************************************************************************//**
87975 + @Function FM_PORT_GetBufferTimeStamp
87976 +
87977 + @Description Returns the time stamp in the data buffer.
87978 + Relevant for Rx ports for getting the buffer time stamp.
87979 + See FM_PORT_ConfigBufferPrefixContent for data buffer prefix
87980 + configuration.
87981 +
87982 + @Param[in] h_FmPort - FM PORT module descriptor
87983 + @Param[in] p_Data - A pointer to the data buffer.
87984 +
87985 + @Return A pointer to the hash result on success, NULL otherwise.
87986 +
87987 + @Cautions Allowed only following FM_PORT_Init().
87988 +*//***************************************************************************/
87989 +uint64_t * FM_PORT_GetBufferTimeStamp(t_Handle h_FmPort, char *p_Data);
87990 +
87991 +/**************************************************************************//**
87992 + @Function FM_PORT_GetBufferHashResult
87993 +
87994 + @Description Given a data buffer, on the condition that hash result was defined
87995 + as a part of the buffer content (see FM_PORT_ConfigBufferPrefixContent)
87996 + this routine will return the pointer to the hash result location in the
87997 + buffer prefix.
87998 +
87999 + @Param[in] h_FmPort - FM PORT module descriptor
88000 + @Param[in] p_Data - A pointer to the data buffer.
88001 +
88002 + @Return A pointer to the hash result on success, NULL otherwise.
88003 +
88004 + @Cautions Allowed only following FM_PORT_Init().
88005 +*//***************************************************************************/
88006 +uint8_t * FM_PORT_GetBufferHashResult(t_Handle h_FmPort, char *p_Data);
88007 +
88008 +/**************************************************************************//**
88009 + @Function FM_PORT_Disable
88010 +
88011 + @Description Gracefully disable an FM port. The port will not start new tasks after all
88012 + tasks associated with the port are terminated.
88013 +
88014 + @Param[in] h_FmPort A handle to a FM Port module.
88015 +
88016 + @Return E_OK on success; Error code otherwise.
88017 +
88018 + @Cautions Allowed only following FM_PORT_Init().
88019 + This is a blocking routine, it returns after port is
88020 + gracefully stopped, i.e. the port will not except new frames,
88021 + but it will finish all frames or tasks which were already began
88022 +*//***************************************************************************/
88023 +t_Error FM_PORT_Disable(t_Handle h_FmPort);
88024 +
88025 +/**************************************************************************//**
88026 + @Function FM_PORT_Enable
88027 +
88028 + @Description A runtime routine provided to allow disable/enable of port.
88029 +
88030 + @Param[in] h_FmPort A handle to a FM Port module.
88031 +
88032 + @Return E_OK on success; Error code otherwise.
88033 +
88034 + @Cautions Allowed only following FM_PORT_Init().
88035 +*//***************************************************************************/
88036 +t_Error FM_PORT_Enable(t_Handle h_FmPort);
88037 +
88038 +/**************************************************************************//**
88039 + @Function FM_PORT_SetRateLimit
88040 +
88041 + @Description Calling this routine enables rate limit algorithm.
88042 + By default, this functionality is disabled.
88043 + Note that rate-limit mechanism uses the FM time stamp.
88044 + The selected rate limit specified here would be
88045 + rounded DOWN to the nearest 16M.
88046 +
88047 + May be used for Tx and OP ports only
88048 +
88049 + @Param[in] h_FmPort A handle to a FM Port module.
88050 + @Param[in] p_RateLimit A structure of rate limit parameters
88051 +
88052 + @Return E_OK on success; Error code otherwise.
88053 +
88054 + @Cautions Allowed only following FM_PORT_Init().
88055 + If rate limit is set on a port that need to send PFC frames,
88056 + it might violate the stop transmit timing.
88057 +*//***************************************************************************/
88058 +t_Error FM_PORT_SetRateLimit(t_Handle h_FmPort, t_FmPortRateLimit *p_RateLimit);
88059 +
88060 +/**************************************************************************//**
88061 + @Function FM_PORT_DeleteRateLimit
88062 +
88063 + @Description Calling this routine disables and clears rate limit
88064 + initialization.
88065 +
88066 + May be used for Tx and OP ports only
88067 +
88068 + @Param[in] h_FmPort A handle to a FM Port module.
88069 +
88070 + @Return E_OK on success; Error code otherwise.
88071 +
88072 + @Cautions Allowed only following FM_PORT_Init().
88073 +*//***************************************************************************/
88074 +t_Error FM_PORT_DeleteRateLimit(t_Handle h_FmPort);
88075 +
88076 +/**************************************************************************//**
88077 + @Function FM_PORT_SetPfcPrioritiesMappingToQmanWQ
88078 +
88079 + @Description Calling this routine maps each PFC received priority to the transmit WQ.
88080 + This WQ will be blocked upon receiving a PFC frame with this priority.
88081 +
88082 + May be used for Tx ports only.
88083 +
88084 + @Param[in] h_FmPort A handle to a FM Port module.
88085 + @Param[in] prio PFC priority (0-7).
88086 + @Param[in] wq Work Queue (0-7).
88087 +
88088 + @Return E_OK on success; Error code otherwise.
88089 +
88090 + @Cautions Allowed only following FM_PORT_Init().
88091 +*//***************************************************************************/
88092 +t_Error FM_PORT_SetPfcPrioritiesMappingToQmanWQ(t_Handle h_FmPort, uint8_t prio, uint8_t wq);
88093 +
88094 +/**************************************************************************//**
88095 + @Function FM_PORT_SetStatisticsCounters
88096 +
88097 + @Description Calling this routine enables/disables port's statistics counters.
88098 + By default, counters are enabled.
88099 +
88100 + May be used for all port types
88101 +
88102 + @Param[in] h_FmPort A handle to a FM Port module.
88103 + @Param[in] enable TRUE to enable, FALSE to disable.
88104 +
88105 + @Return E_OK on success; Error code otherwise.
88106 +
88107 + @Cautions Allowed only following FM_PORT_Init().
88108 +*//***************************************************************************/
88109 +t_Error FM_PORT_SetStatisticsCounters(t_Handle h_FmPort, bool enable);
88110 +
88111 +/**************************************************************************//**
88112 + @Function FM_PORT_SetFrameQueueCounters
88113 +
88114 + @Description Calling this routine enables/disables port's enqueue/dequeue counters.
88115 + By default, counters are enabled.
88116 +
88117 + May be used for all ports
88118 +
88119 + @Param[in] h_FmPort A handle to a FM Port module.
88120 + @Param[in] enable TRUE to enable, FALSE to disable.
88121 +
88122 + @Return E_OK on success; Error code otherwise.
88123 +
88124 + @Cautions Allowed only following FM_PORT_Init().
88125 +*//***************************************************************************/
88126 +t_Error FM_PORT_SetFrameQueueCounters(t_Handle h_FmPort, bool enable);
88127 +
88128 +/**************************************************************************//**
88129 + @Function FM_PORT_AnalyzePerformanceParams
88130 +
88131 + @Description User may call this routine to so the driver will analyze if the
88132 + basic performance parameters are correct and also the driver may
88133 + suggest of improvements; The basic parameters are FIFO sizes, number
88134 + of DMAs and number of TNUMs for the port.
88135 +
88136 + May be used for all port types
88137 +
88138 + @Param[in] h_FmPort A handle to a FM Port module.
88139 +
88140 + @Return E_OK on success; Error code otherwise.
88141 +
88142 + @Cautions Allowed only following FM_PORT_Init().
88143 +*//***************************************************************************/
88144 +t_Error FM_PORT_AnalyzePerformanceParams(t_Handle h_FmPort);
88145 +
88146 +
88147 +/**************************************************************************//**
88148 + @Function FM_PORT_SetAllocBufCounter
88149 +
88150 + @Description Calling this routine enables/disables BM pool allocate
88151 + buffer counters.
88152 + By default, counters are enabled.
88153 +
88154 + May be used for Rx ports only
88155 +
88156 + @Param[in] h_FmPort A handle to a FM Port module.
88157 + @Param[in] poolId BM pool id.
88158 + @Param[in] enable TRUE to enable, FALSE to disable.
88159 +
88160 + @Return E_OK on success; Error code otherwise.
88161 +
88162 + @Cautions Allowed only following FM_PORT_Init().
88163 +*//***************************************************************************/
88164 +t_Error FM_PORT_SetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, bool enable);
88165 +
88166 +/**************************************************************************//**
88167 + @Function FM_PORT_GetBmiCounters
88168 +
88169 + @Description Read port's BMI stat counters and place them into
88170 + a designated structure of counters.
88171 +
88172 + @Param[in] h_FmPort A handle to a FM Port module.
88173 + @Param[out] p_BmiStats counters structure
88174 +
88175 + @Return E_OK on success; Error code otherwise.
88176 +
88177 + @Cautions Allowed only following FM_PORT_Init().
88178 +*//***************************************************************************/
88179 +t_Error FM_PORT_GetBmiCounters(t_Handle h_FmPort, t_FmPortBmiStats *p_BmiStats);
88180 +
88181 +/**************************************************************************//**
88182 + @Function FM_PORT_GetCounter
88183 +
88184 + @Description Reads one of the FM PORT counters.
88185 +
88186 + @Param[in] h_FmPort A handle to a FM Port module.
88187 + @Param[in] fmPortCounter The requested counter.
88188 +
88189 + @Return Counter's current value.
88190 +
88191 + @Cautions Allowed only following FM_PORT_Init().
88192 + Note that it is user's responsibility to call this routine only
88193 + for enabled counters, and there will be no indication if a
88194 + disabled counter is accessed.
88195 +*//***************************************************************************/
88196 +uint32_t FM_PORT_GetCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter);
88197 +
88198 +/**************************************************************************//**
88199 + @Function FM_PORT_ModifyCounter
88200 +
88201 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
88202 +
88203 + @Param[in] h_FmPort A handle to a FM Port module.
88204 + @Param[in] fmPortCounter The requested counter.
88205 + @Param[in] value The requested value to be written into the counter.
88206 +
88207 + @Return E_OK on success; Error code otherwise.
88208 +
88209 + @Cautions Allowed only following FM_PORT_Init().
88210 +*//***************************************************************************/
88211 +t_Error FM_PORT_ModifyCounter(t_Handle h_FmPort, e_FmPortCounters fmPortCounter, uint32_t value);
88212 +
88213 +/**************************************************************************//**
88214 + @Function FM_PORT_GetAllocBufCounter
88215 +
88216 + @Description Reads one of the FM PORT buffer counters.
88217 +
88218 + @Param[in] h_FmPort A handle to a FM Port module.
88219 + @Param[in] poolId The requested pool.
88220 +
88221 + @Return Counter's current value.
88222 +
88223 + @Cautions Allowed only following FM_PORT_Init().
88224 + Note that it is user's responsibility to call this routine only
88225 + for enabled counters, and there will be no indication if a
88226 + disabled counter is accessed.
88227 +*//***************************************************************************/
88228 +uint32_t FM_PORT_GetAllocBufCounter(t_Handle h_FmPort, uint8_t poolId);
88229 +
88230 +/**************************************************************************//**
88231 + @Function FM_PORT_ModifyAllocBufCounter
88232 +
88233 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
88234 +
88235 + @Param[in] h_FmPort A handle to a FM Port module.
88236 + @Param[in] poolId The requested pool.
88237 + @Param[in] value The requested value to be written into the counter.
88238 +
88239 + @Return E_OK on success; Error code otherwise.
88240 +
88241 + @Cautions Allowed only following FM_PORT_Init().
88242 +*//***************************************************************************/
88243 +t_Error FM_PORT_ModifyAllocBufCounter(t_Handle h_FmPort, uint8_t poolId, uint32_t value);
88244 +
88245 +/**************************************************************************//**
88246 + @Function FM_PORT_AddCongestionGrps
88247 +
88248 + @Description This routine effects the corresponding Tx port.
88249 + It should be called in order to enable pause
88250 + frame transmission in case of congestion in one or more
88251 + of the congestion groups relevant to this port.
88252 + Each call to this routine may add one or more congestion
88253 + groups to be considered relevant to this port.
88254 +
88255 + May be used for Rx, or RX+OP ports only (depending on chip)
88256 +
88257 + @Param[in] h_FmPort A handle to a FM Port module.
88258 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
88259 + id's to consider.
88260 +
88261 + @Return E_OK on success; Error code otherwise.
88262 +
88263 + @Cautions Allowed only following FM_PORT_Init().
88264 +*//***************************************************************************/
88265 +t_Error FM_PORT_AddCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
88266 +
88267 +/**************************************************************************//**
88268 + @Function FM_PORT_RemoveCongestionGrps
88269 +
88270 + @Description This routine effects the corresponding Tx port. It should be
88271 + called when congestion groups were
88272 + defined for this port and are no longer relevant, or pause
88273 + frames transmitting is not required on their behalf.
88274 + Each call to this routine may remove one or more congestion
88275 + groups to be considered relevant to this port.
88276 +
88277 + May be used for Rx, or RX+OP ports only (depending on chip)
88278 +
88279 + @Param[in] h_FmPort A handle to a FM Port module.
88280 + @Param[in] p_CongestionGrps A pointer to an array of congestion groups
88281 + id's to consider.
88282 +
88283 + @Return E_OK on success; Error code otherwise.
88284 +
88285 + @Cautions Allowed only following FM_PORT_Init().
88286 +*//***************************************************************************/
88287 +t_Error FM_PORT_RemoveCongestionGrps(t_Handle h_FmPort, t_FmPortCongestionGrps *p_CongestionGrps);
88288 +
88289 +/**************************************************************************//**
88290 + @Function FM_PORT_IsStalled
88291 +
88292 + @Description A routine for checking whether the specified port is stalled.
88293 +
88294 + @Param[in] h_FmPort A handle to a FM Port module.
88295 +
88296 + @Return TRUE if port is stalled, FALSE otherwize
88297 +
88298 + @Cautions Allowed only following FM_PORT_Init().
88299 +*//***************************************************************************/
88300 +bool FM_PORT_IsStalled(t_Handle h_FmPort);
88301 +
88302 +/**************************************************************************//**
88303 + @Function FM_PORT_ReleaseStalled
88304 +
88305 + @Description This routine may be called in case the port was stalled and may
88306 + now be released.
88307 + Note that this routine is available only on older FMan revisions
88308 + (FMan v2, DPAA v1.0 only).
88309 +
88310 + @Param[in] h_FmPort A handle to a FM Port module.
88311 +
88312 + @Return E_OK on success; Error code otherwise.
88313 +
88314 + @Cautions Allowed only following FM_PORT_Init().
88315 +*//***************************************************************************/
88316 +t_Error FM_PORT_ReleaseStalled(t_Handle h_FmPort);
88317 +
88318 +/**************************************************************************//**
88319 + @Function FM_PORT_SetRxL4ChecksumVerify
88320 +
88321 + @Description This routine is relevant for Rx ports (1G and 10G). The routine
88322 + set/clear the L3/L4 checksum verification (on RX side).
88323 + Note that this takes affect only if hw-parser is enabled!
88324 +
88325 + @Param[in] h_FmPort A handle to a FM Port module.
88326 + @Param[in] l4Checksum boolean indicates whether to do L3/L4 checksum
88327 + on frames or not.
88328 +
88329 + @Return E_OK on success; Error code otherwise.
88330 +
88331 + @Cautions Allowed only following FM_PORT_Init().
88332 +*//***************************************************************************/
88333 +t_Error FM_PORT_SetRxL4ChecksumVerify(t_Handle h_FmPort, bool l4Checksum);
88334 +
88335 +/**************************************************************************//**
88336 + @Function FM_PORT_SetErrorsRoute
88337 +
88338 + @Description Errors selected for this routine will cause a frame with that error
88339 + to be enqueued to error queue.
88340 + Errors not selected for this routine will cause a frame with that error
88341 + to be enqueued to the one of the other port queues.
88342 + By default all errors are defined to be enqueued to error queue.
88343 + Errors that were configured to be discarded (at initialization)
88344 + may not be selected here.
88345 +
88346 + May be used for Rx and OP ports only
88347 +
88348 + @Param[in] h_FmPort A handle to a FM Port module.
88349 + @Param[in] errs A list of errors to enqueue to error queue
88350 +
88351 + @Return E_OK on success; Error code otherwise.
88352 +
88353 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
88354 +*//***************************************************************************/
88355 +t_Error FM_PORT_SetErrorsRoute(t_Handle h_FmPort, fmPortFrameErrSelect_t errs);
88356 +
88357 +/**************************************************************************//**
88358 + @Function FM_PORT_SetIMExceptions
88359 +
88360 + @Description Calling this routine enables/disables FM PORT interrupts.
88361 +
88362 + @Param[in] h_FmPort FM PORT module descriptor.
88363 + @Param[in] exception The exception to be selected.
88364 + @Param[in] enable TRUE to enable interrupt, FALSE to mask it.
88365 +
88366 + @Return E_OK on success; Error code otherwise.
88367 +
88368 + @Cautions Allowed only following FM_PORT_Init().
88369 + This routine should NOT be called from guest-partition
88370 + (i.e. guestId != NCSW_MASTER_ID)
88371 +*//***************************************************************************/
88372 +t_Error FM_PORT_SetIMExceptions(t_Handle h_FmPort, e_FmPortExceptions exception, bool enable);
88373 +
88374 +/**************************************************************************//*
88375 + @Function FM_PORT_SetPerformanceCounters
88376 +
88377 + @Description Calling this routine enables/disables port's performance counters.
88378 + By default, counters are enabled.
88379 +
88380 + May be used for all port types
88381 +
88382 + @Param[in] h_FmPort A handle to a FM Port module.
88383 + @Param[in] enable TRUE to enable, FALSE to disable.
88384 +
88385 + @Return E_OK on success; Error code otherwise.
88386 +
88387 + @Cautions Allowed only following FM_PORT_Init().
88388 +*//***************************************************************************/
88389 +t_Error FM_PORT_SetPerformanceCounters(t_Handle h_FmPort, bool enable);
88390 +
88391 +/**************************************************************************//*
88392 + @Function FM_PORT_SetPerformanceCountersParams
88393 +
88394 + @Description Calling this routine defines port's performance
88395 + counters parameters.
88396 +
88397 + May be used for all port types
88398 +
88399 + @Param[in] h_FmPort A handle to a FM Port module.
88400 + @Param[in] p_FmPortPerformanceCnt A pointer to a structure of performance
88401 + counters parameters.
88402 +
88403 + @Return E_OK on success; Error code otherwise.
88404 +
88405 + @Cautions Allowed only following FM_PORT_Init().
88406 +*//***************************************************************************/
88407 +t_Error FM_PORT_SetPerformanceCountersParams(t_Handle h_FmPort, t_FmPortPerformanceCnt *p_FmPortPerformanceCnt);
88408 +
88409 +/**************************************************************************//**
88410 + @Group FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
88411 +
88412 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
88413 +
88414 + @{
88415 +*//***************************************************************************/
88416 +
88417 +/**************************************************************************//**
88418 + @Description A structure defining the KG scheme after the parser.
88419 + This is relevant only to change scheme selection mode - from
88420 + direct to indirect and vice versa, or when the scheme is selected directly,
88421 + to select the scheme id.
88422 +
88423 +*//***************************************************************************/
88424 +typedef struct t_FmPcdKgSchemeSelect {
88425 + bool direct; /**< TRUE to use 'h_Scheme' directly, FALSE to use LCV. */
88426 + t_Handle h_DirectScheme; /**< Scheme handle, selects the scheme after parser;
88427 + Relevant only when 'direct' is TRUE. */
88428 +} t_FmPcdKgSchemeSelect;
88429 +
88430 +/**************************************************************************//**
88431 + @Description A structure of scheme parameters
88432 +*//***************************************************************************/
88433 +typedef struct t_FmPcdPortSchemesParams {
88434 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
88435 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'numOfSchemes' schemes for the
88436 + port to be bound to */
88437 +} t_FmPcdPortSchemesParams;
88438 +
88439 +/**************************************************************************//**
88440 + @Description Union for defining port protocol parameters for parser
88441 +*//***************************************************************************/
88442 +typedef union u_FmPcdHdrPrsOpts {
88443 + /* MPLS */
88444 + struct {
88445 + bool labelInterpretationEnable; /**< When this bit is set, the last MPLS label will be
88446 + interpreted as described in HW spec table. When the bit
88447 + is cleared, the parser will advance to MPLS next parse */
88448 + e_NetHeaderType nextParse; /**< must be equal or higher than IPv4 */
88449 + } mplsPrsOptions;
88450 + /* VLAN */
88451 + struct {
88452 + uint16_t tagProtocolId1; /**< User defined Tag Protocol Identifier, to be recognized
88453 + on VLAN TAG on top of 0x8100 and 0x88A8 */
88454 + uint16_t tagProtocolId2; /**< User defined Tag Protocol Identifier, to be recognized
88455 + on VLAN TAG on top of 0x8100 and 0x88A8 */
88456 + } vlanPrsOptions;
88457 + /* PPP */
88458 + struct{
88459 + bool enableMTUCheck; /**< Check validity of MTU according to RFC2516 */
88460 + } pppoePrsOptions;
88461 +
88462 + /* IPV6 */
88463 + struct{
88464 + bool routingHdrEnable; /**< TRUE to enable routing header, otherwise ignore */
88465 + } ipv6PrsOptions;
88466 +
88467 + /* UDP */
88468 + struct{
88469 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
88470 + } udpPrsOptions;
88471 +
88472 + /* TCP */
88473 + struct {
88474 + bool padIgnoreChecksum; /**< TRUE to ignore pad in checksum */
88475 + } tcpPrsOptions;
88476 +} u_FmPcdHdrPrsOpts;
88477 +
88478 +/**************************************************************************//**
88479 + @Description A structure for defining each header for the parser
88480 +*//***************************************************************************/
88481 +typedef struct t_FmPcdPrsAdditionalHdrParams {
88482 + e_NetHeaderType hdr; /**< Selected header; use HEADER_TYPE_NONE
88483 + to indicate that sw parser is to run first
88484 + (before HW parser, and independent of the
88485 + existence of any protocol), in this case,
88486 + swPrsEnable must be set, and all other
88487 + parameters are irrelevant. */
88488 + bool errDisable; /**< TRUE to disable error indication */
88489 + bool swPrsEnable; /**< Enable jump to SW parser when this
88490 + header is recognized by the HW parser. */
88491 + uint8_t indexPerHdr; /**< Normally 0, if more than one sw parser
88492 + attachments exists for the same header,
88493 + (in the main sw parser code) use this
88494 + index to distinguish between them. */
88495 + bool usePrsOpts; /**< TRUE to use parser options. */
88496 + u_FmPcdHdrPrsOpts prsOpts; /**< A union according to header type,
88497 + defining the parser options selected.*/
88498 +} t_FmPcdPrsAdditionalHdrParams;
88499 +
88500 +/**************************************************************************//**
88501 + @Description struct for defining port PCD parameters
88502 +*//***************************************************************************/
88503 +typedef struct t_FmPortPcdPrsParams {
88504 + uint8_t prsResultPrivateInfo; /**< The private info provides a method of inserting
88505 + port information into the parser result. This information
88506 + may be extracted by Keygen and be used for frames
88507 + distribution when a per-port distinction is required,
88508 + it may also be used as a port logical id for analyzing
88509 + incoming frames. */
88510 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to start parsing */
88511 + e_NetHeaderType firstPrsHdr; /**< The type of the first header expected at 'parsingOffset' */
88512 + bool includeInPrsStatistics; /**< TRUE to include this port in the parser statistics;
88513 + NOTE: this field is not valid when the FM is in "guest" mode
88514 + and IPC is not available. */
88515 + uint8_t numOfHdrsWithAdditionalParams; /**< Normally 0, some headers may get
88516 + special parameters */
88517 + t_FmPcdPrsAdditionalHdrParams additionalParams[FM_PCD_PRS_NUM_OF_HDRS];
88518 + /**< 'numOfHdrsWithAdditionalParams' structures
88519 + of additional parameters
88520 + for each header that requires them */
88521 + bool setVlanTpid1; /**< TRUE to configure user selection of Ethertype to
88522 + indicate a VLAN tag (in addition to the TPID values
88523 + 0x8100 and 0x88A8). */
88524 + uint16_t vlanTpid1; /**< extra tag to use if setVlanTpid1=TRUE. */
88525 + bool setVlanTpid2; /**< TRUE to configure user selection of Ethertype to
88526 + indicate a VLAN tag (in addition to the TPID values
88527 + 0x8100 and 0x88A8). */
88528 + uint16_t vlanTpid2; /**< extra tag to use if setVlanTpid1=TRUE. */
88529 +} t_FmPortPcdPrsParams;
88530 +
88531 +/**************************************************************************//**
88532 + @Description struct for defining coarse alassification parameters
88533 +*//***************************************************************************/
88534 +typedef struct t_FmPortPcdCcParams {
88535 + t_Handle h_CcTree; /**< A handle to a CC tree */
88536 +} t_FmPortPcdCcParams;
88537 +
88538 +/**************************************************************************//**
88539 + @Description struct for defining keygen parameters
88540 +*//***************************************************************************/
88541 +typedef struct t_FmPortPcdKgParams {
88542 + uint8_t numOfSchemes; /**< Number of schemes for port to be bound to. */
88543 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
88544 + /**< Array of 'numOfSchemes' schemes handles for the
88545 + port to be bound to */
88546 + bool directScheme; /**< TRUE for going from parser to a specific scheme,
88547 + regardless of parser result */
88548 + t_Handle h_DirectScheme; /**< relevant only if direct == TRUE, Scheme handle,
88549 + as returned by FM_PCD_KgSetScheme */
88550 +} t_FmPortPcdKgParams;
88551 +
88552 +/**************************************************************************//**
88553 + @Description struct for defining policer parameters
88554 +*//***************************************************************************/
88555 +typedef struct t_FmPortPcdPlcrParams {
88556 + t_Handle h_Profile; /**< Selected profile handle */
88557 +} t_FmPortPcdPlcrParams;
88558 +
88559 +/**************************************************************************//**
88560 + @Description struct for defining port PCD parameters
88561 +*//***************************************************************************/
88562 +typedef struct t_FmPortPcdParams {
88563 + e_FmPortPcdSupport pcdSupport; /**< Relevant for Rx and offline ports only.
88564 + Describes the active PCD engines for this port. */
88565 + t_Handle h_NetEnv; /**< HL Unused in PLCR only mode */
88566 + t_FmPortPcdPrsParams *p_PrsParams; /**< Parser parameters for this port */
88567 + t_FmPortPcdCcParams *p_CcParams; /**< Coarse classification parameters for this port */
88568 + t_FmPortPcdKgParams *p_KgParams; /**< Keygen parameters for this port */
88569 + t_FmPortPcdPlcrParams *p_PlcrParams; /**< Policer parameters for this port; Relevant for one of
88570 + following cases:
88571 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
88572 + e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
88573 + or if any flow uses a KG scheme were policer
88574 + profile is not generated
88575 + ('bypassPlcrProfileGeneration selected'). */
88576 + t_Handle h_IpReassemblyManip; /**< IP Reassembly manipulation */
88577 +#if (DPAA_VERSION >= 11)
88578 + t_Handle h_CapwapReassemblyManip;/**< CAPWAP Reassembly manipulation */
88579 +#endif /* (DPAA_VERSION >= 11) */
88580 +} t_FmPortPcdParams;
88581 +
88582 +/**************************************************************************//**
88583 + @Description A structure for defining the Parser starting point
88584 +*//***************************************************************************/
88585 +typedef struct t_FmPcdPrsStart {
88586 + uint8_t parsingOffset; /**< Number of bytes from beginning of packet to
88587 + start parsing */
88588 + e_NetHeaderType firstPrsHdr; /**< The type of the first header axpected at
88589 + 'parsingOffset' */
88590 +} t_FmPcdPrsStart;
88591 +
88592 +#if (DPAA_VERSION >= 11)
88593 +/**************************************************************************//**
88594 + @Description struct for defining external buffer margins
88595 +*//***************************************************************************/
88596 +typedef struct t_FmPortVSPAllocParams {
88597 + uint8_t numOfProfiles; /**< Number of Virtual Storage Profiles; must be a power of 2 */
88598 + uint8_t dfltRelativeId; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
88599 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
88600 + if relevant function called for Rx port */
88601 + t_Handle h_FmTxPort; /**< Handle to coupled Tx Port; not relevant for OP port. */
88602 +} t_FmPortVSPAllocParams;
88603 +#endif /* (DPAA_VERSION >= 11) */
88604 +
88605 +
88606 +/**************************************************************************//**
88607 + @Function FM_PORT_SetPCD
88608 +
88609 + @Description Calling this routine defines the port's PCD configuration.
88610 + It changes it from its default configuration which is PCD
88611 + disabled (BMI to BMI) and configures it according to the passed
88612 + parameters.
88613 +
88614 + May be used for Rx and OP ports only
88615 +
88616 + @Param[in] h_FmPort A handle to a FM Port module.
88617 + @Param[in] p_FmPortPcd A Structure of parameters defining the port's PCD
88618 + configuration.
88619 +
88620 + @Return E_OK on success; Error code otherwise.
88621 +
88622 + @Cautions Allowed only following FM_PORT_Init().
88623 +*//***************************************************************************/
88624 +t_Error FM_PORT_SetPCD(t_Handle h_FmPort, t_FmPortPcdParams *p_FmPortPcd);
88625 +
88626 +/**************************************************************************//**
88627 + @Function FM_PORT_DeletePCD
88628 +
88629 + @Description Calling this routine releases the port's PCD configuration.
88630 + The port returns to its default configuration which is PCD
88631 + disabled (BMI to BMI) and all PCD configuration is removed.
88632 +
88633 + May be used for Rx and OP ports which are
88634 + in PCD mode only
88635 +
88636 + @Param[in] h_FmPort A handle to a FM Port module.
88637 +
88638 + @Return E_OK on success; Error code otherwise.
88639 +
88640 + @Cautions Allowed only following FM_PORT_Init().
88641 +*//***************************************************************************/
88642 +t_Error FM_PORT_DeletePCD(t_Handle h_FmPort);
88643 +
88644 +/**************************************************************************//**
88645 + @Function FM_PORT_AttachPCD
88646 +
88647 + @Description This routine may be called after FM_PORT_DetachPCD was called,
88648 + to return to the originally configured PCD support flow.
88649 + The couple of routines are used to allow PCD configuration changes
88650 + that demand that PCD will not be used while changes take place.
88651 +
88652 + May be used for Rx and OP ports which are
88653 + in PCD mode only
88654 +
88655 + @Param[in] h_FmPort A handle to a FM Port module.
88656 +
88657 + @Return E_OK on success; Error code otherwise.
88658 +
88659 + @Cautions Allowed only following FM_PORT_Init().
88660 +*//***************************************************************************/
88661 +t_Error FM_PORT_AttachPCD(t_Handle h_FmPort);
88662 +
88663 +/**************************************************************************//**
88664 + @Function FM_PORT_DetachPCD
88665 +
88666 + @Description Calling this routine detaches the port from its PCD functionality.
88667 + The port returns to its default flow which is BMI to BMI.
88668 +
88669 + May be used for Rx and OP ports which are
88670 + in PCD mode only
88671 +
88672 + @Param[in] h_FmPort A handle to a FM Port module.
88673 +
88674 + @Return E_OK on success; Error code otherwise.
88675 +
88676 + @Cautions Allowed only following FM_PORT_AttachPCD().
88677 +*//***************************************************************************/
88678 +t_Error FM_PORT_DetachPCD(t_Handle h_FmPort);
88679 +
88680 +/**************************************************************************//**
88681 + @Function FM_PORT_PcdPlcrAllocProfiles
88682 +
88683 + @Description This routine may be called only for ports that use the Policer in
88684 + order to allocate private policer profiles.
88685 +
88686 + @Param[in] h_FmPort A handle to a FM Port module.
88687 + @Param[in] numOfProfiles The number of required policer profiles
88688 +
88689 + @Return E_OK on success; Error code otherwise.
88690 +
88691 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
88692 + and before FM_PORT_SetPCD().
88693 +*//***************************************************************************/
88694 +t_Error FM_PORT_PcdPlcrAllocProfiles(t_Handle h_FmPort, uint16_t numOfProfiles);
88695 +
88696 +/**************************************************************************//**
88697 + @Function FM_PORT_PcdPlcrFreeProfiles
88698 +
88699 + @Description This routine should be called for freeing private policer profiles.
88700 +
88701 + @Param[in] h_FmPort A handle to a FM Port module.
88702 +
88703 + @Return E_OK on success; Error code otherwise.
88704 +
88705 + @Cautions Allowed only following FM_PORT_Init() and FM_PCD_Init(),
88706 + and before FM_PORT_SetPCD().
88707 +*//***************************************************************************/
88708 +t_Error FM_PORT_PcdPlcrFreeProfiles(t_Handle h_FmPort);
88709 +
88710 +#if (DPAA_VERSION >= 11)
88711 +/**************************************************************************//**
88712 + @Function FM_PORT_VSPAlloc
88713 +
88714 + @Description This routine allocated VSPs per port and forces the port to work
88715 + in VSP mode. Note that the port is initialized by default with the
88716 + physical-storage-profile only.
88717 +
88718 + @Param[in] h_FmPort A handle to a FM Port module.
88719 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
88720 +
88721 + @Return E_OK on success; Error code otherwise.
88722 +
88723 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
88724 + and also before FM_PORT_Enable(); i.e. the port should be disabled.
88725 +*//***************************************************************************/
88726 +t_Error FM_PORT_VSPAlloc(t_Handle h_FmPort, t_FmPortVSPAllocParams *p_Params);
88727 +#endif /* (DPAA_VERSION >= 11) */
88728 +
88729 +/**************************************************************************//**
88730 + @Function FM_PORT_PcdKgModifyInitialScheme
88731 +
88732 + @Description This routine may be called only for ports that use the keygen in
88733 + order to change the initial scheme frame should be routed to.
88734 + The change may be of a scheme id (in case of direct mode),
88735 + from direct to indirect, or from indirect to direct - specifying the scheme id.
88736 +
88737 + @Param[in] h_FmPort A handle to a FM Port module.
88738 + @Param[in] p_FmPcdKgScheme A structure of parameters for defining whether
88739 + a scheme is direct/indirect, and if direct - scheme id.
88740 +
88741 + @Return E_OK on success; Error code otherwise.
88742 +
88743 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
88744 +*//***************************************************************************/
88745 +t_Error FM_PORT_PcdKgModifyInitialScheme (t_Handle h_FmPort, t_FmPcdKgSchemeSelect *p_FmPcdKgScheme);
88746 +
88747 +/**************************************************************************//**
88748 + @Function FM_PORT_PcdPlcrModifyInitialProfile
88749 +
88750 + @Description This routine may be called for ports with flows
88751 + e_FM_PORT_PCD_SUPPORT_PLCR_ONLY or e_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR
88752 + only, to change the initial Policer profile frame should be
88753 + routed to. The change may be of a profile and/or absolute/direct
88754 + mode selection.
88755 +
88756 + @Param[in] h_FmPort A handle to a FM Port module.
88757 + @Param[in] h_Profile Policer profile handle
88758 +
88759 + @Return E_OK on success; Error code otherwise.
88760 +
88761 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
88762 +*//***************************************************************************/
88763 +t_Error FM_PORT_PcdPlcrModifyInitialProfile (t_Handle h_FmPort, t_Handle h_Profile);
88764 +
88765 +/**************************************************************************//**
88766 + @Function FM_PORT_PcdCcModifyTree
88767 +
88768 + @Description This routine may be called for ports that use coarse classification tree
88769 + if the user wishes to replace the tree. The routine may not be called while port
88770 + receives packets using the PCD functionalities, therefor port must be first detached
88771 + from the PCD, only than the routine may be called, and than port be attached to PCD again.
88772 +
88773 + @Param[in] h_FmPort A handle to a FM Port module.
88774 + @Param[in] h_CcTree A CC tree that was already built. The tree id as returned from
88775 + the BuildTree routine.
88776 +
88777 + @Return E_OK on success; Error code otherwise.
88778 +
88779 + @Cautions Allowed only following FM_PORT_Init(), FM_PORT_SetPCD() and FM_PORT_DetachPCD()
88780 +*//***************************************************************************/
88781 +t_Error FM_PORT_PcdCcModifyTree (t_Handle h_FmPort, t_Handle h_CcTree);
88782 +
88783 +/**************************************************************************//**
88784 + @Function FM_PORT_PcdKgBindSchemes
88785 +
88786 + @Description These routines may be called for adding more schemes for the
88787 + port to be bound to. The selected schemes are not added,
88788 + just this specific port starts using them.
88789 +
88790 + @Param[in] h_FmPort A handle to a FM Port module.
88791 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
88792 +
88793 + @Return E_OK on success; Error code otherwise.
88794 +
88795 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
88796 +*//***************************************************************************/
88797 +t_Error FM_PORT_PcdKgBindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
88798 +
88799 +/**************************************************************************//**
88800 + @Function FM_PORT_PcdKgUnbindSchemes
88801 +
88802 + @Description These routines may be called for adding more schemes for the
88803 + port to be bound to. The selected schemes are not removed or invalidated,
88804 + just this specific port stops using them.
88805 +
88806 + @Param[in] h_FmPort A handle to a FM Port module.
88807 + @Param[in] p_PortScheme A structure defining the list of schemes to be added.
88808 +
88809 + @Return E_OK on success; Error code otherwise.
88810 +
88811 + @Cautions Allowed only following FM_PORT_Init() and FM_PORT_SetPCD().
88812 +*//***************************************************************************/
88813 +t_Error FM_PORT_PcdKgUnbindSchemes (t_Handle h_FmPort, t_FmPcdPortSchemesParams *p_PortScheme);
88814 +
88815 +/**************************************************************************//**
88816 + @Function FM_PORT_GetIPv4OptionsCount
88817 +
88818 + @Description TODO
88819 +
88820 + @Param[in] h_FmPort A handle to a FM Port module.
88821 + @Param[out] p_Ipv4OptionsCount will hold the counter value
88822 +
88823 + @Return E_OK on success; Error code otherwise.
88824 +
88825 + @Cautions Allowed only following FM_PORT_Init()
88826 +*//***************************************************************************/
88827 +t_Error FM_PORT_GetIPv4OptionsCount(t_Handle h_FmPort, uint32_t *p_Ipv4OptionsCount);
88828 +
88829 +/** @} */ /* end of FM_PORT_pcd_runtime_control_grp group */
88830 +/** @} */ /* end of FM_PORT_runtime_control_grp group */
88831 +
88832 +
88833 +/**************************************************************************//**
88834 + @Group FM_PORT_runtime_data_grp FM Port Runtime Data-path Unit
88835 +
88836 + @Description FM Port Runtime data unit API functions, definitions and enums.
88837 + This API is valid only if working in Independent-Mode.
88838 +
88839 + @{
88840 +*//***************************************************************************/
88841 +
88842 +/**************************************************************************//**
88843 + @Function FM_PORT_ImTx
88844 +
88845 + @Description Tx function, called to transmit a data buffer on the port.
88846 +
88847 + @Param[in] h_FmPort A handle to a FM Port module.
88848 + @Param[in] p_Data A pointer to an LCP data buffer.
88849 + @Param[in] length Size of data for transmission.
88850 + @Param[in] lastBuffer Buffer position - TRUE for the last buffer
88851 + of a frame, including a single buffer frame
88852 + @Param[in] h_BufContext A handle of the user acossiated with this buffer
88853 +
88854 + @Return E_OK on success; Error code otherwise.
88855 +
88856 + @Cautions Allowed only following FM_PORT_Init().
88857 + NOTE - This routine can be used only when working in
88858 + Independent-Mode mode.
88859 +*//***************************************************************************/
88860 +t_Error FM_PORT_ImTx( t_Handle h_FmPort,
88861 + uint8_t *p_Data,
88862 + uint16_t length,
88863 + bool lastBuffer,
88864 + t_Handle h_BufContext);
88865 +
88866 +/**************************************************************************//**
88867 + @Function FM_PORT_ImTxConf
88868 +
88869 + @Description Tx port confirmation routine, optional, may be called to verify
88870 + transmission of all frames. The procedure performed by this
88871 + routine will be performed automatically on next buffer transmission,
88872 + but if desired, calling this routine will invoke this action on
88873 + demand.
88874 +
88875 + @Param[in] h_FmPort A handle to a FM Port module.
88876 +
88877 + @Cautions Allowed only following FM_PORT_Init().
88878 + NOTE - This routine can be used only when working in
88879 + Independent-Mode mode.
88880 +*//***************************************************************************/
88881 +void FM_PORT_ImTxConf(t_Handle h_FmPort);
88882 +
88883 +/**************************************************************************//**
88884 + @Function FM_PORT_ImRx
88885 +
88886 + @Description Rx function, may be called to poll for received buffers.
88887 + Normally, Rx process is invoked by the driver on Rx interrupt.
88888 + Alternatively, this routine may be called on demand.
88889 +
88890 + @Param[in] h_FmPort A handle to a FM Port module.
88891 +
88892 + @Return E_OK on success; Error code otherwise.
88893 +
88894 + @Cautions Allowed only following FM_PORT_Init().
88895 + NOTE - This routine can be used only when working in
88896 + Independent-Mode mode.
88897 +*//***************************************************************************/
88898 +t_Error FM_PORT_ImRx(t_Handle h_FmPort);
88899 +
88900 +/** @} */ /* end of FM_PORT_runtime_data_grp group */
88901 +/** @} */ /* end of FM_PORT_grp group */
88902 +/** @} */ /* end of FM_grp group */
88903 +
88904 +
88905 +
88906 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
88907 +#define FM_PORT_ConfigTxFifoDeqPipelineDepth FM_PORT_ConfigFifoDeqPipelineDepth
88908 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
88909 +
88910 +
88911 +#endif /* __FM_PORT_EXT */
88912 --- /dev/null
88913 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_rtc_ext.h
88914 @@ -0,0 +1,619 @@
88915 +/*
88916 + * Copyright 2008-2012 Freescale Semiconductor Inc.
88917 + *
88918 + * Redistribution and use in source and binary forms, with or without
88919 + * modification, are permitted provided that the following conditions are met:
88920 + * * Redistributions of source code must retain the above copyright
88921 + * notice, this list of conditions and the following disclaimer.
88922 + * * Redistributions in binary form must reproduce the above copyright
88923 + * notice, this list of conditions and the following disclaimer in the
88924 + * documentation and/or other materials provided with the distribution.
88925 + * * Neither the name of Freescale Semiconductor nor the
88926 + * names of its contributors may be used to endorse or promote products
88927 + * derived from this software without specific prior written permission.
88928 + *
88929 + *
88930 + * ALTERNATIVELY, this software may be distributed under the terms of the
88931 + * GNU General Public License ("GPL") as published by the Free Software
88932 + * Foundation, either version 2 of that License or (at your option) any
88933 + * later version.
88934 + *
88935 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
88936 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
88937 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
88938 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
88939 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
88940 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
88941 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
88942 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
88943 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
88944 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88945 + */
88946 +
88947 +
88948 +/**************************************************************************//**
88949 + @File fm_rtc_ext.h
88950 +
88951 + @Description External definitions and API for FM RTC IEEE1588 Timer Module.
88952 +
88953 + @Cautions None.
88954 +*//***************************************************************************/
88955 +
88956 +#ifndef __FM_RTC_EXT_H__
88957 +#define __FM_RTC_EXT_H__
88958 +
88959 +
88960 +#include "error_ext.h"
88961 +#include "std_ext.h"
88962 +#include "fsl_fman_rtc.h"
88963 +
88964 +/**************************************************************************//**
88965 +
88966 + @Group FM_grp Frame Manager API
88967 +
88968 + @Description FM API functions, definitions and enums
88969 +
88970 + @{
88971 +*//***************************************************************************/
88972 +
88973 +/**************************************************************************//**
88974 + @Group fm_rtc_grp FM RTC
88975 +
88976 + @Description FM RTC functions, definitions and enums.
88977 +
88978 + @{
88979 +*//***************************************************************************/
88980 +
88981 +/**************************************************************************//**
88982 + @Group fm_rtc_init_grp FM RTC Initialization Unit
88983 +
88984 + @Description FM RTC initialization API.
88985 +
88986 + @{
88987 +*//***************************************************************************/
88988 +
88989 +/**************************************************************************//**
88990 + @Description FM RTC Alarm Polarity Options.
88991 +*//***************************************************************************/
88992 +typedef enum e_FmRtcAlarmPolarity
88993 +{
88994 + e_FM_RTC_ALARM_POLARITY_ACTIVE_HIGH = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
88995 + e_FM_RTC_ALARM_POLARITY_ACTIVE_LOW = E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
88996 +} e_FmRtcAlarmPolarity;
88997 +
88998 +/**************************************************************************//**
88999 + @Description FM RTC Trigger Polarity Options.
89000 +*//***************************************************************************/
89001 +typedef enum e_FmRtcTriggerPolarity
89002 +{
89003 + e_FM_RTC_TRIGGER_ON_RISING_EDGE = E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
89004 + e_FM_RTC_TRIGGER_ON_FALLING_EDGE = E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
89005 +} e_FmRtcTriggerPolarity;
89006 +
89007 +/**************************************************************************//**
89008 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
89009 +*//***************************************************************************/
89010 +typedef enum e_FmSrcClock
89011 +{
89012 + e_FM_RTC_SOURCE_CLOCK_EXTERNAL = E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer reference clock */
89013 + e_FM_RTC_SOURCE_CLOCK_SYSTEM = E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
89014 + e_FM_RTC_SOURCE_CLOCK_OSCILATOR = E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
89015 +}e_FmSrcClk;
89016 +
89017 +/**************************************************************************//**
89018 + @Description FM RTC configuration parameters structure.
89019 +
89020 + This structure should be passed to FM_RTC_Config().
89021 +*//***************************************************************************/
89022 +typedef struct t_FmRtcParams
89023 +{
89024 + t_Handle h_Fm; /**< FM Handle*/
89025 + uintptr_t baseAddress; /**< Base address of FM RTC registers */
89026 + t_Handle h_App; /**< A handle to an application layer object; This handle will
89027 + be passed by the driver upon calling the above callbacks */
89028 +} t_FmRtcParams;
89029 +
89030 +
89031 +/**************************************************************************//**
89032 + @Function FM_RTC_Config
89033 +
89034 + @Description Configures the FM RTC module according to user's parameters.
89035 +
89036 + The driver assigns default values to some FM RTC parameters.
89037 + These parameters can be overwritten using the advanced
89038 + configuration routines.
89039 +
89040 + @Param[in] p_FmRtcParam - FM RTC configuration parameters.
89041 +
89042 + @Return Handle to the new FM RTC object; NULL pointer on failure.
89043 +
89044 + @Cautions None
89045 +*//***************************************************************************/
89046 +t_Handle FM_RTC_Config(t_FmRtcParams *p_FmRtcParam);
89047 +
89048 +/**************************************************************************//**
89049 + @Function FM_RTC_Init
89050 +
89051 + @Description Initializes the FM RTC driver and hardware.
89052 +
89053 + @Param[in] h_FmRtc - Handle to FM RTC object.
89054 +
89055 + @Return E_OK on success; Error code otherwise.
89056 +
89057 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89058 +*//***************************************************************************/
89059 +t_Error FM_RTC_Init(t_Handle h_FmRtc);
89060 +
89061 +/**************************************************************************//**
89062 + @Function FM_RTC_Free
89063 +
89064 + @Description Frees the FM RTC object and all allocated resources.
89065 +
89066 + @Param[in] h_FmRtc - Handle to FM RTC object.
89067 +
89068 + @Return E_OK on success; Error code otherwise.
89069 +
89070 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89071 +*//***************************************************************************/
89072 +t_Error FM_RTC_Free(t_Handle h_FmRtc);
89073 +
89074 +
89075 +/**************************************************************************//**
89076 + @Group fm_rtc_adv_config_grp FM RTC Advanced Configuration Unit
89077 +
89078 + @Description FM RTC advanced configuration functions.
89079 +
89080 + @{
89081 +*//***************************************************************************/
89082 +
89083 +/**************************************************************************//**
89084 + @Function FM_RTC_ConfigPeriod
89085 +
89086 + @Description Configures the period of the timestamp if different than
89087 + default [DEFAULT_clockPeriod].
89088 +
89089 + @Param[in] h_FmRtc - Handle to FM RTC object.
89090 + @Param[in] period - Period in nano-seconds.
89091 +
89092 + @Return E_OK on success; Error code otherwise.
89093 +
89094 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89095 +*//***************************************************************************/
89096 +t_Error FM_RTC_ConfigPeriod(t_Handle h_FmRtc, uint32_t period);
89097 +
89098 +/**************************************************************************//**
89099 + @Function FM_RTC_ConfigSourceClock
89100 +
89101 + @Description Configures the source clock of the RTC.
89102 +
89103 + @Param[in] h_FmRtc - Handle to FM RTC object.
89104 + @Param[in] srcClk - Source clock selection.
89105 + @Param[in] freqInMhz - the source-clock frequency (in MHz).
89106 +
89107 + @Return E_OK on success; Error code otherwise.
89108 +
89109 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89110 +*//***************************************************************************/
89111 +t_Error FM_RTC_ConfigSourceClock(t_Handle h_FmRtc,
89112 + e_FmSrcClk srcClk,
89113 + uint32_t freqInMhz);
89114 +
89115 +/**************************************************************************//**
89116 + @Function FM_RTC_ConfigPulseRealignment
89117 +
89118 + @Description Configures the RTC to automatic FIPER pulse realignment in
89119 + response to timer adjustments [DEFAULT_pulseRealign]
89120 +
89121 + In this mode, the RTC clock is identical to the source clock.
89122 + This feature can be useful when the system contains an external
89123 + RTC with inherent frequency compensation.
89124 +
89125 + @Param[in] h_FmRtc - Handle to FM RTC object.
89126 + @Param[in] enable - TRUE to enable automatic realignment.
89127 +
89128 + @Return E_OK on success; Error code otherwise.
89129 +
89130 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89131 +*//***************************************************************************/
89132 +t_Error FM_RTC_ConfigPulseRealignment(t_Handle h_FmRtc, bool enable);
89133 +
89134 +/**************************************************************************//**
89135 + @Function FM_RTC_ConfigFrequencyBypass
89136 +
89137 + @Description Configures the RTC to bypass the frequency compensation
89138 + mechanism. [DEFAULT_bypass]
89139 +
89140 + In this mode, the RTC clock is identical to the source clock.
89141 + This feature can be useful when the system contains an external
89142 + RTC with inherent frequency compensation.
89143 +
89144 + @Param[in] h_FmRtc - Handle to FM RTC object.
89145 + @Param[in] enabled - TRUE to bypass frequency compensation;
89146 + FALSE otherwise.
89147 +
89148 + @Return E_OK on success; Error code otherwise.
89149 +
89150 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89151 +*//***************************************************************************/
89152 +t_Error FM_RTC_ConfigFrequencyBypass(t_Handle h_FmRtc, bool enabled);
89153 +
89154 +/**************************************************************************//**
89155 + @Function FM_RTC_ConfigInvertedInputClockPhase
89156 +
89157 + @Description Configures the RTC to invert the source clock phase on input.
89158 + [DEFAULT_invertInputClkPhase]
89159 +
89160 + @Param[in] h_FmRtc - Handle to FM RTC object.
89161 + @Param[in] inverted - TRUE to invert the source clock phase on input.
89162 + FALSE otherwise.
89163 +
89164 + @Return E_OK on success; Error code otherwise.
89165 +
89166 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89167 +*//***************************************************************************/
89168 +t_Error FM_RTC_ConfigInvertedInputClockPhase(t_Handle h_FmRtc, bool inverted);
89169 +
89170 +/**************************************************************************//**
89171 + @Function FM_RTC_ConfigInvertedOutputClockPhase
89172 +
89173 + @Description Configures the RTC to invert the output clock phase.
89174 + [DEFAULT_invertOutputClkPhase]
89175 +
89176 + @Param[in] h_FmRtc - Handle to FM RTC object.
89177 + @Param[in] inverted - TRUE to invert the output clock phase.
89178 + FALSE otherwise.
89179 +
89180 + @Return E_OK on success; Error code otherwise.
89181 +
89182 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89183 +*//***************************************************************************/
89184 +t_Error FM_RTC_ConfigInvertedOutputClockPhase(t_Handle h_FmRtc, bool inverted);
89185 +
89186 +/**************************************************************************//**
89187 + @Function FM_RTC_ConfigOutputClockDivisor
89188 +
89189 + @Description Configures the divisor for generating the output clock from
89190 + the RTC clock. [DEFAULT_outputClockDivisor]
89191 +
89192 + @Param[in] h_FmRtc - Handle to FM RTC object.
89193 + @Param[in] divisor - Divisor for generation of the output clock.
89194 +
89195 + @Return E_OK on success; Error code otherwise.
89196 +
89197 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89198 +*//***************************************************************************/
89199 +t_Error FM_RTC_ConfigOutputClockDivisor(t_Handle h_FmRtc, uint16_t divisor);
89200 +
89201 +/**************************************************************************//**
89202 + @Function FM_RTC_ConfigAlarmPolarity
89203 +
89204 + @Description Configures the polarity (active-high/active-low) of a specific
89205 + alarm signal. [DEFAULT_alarmPolarity]
89206 +
89207 + @Param[in] h_FmRtc - Handle to FM RTC object.
89208 + @Param[in] alarmId - Alarm ID.
89209 + @Param[in] alarmPolarity - Alarm polarity.
89210 +
89211 + @Return E_OK on success; Error code otherwise.
89212 +
89213 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89214 +*//***************************************************************************/
89215 +t_Error FM_RTC_ConfigAlarmPolarity(t_Handle h_FmRtc,
89216 + uint8_t alarmId,
89217 + e_FmRtcAlarmPolarity alarmPolarity);
89218 +
89219 +/**************************************************************************//**
89220 + @Function FM_RTC_ConfigExternalTriggerPolarity
89221 +
89222 + @Description Configures the polarity (rising/falling edge) of a specific
89223 + external trigger signal. [DEFAULT_triggerPolarity]
89224 +
89225 + @Param[in] h_FmRtc - Handle to FM RTC object.
89226 + @Param[in] triggerId - Trigger ID.
89227 + @Param[in] triggerPolarity - Trigger polarity.
89228 +
89229 + @Return E_OK on success; Error code otherwise.
89230 +
89231 + @Cautions h_FmRtc must have been previously created using FM_RTC_Config().
89232 +*//***************************************************************************/
89233 +t_Error FM_RTC_ConfigExternalTriggerPolarity(t_Handle h_FmRtc,
89234 + uint8_t triggerId,
89235 + e_FmRtcTriggerPolarity triggerPolarity);
89236 +
89237 +/** @} */ /* end of fm_rtc_adv_config_grp */
89238 +/** @} */ /* end of fm_rtc_init_grp */
89239 +
89240 +
89241 +/**************************************************************************//**
89242 + @Group fm_rtc_control_grp FM RTC Control Unit
89243 +
89244 + @Description FM RTC runtime control API.
89245 +
89246 + @{
89247 +*//***************************************************************************/
89248 +
89249 +/**************************************************************************//**
89250 + @Function t_FmRtcExceptionsCallback
89251 +
89252 + @Description Exceptions user callback routine, used for RTC different mechanisms.
89253 +
89254 + @Param[in] h_App - User's application descriptor.
89255 + @Param[in] id - source id.
89256 +*//***************************************************************************/
89257 +typedef void (t_FmRtcExceptionsCallback) ( t_Handle h_App, uint8_t id);
89258 +
89259 +/**************************************************************************//**
89260 + @Description FM RTC alarm parameters.
89261 +*//***************************************************************************/
89262 +typedef struct t_FmRtcAlarmParams {
89263 + uint8_t alarmId; /**< 0 or 1 */
89264 + uint64_t alarmTime; /**< In nanoseconds, the time when the alarm
89265 + should go off - must be a multiple of
89266 + the RTC period */
89267 + t_FmRtcExceptionsCallback *f_AlarmCallback; /**< This routine will be called when RTC
89268 + reaches alarmTime */
89269 + bool clearOnExpiration; /**< TRUE to turn off the alarm once expired. */
89270 +} t_FmRtcAlarmParams;
89271 +
89272 +/**************************************************************************//**
89273 + @Description FM RTC Periodic Pulse parameters.
89274 +*//***************************************************************************/
89275 +typedef struct t_FmRtcPeriodicPulseParams {
89276 + uint8_t periodicPulseId; /**< 0 or 1 */
89277 + uint64_t periodicPulsePeriod; /**< In Nanoseconds. Must be
89278 + a multiple of the RTC period */
89279 + t_FmRtcExceptionsCallback *f_PeriodicPulseCallback; /**< This routine will be called every
89280 + periodicPulsePeriod. */
89281 +} t_FmRtcPeriodicPulseParams;
89282 +
89283 +/**************************************************************************//**
89284 + @Description FM RTC Periodic Pulse parameters.
89285 +*//***************************************************************************/
89286 +typedef struct t_FmRtcExternalTriggerParams {
89287 + uint8_t externalTriggerId; /**< 0 or 1 */
89288 + bool usePulseAsInput; /**< Use the pulse interrupt instead of
89289 + an external signal */
89290 + t_FmRtcExceptionsCallback *f_ExternalTriggerCallback; /**< This routine will be called every
89291 + periodicPulsePeriod. */
89292 +} t_FmRtcExternalTriggerParams;
89293 +
89294 +
89295 +/**************************************************************************//**
89296 + @Function FM_RTC_Enable
89297 +
89298 + @Description Enable the RTC (time count is started).
89299 +
89300 + The user can select to resume the time count from previous
89301 + point, or to restart the time count.
89302 +
89303 + @Param[in] h_FmRtc - Handle to FM RTC object.
89304 + @Param[in] resetClock - Restart the time count from zero.
89305 +
89306 + @Return E_OK on success; Error code otherwise.
89307 +
89308 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89309 +*//***************************************************************************/
89310 +t_Error FM_RTC_Enable(t_Handle h_FmRtc, bool resetClock);
89311 +
89312 +/**************************************************************************//**
89313 + @Function FM_RTC_Disable
89314 +
89315 + @Description Disables the RTC (time count is stopped).
89316 +
89317 + @Param[in] h_FmRtc - Handle to FM RTC object.
89318 +
89319 + @Return E_OK on success; Error code otherwise.
89320 +
89321 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89322 +*//***************************************************************************/
89323 +t_Error FM_RTC_Disable(t_Handle h_FmRtc);
89324 +
89325 +/**************************************************************************//**
89326 + @Function FM_RTC_SetClockOffset
89327 +
89328 + @Description Sets the clock offset (usually relative to another clock).
89329 +
89330 + The user can pass a negative offset value.
89331 +
89332 + @Param[in] h_FmRtc - Handle to FM RTC object.
89333 + @Param[in] offset - New clock offset (in nanoseconds).
89334 +
89335 + @Return E_OK on success; Error code otherwise.
89336 +
89337 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89338 +*//***************************************************************************/
89339 +t_Error FM_RTC_SetClockOffset(t_Handle h_FmRtc, int64_t offset);
89340 +
89341 +/**************************************************************************//**
89342 + @Function FM_RTC_SetAlarm
89343 +
89344 + @Description Schedules an alarm event to a given RTC time.
89345 +
89346 + @Param[in] h_FmRtc - Handle to FM RTC object.
89347 + @Param[in] p_FmRtcAlarmParams - Alarm parameters.
89348 +
89349 + @Return E_OK on success; Error code otherwise.
89350 +
89351 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89352 + Must be called only prior to FM_RTC_Enable().
89353 +*//***************************************************************************/
89354 +t_Error FM_RTC_SetAlarm(t_Handle h_FmRtc, t_FmRtcAlarmParams *p_FmRtcAlarmParams);
89355 +
89356 +/**************************************************************************//**
89357 + @Function FM_RTC_SetPeriodicPulse
89358 +
89359 + @Description Sets a periodic pulse.
89360 +
89361 + @Param[in] h_FmRtc - Handle to FM RTC object.
89362 + @Param[in] p_FmRtcPeriodicPulseParams - Periodic pulse parameters.
89363 +
89364 + @Return E_OK on success; Error code otherwise.
89365 +
89366 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89367 + Must be called only prior to FM_RTC_Enable().
89368 +*//***************************************************************************/
89369 +t_Error FM_RTC_SetPeriodicPulse(t_Handle h_FmRtc, t_FmRtcPeriodicPulseParams *p_FmRtcPeriodicPulseParams);
89370 +
89371 +/**************************************************************************//**
89372 + @Function FM_RTC_ClearPeriodicPulse
89373 +
89374 + @Description Clears a periodic pulse.
89375 +
89376 + @Param[in] h_FmRtc - Handle to FM RTC object.
89377 + @Param[in] periodicPulseId - Periodic pulse id.
89378 +
89379 + @Return E_OK on success; Error code otherwise.
89380 +
89381 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89382 +*//***************************************************************************/
89383 +t_Error FM_RTC_ClearPeriodicPulse(t_Handle h_FmRtc, uint8_t periodicPulseId);
89384 +
89385 +/**************************************************************************//**
89386 + @Function FM_RTC_SetExternalTrigger
89387 +
89388 + @Description Sets an external trigger indication and define a callback
89389 + routine to be called on such event.
89390 +
89391 + @Param[in] h_FmRtc - Handle to FM RTC object.
89392 + @Param[in] p_FmRtcExternalTriggerParams - External Trigger parameters.
89393 +
89394 + @Return E_OK on success; Error code otherwise.
89395 +
89396 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89397 +*//***************************************************************************/
89398 +t_Error FM_RTC_SetExternalTrigger(t_Handle h_FmRtc, t_FmRtcExternalTriggerParams *p_FmRtcExternalTriggerParams);
89399 +
89400 +/**************************************************************************//**
89401 + @Function FM_RTC_ClearExternalTrigger
89402 +
89403 + @Description Clears external trigger indication.
89404 +
89405 + @Param[in] h_FmRtc - Handle to FM RTC object.
89406 + @Param[in] id - External Trigger id.
89407 +
89408 + @Return E_OK on success; Error code otherwise.
89409 +
89410 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89411 +*//***************************************************************************/
89412 +t_Error FM_RTC_ClearExternalTrigger(t_Handle h_FmRtc, uint8_t id);
89413 +
89414 +/**************************************************************************//**
89415 + @Function FM_RTC_GetExternalTriggerTimeStamp
89416 +
89417 + @Description Reads the External Trigger TimeStamp.
89418 +
89419 + @Param[in] h_FmRtc - Handle to FM RTC object.
89420 + @Param[in] triggerId - External Trigger id.
89421 + @Param[out] p_TimeStamp - External Trigger timestamp (in nanoseconds).
89422 +
89423 + @Return E_OK on success; Error code otherwise.
89424 +
89425 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89426 +*//***************************************************************************/
89427 +t_Error FM_RTC_GetExternalTriggerTimeStamp(t_Handle h_FmRtc,
89428 + uint8_t triggerId,
89429 + uint64_t *p_TimeStamp);
89430 +
89431 +/**************************************************************************//**
89432 + @Function FM_RTC_GetCurrentTime
89433 +
89434 + @Description Returns the current RTC time.
89435 +
89436 + @Param[in] h_FmRtc - Handle to FM RTC object.
89437 + @Param[out] p_Ts - returned time stamp (in nanoseconds).
89438 +
89439 + @Return E_OK on success; Error code otherwise.
89440 +
89441 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89442 +*//***************************************************************************/
89443 +t_Error FM_RTC_GetCurrentTime(t_Handle h_FmRtc, uint64_t *p_Ts);
89444 +
89445 +/**************************************************************************//**
89446 + @Function FM_RTC_SetCurrentTime
89447 +
89448 + @Description Sets the current RTC time.
89449 +
89450 + @Param[in] h_FmRtc - Handle to FM RTC object.
89451 + @Param[in] ts - The new time stamp (in nanoseconds).
89452 +
89453 + @Return E_OK on success; Error code otherwise.
89454 +
89455 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89456 +*//***************************************************************************/
89457 +t_Error FM_RTC_SetCurrentTime(t_Handle h_FmRtc, uint64_t ts);
89458 +
89459 +/**************************************************************************//**
89460 + @Function FM_RTC_GetFreqCompensation
89461 +
89462 + @Description Retrieves the frequency compensation value
89463 +
89464 + @Param[in] h_FmRtc - Handle to FM RTC object.
89465 + @Param[out] p_Compensation - A pointer to the returned value of compensation.
89466 +
89467 + @Return E_OK on success; Error code otherwise.
89468 +
89469 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89470 +*//***************************************************************************/
89471 +t_Error FM_RTC_GetFreqCompensation(t_Handle h_FmRtc, uint32_t *p_Compensation);
89472 +
89473 +/**************************************************************************//**
89474 + @Function FM_RTC_SetFreqCompensation
89475 +
89476 + @Description Sets a new frequency compensation value.
89477 +
89478 + @Param[in] h_FmRtc - Handle to FM RTC object.
89479 + @Param[in] freqCompensation - The new frequency compensation value to set.
89480 +
89481 + @Return E_OK on success; Error code otherwise.
89482 +
89483 + @Cautions h_FmRtc must have been previously initialized using FM_RTC_Init().
89484 +*//***************************************************************************/
89485 +t_Error FM_RTC_SetFreqCompensation(t_Handle h_FmRtc, uint32_t freqCompensation);
89486 +
89487 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
89488 +/**************************************************************************//**
89489 +*@Function FM_RTC_EnableInterrupt
89490 +*
89491 +*@Description Enable interrupt of FM RTC.
89492 +*
89493 +*@Param[in] h_FmRtc - Handle to FM RTC object.
89494 +*@Param[in] events - Interrupt events.
89495 +*
89496 +*@Return E_OK on success; Error code otherwise.
89497 +*//***************************************************************************/
89498 +t_Error FM_RTC_EnableInterrupt(t_Handle h_FmRtc, uint32_t events);
89499 +
89500 +/**************************************************************************//**
89501 +*@Function FM_RTC_DisableInterrupt
89502 +*
89503 +*@Description Disable interrupt of FM RTC.
89504 +*
89505 +*@Param[in] h_FmRtc - Handle to FM RTC object.
89506 +*@Param[in] events - Interrupt events.
89507 +*
89508 +*@Return E_OK on success; Error code otherwise.
89509 +*//***************************************************************************/
89510 +t_Error FM_RTC_DisableInterrupt(t_Handle h_FmRtc, uint32_t events);
89511 +#endif
89512 +
89513 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
89514 +/**************************************************************************//**
89515 + @Function FM_RTC_DumpRegs
89516 +
89517 + @Description Dumps all FM registers
89518 +
89519 + @Param[in] h_FmRtc A handle to an FM RTC Module.
89520 +
89521 + @Return E_OK on success;
89522 +
89523 + @Cautions Allowed only FM_Init().
89524 +*//***************************************************************************/
89525 +t_Error FM_RTC_DumpRegs(t_Handle h_FmRtc);
89526 +#endif /* (defined(DEBUG_ERRORS) && ... */
89527 +
89528 +/** @} */ /* end of fm_rtc_control_grp */
89529 +/** @} */ /* end of fm_rtc_grp */
89530 +/** @} */ /* end of FM_grp group */
89531 +
89532 +
89533 +#endif /* __FM_RTC_EXT_H__ */
89534 --- /dev/null
89535 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/fm_vsp_ext.h
89536 @@ -0,0 +1,411 @@
89537 +/*
89538 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89539 + *
89540 + * Redistribution and use in source and binary forms, with or without
89541 + * modification, are permitted provided that the following conditions are met:
89542 + * * Redistributions of source code must retain the above copyright
89543 + * notice, this list of conditions and the following disclaimer.
89544 + * * Redistributions in binary form must reproduce the above copyright
89545 + * notice, this list of conditions and the following disclaimer in the
89546 + * documentation and/or other materials provided with the distribution.
89547 + * * Neither the name of Freescale Semiconductor nor the
89548 + * names of its contributors may be used to endorse or promote products
89549 + * derived from this software without specific prior written permission.
89550 + *
89551 + *
89552 + * ALTERNATIVELY, this software may be distributed under the terms of the
89553 + * GNU General Public License ("GPL") as published by the Free Software
89554 + * Foundation, either version 2 of that License or (at your option) any
89555 + * later version.
89556 + *
89557 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89558 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89559 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89560 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89561 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89562 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89563 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89564 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89565 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89566 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89567 + */
89568 +
89569 +
89570 +/**************************************************************************//**
89571 + @File fm_vsp_ext.h
89572 +
89573 + @Description FM Virtual Storage-Profile ...
89574 +*//***************************************************************************/
89575 +#ifndef __FM_VSP_EXT_H
89576 +#define __FM_VSP_EXT_H
89577 +
89578 +#include "std_ext.h"
89579 +#include "error_ext.h"
89580 +#include "string_ext.h"
89581 +#include "debug_ext.h"
89582 +
89583 +#include "fm_ext.h"
89584 +
89585 +
89586 +/**************************************************************************//**
89587 +
89588 + @Group FM_grp Frame Manager API
89589 +
89590 + @Description FM API functions, definitions and enums
89591 +
89592 + @{
89593 +*//***************************************************************************/
89594 +
89595 +/**************************************************************************//**
89596 + @Group FM_VSP_grp FM Virtual-Storage-Profile
89597 +
89598 + @Description FM Virtual-Storage-Profile API
89599 +
89600 + @{
89601 +*//***************************************************************************/
89602 +
89603 +/**************************************************************************//**
89604 + @Group FM_VSP_init_grp FM VSP Initialization Unit
89605 +
89606 + @Description FM VSP initialization API.
89607 +
89608 + @{
89609 +*//***************************************************************************/
89610 +
89611 +/**************************************************************************//**
89612 + @Description Virtual Storage Profile
89613 +*//***************************************************************************/
89614 +typedef struct t_FmVspParams {
89615 + t_Handle h_Fm; /**< A handle to the FM object this VSP related to */
89616 + t_FmExtPools extBufPools; /**< Which external buffer pools are used
89617 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
89618 + parameter associated with Rx / OP port */
89619 + uint16_t liodnOffset; /**< VSP's LIODN offset */
89620 + struct {
89621 + e_FmPortType portType; /**< Port type */
89622 + uint8_t portId; /**< Port Id - relative to type */
89623 + } portParams;
89624 + uint8_t relativeProfileId; /**< VSP Id - relative to VSP's range
89625 + defined in relevant FM object */
89626 +} t_FmVspParams;
89627 +
89628 +
89629 +/**************************************************************************//**
89630 + @Function FM_VSP_Config
89631 +
89632 + @Description Creates descriptor for the FM VSP module.
89633 +
89634 + The routine returns a handle (descriptor) to the FM VSP object.
89635 + This descriptor must be passed as first parameter to all other
89636 + FM VSP function calls.
89637 +
89638 + No actual initialization or configuration of FM hardware is
89639 + done by this routine.
89640 +
89641 +@Param[in] p_FmVspParams Pointer to data structure of parameters
89642 +
89643 + @Retval Handle to FM VSP object, or NULL for Failure.
89644 +*//***************************************************************************/
89645 +t_Handle FM_VSP_Config(t_FmVspParams *p_FmVspParams);
89646 +
89647 +/**************************************************************************//**
89648 + @Function FM_VSP_Init
89649 +
89650 + @Description Initializes the FM VSP module
89651 +
89652 + @Param[in] h_FmVsp - FM VSP module descriptor
89653 +
89654 + @Return E_OK on success; Error code otherwise.
89655 +*//***************************************************************************/
89656 +t_Error FM_VSP_Init(t_Handle h_FmVsp);
89657 +
89658 +/**************************************************************************//**
89659 + @Function FM_VSP_Free
89660 +
89661 + @Description Frees all resources that were assigned to FM VSP module.
89662 +
89663 + Calling this routine invalidates the descriptor.
89664 +
89665 + @Param[in] h_FmVsp - FM VSP module descriptor
89666 +
89667 + @Return E_OK on success; Error code otherwise.
89668 +*//***************************************************************************/
89669 +t_Error FM_VSP_Free(t_Handle h_FmVsp);
89670 +
89671 +
89672 +/**************************************************************************//**
89673 + @Group FM_VSP_adv_config_grp FM VSP Advanced Configuration Unit
89674 +
89675 + @Description FM VSP advanced configuration functions.
89676 +
89677 + @{
89678 +*//***************************************************************************/
89679 +
89680 +/**************************************************************************//**
89681 + @Function FM_VSP_ConfigBufferPrefixContent
89682 +
89683 + @Description Defines the structure, size and content of the application buffer.
89684 +
89685 + The prefix will
89686 + In VSPs defined for Tx ports, if 'passPrsResult', the application
89687 + should set a value to their offsets in the prefix of
89688 + the FM will save the first 'privDataSize', than,
89689 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
89690 + and timeStamp, and the packet itself (in this order), to the
89691 + application buffer, and to offset.
89692 +
89693 + Calling this routine changes the buffer margins definitions
89694 + in the internal driver data base from its default
89695 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
89696 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
89697 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
89698 +
89699 + @Param[in] h_FmVsp A handle to a FM VSP module.
89700 + @Param[in,out] p_FmBufferPrefixContent A structure of parameters describing the
89701 + structure of the buffer.
89702 + Out parameter: Start margin - offset
89703 + of data from start of external buffer.
89704 +
89705 + @Return E_OK on success; Error code otherwise.
89706 +
89707 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89708 +*//***************************************************************************/
89709 +t_Error FM_VSP_ConfigBufferPrefixContent(t_Handle h_FmVsp,
89710 + t_FmBufferPrefixContent *p_FmBufferPrefixContent);
89711 +
89712 +/**************************************************************************//**
89713 + @Function FM_VSP_ConfigDmaSwapData
89714 +
89715 + @Description Calling this routine changes the DMA swap data parameter
89716 + in the internal driver data base from its default
89717 + configuration [DEFAULT_FM_SP_dmaSwapData]
89718 +
89719 + @Param[in] h_FmVsp A handle to a FM VSP module.
89720 + @Param[in] swapData New selection
89721 +
89722 + @Return E_OK on success; Error code otherwise.
89723 +
89724 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89725 +*//***************************************************************************/
89726 +t_Error FM_VSP_ConfigDmaSwapData(t_Handle h_FmVsp, e_FmDmaSwapOption swapData);
89727 +
89728 +/**************************************************************************//**
89729 + @Function FM_VSP_ConfigDmaIcCacheAttr
89730 +
89731 + @Description Calling this routine changes the internal context cache
89732 + attribute parameter in the internal driver data base
89733 + from its default configuration [DEFAULT_FM_SP_dmaIntContextCacheAttr]
89734 +
89735 + @Param[in] h_FmVsp A handle to a FM VSP module.
89736 + @Param[in] intContextCacheAttr New selection
89737 +
89738 + @Return E_OK on success; Error code otherwise.
89739 +
89740 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89741 +*//***************************************************************************/
89742 +t_Error FM_VSP_ConfigDmaIcCacheAttr(t_Handle h_FmVsp,
89743 + e_FmDmaCacheOption intContextCacheAttr);
89744 +
89745 +/**************************************************************************//**
89746 + @Function FM_VSP_ConfigDmaHdrAttr
89747 +
89748 + @Description Calling this routine changes the header cache
89749 + attribute parameter in the internal driver data base
89750 + from its default configuration [DEFAULT_FM_SP_dmaHeaderCacheAttr]
89751 +
89752 + @Param[in] h_FmVsp A handle to a FM VSP module.
89753 + @Param[in] headerCacheAttr New selection
89754 +
89755 + @Return E_OK on success; Error code otherwise.
89756 +
89757 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89758 +*//***************************************************************************/
89759 +t_Error FM_VSP_ConfigDmaHdrAttr(t_Handle h_FmVsp, e_FmDmaCacheOption headerCacheAttr);
89760 +
89761 +/**************************************************************************//**
89762 + @Function FM_VSP_ConfigDmaScatterGatherAttr
89763 +
89764 + @Description Calling this routine changes the scatter gather cache
89765 + attribute parameter in the internal driver data base
89766 + from its default configuration [DEFAULT_FM_SP_dmaScatterGatherCacheAttr]
89767 +
89768 + @Param[in] h_FmVsp A handle to a FM VSP module.
89769 + @Param[in] scatterGatherCacheAttr New selection
89770 +
89771 + @Return E_OK on success; Error code otherwise.
89772 +
89773 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89774 +*//***************************************************************************/
89775 +t_Error FM_VSP_ConfigDmaScatterGatherAttr(t_Handle h_FmVsp,
89776 + e_FmDmaCacheOption scatterGatherCacheAttr);
89777 +
89778 +/**************************************************************************//**
89779 + @Function FM_VSP_ConfigDmaWriteOptimize
89780 +
89781 + @Description Calling this routine changes the write optimization
89782 + parameter in the internal driver data base
89783 + from its default configuration: optimize = [DEFAULT_FM_SP_dmaWriteOptimize]
89784 +
89785 + @Param[in] h_FmVsp A handle to a FM VSP module.
89786 + @Param[in] optimize TRUE to enable optimization, FALSE for normal operation
89787 +
89788 + @Return E_OK on success; Error code otherwise.
89789 +
89790 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89791 +*//***************************************************************************/
89792 +t_Error FM_VSP_ConfigDmaWriteOptimize(t_Handle h_FmVsp, bool optimize);
89793 +
89794 +/**************************************************************************//**
89795 + @Function FM_VSP_ConfigNoScatherGather
89796 +
89797 + @Description Calling this routine changes the possibility to receive S/G frame
89798 + in the internal driver data base
89799 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
89800 +
89801 + @Param[in] h_FmVsp A handle to a FM VSP module.
89802 + @Param[in] noScatherGather TRUE to operate without scatter/gather capability.
89803 +
89804 + @Return E_OK on success; Error code otherwise.
89805 +
89806 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89807 +*//***************************************************************************/
89808 +t_Error FM_VSP_ConfigNoScatherGather(t_Handle h_FmVsp, bool noScatherGather);
89809 +
89810 +/**************************************************************************//**
89811 + @Function FM_VSP_ConfigPoolDepletion
89812 +
89813 + @Description Calling this routine enables pause frame generation depending on the
89814 + depletion status of BM pools. It also defines the conditions to activate
89815 + this functionality. By default, this functionality is disabled.
89816 +
89817 + @Param[in] h_FmVsp A handle to a FM VSP module.
89818 + @Param[in] p_BufPoolDepletion A structure of pool depletion parameters
89819 +
89820 + @Return E_OK on success; Error code otherwise.
89821 +
89822 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89823 +*//***************************************************************************/
89824 +t_Error FM_VSP_ConfigPoolDepletion(t_Handle h_FmVsp, t_FmBufPoolDepletion *p_BufPoolDepletion);
89825 +
89826 +/**************************************************************************//**
89827 + @Function FM_VSP_ConfigBackupPools
89828 +
89829 + @Description Calling this routine allows the configuration of some of the BM pools
89830 + defined for this port as backup pools.
89831 + A pool configured to be a backup pool will be used only if all other
89832 + enabled non-backup pools are depleted.
89833 +
89834 + @Param[in] h_FmVsp A handle to a FM VSP module.
89835 + @Param[in] p_BackupBmPools An array of pool id's. All pools specified here will
89836 + be defined as backup pools.
89837 +
89838 + @Return E_OK on success; Error code otherwise.
89839 +
89840 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
89841 +*//***************************************************************************/
89842 +t_Error FM_VSP_ConfigBackupPools(t_Handle h_FmVsp, t_FmBackupBmPools *p_BackupBmPools);
89843 +
89844 +/** @} */ /* end of FM_VSP_adv_config_grp group */
89845 +/** @} */ /* end of FM_VSP_init_grp group */
89846 +
89847 +
89848 +/**************************************************************************//**
89849 + @Group FM_VSP_control_grp FM VSP Control Unit
89850 +
89851 + @Description FM VSP runtime control API.
89852 +
89853 + @{
89854 +*//***************************************************************************/
89855 +
89856 +/**************************************************************************//**
89857 + @Function FM_VSP_GetBufferDataOffset
89858 +
89859 + @Description Relevant for Rx ports.
89860 + Returns the data offset from the beginning of the data buffer
89861 +
89862 + @Param[in] h_FmVsp - FM PORT module descriptor
89863 +
89864 + @Return data offset.
89865 +
89866 + @Cautions Allowed only following FM_VSP_Init().
89867 +*//***************************************************************************/
89868 +uint32_t FM_VSP_GetBufferDataOffset(t_Handle h_FmVsp);
89869 +
89870 +/**************************************************************************//**
89871 + @Function FM_VSP_GetBufferICInfo
89872 +
89873 + @Description Returns the Internal Context offset from the beginning of the data buffer
89874 +
89875 + @Param[in] h_FmVsp - FM PORT module descriptor
89876 + @Param[in] p_Data - A pointer to the data buffer.
89877 +
89878 + @Return Internal context info pointer on success, NULL if 'allOtherInfo' was not
89879 + configured for this port.
89880 +
89881 + @Cautions Allowed only following FM_VSP_Init().
89882 +*//***************************************************************************/
89883 +uint8_t * FM_VSP_GetBufferICInfo(t_Handle h_FmVsp, char *p_Data);
89884 +
89885 +/**************************************************************************//**
89886 + @Function FM_VSP_GetBufferPrsResult
89887 +
89888 + @Description Returns the pointer to the parse result in the data buffer.
89889 + In Rx ports this is relevant after reception, if parse
89890 + result is configured to be part of the data passed to the
89891 + application. For non Rx ports it may be used to get the pointer
89892 + of the area in the buffer where parse result should be
89893 + initialized - if so configured.
89894 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
89895 + configuration.
89896 +
89897 + @Param[in] h_FmVsp - FM PORT module descriptor
89898 + @Param[in] p_Data - A pointer to the data buffer.
89899 +
89900 + @Return Parse result pointer on success, NULL if parse result was not
89901 + configured for this port.
89902 +
89903 + @Cautions Allowed only following FM_VSP_Init().
89904 +*//***************************************************************************/
89905 +t_FmPrsResult * FM_VSP_GetBufferPrsResult(t_Handle h_FmVsp, char *p_Data);
89906 +
89907 +/**************************************************************************//**
89908 + @Function FM_VSP_GetBufferTimeStamp
89909 +
89910 + @Description Returns the time stamp in the data buffer.
89911 + Relevant for Rx ports for getting the buffer time stamp.
89912 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
89913 + configuration.
89914 +
89915 + @Param[in] h_FmVsp - FM PORT module descriptor
89916 + @Param[in] p_Data - A pointer to the data buffer.
89917 +
89918 + @Return A pointer to the hash result on success, NULL otherwise.
89919 +
89920 + @Cautions Allowed only following FM_VSP_Init().
89921 +*//***************************************************************************/
89922 +uint64_t * FM_VSP_GetBufferTimeStamp(t_Handle h_FmVsp, char *p_Data);
89923 +
89924 +/**************************************************************************//**
89925 + @Function FM_VSP_GetBufferHashResult
89926 +
89927 + @Description Given a data buffer, on the condition that hash result was defined
89928 + as a part of the buffer content (see FM_VSP_ConfigBufferPrefixContent)
89929 + this routine will return the pointer to the hash result location in the
89930 + buffer prefix.
89931 +
89932 + @Param[in] h_FmVsp - FM PORT module descriptor
89933 + @Param[in] p_Data - A pointer to the data buffer.
89934 +
89935 + @Return A pointer to the hash result on success, NULL otherwise.
89936 +
89937 + @Cautions Allowed only following FM_VSP_Init().
89938 +*//***************************************************************************/
89939 +uint8_t * FM_VSP_GetBufferHashResult(t_Handle h_FmVsp, char *p_Data);
89940 +
89941 +
89942 +/** @} */ /* end of FM_VSP_control_grp group */
89943 +/** @} */ /* end of FM_VSP_grp group */
89944 +/** @} */ /* end of FM_grp group */
89945 +
89946 +
89947 +#endif /* __FM_VSP_EXT_H */
89948 --- /dev/null
89949 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/Peripherals/mii_acc_ext.h
89950 @@ -0,0 +1,76 @@
89951 +/*
89952 + * Copyright 2008-2012 Freescale Semiconductor Inc.
89953 + *
89954 + * Redistribution and use in source and binary forms, with or without
89955 + * modification, are permitted provided that the following conditions are met:
89956 + * * Redistributions of source code must retain the above copyright
89957 + * notice, this list of conditions and the following disclaimer.
89958 + * * Redistributions in binary form must reproduce the above copyright
89959 + * notice, this list of conditions and the following disclaimer in the
89960 + * documentation and/or other materials provided with the distribution.
89961 + * * Neither the name of Freescale Semiconductor nor the
89962 + * names of its contributors may be used to endorse or promote products
89963 + * derived from this software without specific prior written permission.
89964 + *
89965 + *
89966 + * ALTERNATIVELY, this software may be distributed under the terms of the
89967 + * GNU General Public License ("GPL") as published by the Free Software
89968 + * Foundation, either version 2 of that License or (at your option) any
89969 + * later version.
89970 + *
89971 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
89972 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
89973 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
89974 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
89975 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
89976 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
89977 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
89978 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
89979 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
89980 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
89981 + */
89982 +
89983 +
89984 +
89985 +#ifndef __MII_ACC_EXT_H
89986 +#define __MII_ACC_EXT_H
89987 +
89988 +
89989 +/**************************************************************************//**
89990 + @Function MII_ReadPhyReg
89991 +
89992 + @Description This routine is called to read a specified PHY
89993 + register value.
89994 +
89995 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
89996 + @Param[in] phyAddr - PHY address (0-31).
89997 + @Param[in] reg - PHY register to read
89998 + @Param[out] p_Data - Gets the register value.
89999 +
90000 + @Return Always zero (success).
90001 +*//***************************************************************************/
90002 +int MII_ReadPhyReg(t_Handle h_MiiAccess,
90003 + uint8_t phyAddr,
90004 + uint8_t reg,
90005 + uint16_t *p_Data);
90006 +
90007 +/**************************************************************************//**
90008 + @Function MII_WritePhyReg
90009 +
90010 + @Description This routine is called to write data to a specified PHY
90011 + register.
90012 +
90013 + @Param[in] h_MiiAccess - Handle to MII configuration access registers
90014 + @Param[in] phyAddr - PHY address (0-31).
90015 + @Param[in] reg - PHY register to write
90016 + @Param[in] data - Data to write in register.
90017 +
90018 + @Return Always zero (success).
90019 +*//***************************************************************************/
90020 +int MII_WritePhyReg(t_Handle h_MiiAccess,
90021 + uint8_t phyAddr,
90022 + uint8_t reg,
90023 + uint16_t data);
90024 +
90025 +
90026 +#endif /* __MII_ACC_EXT_H */
90027 --- /dev/null
90028 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/core_ext.h
90029 @@ -0,0 +1,90 @@
90030 +/*
90031 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90032 + *
90033 + * Redistribution and use in source and binary forms, with or without
90034 + * modification, are permitted provided that the following conditions are met:
90035 + * * Redistributions of source code must retain the above copyright
90036 + * notice, this list of conditions and the following disclaimer.
90037 + * * Redistributions in binary form must reproduce the above copyright
90038 + * notice, this list of conditions and the following disclaimer in the
90039 + * documentation and/or other materials provided with the distribution.
90040 + * * Neither the name of Freescale Semiconductor nor the
90041 + * names of its contributors may be used to endorse or promote products
90042 + * derived from this software without specific prior written permission.
90043 + *
90044 + *
90045 + * ALTERNATIVELY, this software may be distributed under the terms of the
90046 + * GNU General Public License ("GPL") as published by the Free Software
90047 + * Foundation, either version 2 of that License or (at your option) any
90048 + * later version.
90049 + *
90050 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90051 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90052 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90053 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90054 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90055 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90056 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90057 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90058 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90059 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90060 + */
90061 +
90062 +
90063 +/**************************************************************************//**
90064 + @File core_ext.h
90065 +
90066 + @Description Generic interface to basic core operations.
90067 +
90068 + The system integrator must ensure that this interface is
90069 + mapped to a specific core implementation, by including the
90070 + appropriate header file.
90071 +*//***************************************************************************/
90072 +#ifndef __CORE_EXT_H
90073 +#define __CORE_EXT_H
90074 +
90075 +#ifdef CONFIG_FMAN_ARM
90076 +#include "arm_ext.h"
90077 +#include <linux/smp.h>
90078 +#else
90079 +#ifdef NCSW_PPC_CORE
90080 +#include "ppc_ext.h"
90081 +#elif defined(NCSW_VXWORKS)
90082 +#include "core_vxw_ext.h"
90083 +#else
90084 +#error "Core is not defined!"
90085 +#endif /* NCSW_CORE */
90086 +
90087 +#if (!defined(CORE_IS_LITTLE_ENDIAN) && !defined(CORE_IS_BIG_ENDIAN))
90088 +#error "Must define core as little-endian or big-endian!"
90089 +#endif /* (!defined(CORE_IS_LITTLE_ENDIAN) && ... */
90090 +
90091 +#ifndef CORE_CACHELINE_SIZE
90092 +#error "Must define the core cache-line size!"
90093 +#endif /* !CORE_CACHELINE_SIZE */
90094 +
90095 +#endif /* CONFIG_FMAN_ARM */
90096 +
90097 +
90098 +/**************************************************************************//**
90099 + @Function CORE_GetId
90100 +
90101 + @Description Returns the core ID in the system.
90102 +
90103 + @Return Core ID.
90104 +*//***************************************************************************/
90105 +uint32_t CORE_GetId(void);
90106 +
90107 +/**************************************************************************//**
90108 + @Function CORE_MemoryBarrier
90109 +
90110 + @Description This routine will cause the core to stop executing any commands
90111 + until all previous memory read/write commands are completely out
90112 + of the core's pipeline.
90113 +
90114 + @Return None.
90115 +*//***************************************************************************/
90116 +void CORE_MemoryBarrier(void);
90117 +#define fsl_mem_core_barrier() CORE_MemoryBarrier()
90118 +
90119 +#endif /* __CORE_EXT_H */
90120 --- /dev/null
90121 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/arm_ext.h
90122 @@ -0,0 +1,55 @@
90123 +/*
90124 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90125 + *
90126 + * Redistribution and use in source and binary forms, with or without
90127 + * modification, are permitted provided that the following conditions are met:
90128 + * * Redistributions of source code must retain the above copyright
90129 + * notice, this list of conditions and the following disclaimer.
90130 + * * Redistributions in binary form must reproduce the above copyright
90131 + * notice, this list of conditions and the following disclaimer in the
90132 + * documentation and/or other materials provided with the distribution.
90133 + * * Neither the name of Freescale Semiconductor nor the
90134 + * names of its contributors may be used to endorse or promote products
90135 + * derived from this software without specific prior written permission.
90136 + *
90137 + *
90138 + * ALTERNATIVELY, this software may be distributed under the terms of the
90139 + * GNU General Public License ("GPL") as published by the Free Software
90140 + * Foundation, either version 2 of that License or (at your option) any
90141 + * later version.
90142 + *
90143 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90144 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90145 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90146 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90147 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90148 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90149 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90150 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90151 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90152 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90153 + */
90154 +
90155 +
90156 +/**************************************************************************//**
90157 + @File arm_ext.h
90158 +
90159 + @Description Core API for ARM cores
90160 +
90161 + These routines must be implemented by each specific PowerPC
90162 + core driver.
90163 +*//***************************************************************************/
90164 +#ifndef __ARM_EXT_H
90165 +#define __ARM_EXT_H
90166 +
90167 +#include "part_ext.h"
90168 +
90169 +
90170 +#define CORE_IS_LITTLE_ENDIAN
90171 +
90172 +static __inline__ void CORE_MemoryBarrier(void)
90173 +{
90174 + mb();
90175 +}
90176 +
90177 +#endif /* __PPC_EXT_H */
90178 --- /dev/null
90179 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/e500v2_ext.h
90180 @@ -0,0 +1,476 @@
90181 +/*
90182 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90183 + *
90184 + * Redistribution and use in source and binary forms, with or without
90185 + * modification, are permitted provided that the following conditions are met:
90186 + * * Redistributions of source code must retain the above copyright
90187 + * notice, this list of conditions and the following disclaimer.
90188 + * * Redistributions in binary form must reproduce the above copyright
90189 + * notice, this list of conditions and the following disclaimer in the
90190 + * documentation and/or other materials provided with the distribution.
90191 + * * Neither the name of Freescale Semiconductor nor the
90192 + * names of its contributors may be used to endorse or promote products
90193 + * derived from this software without specific prior written permission.
90194 + *
90195 + *
90196 + * ALTERNATIVELY, this software may be distributed under the terms of the
90197 + * GNU General Public License ("GPL") as published by the Free Software
90198 + * Foundation, either version 2 of that License or (at your option) any
90199 + * later version.
90200 + *
90201 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90202 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90203 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90204 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90205 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90206 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90207 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90208 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90209 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90210 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90211 + */
90212 +
90213 +
90214 +/**************************************************************************//**
90215 + @File e500v2_ext.h
90216 +
90217 + @Description E500 external definitions prototypes
90218 + This file is not included by the E500
90219 + source file as it is an assembly file. It is used
90220 + only for prototypes exposure, for inclusion
90221 + by user and other modules.
90222 +*//***************************************************************************/
90223 +
90224 +#ifndef __E500V2_EXT_H
90225 +#define __E500V2_EXT_H
90226 +
90227 +#include "std_ext.h"
90228 +
90229 +
90230 +/* Layer 1 Cache Manipulations
90231 + *==============================
90232 + * Should not be called directly by the user.
90233 + */
90234 +void L1DCache_Invalidate (void);
90235 +void L1ICache_Invalidate(void);
90236 +void L1DCache_Enable(void);
90237 +void L1ICache_Enable(void);
90238 +void L1DCache_Disable(void);
90239 +void L1ICache_Disable(void);
90240 +void L1DCache_Flush(void);
90241 +void L1ICache_Flush(void);
90242 +uint32_t L1ICache_IsEnabled(void);
90243 +uint32_t L1DCache_IsEnabled(void);
90244 +/*
90245 + *
90246 + */
90247 +uint32_t L1DCache_LineLock(uint32_t addr);
90248 +uint32_t L1ICache_LineLock(uint32_t addr);
90249 +void L1Cache_BroadCastEnable(void);
90250 +void L1Cache_BroadCastDisable(void);
90251 +
90252 +
90253 +#define CORE_DCacheEnable E500_DCacheEnable
90254 +#define CORE_ICacheEnable E500_ICacheEnable
90255 +#define CORE_DCacheDisable E500_DCacheDisable
90256 +#define CORE_ICacheDisable E500_ICacheDisable
90257 +#define CORE_GetId E500_GetId
90258 +#define CORE_TestAndSet E500_TestAndSet
90259 +#define CORE_MemoryBarrier E500_MemoryBarrier
90260 +#define CORE_InstructionSync E500_InstructionSync
90261 +
90262 +#define CORE_SetDozeMode E500_SetDozeMode
90263 +#define CORE_SetNapMode E500_SetNapMode
90264 +#define CORE_SetSleepMode E500_SetSleepMode
90265 +#define CORE_SetJogMode E500_SetJogMode
90266 +#define CORE_SetDeepSleepMode E500_SetDeepSleepMode
90267 +
90268 +#define CORE_RecoverDozeMode E500_RecoverDozeMode
90269 +#define CORE_RecoverNapMode E500_RecoverNapMode
90270 +#define CORE_RecoverSleepMode E500_RecoverSleepMode
90271 +#define CORE_RecoverJogMode E500_RecoverJogMode
90272 +
90273 +void E500_SetDozeMode(void);
90274 +void E500_SetNapMode(void);
90275 +void E500_SetSleepMode(void);
90276 +void E500_SetJogMode(void);
90277 +t_Error E500_SetDeepSleepMode(uint32_t bptrAddress);
90278 +
90279 +void E500_RecoverDozeMode(void);
90280 +void E500_RecoverNapMode(void);
90281 +void E500_RecoverSleepMode(void);
90282 +void E500_RecoverJogMode(void);
90283 +
90284 +
90285 +/**************************************************************************//**
90286 + @Group E500_id E500 Application Programming Interface
90287 +
90288 + @Description E500 API functions, definitions and enums
90289 +
90290 + @{
90291 +*//***************************************************************************/
90292 +
90293 +/**************************************************************************//**
90294 + @Group E500_init_grp E500 Initialization Unit
90295 +
90296 + @Description E500 initialization unit API functions, definitions and enums
90297 +
90298 + @{
90299 +*//***************************************************************************/
90300 +
90301 +
90302 +/**************************************************************************//**
90303 + @Function E500_DCacheEnable
90304 +
90305 + @Description Enables the data cache for memory pages that are
90306 + not cache inhibited.
90307 +
90308 + @Return None.
90309 +*//***************************************************************************/
90310 +void E500_DCacheEnable(void);
90311 +
90312 +/**************************************************************************//**
90313 + @Function E500_ICacheEnable
90314 +
90315 + @Description Enables the instruction cache for memory pages that are
90316 + not cache inhibited.
90317 +
90318 + @Return None.
90319 +*//***************************************************************************/
90320 +void E500_ICacheEnable(void);
90321 +
90322 +/**************************************************************************//**
90323 + @Function E500_DCacheDisable
90324 +
90325 + @Description Disables the data cache.
90326 +
90327 + @Return None.
90328 +*//***************************************************************************/
90329 +void E500_DCacheDisable(void);
90330 +
90331 +/**************************************************************************//**
90332 + @Function E500_ICacheDisable
90333 +
90334 + @Description Disables the instruction cache.
90335 +
90336 + @Return None.
90337 +*//***************************************************************************/
90338 +void E500_ICacheDisable(void);
90339 +
90340 +/**************************************************************************//**
90341 + @Function E500_DCacheFlush
90342 +
90343 + @Description Flushes the data cache
90344 +
90345 + @Return None.
90346 +*//***************************************************************************/
90347 +void E500_DCacheFlush(void);
90348 +
90349 +/**************************************************************************//**
90350 + @Function E500_ICacheFlush
90351 +
90352 + @Description Flushes the instruction cache.
90353 +
90354 + @Return None.
90355 +*//***************************************************************************/
90356 +void E500_ICacheFlush(void);
90357 +
90358 +/**************************************************************************//**
90359 + @Function E500_DCacheSetStashId
90360 +
90361 + @Description Set Stash Id for data cache
90362 +
90363 + @Param[in] stashId the stash id to be set.
90364 +
90365 + @Return None.
90366 +*//***************************************************************************/
90367 +void E500_DCacheSetStashId(uint8_t stashId);
90368 +
90369 +/**************************************************************************//**
90370 + @Description E500mc L2 Cache Operation Mode
90371 +*//***************************************************************************/
90372 +typedef enum e_E500mcL2CacheMode
90373 +{
90374 + e_L2_CACHE_MODE_DATA_ONLY = 0x00000001, /**< Cache data only */
90375 + e_L2_CACHE_MODE_INST_ONLY = 0x00000002, /**< Cache instructions only */
90376 + e_L2_CACHE_MODE_DATA_AND_INST = 0x00000003 /**< Cache data and instructions */
90377 +} e_E500mcL2CacheMode;
90378 +
90379 +#if defined(CORE_E500MC) || defined(CORE_E5500)
90380 +/**************************************************************************//**
90381 + @Function E500_L2CacheEnable
90382 +
90383 + @Description Enables the cache for memory pages that are not cache inhibited.
90384 +
90385 + @param[in] mode - L2 cache mode: data only, instruction only or instruction and data.
90386 +
90387 + @Return None.
90388 +
90389 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
90390 + not possible to call this routine for i-cache and than to call
90391 + again for d-cache; The second call will override the first one.
90392 +*//***************************************************************************/
90393 +void E500_L2CacheEnable(e_E500mcL2CacheMode mode);
90394 +
90395 +/**************************************************************************//**
90396 + @Function E500_L2CacheDisable
90397 +
90398 + @Description Disables the cache (data instruction or both).
90399 +
90400 + @Return None.
90401 +
90402 +*//***************************************************************************/
90403 +void E500_L2CacheDisable(void);
90404 +
90405 +/**************************************************************************//**
90406 + @Function E500_L2CacheFlush
90407 +
90408 + @Description Flushes the cache.
90409 +
90410 + @Return None.
90411 +*//***************************************************************************/
90412 +void E500_L2CacheFlush(void);
90413 +
90414 +/**************************************************************************//**
90415 + @Function E500_L2SetStashId
90416 +
90417 + @Description Set Stash Id
90418 +
90419 + @Param[in] stashId the stash id to be set.
90420 +
90421 + @Return None.
90422 +*//***************************************************************************/
90423 +void E500_L2SetStashId(uint8_t stashId);
90424 +#endif /* defined(CORE_E500MC) || defined(CORE_E5500) */
90425 +
90426 +#ifdef CORE_E6500
90427 +/**************************************************************************//**
90428 + @Function E6500_L2CacheEnable
90429 +
90430 + @Description Enables the cache for memory pages that are not cache inhibited.
90431 +
90432 + @param[in] mode - L2 cache mode: support data & instruction only.
90433 +
90434 + @Return None.
90435 +
90436 + @Cautions This routine must be call only ONCE for both caches. I.e. it is
90437 + not possible to call this routine for i-cache and than to call
90438 + again for d-cache; The second call will override the first one.
90439 +*//***************************************************************************/
90440 +void E6500_L2CacheEnable(uintptr_t clusterBase);
90441 +
90442 +/**************************************************************************//**
90443 + @Function E6500_L2CacheDisable
90444 +
90445 + @Description Disables the cache (data instruction or both).
90446 +
90447 + @Return None.
90448 +
90449 +*//***************************************************************************/
90450 +void E6500_L2CacheDisable(uintptr_t clusterBase);
90451 +
90452 +/**************************************************************************//**
90453 + @Function E6500_L2CacheFlush
90454 +
90455 + @Description Flushes the cache.
90456 +
90457 + @Return None.
90458 +*//***************************************************************************/
90459 +void E6500_L2CacheFlush(uintptr_t clusterBase);
90460 +
90461 +/**************************************************************************//**
90462 + @Function E6500_L2SetStashId
90463 +
90464 + @Description Set Stash Id
90465 +
90466 + @Param[in] stashId the stash id to be set.
90467 +
90468 + @Return None.
90469 +*//***************************************************************************/
90470 +void E6500_L2SetStashId(uintptr_t clusterBase, uint8_t stashId);
90471 +
90472 +/**************************************************************************//**
90473 + @Function E6500_GetCcsrBase
90474 +
90475 + @Description Obtain SoC CCSR base address
90476 +
90477 + @Param[in] None.
90478 +
90479 + @Return Physical CCSR base address.
90480 +*//***************************************************************************/
90481 +physAddress_t E6500_GetCcsrBase(void);
90482 +#endif /* CORE_E6500 */
90483 +
90484 +/**************************************************************************//**
90485 + @Function E500_AddressBusStreamingEnable
90486 +
90487 + @Description Enables address bus streaming on the CCB.
90488 +
90489 + This setting, along with the ECM streaming configuration
90490 + parameters, enables address bus streaming on the CCB.
90491 +
90492 + @Return None.
90493 +*//***************************************************************************/
90494 +void E500_AddressBusStreamingEnable(void);
90495 +
90496 +/**************************************************************************//**
90497 + @Function E500_AddressBusStreamingDisable
90498 +
90499 + @Description Disables address bus streaming on the CCB.
90500 +
90501 + @Return None.
90502 +*//***************************************************************************/
90503 +void E500_AddressBusStreamingDisable(void);
90504 +
90505 +/**************************************************************************//**
90506 + @Function E500_AddressBroadcastEnable
90507 +
90508 + @Description Enables address broadcast.
90509 +
90510 + The e500 broadcasts cache management instructions (dcbst, dcblc
90511 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
90512 + based on ABE. ABE must be set to allow management of external
90513 + L2 caches.
90514 +
90515 + @Return None.
90516 +*//***************************************************************************/
90517 +void E500_AddressBroadcastEnable(void);
90518 +
90519 +/**************************************************************************//**
90520 + @Function E500_AddressBroadcastDisable
90521 +
90522 + @Description Disables address broadcast.
90523 +
90524 + The e500 broadcasts cache management instructions (dcbst, dcblc
90525 + (CT = 1), icblc (CT = 1), dcbf, dcbi, mbar, msync, tlbsync, icbi)
90526 + based on ABE. ABE must be set to allow management of external
90527 + L2 caches.
90528 +
90529 + @Return None.
90530 +*//***************************************************************************/
90531 +void E500_AddressBroadcastDisable(void);
90532 +
90533 +/**************************************************************************//**
90534 + @Function E500_IsTaskletSupported
90535 +
90536 + @Description Checks if tasklets are supported by the e500 interrupt handler.
90537 +
90538 + @Retval TRUE - Tasklets are supported.
90539 + @Retval FALSE - Tasklets are not supported.
90540 +*//***************************************************************************/
90541 +bool E500_IsTaskletSupported(void);
90542 +
90543 +void E500_EnableTimeBase(void);
90544 +void E500_DisableTimeBase(void);
90545 +
90546 +uint64_t E500_GetTimeBaseTime(void);
90547 +
90548 +void E500_GenericIntrInit(void);
90549 +
90550 +t_Error E500_SetIntr(int ppcIntrSrc,
90551 + void (* Isr)(t_Handle handle),
90552 + t_Handle handle);
90553 +
90554 +t_Error E500_ClearIntr(int ppcIntrSrc);
90555 +
90556 +/**************************************************************************//**
90557 + @Function E500_GenericIntrHandler
90558 +
90559 + @Description This is the general e500 interrupt handler.
90560 +
90561 + It is called by the main assembly interrupt handler
90562 + when an exception occurs and no other function has been
90563 + assigned to this exception.
90564 +
90565 + @Param intrEntry - (In) The exception interrupt vector entry.
90566 +*//***************************************************************************/
90567 +void E500_GenericIntrHandler(uint32_t intrEntry);
90568 +
90569 +/**************************************************************************//**
90570 + @Function CriticalIntr
90571 +
90572 + @Description This is the specific critical e500 interrupt handler.
90573 +
90574 + It is called by the main assembly interrupt handler
90575 + when an critical interrupt.
90576 +
90577 + @Param intrEntry - (In) The exception interrupt vector entry.
90578 +*//***************************************************************************/
90579 +void CriticalIntr(uint32_t intrEntry);
90580 +
90581 +
90582 +/**************************************************************************//**
90583 + @Function E500_GetId
90584 +
90585 + @Description Returns the core ID in the system.
90586 +
90587 + @Return Core ID.
90588 +*//***************************************************************************/
90589 +uint32_t E500_GetId(void);
90590 +
90591 +/**************************************************************************//**
90592 + @Function E500_TestAndSet
90593 +
90594 + @Description This routine tries to atomically test-and-set an integer
90595 + in memory to a non-zero value.
90596 +
90597 + The memory will be set only if it is tested as zero, in which
90598 + case the routine returns the new non-zero value; otherwise the
90599 + routine returns zero.
90600 +
90601 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
90602 + operation should be made.
90603 +
90604 + @Retval Zero - Operation failed - memory was already set.
90605 + @Retval Non-zero - Operation succeeded - memory has been set.
90606 +*//***************************************************************************/
90607 +int E500_TestAndSet(volatile int *p);
90608 +
90609 +/**************************************************************************//**
90610 + @Function E500_MemoryBarrier
90611 +
90612 + @Description This routine will cause the core to stop executing any commands
90613 + until all previous memory read/write commands are completely out
90614 + of the core's pipeline.
90615 +
90616 + @Return None.
90617 +*//***************************************************************************/
90618 +static __inline__ void E500_MemoryBarrier(void)
90619 +{
90620 +#ifndef CORE_E500V2
90621 + __asm__ ("mbar 1");
90622 +#else /* CORE_E500V2 */
90623 + /**** ERRATA WORK AROUND START ****/
90624 + /* ERRATA num: CPU1 */
90625 + /* Description: "mbar MO = 1" instruction fails to order caching-inhibited
90626 + guarded loads and stores. */
90627 +
90628 + /* "msync" instruction is used instead */
90629 +
90630 + __asm__ ("msync");
90631 +
90632 + /**** ERRATA WORK AROUND END ****/
90633 +#endif /* CORE_E500V2 */
90634 +}
90635 +
90636 +/**************************************************************************//**
90637 + @Function E500_InstructionSync
90638 +
90639 + @Description This routine will cause the core to wait for previous instructions
90640 + (including any interrupts they generate) to complete before the
90641 + synchronization command executes, which purges all instructions
90642 + from the processor's pipeline and refetches the next instruction.
90643 +
90644 + @Return None.
90645 +*//***************************************************************************/
90646 +static __inline__ void E500_InstructionSync(void)
90647 +{
90648 + __asm__ ("isync");
90649 +}
90650 +
90651 +
90652 +/** @} */ /* end of E500_init_grp group */
90653 +/** @} */ /* end of E500_grp group */
90654 +
90655 +
90656 +#endif /* __E500V2_EXT_H */
90657 --- /dev/null
90658 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/cores/ppc_ext.h
90659 @@ -0,0 +1,141 @@
90660 +/*
90661 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90662 + *
90663 + * Redistribution and use in source and binary forms, with or without
90664 + * modification, are permitted provided that the following conditions are met:
90665 + * * Redistributions of source code must retain the above copyright
90666 + * notice, this list of conditions and the following disclaimer.
90667 + * * Redistributions in binary form must reproduce the above copyright
90668 + * notice, this list of conditions and the following disclaimer in the
90669 + * documentation and/or other materials provided with the distribution.
90670 + * * Neither the name of Freescale Semiconductor nor the
90671 + * names of its contributors may be used to endorse or promote products
90672 + * derived from this software without specific prior written permission.
90673 + *
90674 + *
90675 + * ALTERNATIVELY, this software may be distributed under the terms of the
90676 + * GNU General Public License ("GPL") as published by the Free Software
90677 + * Foundation, either version 2 of that License or (at your option) any
90678 + * later version.
90679 + *
90680 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90681 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90682 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90683 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90684 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90685 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90686 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90687 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90688 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90689 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90690 + */
90691 +
90692 +
90693 +/**************************************************************************//**
90694 + @File ppc_ext.h
90695 +
90696 + @Description Core API for PowerPC cores
90697 +
90698 + These routines must be implemented by each specific PowerPC
90699 + core driver.
90700 +*//***************************************************************************/
90701 +#ifndef __PPC_EXT_H
90702 +#define __PPC_EXT_H
90703 +
90704 +#include "part_ext.h"
90705 +
90706 +
90707 +#define CORE_IS_BIG_ENDIAN
90708 +
90709 +#if defined(CORE_E300) || defined(CORE_E500V2)
90710 +#define CORE_CACHELINE_SIZE 32
90711 +#elif defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
90712 +#define CORE_CACHELINE_SIZE 64
90713 +#else
90714 +#error "Core not defined!"
90715 +#endif /* defined(CORE_E300) || ... */
90716 +
90717 +
90718 +/**************************************************************************//**
90719 + @Function CORE_TestAndSet
90720 +
90721 + @Description This routine tries to atomically test-and-set an integer
90722 + in memory to a non-zero value.
90723 +
90724 + The memory will be set only if it is tested as zero, in which
90725 + case the routine returns the new non-zero value; otherwise the
90726 + routine returns zero.
90727 +
90728 + @Param[in] p - pointer to a volatile int in memory, on which test-and-set
90729 + operation should be made.
90730 +
90731 + @Retval Zero - Operation failed - memory was already set.
90732 + @Retval Non-zero - Operation succeeded - memory has been set.
90733 +*//***************************************************************************/
90734 +int CORE_TestAndSet(volatile int *p);
90735 +
90736 +/**************************************************************************//**
90737 + @Function CORE_InstructionSync
90738 +
90739 + @Description This routine will cause the core to wait for previous instructions
90740 + (including any interrupts they generate) to complete before the
90741 + synchronization command executes, which purges all instructions
90742 + from the processor's pipeline and refetches the next instruction.
90743 +
90744 + @Return None.
90745 +*//***************************************************************************/
90746 +void CORE_InstructionSync(void);
90747 +
90748 +/**************************************************************************//**
90749 + @Function CORE_DCacheEnable
90750 +
90751 + @Description Enables the data cache for memory pages that are
90752 + not cache inhibited.
90753 +
90754 + @Return None.
90755 +*//***************************************************************************/
90756 +void CORE_DCacheEnable(void);
90757 +
90758 +/**************************************************************************//**
90759 + @Function CORE_ICacheEnable
90760 +
90761 + @Description Enables the instruction cache for memory pages that are
90762 + not cache inhibited.
90763 +
90764 + @Return None.
90765 +*//***************************************************************************/
90766 +void CORE_ICacheEnable(void);
90767 +
90768 +/**************************************************************************//**
90769 + @Function CORE_DCacheDisable
90770 +
90771 + @Description Disables the data cache.
90772 +
90773 + @Return None.
90774 +*//***************************************************************************/
90775 +void CORE_DCacheDisable(void);
90776 +
90777 +/**************************************************************************//**
90778 + @Function CORE_ICacheDisable
90779 +
90780 + @Description Disables the instruction cache.
90781 +
90782 + @Return None.
90783 +*//***************************************************************************/
90784 +void CORE_ICacheDisable(void);
90785 +
90786 +
90787 +
90788 +#if defined(CORE_E300)
90789 +#include "e300_ext.h"
90790 +#elif defined(CORE_E500V2) || defined(CORE_E500MC) || defined(CORE_E5500) || defined(CORE_E6500)
90791 +#include "e500v2_ext.h"
90792 +#if !defined(NCSW_LINUX)
90793 +#include "e500v2_asm_ext.h"
90794 +#endif
90795 +#else
90796 +#error "Core not defined!"
90797 +#endif
90798 +
90799 +
90800 +#endif /* __PPC_EXT_H */
90801 --- /dev/null
90802 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ddr_std_ext.h
90803 @@ -0,0 +1,77 @@
90804 +/*
90805 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90806 + *
90807 + * Redistribution and use in source and binary forms, with or without
90808 + * modification, are permitted provided that the following conditions are met:
90809 + * * Redistributions of source code must retain the above copyright
90810 + * notice, this list of conditions and the following disclaimer.
90811 + * * Redistributions in binary form must reproduce the above copyright
90812 + * notice, this list of conditions and the following disclaimer in the
90813 + * documentation and/or other materials provided with the distribution.
90814 + * * Neither the name of Freescale Semiconductor nor the
90815 + * names of its contributors may be used to endorse or promote products
90816 + * derived from this software without specific prior written permission.
90817 + *
90818 + *
90819 + * ALTERNATIVELY, this software may be distributed under the terms of the
90820 + * GNU General Public License ("GPL") as published by the Free Software
90821 + * Foundation, either version 2 of that License or (at your option) any
90822 + * later version.
90823 + *
90824 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90825 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90826 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90827 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90828 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90829 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90830 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90831 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90832 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90833 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90834 + */
90835 +
90836 +#ifndef __DDR_SDT_EXT_H
90837 +#define __DDR_SDT_EXT_H
90838 +
90839 +
90840 +/**************************************************************************//**
90841 + @Group ddr_Generic_Resources
90842 +
90843 + @Description ddr generic functions, definitions and enums.
90844 +
90845 + @{
90846 +*//***************************************************************************/
90847 +
90848 +
90849 +/**************************************************************************//**
90850 + @Description SPD maximum size
90851 +*//***************************************************************************/
90852 +#define SPD_MAX_SIZE 256
90853 +
90854 +/**************************************************************************//**
90855 + @Description DDR types select
90856 +*//***************************************************************************/
90857 +typedef enum e_DdrType
90858 +{
90859 + e_DDR_DDR1,
90860 + e_DDR_DDR2,
90861 + e_DDR_DDR3,
90862 + e_DDR_DDR3L,
90863 + e_DDR_DDR4
90864 +} e_DdrType;
90865 +
90866 +/**************************************************************************//**
90867 + @Description DDR Mode.
90868 +*//***************************************************************************/
90869 +typedef enum e_DdrMode
90870 +{
90871 + e_DDR_BUS_WIDTH_32BIT,
90872 + e_DDR_BUS_WIDTH_64BIT
90873 +} e_DdrMode;
90874 +
90875 +/** @} */ /* end of ddr_Generic_Resources group */
90876 +
90877 +
90878 +
90879 +#endif /* __DDR_SDT_EXT_H */
90880 +
90881 --- /dev/null
90882 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/debug_ext.h
90883 @@ -0,0 +1,233 @@
90884 +/*
90885 + * Copyright 2008-2012 Freescale Semiconductor Inc.
90886 + *
90887 + * Redistribution and use in source and binary forms, with or without
90888 + * modification, are permitted provided that the following conditions are met:
90889 + * * Redistributions of source code must retain the above copyright
90890 + * notice, this list of conditions and the following disclaimer.
90891 + * * Redistributions in binary form must reproduce the above copyright
90892 + * notice, this list of conditions and the following disclaimer in the
90893 + * documentation and/or other materials provided with the distribution.
90894 + * * Neither the name of Freescale Semiconductor nor the
90895 + * names of its contributors may be used to endorse or promote products
90896 + * derived from this software without specific prior written permission.
90897 + *
90898 + *
90899 + * ALTERNATIVELY, this software may be distributed under the terms of the
90900 + * GNU General Public License ("GPL") as published by the Free Software
90901 + * Foundation, either version 2 of that License or (at your option) any
90902 + * later version.
90903 + *
90904 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
90905 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
90906 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
90907 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
90908 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
90909 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
90910 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
90911 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
90912 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
90913 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
90914 + */
90915 +
90916 +
90917 +/**************************************************************************//**
90918 + @File debug_ext.h
90919 +
90920 + @Description Debug mode definitions.
90921 +*//***************************************************************************/
90922 +
90923 +#ifndef __DEBUG_EXT_H
90924 +#define __DEBUG_EXT_H
90925 +
90926 +#include "std_ext.h"
90927 +#include "xx_ext.h"
90928 +#include "memcpy_ext.h"
90929 +#if (DEBUG_ERRORS > 0)
90930 +#include "sprint_ext.h"
90931 +#include "string_ext.h"
90932 +#endif /* DEBUG_ERRORS > 0 */
90933 +
90934 +
90935 +#if (DEBUG_ERRORS > 0)
90936 +
90937 +/* Internally used macros */
90938 +
90939 +#define DUMP_Print XX_Print
90940 +#define DUMP_MAX_LEVELS 6
90941 +#define DUMP_IDX_LEN 6
90942 +#define DUMP_MAX_STR 64
90943 +
90944 +
90945 +#define _CREATE_DUMP_SUBSTR(phrase) \
90946 + dumpTmpLevel = 0; dumpSubStr[0] = '\0'; \
90947 + snprintf(dumpTmpStr, DUMP_MAX_STR, "%s", #phrase); \
90948 + p_DumpToken = strtok(dumpTmpStr, (dumpIsArr[0] ? "[" : ".")); \
90949 + while ((p_DumpToken != NULL) && (dumpTmpLevel < DUMP_MAX_LEVELS)) \
90950 + { \
90951 + strlcat(dumpSubStr, p_DumpToken, DUMP_MAX_STR); \
90952 + if (dumpIsArr[dumpTmpLevel]) \
90953 + { \
90954 + strlcat(dumpSubStr, dumpIdxStr[dumpTmpLevel], DUMP_MAX_STR); \
90955 + p_DumpToken = strtok(NULL, "."); \
90956 + } \
90957 + if ((p_DumpToken != NULL) && \
90958 + ((p_DumpToken = strtok(NULL, (dumpIsArr[++dumpTmpLevel] ? "[" : "."))) != NULL)) \
90959 + strlcat(dumpSubStr, ".", DUMP_MAX_STR); \
90960 + }
90961 +
90962 +
90963 +/**************************************************************************//**
90964 + @Group gen_id General Drivers Utilities
90965 +
90966 + @Description External routines.
90967 +
90968 + @{
90969 +*//***************************************************************************/
90970 +
90971 +/**************************************************************************//**
90972 + @Group dump_id Memory and Registers Dump Mechanism
90973 +
90974 + @Description Macros for dumping memory mapped structures.
90975 +
90976 + @{
90977 +*//***************************************************************************/
90978 +
90979 +/**************************************************************************//**
90980 + @Description Declaration of dump mechanism variables.
90981 +
90982 + This macro must be declared at the beginning of each routine
90983 + which uses the dump mechanism macros, before the routine's code
90984 + starts.
90985 +*//***************************************************************************/
90986 +#define DECLARE_DUMP \
90987 + char dumpIdxStr[DUMP_MAX_LEVELS + 1][DUMP_IDX_LEN] = { "", }; \
90988 + char dumpSubStr[DUMP_MAX_STR] = ""; \
90989 + char dumpTmpStr[DUMP_MAX_STR] = ""; \
90990 + char *p_DumpToken = NULL; \
90991 + int dumpArrIdx = 0, dumpArrSize = 0, dumpLevel = 0, dumpTmpLevel = 0; \
90992 + uint8_t dumpIsArr[DUMP_MAX_LEVELS + 1] = { 0 }; \
90993 + /* Prevent warnings if not all used */ \
90994 + UNUSED(dumpIdxStr[0][0]); \
90995 + UNUSED(dumpSubStr[0]); \
90996 + UNUSED(dumpTmpStr[0]); \
90997 + UNUSED(p_DumpToken); \
90998 + UNUSED(dumpArrIdx); \
90999 + UNUSED(dumpArrSize); \
91000 + UNUSED(dumpLevel); \
91001 + UNUSED(dumpTmpLevel); \
91002 + UNUSED(dumpIsArr[0]);
91003 +
91004 +
91005 +/**************************************************************************//**
91006 + @Description Prints a title for a subsequent dumped structure or memory.
91007 +
91008 + The inputs for this macro are the structure/memory title and
91009 + its base addresses.
91010 +*//***************************************************************************/
91011 +#define DUMP_TITLE(addr, msg) \
91012 + DUMP_Print("\r\n"); DUMP_Print msg; \
91013 + if (addr) \
91014 + DUMP_Print(" (%p)", (addr)); \
91015 + DUMP_Print("\r\n---------------------------------------------------------\r\n");
91016 +
91017 +/**************************************************************************//**
91018 + @Description Prints a subtitle for a subsequent dumped sub-structure (optional).
91019 +
91020 + The inputs for this macro are the sub-structure subtitle.
91021 + A separating line with this subtitle will be printed.
91022 +*//***************************************************************************/
91023 +#define DUMP_SUBTITLE(subtitle) \
91024 + DUMP_Print("----------- "); DUMP_Print subtitle; DUMP_Print("\r\n")
91025 +
91026 +
91027 +/**************************************************************************//**
91028 + @Description Dumps a memory region in 4-bytes aligned format.
91029 +
91030 + The inputs for this macro are the base addresses and size
91031 + (in bytes) of the memory region.
91032 +*//***************************************************************************/
91033 +#define DUMP_MEMORY(addr, size) \
91034 + MemDisp((uint8_t *)(addr), (int)(size))
91035 +
91036 +
91037 +/**************************************************************************//**
91038 + @Description Declares a dump loop, for dumping a sub-structure array.
91039 +
91040 + The inputs for this macro are:
91041 + - idx: an index variable, for indexing the sub-structure items
91042 + inside the loop. This variable must be declared separately
91043 + in the beginning of the routine.
91044 + - cnt: the number of times to repeat the loop. This number should
91045 + equal the number of items in the sub-structures array.
91046 +
91047 + Note, that the body of the loop must be written inside brackets.
91048 +*//***************************************************************************/
91049 +#define DUMP_SUBSTRUCT_ARRAY(idx, cnt) \
91050 + for (idx=0, dumpIsArr[dumpLevel++] = 1; \
91051 + (idx < cnt) && (dumpLevel > 0) && snprintf(dumpIdxStr[dumpLevel-1], DUMP_IDX_LEN, "[%d]", idx); \
91052 + idx++, ((idx < cnt) || (dumpIsArr[--dumpLevel] = 0)))
91053 +
91054 +
91055 +/**************************************************************************//**
91056 + @Description Dumps a structure's member variable.
91057 +
91058 + The input for this macro is the full reference for the member
91059 + variable, where the structure is referenced using a pointer.
91060 +
91061 + Note, that a members array must be dumped using DUMP_ARR macro,
91062 + rather than using this macro.
91063 +
91064 + If the member variable is part of a sub-structure hierarchy,
91065 + the full hierarchy (including array indexing) must be specified.
91066 +
91067 + Examples: p_Struct->member
91068 + p_Struct->sub.member
91069 + p_Struct->sub[i].member
91070 +*//***************************************************************************/
91071 +#define DUMP_VAR(st, phrase) \
91072 + do { \
91073 + void *addr = (void *)&((st)->phrase); \
91074 + physAddress_t physAddr = XX_VirtToPhys(addr); \
91075 + _CREATE_DUMP_SUBSTR(phrase); \
91076 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s\r\n", \
91077 + physAddr, GET_UINT32(*(uint32_t*)addr), "", dumpSubStr); \
91078 + } while (0)
91079 +
91080 +
91081 +/**************************************************************************//**
91082 + @Description Dumps a structure's members array.
91083 +
91084 + The input for this macro is the full reference for the members
91085 + array, where the structure is referenced using a pointer.
91086 +
91087 + If the members array is part of a sub-structure hierarchy,
91088 + the full hierarchy (including array indexing) must be specified.
91089 +
91090 + Examples: p_Struct->array
91091 + p_Struct->sub.array
91092 + p_Struct->sub[i].array
91093 +*//***************************************************************************/
91094 +#define DUMP_ARR(st, phrase) \
91095 + do { \
91096 + physAddress_t physAddr; \
91097 + _CREATE_DUMP_SUBSTR(phrase); \
91098 + dumpArrSize = ARRAY_SIZE((st)->phrase); \
91099 + for (dumpArrIdx=0; dumpArrIdx < dumpArrSize; dumpArrIdx++) { \
91100 + physAddr = XX_VirtToPhys((void *)&((st)->phrase[dumpArrIdx])); \
91101 + DUMP_Print("0x%010llX: 0x%08x%8s\t%s[%d]\r\n", \
91102 + physAddr, GET_UINT32((st)->phrase[dumpArrIdx]), "", dumpSubStr, dumpArrIdx); \
91103 + } \
91104 + } while (0)
91105 +
91106 +
91107 +
91108 +#endif /* DEBUG_ERRORS > 0 */
91109 +
91110 +
91111 +/** @} */ /* end of dump_id group */
91112 +/** @} */ /* end of gen_id group */
91113 +
91114 +
91115 +#endif /* __DEBUG_EXT_H */
91116 +
91117 --- /dev/null
91118 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/endian_ext.h
91119 @@ -0,0 +1,447 @@
91120 +/*
91121 + * Copyright 2008-2012 Freescale Semiconductor Inc.
91122 + *
91123 + * Redistribution and use in source and binary forms, with or without
91124 + * modification, are permitted provided that the following conditions are met:
91125 + * * Redistributions of source code must retain the above copyright
91126 + * notice, this list of conditions and the following disclaimer.
91127 + * * Redistributions in binary form must reproduce the above copyright
91128 + * notice, this list of conditions and the following disclaimer in the
91129 + * documentation and/or other materials provided with the distribution.
91130 + * * Neither the name of Freescale Semiconductor nor the
91131 + * names of its contributors may be used to endorse or promote products
91132 + * derived from this software without specific prior written permission.
91133 + *
91134 + *
91135 + * ALTERNATIVELY, this software may be distributed under the terms of the
91136 + * GNU General Public License ("GPL") as published by the Free Software
91137 + * Foundation, either version 2 of that License or (at your option) any
91138 + * later version.
91139 + *
91140 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91141 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91142 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91143 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91144 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91145 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91146 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91147 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91148 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91149 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91150 + */
91151 +
91152 +
91153 +/**************************************************************************//**
91154 +
91155 + @File endian_ext.h
91156 +
91157 + @Description Big/little endian swapping routines.
91158 +*//***************************************************************************/
91159 +
91160 +#ifndef __ENDIAN_EXT_H
91161 +#define __ENDIAN_EXT_H
91162 +
91163 +#include "std_ext.h"
91164 +
91165 +
91166 +/**************************************************************************//**
91167 + @Group gen_id General Drivers Utilities
91168 +
91169 + @Description General usage API. This API is intended for usage by both the
91170 + internal modules and the user's application.
91171 +
91172 + @{
91173 +*//***************************************************************************/
91174 +
91175 +/**************************************************************************//**
91176 + @Group endian_id Big/Little-Endian Conversion
91177 +
91178 + @Description Routines and macros for Big/Little-Endian conversion and
91179 + general byte swapping.
91180 +
91181 + All routines and macros are expecting unsigned values as
91182 + parameters, but will generate the correct result also for
91183 + signed values. Therefore, signed/unsigned casting is allowed.
91184 + @{
91185 +*//***************************************************************************/
91186 +
91187 +/**************************************************************************//**
91188 + @Collection Byte-Swap Macros
91189 +
91190 + Macros for swapping byte order.
91191 +
91192 + @Cautions The parameters of these macros are evaluated multiple times.
91193 + For calculated expressions or expressions that contain function
91194 + calls it is recommended to use the byte-swap routines.
91195 +
91196 + @{
91197 +*//***************************************************************************/
91198 +
91199 +/**************************************************************************//**
91200 + @Description Swaps the byte order of a given 16-bit value.
91201 +
91202 + @Param[in] val - The 16-bit value to swap.
91203 +
91204 + @Return The byte-swapped value..
91205 +
91206 + @Cautions The given value is evaluated multiple times by this macro.
91207 + For calculated expressions or expressions that contain function
91208 + calls it is recommended to use the SwapUint16() routine.
91209 +
91210 + @hideinitializer
91211 +*//***************************************************************************/
91212 +#define SWAP_UINT16(val) \
91213 + ((uint16_t)((((val) & 0x00FF) << 8) | (((val) & 0xFF00) >> 8)))
91214 +
91215 +/**************************************************************************//**
91216 + @Description Swaps the byte order of a given 32-bit value.
91217 +
91218 + @Param[in] val - The 32-bit value to swap.
91219 +
91220 + @Return The byte-swapped value..
91221 +
91222 + @Cautions The given value is evaluated multiple times by this macro.
91223 + For calculated expressions or expressions that contain function
91224 + calls it is recommended to use the SwapUint32() routine.
91225 +
91226 + @hideinitializer
91227 +*//***************************************************************************/
91228 +#define SWAP_UINT32(val) \
91229 + ((uint32_t)((((val) & 0x000000FF) << 24) | \
91230 + (((val) & 0x0000FF00) << 8) | \
91231 + (((val) & 0x00FF0000) >> 8) | \
91232 + (((val) & 0xFF000000) >> 24)))
91233 +
91234 +/**************************************************************************//**
91235 + @Description Swaps the byte order of a given 64-bit value.
91236 +
91237 + @Param[in] val - The 64-bit value to swap.
91238 +
91239 + @Return The byte-swapped value..
91240 +
91241 + @Cautions The given value is evaluated multiple times by this macro.
91242 + For calculated expressions or expressions that contain function
91243 + calls it is recommended to use the SwapUint64() routine.
91244 +
91245 + @hideinitializer
91246 +*//***************************************************************************/
91247 +#define SWAP_UINT64(val) \
91248 + ((uint64_t)((((val) & 0x00000000000000FFULL) << 56) | \
91249 + (((val) & 0x000000000000FF00ULL) << 40) | \
91250 + (((val) & 0x0000000000FF0000ULL) << 24) | \
91251 + (((val) & 0x00000000FF000000ULL) << 8) | \
91252 + (((val) & 0x000000FF00000000ULL) >> 8) | \
91253 + (((val) & 0x0000FF0000000000ULL) >> 24) | \
91254 + (((val) & 0x00FF000000000000ULL) >> 40) | \
91255 + (((val) & 0xFF00000000000000ULL) >> 56)))
91256 +
91257 +/* @} */
91258 +
91259 +/**************************************************************************//**
91260 + @Collection Byte-Swap Routines
91261 +
91262 + Routines for swapping the byte order of a given parameter and
91263 + returning the swapped value.
91264 +
91265 + These inline routines are safer than the byte-swap macros,
91266 + because they evaluate the parameter expression only once.
91267 + @{
91268 +*//***************************************************************************/
91269 +
91270 +/**************************************************************************//**
91271 + @Function SwapUint16
91272 +
91273 + @Description Returns the byte-swapped value of a given 16-bit value.
91274 +
91275 + @Param[in] val - The 16-bit value.
91276 +
91277 + @Return The byte-swapped value of the parameter.
91278 +*//***************************************************************************/
91279 +static __inline__ uint16_t SwapUint16(uint16_t val)
91280 +{
91281 + return (uint16_t)(((val & 0x00FF) << 8) |
91282 + ((val & 0xFF00) >> 8));
91283 +}
91284 +
91285 +/**************************************************************************//**
91286 + @Function SwapUint32
91287 +
91288 + @Description Returns the byte-swapped value of a given 32-bit value.
91289 +
91290 + @Param[in] val - The 32-bit value.
91291 +
91292 + @Return The byte-swapped value of the parameter.
91293 +*//***************************************************************************/
91294 +static __inline__ uint32_t SwapUint32(uint32_t val)
91295 +{
91296 + return (uint32_t)(((val & 0x000000FF) << 24) |
91297 + ((val & 0x0000FF00) << 8) |
91298 + ((val & 0x00FF0000) >> 8) |
91299 + ((val & 0xFF000000) >> 24));
91300 +}
91301 +
91302 +/**************************************************************************//**
91303 + @Function SwapUint64
91304 +
91305 + @Description Returns the byte-swapped value of a given 64-bit value.
91306 +
91307 + @Param[in] val - The 64-bit value.
91308 +
91309 + @Return The byte-swapped value of the parameter.
91310 +*//***************************************************************************/
91311 +static __inline__ uint64_t SwapUint64(uint64_t val)
91312 +{
91313 + return (uint64_t)(((val & 0x00000000000000FFULL) << 56) |
91314 + ((val & 0x000000000000FF00ULL) << 40) |
91315 + ((val & 0x0000000000FF0000ULL) << 24) |
91316 + ((val & 0x00000000FF000000ULL) << 8) |
91317 + ((val & 0x000000FF00000000ULL) >> 8) |
91318 + ((val & 0x0000FF0000000000ULL) >> 24) |
91319 + ((val & 0x00FF000000000000ULL) >> 40) |
91320 + ((val & 0xFF00000000000000ULL) >> 56));
91321 +}
91322 +
91323 +/* @} */
91324 +
91325 +/**************************************************************************//**
91326 + @Collection In-place Byte-Swap-And-Set Routines
91327 +
91328 + Routines for swapping the byte order of a given variable and
91329 + setting the swapped value back to the same variable.
91330 + @{
91331 +*//***************************************************************************/
91332 +
91333 +/**************************************************************************//**
91334 + @Function SwapUint16P
91335 +
91336 + @Description Swaps the byte order of a given 16-bit variable.
91337 +
91338 + @Param[in] p_Val - Pointer to the 16-bit variable.
91339 +
91340 + @Return None.
91341 +*//***************************************************************************/
91342 +static __inline__ void SwapUint16P(uint16_t *p_Val)
91343 +{
91344 + *p_Val = SwapUint16(*p_Val);
91345 +}
91346 +
91347 +/**************************************************************************//**
91348 + @Function SwapUint32P
91349 +
91350 + @Description Swaps the byte order of a given 32-bit variable.
91351 +
91352 + @Param[in] p_Val - Pointer to the 32-bit variable.
91353 +
91354 + @Return None.
91355 +*//***************************************************************************/
91356 +static __inline__ void SwapUint32P(uint32_t *p_Val)
91357 +{
91358 + *p_Val = SwapUint32(*p_Val);
91359 +}
91360 +
91361 +/**************************************************************************//**
91362 + @Function SwapUint64P
91363 +
91364 + @Description Swaps the byte order of a given 64-bit variable.
91365 +
91366 + @Param[in] p_Val - Pointer to the 64-bit variable.
91367 +
91368 + @Return None.
91369 +*//***************************************************************************/
91370 +static __inline__ void SwapUint64P(uint64_t *p_Val)
91371 +{
91372 + *p_Val = SwapUint64(*p_Val);
91373 +}
91374 +
91375 +/* @} */
91376 +
91377 +
91378 +/**************************************************************************//**
91379 + @Collection Little-Endian Conversion Macros
91380 +
91381 + These macros convert given parameters to or from Little-Endian
91382 + format. Use these macros when you want to read or write a specific
91383 + Little-Endian value in memory, without a-priori knowing the CPU
91384 + byte order.
91385 +
91386 + These macros use the byte-swap routines. For conversion of
91387 + constants in initialization structures, you may use the CONST
91388 + versions of these macros (see below), which are using the
91389 + byte-swap macros instead.
91390 + @{
91391 +*//***************************************************************************/
91392 +
91393 +/**************************************************************************//**
91394 + @Description Converts a given 16-bit value from CPU byte order to
91395 + Little-Endian byte order.
91396 +
91397 + @Param[in] val - The 16-bit value to convert.
91398 +
91399 + @Return The converted value.
91400 +
91401 + @hideinitializer
91402 +*//***************************************************************************/
91403 +#define CPU_TO_LE16(val) SwapUint16(val)
91404 +
91405 +/**************************************************************************//**
91406 + @Description Converts a given 32-bit value from CPU byte order to
91407 + Little-Endian byte order.
91408 +
91409 + @Param[in] val - The 32-bit value to convert.
91410 +
91411 + @Return The converted value.
91412 +
91413 + @hideinitializer
91414 +*//***************************************************************************/
91415 +#define CPU_TO_LE32(val) SwapUint32(val)
91416 +
91417 +/**************************************************************************//**
91418 + @Description Converts a given 64-bit value from CPU byte order to
91419 + Little-Endian byte order.
91420 +
91421 + @Param[in] val - The 64-bit value to convert.
91422 +
91423 + @Return The converted value.
91424 +
91425 + @hideinitializer
91426 +*//***************************************************************************/
91427 +#define CPU_TO_LE64(val) SwapUint64(val)
91428 +
91429 +
91430 +/**************************************************************************//**
91431 + @Description Converts a given 16-bit value from Little-Endian byte order to
91432 + CPU byte order.
91433 +
91434 + @Param[in] val - The 16-bit value to convert.
91435 +
91436 + @Return The converted value.
91437 +
91438 + @hideinitializer
91439 +*//***************************************************************************/
91440 +#define LE16_TO_CPU(val) CPU_TO_LE16(val)
91441 +
91442 +/**************************************************************************//**
91443 + @Description Converts a given 32-bit value from Little-Endian byte order to
91444 + CPU byte order.
91445 +
91446 + @Param[in] val - The 32-bit value to convert.
91447 +
91448 + @Return The converted value.
91449 +
91450 + @hideinitializer
91451 +*//***************************************************************************/
91452 +#define LE32_TO_CPU(val) CPU_TO_LE32(val)
91453 +
91454 +/**************************************************************************//**
91455 + @Description Converts a given 64-bit value from Little-Endian byte order to
91456 + CPU byte order.
91457 +
91458 + @Param[in] val - The 64-bit value to convert.
91459 +
91460 + @Return The converted value.
91461 +
91462 + @hideinitializer
91463 +*//***************************************************************************/
91464 +#define LE64_TO_CPU(val) CPU_TO_LE64(val)
91465 +
91466 +/* @} */
91467 +
91468 +/**************************************************************************//**
91469 + @Collection Little-Endian Constant Conversion Macros
91470 +
91471 + These macros convert given constants to or from Little-Endian
91472 + format. Use these macros when you want to read or write a specific
91473 + Little-Endian constant in memory, without a-priori knowing the
91474 + CPU byte order.
91475 +
91476 + These macros use the byte-swap macros, therefore can be used for
91477 + conversion of constants in initialization structures.
91478 +
91479 + @Cautions The parameters of these macros are evaluated multiple times.
91480 + For non-constant expressions, use the non-CONST macro versions.
91481 +
91482 + @{
91483 +*//***************************************************************************/
91484 +
91485 +/**************************************************************************//**
91486 + @Description Converts a given 16-bit constant from CPU byte order to
91487 + Little-Endian byte order.
91488 +
91489 + @Param[in] val - The 16-bit value to convert.
91490 +
91491 + @Return The converted value.
91492 +
91493 + @hideinitializer
91494 +*//***************************************************************************/
91495 +#define CONST_CPU_TO_LE16(val) SWAP_UINT16(val)
91496 +
91497 +/**************************************************************************//**
91498 + @Description Converts a given 32-bit constant from CPU byte order to
91499 + Little-Endian byte order.
91500 +
91501 + @Param[in] val - The 32-bit value to convert.
91502 +
91503 + @Return The converted value.
91504 +
91505 + @hideinitializer
91506 +*//***************************************************************************/
91507 +#define CONST_CPU_TO_LE32(val) SWAP_UINT32(val)
91508 +
91509 +/**************************************************************************//**
91510 + @Description Converts a given 64-bit constant from CPU byte order to
91511 + Little-Endian byte order.
91512 +
91513 + @Param[in] val - The 64-bit value to convert.
91514 +
91515 + @Return The converted value.
91516 +
91517 + @hideinitializer
91518 +*//***************************************************************************/
91519 +#define CONST_CPU_TO_LE64(val) SWAP_UINT64(val)
91520 +
91521 +
91522 +/**************************************************************************//**
91523 + @Description Converts a given 16-bit constant from Little-Endian byte order
91524 + to CPU byte order.
91525 +
91526 + @Param[in] val - The 16-bit value to convert.
91527 +
91528 + @Return The converted value.
91529 +
91530 + @hideinitializer
91531 +*//***************************************************************************/
91532 +#define CONST_LE16_TO_CPU(val) CONST_CPU_TO_LE16(val)
91533 +
91534 +/**************************************************************************//**
91535 + @Description Converts a given 32-bit constant from Little-Endian byte order
91536 + to CPU byte order.
91537 +
91538 + @Param[in] val - The 32-bit value to convert.
91539 +
91540 + @Return The converted value.
91541 +
91542 + @hideinitializer
91543 +*//***************************************************************************/
91544 +#define CONST_LE32_TO_CPU(val) CONST_CPU_TO_LE32(val)
91545 +
91546 +/**************************************************************************//**
91547 + @Description Converts a given 64-bit constant from Little-Endian byte order
91548 + to CPU byte order.
91549 +
91550 + @Param[in] val - The 64-bit value to convert.
91551 +
91552 + @Return The converted value.
91553 +
91554 + @hideinitializer
91555 +*//***************************************************************************/
91556 +#define CONST_LE64_TO_CPU(val) CONST_CPU_TO_LE64(val)
91557 +
91558 +/* @} */
91559 +
91560 +
91561 +/** @} */ /* end of endian_id group */
91562 +/** @} */ /* end of gen_id group */
91563 +
91564 +
91565 +#endif /* __ENDIAN_EXT_H */
91566 +
91567 --- /dev/null
91568 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/enet_ext.h
91569 @@ -0,0 +1,205 @@
91570 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91571 + * All rights reserved.
91572 + *
91573 + * Redistribution and use in source and binary forms, with or without
91574 + * modification, are permitted provided that the following conditions are met:
91575 + * * Redistributions of source code must retain the above copyright
91576 + * notice, this list of conditions and the following disclaimer.
91577 + * * Redistributions in binary form must reproduce the above copyright
91578 + * notice, this list of conditions and the following disclaimer in the
91579 + * documentation and/or other materials provided with the distribution.
91580 + * * Neither the name of Freescale Semiconductor nor the
91581 + * names of its contributors may be used to endorse or promote products
91582 + * derived from this software without specific prior written permission.
91583 + *
91584 + *
91585 + * ALTERNATIVELY, this software may be distributed under the terms of the
91586 + * GNU General Public License ("GPL") as published by the Free Software
91587 + * Foundation, either version 2 of that License or (at your option) any
91588 + * later version.
91589 + *
91590 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91591 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91592 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91593 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91594 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91595 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91596 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91597 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91598 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91599 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91600 + */
91601 +
91602 +
91603 +/**************************************************************************//**
91604 + @File enet_ext.h
91605 +
91606 + @Description Ethernet generic definitions and enums.
91607 +*//***************************************************************************/
91608 +
91609 +#ifndef __ENET_EXT_H
91610 +#define __ENET_EXT_H
91611 +
91612 +#include "fsl_enet.h"
91613 +
91614 +#define ENET_NUM_OCTETS_PER_ADDRESS 6 /**< Number of octets (8-bit bytes) in an ethernet address */
91615 +#define ENET_GROUP_ADDR 0x01 /**< Group address mask for ethernet addresses */
91616 +
91617 +
91618 +/**************************************************************************//**
91619 + @Description Ethernet Address
91620 +*//***************************************************************************/
91621 +typedef uint8_t t_EnetAddr[ENET_NUM_OCTETS_PER_ADDRESS];
91622 +
91623 +/**************************************************************************//**
91624 + @Description Ethernet Address Type.
91625 +*//***************************************************************************/
91626 +typedef enum e_EnetAddrType
91627 +{
91628 + e_ENET_ADDR_TYPE_INDIVIDUAL, /**< Individual (unicast) address */
91629 + e_ENET_ADDR_TYPE_GROUP, /**< Group (multicast) address */
91630 + e_ENET_ADDR_TYPE_BROADCAST /**< Broadcast address */
91631 +} e_EnetAddrType;
91632 +
91633 +/**************************************************************************//**
91634 + @Description Ethernet MAC-PHY Interface
91635 +*//***************************************************************************/
91636 +typedef enum e_EnetInterface
91637 +{
91638 + e_ENET_IF_MII = E_ENET_IF_MII, /**< MII interface */
91639 + e_ENET_IF_RMII = E_ENET_IF_RMII, /**< RMII interface */
91640 + e_ENET_IF_SMII = E_ENET_IF_SMII, /**< SMII interface */
91641 + e_ENET_IF_GMII = E_ENET_IF_GMII, /**< GMII interface */
91642 + e_ENET_IF_RGMII = E_ENET_IF_RGMII, /**< RGMII interface */
91643 + e_ENET_IF_TBI = E_ENET_IF_TBI, /**< TBI interface */
91644 + e_ENET_IF_RTBI = E_ENET_IF_RTBI, /**< RTBI interface */
91645 + e_ENET_IF_SGMII = E_ENET_IF_SGMII, /**< SGMII interface */
91646 + e_ENET_IF_XGMII = E_ENET_IF_XGMII, /**< XGMII interface */
91647 + e_ENET_IF_QSGMII= E_ENET_IF_QSGMII, /**< QSGMII interface */
91648 + e_ENET_IF_XFI = E_ENET_IF_XFI /**< XFI interface */
91649 +} e_EnetInterface;
91650 +
91651 +#define ENET_IF_SGMII_BASEX 0x80000000 /**< SGMII/QSGII interface with 1000BaseX
91652 + auto-negotiation between MAC and phy
91653 + or backplane;
91654 + Note: 1000BaseX auto-negotiation relates
91655 + only to interface between MAC and phy/backplane,
91656 + SGMII phy can still synchronize with far-end phy
91657 + at 10Mbps, 100Mbps or 1000Mbps */
91658 +
91659 +/**************************************************************************//**
91660 + @Description Ethernet Duplex Mode
91661 +*//***************************************************************************/
91662 +typedef enum e_EnetDuplexMode
91663 +{
91664 + e_ENET_HALF_DUPLEX, /**< Half-Duplex mode */
91665 + e_ENET_FULL_DUPLEX /**< Full-Duplex mode */
91666 +} e_EnetDuplexMode;
91667 +
91668 +/**************************************************************************//**
91669 + @Description Ethernet Speed (nominal data rate)
91670 +*//***************************************************************************/
91671 +typedef enum e_EnetSpeed
91672 +{
91673 + e_ENET_SPEED_10 = E_ENET_SPEED_10, /**< 10 Mbps */
91674 + e_ENET_SPEED_100 = E_ENET_SPEED_100, /**< 100 Mbps */
91675 + e_ENET_SPEED_1000 = E_ENET_SPEED_1000, /**< 1000 Mbps = 1 Gbps */
91676 + e_ENET_SPEED_2500 = E_ENET_SPEED_2500, /**< 2500 Mbps = 2.5 Gbps */
91677 + e_ENET_SPEED_10000 = E_ENET_SPEED_10000 /**< 10000 Mbps = 10 Gbps */
91678 +} e_EnetSpeed;
91679 +
91680 +/**************************************************************************//**
91681 + @Description Ethernet mode (combination of MAC-PHY interface and speed)
91682 +*//***************************************************************************/
91683 +typedef enum e_EnetMode
91684 +{
91685 + e_ENET_MODE_INVALID = 0, /**< Invalid Ethernet mode */
91686 + e_ENET_MODE_MII_10 = (e_ENET_IF_MII | e_ENET_SPEED_10), /**< 10 Mbps MII */
91687 + e_ENET_MODE_MII_100 = (e_ENET_IF_MII | e_ENET_SPEED_100), /**< 100 Mbps MII */
91688 + e_ENET_MODE_RMII_10 = (e_ENET_IF_RMII | e_ENET_SPEED_10), /**< 10 Mbps RMII */
91689 + e_ENET_MODE_RMII_100 = (e_ENET_IF_RMII | e_ENET_SPEED_100), /**< 100 Mbps RMII */
91690 + e_ENET_MODE_SMII_10 = (e_ENET_IF_SMII | e_ENET_SPEED_10), /**< 10 Mbps SMII */
91691 + e_ENET_MODE_SMII_100 = (e_ENET_IF_SMII | e_ENET_SPEED_100), /**< 100 Mbps SMII */
91692 + e_ENET_MODE_GMII_1000 = (e_ENET_IF_GMII | e_ENET_SPEED_1000), /**< 1000 Mbps GMII */
91693 + e_ENET_MODE_RGMII_10 = (e_ENET_IF_RGMII | e_ENET_SPEED_10), /**< 10 Mbps RGMII */
91694 + e_ENET_MODE_RGMII_100 = (e_ENET_IF_RGMII | e_ENET_SPEED_100), /**< 100 Mbps RGMII */
91695 + e_ENET_MODE_RGMII_1000 = (e_ENET_IF_RGMII | e_ENET_SPEED_1000), /**< 1000 Mbps RGMII */
91696 + e_ENET_MODE_TBI_1000 = (e_ENET_IF_TBI | e_ENET_SPEED_1000), /**< 1000 Mbps TBI */
91697 + e_ENET_MODE_RTBI_1000 = (e_ENET_IF_RTBI | e_ENET_SPEED_1000), /**< 1000 Mbps RTBI */
91698 + e_ENET_MODE_SGMII_10 = (e_ENET_IF_SGMII | e_ENET_SPEED_10),
91699 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
91700 + SGMII phy according to Cisco SGMII specification */
91701 + e_ENET_MODE_SGMII_100 = (e_ENET_IF_SGMII | e_ENET_SPEED_100),
91702 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
91703 + SGMII phy according to Cisco SGMII specification */
91704 + e_ENET_MODE_SGMII_1000 = (e_ENET_IF_SGMII | e_ENET_SPEED_1000),
91705 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
91706 + SGMII phy according to Cisco SGMII specification */
91707 + e_ENET_MODE_SGMII_2500 = (e_ENET_IF_SGMII | e_ENET_SPEED_2500),
91708 + e_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_10),
91709 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
91710 + MAC and SGMII phy or backplane */
91711 + e_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_100),
91712 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
91713 + MAC and SGMII phy or backplane */
91714 + e_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_SGMII | e_ENET_SPEED_1000),
91715 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
91716 + MAC and SGMII phy or backplane */
91717 + e_ENET_MODE_QSGMII_1000 = (e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
91718 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
91719 + QSGMII phy according to Cisco QSGMII specification */
91720 + e_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | e_ENET_IF_QSGMII| e_ENET_SPEED_1000),
91721 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
91722 + MAC and QSGMII phy or backplane */
91723 + e_ENET_MODE_XGMII_10000 = (e_ENET_IF_XGMII | e_ENET_SPEED_10000), /**< 10000 Mbps XGMII */
91724 + e_ENET_MODE_XFI_10000 = (e_ENET_IF_XFI | e_ENET_SPEED_10000) /**< 10000 Mbps XFI */
91725 +} e_EnetMode;
91726 +
91727 +
91728 +#define IS_ENET_MODE_VALID(mode) \
91729 + (((mode) == e_ENET_MODE_MII_10 ) || \
91730 + ((mode) == e_ENET_MODE_MII_100 ) || \
91731 + ((mode) == e_ENET_MODE_RMII_10 ) || \
91732 + ((mode) == e_ENET_MODE_RMII_100 ) || \
91733 + ((mode) == e_ENET_MODE_SMII_10 ) || \
91734 + ((mode) == e_ENET_MODE_SMII_100 ) || \
91735 + ((mode) == e_ENET_MODE_GMII_1000 ) || \
91736 + ((mode) == e_ENET_MODE_RGMII_10 ) || \
91737 + ((mode) == e_ENET_MODE_RGMII_100 ) || \
91738 + ((mode) == e_ENET_MODE_RGMII_1000 ) || \
91739 + ((mode) == e_ENET_MODE_TBI_1000 ) || \
91740 + ((mode) == e_ENET_MODE_RTBI_1000 ) || \
91741 + ((mode) == e_ENET_MODE_SGMII_10 ) || \
91742 + ((mode) == e_ENET_MODE_SGMII_100 ) || \
91743 + ((mode) == e_ENET_MODE_SGMII_1000 ) || \
91744 + ((mode) == e_ENET_MODE_SGMII_BASEX_10 ) || \
91745 + ((mode) == e_ENET_MODE_SGMII_BASEX_100 ) || \
91746 + ((mode) == e_ENET_MODE_SGMII_BASEX_1000 ) || \
91747 + ((mode) == e_ENET_MODE_XGMII_10000) || \
91748 + ((mode) == e_ENET_MODE_QSGMII_1000) || \
91749 + ((mode) == e_ENET_MODE_QSGMII_BASEX_1000) || \
91750 + ((mode) == e_ENET_MODE_XFI_10000))
91751 +
91752 +
91753 +#define MAKE_ENET_MODE(_interface, _speed) (e_EnetMode)((_interface) | (_speed))
91754 +
91755 +#define ENET_INTERFACE_FROM_MODE(mode) (e_EnetInterface)((mode) & 0x0FFF0000)
91756 +#define ENET_SPEED_FROM_MODE(mode) (e_EnetSpeed)((mode) & 0x0000FFFF)
91757 +
91758 +#define ENET_ADDR_TO_UINT64(_enetAddr) \
91759 + (uint64_t)(((uint64_t)(_enetAddr)[0] << 40) | \
91760 + ((uint64_t)(_enetAddr)[1] << 32) | \
91761 + ((uint64_t)(_enetAddr)[2] << 24) | \
91762 + ((uint64_t)(_enetAddr)[3] << 16) | \
91763 + ((uint64_t)(_enetAddr)[4] << 8) | \
91764 + ((uint64_t)(_enetAddr)[5]))
91765 +
91766 +#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enetAddr) \
91767 + do { \
91768 + int i; \
91769 + for (i=0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
91770 + (_enetAddr)[i] = (uint8_t)((_addr64) >> ((5-i)*8)); \
91771 + } while (0)
91772 +
91773 +
91774 +#endif /* __ENET_EXT_H */
91775 --- /dev/null
91776 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/error_ext.h
91777 @@ -0,0 +1,529 @@
91778 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
91779 + * All rights reserved.
91780 + *
91781 + * Redistribution and use in source and binary forms, with or without
91782 + * modification, are permitted provided that the following conditions are met:
91783 + * * Redistributions of source code must retain the above copyright
91784 + * notice, this list of conditions and the following disclaimer.
91785 + * * Redistributions in binary form must reproduce the above copyright
91786 + * notice, this list of conditions and the following disclaimer in the
91787 + * documentation and/or other materials provided with the distribution.
91788 + * * Neither the name of Freescale Semiconductor nor the
91789 + * names of its contributors may be used to endorse or promote products
91790 + * derived from this software without specific prior written permission.
91791 + *
91792 + *
91793 + * ALTERNATIVELY, this software may be distributed under the terms of the
91794 + * GNU General Public License ("GPL") as published by the Free Software
91795 + * Foundation, either version 2 of that License or (at your option) any
91796 + * later version.
91797 + *
91798 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
91799 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
91800 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
91801 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
91802 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
91803 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
91804 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
91805 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
91806 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
91807 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91808 + */
91809 +
91810 +
91811 +/**************************************************************************//**
91812 + @File error_ext.h
91813 +
91814 + @Description Error definitions.
91815 +*//***************************************************************************/
91816 +
91817 +#ifndef __ERROR_EXT_H
91818 +#define __ERROR_EXT_H
91819 +
91820 +#if !defined(NCSW_LINUX)
91821 +#include <errno.h>
91822 +#endif
91823 +
91824 +#include "std_ext.h"
91825 +#include "xx_ext.h"
91826 +#include "core_ext.h"
91827 +
91828 +
91829 +
91830 +
91831 +/**************************************************************************//**
91832 + @Group gen_id General Drivers Utilities
91833 +
91834 + @Description External routines.
91835 +
91836 + @{
91837 +*//***************************************************************************/
91838 +
91839 +/**************************************************************************//**
91840 + @Group gen_error_id Errors, Events and Debug
91841 +
91842 + @Description External routines.
91843 +
91844 + @{
91845 +*//***************************************************************************/
91846 +
91847 +/******************************************************************************
91848 +The scheme below provides the bits description for error codes:
91849 +
91850 + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
91851 +| Reserved (should be zero) | Module ID |
91852 +
91853 + 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
91854 +| Error Type |
91855 +******************************************************************************/
91856 +
91857 +#define ERROR_CODE(_err) ((((uint32_t)_err) & 0x0000FFFF) | __ERR_MODULE__)
91858 +
91859 +#define GET_ERROR_TYPE(_errcode) ((_errcode) & 0x0000FFFF)
91860 + /**< Extract module code from error code (#t_Error) */
91861 +
91862 +#define GET_ERROR_MODULE(_errcode) ((_errcode) & 0x00FF0000)
91863 + /**< Extract error type (#e_ErrorType) from
91864 + error code (#t_Error) */
91865 +
91866 +
91867 +/**************************************************************************//**
91868 + @Description Error Type Enumeration
91869 +*//***************************************************************************/
91870 +typedef enum e_ErrorType /* Comments / Associated Message Strings */
91871 +{ /* ------------------------------------------------------------ */
91872 + E_OK = 0 /* Never use "RETURN_ERROR" with E_OK; Use "return E_OK;" */
91873 + ,E_WRITE_FAILED = EIO /**< Write access failed on memory/device. */
91874 + /* String: none, or device name. */
91875 + ,E_NO_DEVICE = ENXIO /**< The associated device is not initialized. */
91876 + /* String: none. */
91877 + ,E_NOT_AVAILABLE = EAGAIN
91878 + /**< Resource is unavailable. */
91879 + /* String: none, unless the operation is not the main goal
91880 + of the function (in this case add resource description). */
91881 + ,E_NO_MEMORY = ENOMEM /**< External memory allocation failed. */
91882 + /* String: description of item for which allocation failed. */
91883 + ,E_INVALID_ADDRESS = EFAULT
91884 + /**< Invalid address. */
91885 + /* String: description of the specific violation. */
91886 + ,E_BUSY = EBUSY /**< Resource or module is busy. */
91887 + /* String: none, unless the operation is not the main goal
91888 + of the function (in this case add resource description). */
91889 + ,E_ALREADY_EXISTS = EEXIST
91890 + /**< Requested resource or item already exists. */
91891 + /* Use when resource duplication or sharing are not allowed.
91892 + String: none, unless the operation is not the main goal
91893 + of the function (in this case add item description). */
91894 + ,E_INVALID_OPERATION = ENODEV
91895 + /**< The operation/command is invalid (unrecognized). */
91896 + /* String: none. */
91897 + ,E_INVALID_VALUE = EDOM /**< Invalid value. */
91898 + /* Use for non-enumeration parameters, and
91899 + only when other error types are not suitable.
91900 + String: parameter description + "(should be <attribute>)",
91901 + e.g: "Maximum Rx buffer length (should be divisible by 8)",
91902 + "Channel number (should be even)". */
91903 + ,E_NOT_IN_RANGE = ERANGE/**< Parameter value is out of range. */
91904 + /* Don't use this error for enumeration parameters.
91905 + String: parameter description + "(should be %d-%d)",
91906 + e.g: "Number of pad characters (should be 0-15)". */
91907 + ,E_NOT_SUPPORTED = ENOSYS
91908 + /**< The function is not supported or not implemented. */
91909 + /* String: none. */
91910 + ,E_INVALID_STATE /**< The operation is not allowed in current module state. */
91911 + /* String: none. */
91912 + ,E_INVALID_HANDLE /**< Invalid handle of module or object. */
91913 + /* String: none, unless the function takes in more than one
91914 + handle (in this case add the handle description) */
91915 + ,E_INVALID_ID /**< Invalid module ID (usually enumeration or index). */
91916 + /* String: none, unless the function takes in more than one
91917 + ID (in this case add the ID description) */
91918 + ,E_NULL_POINTER /**< Unexpected NULL pointer. */
91919 + /* String: pointer description. */
91920 + ,E_INVALID_SELECTION /**< Invalid selection or mode. */
91921 + /* Use for enumeration values, only when other error types
91922 + are not suitable.
91923 + String: parameter description. */
91924 + ,E_INVALID_COMM_MODE /**< Invalid communication mode. */
91925 + /* String: none, unless the function takes in more than one
91926 + communication mode indications (in this case add
91927 + parameter description). */
91928 + ,E_INVALID_MEMORY_TYPE /**< Invalid memory type. */
91929 + /* String: none, unless the function takes in more than one
91930 + memory types (in this case add memory description,
91931 + e.g: "Data memory", "Buffer descriptors memory"). */
91932 + ,E_INVALID_CLOCK /**< Invalid clock. */
91933 + /* String: none, unless the function takes in more than one
91934 + clocks (in this case add clock description,
91935 + e.g: "Rx clock", "Tx clock"). */
91936 + ,E_CONFLICT /**< Some setting conflicts with another setting. */
91937 + /* String: description of the conflicting settings. */
91938 + ,E_NOT_ALIGNED /**< Non-aligned address. */
91939 + /* String: parameter description + "(should be %d-bytes aligned)",
91940 + e.g: "Rx data buffer (should be 32-bytes aligned)". */
91941 + ,E_NOT_FOUND /**< Requested resource or item was not found. */
91942 + /* Use only when the resource/item is uniquely identified.
91943 + String: none, unless the operation is not the main goal
91944 + of the function (in this case add item description). */
91945 + ,E_FULL /**< Resource is full. */
91946 + /* String: none, unless the operation is not the main goal
91947 + of the function (in this case add resource description). */
91948 + ,E_EMPTY /**< Resource is empty. */
91949 + /* String: none, unless the operation is not the main goal
91950 + of the function (in this case add resource description). */
91951 + ,E_ALREADY_FREE /**< Specified resource or item is already free or deleted. */
91952 + /* String: none, unless the operation is not the main goal
91953 + of the function (in this case add item description). */
91954 + ,E_READ_FAILED /**< Read access failed on memory/device. */
91955 + /* String: none, or device name. */
91956 + ,E_INVALID_FRAME /**< Invalid frame object (NULL handle or missing buffers). */
91957 + /* String: none. */
91958 + ,E_SEND_FAILED /**< Send operation failed on device. */
91959 + /* String: none, or device name. */
91960 + ,E_RECEIVE_FAILED /**< Receive operation failed on device. */
91961 + /* String: none, or device name. */
91962 + ,E_TIMEOUT/* = ETIMEDOUT*/ /**< The operation timed out. */
91963 + /* String: none. */
91964 +
91965 + ,E_DUMMY_LAST /* NEVER USED */
91966 +
91967 +} e_ErrorType;
91968 +
91969 +/**************************************************************************//**
91970 + @Description Event Type Enumeration
91971 +*//***************************************************************************/
91972 +typedef enum e_Event /* Comments / Associated Flags and Message Strings */
91973 +{ /* ------------------------------------------------------------ */
91974 + EV_NO_EVENT = 0 /**< No event; Never used. */
91975 +
91976 + ,EV_RX_DISCARD /**< Received packet discarded (by the driver, and only for
91977 + complete packets);
91978 + Flags: error flags in case of error, zero otherwise. */
91979 + /* String: reason for discard, e.g: "Error in frame",
91980 + "Disordered frame", "Incomplete frame", "No frame object". */
91981 + ,EV_RX_ERROR /**< Receive error (by hardware/firmware);
91982 + Flags: usually status flags from the buffer descriptor. */
91983 + /* String: none. */
91984 + ,EV_TX_ERROR /**< Transmit error (by hardware/firmware);
91985 + Flags: usually status flags from the buffer descriptor. */
91986 + /* String: none. */
91987 + ,EV_NO_BUFFERS /**< System ran out of buffer objects;
91988 + Flags: zero. */
91989 + /* String: none. */
91990 + ,EV_NO_MB_FRAMES /**< System ran out of multi-buffer frame objects;
91991 + Flags: zero. */
91992 + /* String: none. */
91993 + ,EV_NO_SB_FRAMES /**< System ran out of single-buffer frame objects;
91994 + Flags: zero. */
91995 + /* String: none. */
91996 + ,EV_TX_QUEUE_FULL /**< Transmit queue is full;
91997 + Flags: zero. */
91998 + /* String: none. */
91999 + ,EV_RX_QUEUE_FULL /**< Receive queue is full;
92000 + Flags: zero. */
92001 + /* String: none. */
92002 + ,EV_INTR_QUEUE_FULL /**< Interrupt queue overflow;
92003 + Flags: zero. */
92004 + /* String: none. */
92005 + ,EV_NO_DATA_BUFFER /**< Data buffer allocation (from higher layer) failed;
92006 + Flags: zero. */
92007 + /* String: none. */
92008 + ,EV_OBJ_POOL_EMPTY /**< Objects pool is empty;
92009 + Flags: zero. */
92010 + /* String: object description (name). */
92011 + ,EV_BUS_ERROR /**< Illegal access on bus;
92012 + Flags: the address (if available) or bus identifier */
92013 + /* String: bus/address/module description. */
92014 + ,EV_PTP_TXTS_QUEUE_FULL /**< PTP Tx timestamps queue is full;
92015 + Flags: zero. */
92016 + /* String: none. */
92017 + ,EV_PTP_RXTS_QUEUE_FULL /**< PTP Rx timestamps queue is full;
92018 + Flags: zero. */
92019 + /* String: none. */
92020 + ,EV_DUMMY_LAST
92021 +
92022 +} e_Event;
92023 +
92024 +
92025 +/**************************************************************************//**
92026 + @Collection Debug Levels for Errors and Events
92027 +
92028 + The level description refers to errors only.
92029 + For events, classification is done by the user.
92030 +
92031 + The TRACE, INFO and WARNING levels are allowed only when using
92032 + the DBG macro, and are not allowed when using the error macros
92033 + (RETURN_ERROR or REPORT_ERROR).
92034 + @{
92035 +*//***************************************************************************/
92036 +#define REPORT_LEVEL_CRITICAL 1 /**< Crasher: Incorrect flow, NULL pointers/handles. */
92037 +#define REPORT_LEVEL_MAJOR 2 /**< Cannot proceed: Invalid operation, parameters or
92038 + configuration. */
92039 +#define REPORT_LEVEL_MINOR 3 /**< Recoverable problem: a repeating call with the same
92040 + parameters may be successful. */
92041 +#define REPORT_LEVEL_WARNING 4 /**< Something is not exactly right, yet it is not an error. */
92042 +#define REPORT_LEVEL_INFO 5 /**< Messages which may be of interest to user/programmer. */
92043 +#define REPORT_LEVEL_TRACE 6 /**< Program flow messages. */
92044 +
92045 +#define EVENT_DISABLED 0xFF /**< Disabled event (not reported at all) */
92046 +
92047 +/* @} */
92048 +
92049 +
92050 +
92051 +#define NO_MSG ("")
92052 +
92053 +#ifndef DEBUG_GLOBAL_LEVEL
92054 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
92055 +#endif /* DEBUG_GLOBAL_LEVEL */
92056 +
92057 +#ifndef ERROR_GLOBAL_LEVEL
92058 +#define ERROR_GLOBAL_LEVEL DEBUG_GLOBAL_LEVEL
92059 +#endif /* ERROR_GLOBAL_LEVEL */
92060 +
92061 +#ifndef EVENT_GLOBAL_LEVEL
92062 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
92063 +#endif /* EVENT_GLOBAL_LEVEL */
92064 +
92065 +#ifdef EVENT_LOCAL_LEVEL
92066 +#define EVENT_DYNAMIC_LEVEL EVENT_LOCAL_LEVEL
92067 +#else
92068 +#define EVENT_DYNAMIC_LEVEL EVENT_GLOBAL_LEVEL
92069 +#endif /* EVENT_LOCAL_LEVEL */
92070 +
92071 +
92072 +#ifndef DEBUG_DYNAMIC_LEVEL
92073 +#define DEBUG_USING_STATIC_LEVEL
92074 +
92075 +#ifdef DEBUG_STATIC_LEVEL
92076 +#define DEBUG_DYNAMIC_LEVEL DEBUG_STATIC_LEVEL
92077 +#else
92078 +#define DEBUG_DYNAMIC_LEVEL DEBUG_GLOBAL_LEVEL
92079 +#endif /* DEBUG_STATIC_LEVEL */
92080 +
92081 +#else /* DEBUG_DYNAMIC_LEVEL */
92082 +#ifdef DEBUG_STATIC_LEVEL
92083 +#error "Please use either DEBUG_STATIC_LEVEL or DEBUG_DYNAMIC_LEVEL (not both)"
92084 +#else
92085 +int DEBUG_DYNAMIC_LEVEL = DEBUG_GLOBAL_LEVEL;
92086 +#endif /* DEBUG_STATIC_LEVEL */
92087 +#endif /* !DEBUG_DYNAMIC_LEVEL */
92088 +
92089 +
92090 +#ifndef ERROR_DYNAMIC_LEVEL
92091 +
92092 +#ifdef ERROR_STATIC_LEVEL
92093 +#define ERROR_DYNAMIC_LEVEL ERROR_STATIC_LEVEL
92094 +#else
92095 +#define ERROR_DYNAMIC_LEVEL ERROR_GLOBAL_LEVEL
92096 +#endif /* ERROR_STATIC_LEVEL */
92097 +
92098 +#else /* ERROR_DYNAMIC_LEVEL */
92099 +#ifdef ERROR_STATIC_LEVEL
92100 +#error "Please use either ERROR_STATIC_LEVEL or ERROR_DYNAMIC_LEVEL (not both)"
92101 +#else
92102 +int ERROR_DYNAMIC_LEVEL = ERROR_GLOBAL_LEVEL;
92103 +#endif /* ERROR_STATIC_LEVEL */
92104 +#endif /* !ERROR_DYNAMIC_LEVEL */
92105 +
92106 +#define PRINT_FORMAT "[CPU%02d, %s:%d %s]"
92107 +#define PRINT_FMT_PARAMS raw_smp_processor_id(), __FILE__, __LINE__, __FUNCTION__
92108 +
92109 +#if (!(defined(DEBUG_ERRORS)) || (DEBUG_ERRORS == 0))
92110 +/* No debug/error/event messages at all */
92111 +#define DBG(_level, _vmsg)
92112 +
92113 +#define REPORT_ERROR(_level, _err, _vmsg)
92114 +
92115 +#define RETURN_ERROR(_level, _err, _vmsg) \
92116 + return ERROR_CODE(_err)
92117 +
92118 +#if (REPORT_EVENTS > 0)
92119 +
92120 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
92121 + do { \
92122 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
92123 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
92124 + } \
92125 + } while (0)
92126 +
92127 +#else
92128 +
92129 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
92130 +
92131 +#endif /* (REPORT_EVENTS > 0) */
92132 +
92133 +
92134 +#else /* DEBUG_ERRORS > 0 */
92135 +
92136 +extern const char *dbgLevelStrings[];
92137 +extern const char *moduleStrings[];
92138 +#if (REPORT_EVENTS > 0)
92139 +extern const char *eventStrings[];
92140 +#endif /* (REPORT_EVENTS > 0) */
92141 +
92142 +char * ErrTypeStrings (e_ErrorType err);
92143 +
92144 +
92145 +#if ((defined(DEBUG_USING_STATIC_LEVEL)) && (DEBUG_DYNAMIC_LEVEL < REPORT_LEVEL_WARNING))
92146 +/* No need for DBG macro - debug level is higher anyway */
92147 +#define DBG(_level, _vmsg)
92148 +#else
92149 +#define DBG(_level, _vmsg) \
92150 + do { \
92151 + if (REPORT_LEVEL_##_level <= DEBUG_DYNAMIC_LEVEL) { \
92152 + XX_Print("> %s (%s) " PRINT_FORMAT ": ", \
92153 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
92154 + moduleStrings[__ERR_MODULE__ >> 16], \
92155 + PRINT_FMT_PARAMS); \
92156 + XX_Print _vmsg; \
92157 + XX_Print("\r\n"); \
92158 + } \
92159 + } while (0)
92160 +#endif /* (defined(DEBUG_USING_STATIC_LEVEL) && (DEBUG_DYNAMIC_LEVEL < WARNING)) */
92161 +
92162 +
92163 +#define REPORT_ERROR(_level, _err, _vmsg) \
92164 + do { \
92165 + if (REPORT_LEVEL_##_level <= ERROR_DYNAMIC_LEVEL) { \
92166 + XX_Print("! %s %s Error " PRINT_FORMAT ": %s; ", \
92167 + dbgLevelStrings[REPORT_LEVEL_##_level - 1], \
92168 + moduleStrings[__ERR_MODULE__ >> 16], \
92169 + PRINT_FMT_PARAMS, \
92170 + ErrTypeStrings((e_ErrorType)GET_ERROR_TYPE(_err))); \
92171 + XX_Print _vmsg; \
92172 + XX_Print("\r\n"); \
92173 + } \
92174 + } while (0)
92175 +
92176 +
92177 +#define RETURN_ERROR(_level, _err, _vmsg) \
92178 + do { \
92179 + REPORT_ERROR(_level, (_err), _vmsg); \
92180 + return ERROR_CODE(_err); \
92181 + } while (0)
92182 +
92183 +
92184 +#if (REPORT_EVENTS > 0)
92185 +
92186 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg) \
92187 + do { \
92188 + if (_ev##_LEVEL <= EVENT_DYNAMIC_LEVEL) { \
92189 + XX_Print("~ %s %s Event " PRINT_FORMAT ": %s (flags: 0x%04x); ", \
92190 + dbgLevelStrings[_ev##_LEVEL - 1], \
92191 + moduleStrings[__ERR_MODULE__ >> 16], \
92192 + PRINT_FMT_PARAMS, \
92193 + eventStrings[((_ev) - EV_NO_EVENT - 1)], \
92194 + (uint16_t)(_flg)); \
92195 + XX_Print _vmsg; \
92196 + XX_Print("\r\n"); \
92197 + XX_EventById((uint32_t)(_ev), (t_Handle)(_appId), (uint16_t)(_flg), NO_MSG); \
92198 + } \
92199 + } while (0)
92200 +
92201 +#else /* not REPORT_EVENTS */
92202 +
92203 +#define REPORT_EVENT(_ev, _appId, _flg, _vmsg)
92204 +
92205 +#endif /* (REPORT_EVENTS > 0) */
92206 +
92207 +#endif /* (DEBUG_ERRORS > 0) */
92208 +
92209 +
92210 +/**************************************************************************//**
92211 + @Function ASSERT_COND
92212 +
92213 + @Description Assertion macro.
92214 +
92215 + @Param[in] _cond - The condition being checked, in positive form;
92216 + Failure of the condition triggers the assert.
92217 +*//***************************************************************************/
92218 +#ifdef DISABLE_ASSERTIONS
92219 +#define ASSERT_COND(_cond)
92220 +#else
92221 +#define ASSERT_COND(_cond) \
92222 + do { \
92223 + if (!(_cond)) { \
92224 + XX_Print("*** ASSERT_COND failed " PRINT_FORMAT "\r\n", \
92225 + PRINT_FMT_PARAMS); \
92226 + XX_Exit(1); \
92227 + } \
92228 + } while (0)
92229 +#endif /* DISABLE_ASSERTIONS */
92230 +
92231 +
92232 +#ifdef DISABLE_INIT_PARAMETERS_CHECK
92233 +
92234 +#define CHECK_INIT_PARAMETERS(handle, f_check)
92235 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval)
92236 +
92237 +#else
92238 +
92239 +#define CHECK_INIT_PARAMETERS(handle, f_check) \
92240 + do { \
92241 + t_Error err = f_check(handle); \
92242 + if (err != E_OK) { \
92243 + RETURN_ERROR(MAJOR, err, NO_MSG); \
92244 + } \
92245 + } while (0)
92246 +
92247 +#define CHECK_INIT_PARAMETERS_RETURN_VALUE(handle, f_check, retval) \
92248 + do { \
92249 + t_Error err = f_check(handle); \
92250 + if (err != E_OK) { \
92251 + REPORT_ERROR(MAJOR, err, NO_MSG); \
92252 + return (retval); \
92253 + } \
92254 + } while (0)
92255 +
92256 +#endif /* DISABLE_INIT_PARAMETERS_CHECK */
92257 +
92258 +#ifdef DISABLE_SANITY_CHECKS
92259 +
92260 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err)
92261 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval)
92262 +#define SANITY_CHECK_RETURN(_cond, _err)
92263 +#define SANITY_CHECK_EXIT(_cond, _err)
92264 +
92265 +#else /* DISABLE_SANITY_CHECKS */
92266 +
92267 +#define SANITY_CHECK_RETURN_ERROR(_cond, _err) \
92268 + do { \
92269 + if (!(_cond)) { \
92270 + RETURN_ERROR(CRITICAL, (_err), NO_MSG); \
92271 + } \
92272 + } while (0)
92273 +
92274 +#define SANITY_CHECK_RETURN_VALUE(_cond, _err, retval) \
92275 + do { \
92276 + if (!(_cond)) { \
92277 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
92278 + return (retval); \
92279 + } \
92280 + } while (0)
92281 +
92282 +#define SANITY_CHECK_RETURN(_cond, _err) \
92283 + do { \
92284 + if (!(_cond)) { \
92285 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
92286 + return; \
92287 + } \
92288 + } while (0)
92289 +
92290 +#define SANITY_CHECK_EXIT(_cond, _err) \
92291 + do { \
92292 + if (!(_cond)) { \
92293 + REPORT_ERROR(CRITICAL, (_err), NO_MSG); \
92294 + XX_Exit(1); \
92295 + } \
92296 + } while (0)
92297 +
92298 +#endif /* DISABLE_SANITY_CHECKS */
92299 +
92300 +/** @} */ /* end of Debug/error Utils group */
92301 +
92302 +/** @} */ /* end of General Utils group */
92303 +
92304 +#endif /* __ERROR_EXT_H */
92305 +
92306 +
92307 --- /dev/null
92308 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/list_ext.h
92309 @@ -0,0 +1,358 @@
92310 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
92311 + * All rights reserved.
92312 + *
92313 + * Redistribution and use in source and binary forms, with or without
92314 + * modification, are permitted provided that the following conditions are met:
92315 + * * Redistributions of source code must retain the above copyright
92316 + * notice, this list of conditions and the following disclaimer.
92317 + * * Redistributions in binary form must reproduce the above copyright
92318 + * notice, this list of conditions and the following disclaimer in the
92319 + * documentation and/or other materials provided with the distribution.
92320 + * * Neither the name of Freescale Semiconductor nor the
92321 + * names of its contributors may be used to endorse or promote products
92322 + * derived from this software without specific prior written permission.
92323 + *
92324 + *
92325 + * ALTERNATIVELY, this software may be distributed under the terms of the
92326 + * GNU General Public License ("GPL") as published by the Free Software
92327 + * Foundation, either version 2 of that License or (at your option) any
92328 + * later version.
92329 + *
92330 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92331 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92332 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92333 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92334 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92335 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92336 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92337 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92338 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92339 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92340 + */
92341 +
92342 +
92343 +/**************************************************************************//**
92344 +
92345 + @File list_ext.h
92346 +
92347 + @Description External prototypes for list.c
92348 +*//***************************************************************************/
92349 +
92350 +#ifndef __LIST_EXT_H
92351 +#define __LIST_EXT_H
92352 +
92353 +
92354 +#include "std_ext.h"
92355 +
92356 +
92357 +/**************************************************************************//**
92358 + @Group etc_id Utility Library Application Programming Interface
92359 +
92360 + @Description External routines.
92361 +
92362 + @{
92363 +*//***************************************************************************/
92364 +
92365 +/**************************************************************************//**
92366 + @Group list_id List
92367 +
92368 + @Description List module functions,definitions and enums.
92369 +
92370 + @{
92371 +*//***************************************************************************/
92372 +
92373 +/**************************************************************************//**
92374 + @Description List structure.
92375 +*//***************************************************************************/
92376 +typedef struct List
92377 +{
92378 + struct List *p_Next; /**< A pointer to the next list object */
92379 + struct List *p_Prev; /**< A pointer to the previous list object */
92380 +} t_List;
92381 +
92382 +
92383 +/**************************************************************************//**
92384 + @Function LIST_FIRST/LIST_LAST/LIST_NEXT/LIST_PREV
92385 +
92386 + @Description Macro to get first/last/next/previous entry in a list.
92387 +
92388 + @Param[in] p_List - A pointer to a list.
92389 +*//***************************************************************************/
92390 +#define LIST_FIRST(p_List) (p_List)->p_Next
92391 +#define LIST_LAST(p_List) (p_List)->p_Prev
92392 +#define LIST_NEXT LIST_FIRST
92393 +#define LIST_PREV LIST_LAST
92394 +
92395 +
92396 +/**************************************************************************//**
92397 + @Function LIST_INIT
92398 +
92399 + @Description Macro for initialization of a list struct.
92400 +
92401 + @Param[in] lst - The t_List object to initialize.
92402 +*//***************************************************************************/
92403 +#define LIST_INIT(lst) {&(lst), &(lst)}
92404 +
92405 +
92406 +/**************************************************************************//**
92407 + @Function LIST
92408 +
92409 + @Description Macro to declare of a list.
92410 +
92411 + @Param[in] listName - The list object name.
92412 +*//***************************************************************************/
92413 +#define LIST(listName) t_List listName = LIST_INIT(listName)
92414 +
92415 +
92416 +/**************************************************************************//**
92417 + @Function INIT_LIST
92418 +
92419 + @Description Macro to initialize a list pointer.
92420 +
92421 + @Param[in] p_List - The list pointer.
92422 +*//***************************************************************************/
92423 +#define INIT_LIST(p_List) LIST_FIRST(p_List) = LIST_LAST(p_List) = (p_List)
92424 +
92425 +
92426 +/**************************************************************************//**
92427 + @Function LIST_OBJECT
92428 +
92429 + @Description Macro to get the struct (object) for this entry.
92430 +
92431 + @Param[in] type - The type of the struct (object) this list is embedded in.
92432 + @Param[in] member - The name of the t_List object within the struct.
92433 +
92434 + @Return The structure pointer for this entry.
92435 +*//***************************************************************************/
92436 +#define MEMBER_OFFSET(type, member) (PTR_TO_UINT(&((type *)0)->member))
92437 +#define LIST_OBJECT(p_List, type, member) \
92438 + ((type *)((char *)(p_List)-MEMBER_OFFSET(type, member)))
92439 +
92440 +
92441 +/**************************************************************************//**
92442 + @Function LIST_FOR_EACH
92443 +
92444 + @Description Macro to iterate over a list.
92445 +
92446 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
92447 + @Param[in] p_Head - A pointer to the head for your list pointer.
92448 +
92449 + @Cautions You can't delete items with this routine.
92450 + For deletion use LIST_FOR_EACH_SAFE().
92451 +*//***************************************************************************/
92452 +#define LIST_FOR_EACH(p_Pos, p_Head) \
92453 + for (p_Pos = LIST_FIRST(p_Head); p_Pos != (p_Head); p_Pos = LIST_NEXT(p_Pos))
92454 +
92455 +
92456 +/**************************************************************************//**
92457 + @Function LIST_FOR_EACH_SAFE
92458 +
92459 + @Description Macro to iterate over a list safe against removal of list entry.
92460 +
92461 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
92462 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
92463 + @Param[in] p_Head - A pointer to the head for your list pointer.
92464 +*//***************************************************************************/
92465 +#define LIST_FOR_EACH_SAFE(p_Pos, p_Tmp, p_Head) \
92466 + for (p_Pos = LIST_FIRST(p_Head), p_Tmp = LIST_FIRST(p_Pos); \
92467 + p_Pos != (p_Head); \
92468 + p_Pos = p_Tmp, p_Tmp = LIST_NEXT(p_Pos))
92469 +
92470 +
92471 +/**************************************************************************//**
92472 + @Function LIST_FOR_EACH_OBJECT_SAFE
92473 +
92474 + @Description Macro to iterate over list of given type safely.
92475 +
92476 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
92477 + @Param[in] p_Tmp - Another pointer to a list to use as temporary storage.
92478 + @Param[in] type - The type of the struct this is embedded in.
92479 + @Param[in] p_Head - A pointer to the head for your list pointer.
92480 + @Param[in] member - The name of the list_struct within the struct.
92481 +
92482 + @Cautions You can't delete items with this routine.
92483 + For deletion use LIST_FOR_EACH_SAFE().
92484 +*//***************************************************************************/
92485 +#define LIST_FOR_EACH_OBJECT_SAFE(p_Pos, p_Tmp, p_Head, type, member) \
92486 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member), \
92487 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member); \
92488 + &p_Pos->member != (p_Head); \
92489 + p_Pos = p_Tmp, \
92490 + p_Tmp = LIST_OBJECT(LIST_FIRST(&p_Pos->member), type, member))
92491 +
92492 +/**************************************************************************//**
92493 + @Function LIST_FOR_EACH_OBJECT
92494 +
92495 + @Description Macro to iterate over list of given type.
92496 +
92497 + @Param[in] p_Pos - A pointer to a list to use as a loop counter.
92498 + @Param[in] type - The type of the struct this is embedded in.
92499 + @Param[in] p_Head - A pointer to the head for your list pointer.
92500 + @Param[in] member - The name of the list_struct within the struct.
92501 +
92502 + @Cautions You can't delete items with this routine.
92503 + For deletion use LIST_FOR_EACH_SAFE().
92504 +*//***************************************************************************/
92505 +#define LIST_FOR_EACH_OBJECT(p_Pos, type, p_Head, member) \
92506 + for (p_Pos = LIST_OBJECT(LIST_FIRST(p_Head), type, member); \
92507 + &p_Pos->member != (p_Head); \
92508 + p_Pos = LIST_OBJECT(LIST_FIRST(&(p_Pos->member)), type, member))
92509 +
92510 +
92511 +/**************************************************************************//**
92512 + @Function LIST_Add
92513 +
92514 + @Description Add a new entry to a list.
92515 +
92516 + Insert a new entry after the specified head.
92517 + This is good for implementing stacks.
92518 +
92519 + @Param[in] p_New - A pointer to a new list entry to be added.
92520 + @Param[in] p_Head - A pointer to a list head to add it after.
92521 +
92522 + @Return none.
92523 +*//***************************************************************************/
92524 +static __inline__ void LIST_Add(t_List *p_New, t_List *p_Head)
92525 +{
92526 + LIST_PREV(LIST_NEXT(p_Head)) = p_New;
92527 + LIST_NEXT(p_New) = LIST_NEXT(p_Head);
92528 + LIST_PREV(p_New) = p_Head;
92529 + LIST_NEXT(p_Head) = p_New;
92530 +}
92531 +
92532 +
92533 +/**************************************************************************//**
92534 + @Function LIST_AddToTail
92535 +
92536 + @Description Add a new entry to a list.
92537 +
92538 + Insert a new entry before the specified head.
92539 + This is useful for implementing queues.
92540 +
92541 + @Param[in] p_New - A pointer to a new list entry to be added.
92542 + @Param[in] p_Head - A pointer to a list head to add it before.
92543 +
92544 + @Return none.
92545 +*//***************************************************************************/
92546 +static __inline__ void LIST_AddToTail(t_List *p_New, t_List *p_Head)
92547 +{
92548 + LIST_NEXT(LIST_PREV(p_Head)) = p_New;
92549 + LIST_PREV(p_New) = LIST_PREV(p_Head);
92550 + LIST_NEXT(p_New) = p_Head;
92551 + LIST_PREV(p_Head) = p_New;
92552 +}
92553 +
92554 +
92555 +/**************************************************************************//**
92556 + @Function LIST_Del
92557 +
92558 + @Description Deletes entry from a list.
92559 +
92560 + @Param[in] p_Entry - A pointer to the element to delete from the list.
92561 +
92562 + @Return none.
92563 +
92564 + @Cautions LIST_IsEmpty() on entry does not return true after this,
92565 + the entry is in an undefined state.
92566 +*//***************************************************************************/
92567 +static __inline__ void LIST_Del(t_List *p_Entry)
92568 +{
92569 + LIST_PREV(LIST_NEXT(p_Entry)) = LIST_PREV(p_Entry);
92570 + LIST_NEXT(LIST_PREV(p_Entry)) = LIST_NEXT(p_Entry);
92571 +}
92572 +
92573 +
92574 +/**************************************************************************//**
92575 + @Function LIST_DelAndInit
92576 +
92577 + @Description Deletes entry from list and reinitialize it.
92578 +
92579 + @Param[in] p_Entry - A pointer to the element to delete from the list.
92580 +
92581 + @Return none.
92582 +*//***************************************************************************/
92583 +static __inline__ void LIST_DelAndInit(t_List *p_Entry)
92584 +{
92585 + LIST_Del(p_Entry);
92586 + INIT_LIST(p_Entry);
92587 +}
92588 +
92589 +
92590 +/**************************************************************************//**
92591 + @Function LIST_Move
92592 +
92593 + @Description Delete from one list and add as another's head.
92594 +
92595 + @Param[in] p_Entry - A pointer to the list entry to move.
92596 + @Param[in] p_Head - A pointer to the list head that will precede our entry.
92597 +
92598 + @Return none.
92599 +*//***************************************************************************/
92600 +static __inline__ void LIST_Move(t_List *p_Entry, t_List *p_Head)
92601 +{
92602 + LIST_Del(p_Entry);
92603 + LIST_Add(p_Entry, p_Head);
92604 +}
92605 +
92606 +
92607 +/**************************************************************************//**
92608 + @Function LIST_MoveToTail
92609 +
92610 + @Description Delete from one list and add as another's tail.
92611 +
92612 + @Param[in] p_Entry - A pointer to the entry to move.
92613 + @Param[in] p_Head - A pointer to the list head that will follow our entry.
92614 +
92615 + @Return none.
92616 +*//***************************************************************************/
92617 +static __inline__ void LIST_MoveToTail(t_List *p_Entry, t_List *p_Head)
92618 +{
92619 + LIST_Del(p_Entry);
92620 + LIST_AddToTail(p_Entry, p_Head);
92621 +}
92622 +
92623 +
92624 +/**************************************************************************//**
92625 + @Function LIST_IsEmpty
92626 +
92627 + @Description Tests whether a list is empty.
92628 +
92629 + @Param[in] p_List - A pointer to the list to test.
92630 +
92631 + @Return 1 if the list is empty, 0 otherwise.
92632 +*//***************************************************************************/
92633 +static __inline__ int LIST_IsEmpty(t_List *p_List)
92634 +{
92635 + return (LIST_FIRST(p_List) == p_List);
92636 +}
92637 +
92638 +
92639 +/**************************************************************************//**
92640 + @Function LIST_Append
92641 +
92642 + @Description Join two lists.
92643 +
92644 + @Param[in] p_NewList - A pointer to the new list to add.
92645 + @Param[in] p_Head - A pointer to the place to add it in the first list.
92646 +
92647 + @Return none.
92648 +*//***************************************************************************/
92649 +void LIST_Append(t_List *p_NewList, t_List *p_Head);
92650 +
92651 +
92652 +/**************************************************************************//**
92653 + @Function LIST_NumOfObjs
92654 +
92655 + @Description Counts number of objects in the list
92656 +
92657 + @Param[in] p_List - A pointer to the list which objects are to be counted.
92658 +
92659 + @Return Number of objects in the list.
92660 +*//***************************************************************************/
92661 +int LIST_NumOfObjs(t_List *p_List);
92662 +
92663 +/** @} */ /* end of list_id group */
92664 +/** @} */ /* end of etc_id group */
92665 +
92666 +
92667 +#endif /* __LIST_EXT_H */
92668 --- /dev/null
92669 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mem_ext.h
92670 @@ -0,0 +1,318 @@
92671 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
92672 + * All rights reserved.
92673 + *
92674 + * Redistribution and use in source and binary forms, with or without
92675 + * modification, are permitted provided that the following conditions are met:
92676 + * * Redistributions of source code must retain the above copyright
92677 + * notice, this list of conditions and the following disclaimer.
92678 + * * Redistributions in binary form must reproduce the above copyright
92679 + * notice, this list of conditions and the following disclaimer in the
92680 + * documentation and/or other materials provided with the distribution.
92681 + * * Neither the name of Freescale Semiconductor nor the
92682 + * names of its contributors may be used to endorse or promote products
92683 + * derived from this software without specific prior written permission.
92684 + *
92685 + *
92686 + * ALTERNATIVELY, this software may be distributed under the terms of the
92687 + * GNU General Public License ("GPL") as published by the Free Software
92688 + * Foundation, either version 2 of that License or (at your option) any
92689 + * later version.
92690 + *
92691 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
92692 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
92693 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
92694 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
92695 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
92696 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
92697 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
92698 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
92699 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
92700 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
92701 + */
92702 +
92703 +
92704 +/**************************************************************************//**
92705 +
92706 + @File mem_ext.h
92707 +
92708 + @Description External prototypes for the memory manager object
92709 +*//***************************************************************************/
92710 +
92711 +#ifndef __MEM_EXT_H
92712 +#define __MEM_EXT_H
92713 +
92714 +#include "std_ext.h"
92715 +#include "part_ext.h"
92716 +
92717 +
92718 +/**************************************************************************//**
92719 + @Group etc_id Utility Library Application Programming Interface
92720 +
92721 + @Description External routines.
92722 +
92723 + @{
92724 +*//***************************************************************************/
92725 +
92726 +/**************************************************************************//**
92727 + @Group mem_id Slab Memory Manager
92728 +
92729 + @Description Slab Memory Manager module functions, definitions and enums.
92730 +
92731 + @{
92732 +*//***************************************************************************/
92733 +
92734 +/* Each block is of the following structure:
92735 + *
92736 + *
92737 + * +-----------+----------+---------------------------+-----------+-----------+
92738 + * | Alignment | Prefix | Data | Postfix | Alignment |
92739 + * | field | field | field | field | Padding |
92740 + * | | | | | |
92741 + * +-----------+----------+---------------------------+-----------+-----------+
92742 + * and at the beginning of all bytes, an additional optional padding might reside
92743 + * to ensure that the first blocks data field is aligned as requested.
92744 + */
92745 +
92746 +
92747 +#define MEM_MAX_NAME_LENGTH 8
92748 +
92749 +/**************************************************************************//*
92750 + @Description Memory Segment structure
92751 +*//***************************************************************************/
92752 +
92753 +typedef struct
92754 +{
92755 + char name[MEM_MAX_NAME_LENGTH];
92756 + /* The segment's name */
92757 + uint8_t **p_Bases; /* Base addresses of the segments */
92758 + uint8_t **p_BlocksStack; /* Array of pointers to blocks */
92759 + t_Handle h_Spinlock;
92760 + uint16_t dataSize; /* Size of each data block */
92761 + uint16_t prefixSize; /* How many bytes to reserve before the data */
92762 + uint16_t postfixSize; /* How many bytes to reserve after the data */
92763 + uint16_t alignment; /* Requested alignment for the data field */
92764 + int allocOwner; /* Memory allocation owner */
92765 + uint32_t getFailures; /* Number of times get failed */
92766 + uint32_t num; /* Number of blocks in segment */
92767 + uint32_t current; /* Current block */
92768 + bool consecutiveMem; /* Allocate consecutive data blocks memory */
92769 +#ifdef DEBUG_MEM_LEAKS
92770 + void *p_MemDbg; /* MEM debug database (MEM leaks detection) */
92771 + uint32_t blockOffset;
92772 + uint32_t blockSize;
92773 +#endif /* DEBUG_MEM_LEAKS */
92774 +} t_MemorySegment;
92775 +
92776 +
92777 +
92778 +/**************************************************************************//**
92779 + @Function MEM_Init
92780 +
92781 + @Description Create a new memory segment.
92782 +
92783 + @Param[in] name - Name of memory partition.
92784 + @Param[in] p_Handle - Handle to new segment is returned through here.
92785 + @Param[in] num - Number of blocks in new segment.
92786 + @Param[in] dataSize - Size of blocks in segment.
92787 + @Param[in] prefixSize - How many bytes to allocate before the data.
92788 + @Param[in] postfixSize - How many bytes to allocate after the data.
92789 + @Param[in] alignment - Requested alignment for data field (in bytes).
92790 +
92791 + @Return E_OK - success, E_NO_MEMORY - out of memory.
92792 +*//***************************************************************************/
92793 +t_Error MEM_Init(char name[],
92794 + t_Handle *p_Handle,
92795 + uint32_t num,
92796 + uint16_t dataSize,
92797 + uint16_t prefixSize,
92798 + uint16_t postfixSize,
92799 + uint16_t alignment);
92800 +
92801 +/**************************************************************************//**
92802 + @Function MEM_InitSmart
92803 +
92804 + @Description Create a new memory segment.
92805 +
92806 + @Param[in] name - Name of memory partition.
92807 + @Param[in] p_Handle - Handle to new segment is returned through here.
92808 + @Param[in] num - Number of blocks in new segment.
92809 + @Param[in] dataSize - Size of blocks in segment.
92810 + @Param[in] prefixSize - How many bytes to allocate before the data.
92811 + @Param[in] postfixSize - How many bytes to allocate after the data.
92812 + @Param[in] alignment - Requested alignment for data field (in bytes).
92813 + @Param[in] memPartitionId - Memory partition ID for allocation.
92814 + @Param[in] consecutiveMem - Whether to allocate the memory blocks
92815 + continuously or not.
92816 +
92817 + @Return E_OK - success, E_NO_MEMORY - out of memory.
92818 +*//***************************************************************************/
92819 +t_Error MEM_InitSmart(char name[],
92820 + t_Handle *p_Handle,
92821 + uint32_t num,
92822 + uint16_t dataSize,
92823 + uint16_t prefixSize,
92824 + uint16_t postfixSize,
92825 + uint16_t alignment,
92826 + uint8_t memPartitionId,
92827 + bool consecutiveMem);
92828 +
92829 +/**************************************************************************//**
92830 + @Function MEM_InitByAddress
92831 +
92832 + @Description Create a new memory segment with a specified base address.
92833 +
92834 + @Param[in] name - Name of memory partition.
92835 + @Param[in] p_Handle - Handle to new segment is returned through here.
92836 + @Param[in] num - Number of blocks in new segment.
92837 + @Param[in] dataSize - Size of blocks in segment.
92838 + @Param[in] prefixSize - How many bytes to allocate before the data.
92839 + @Param[in] postfixSize - How many bytes to allocate after the data.
92840 + @Param[in] alignment - Requested alignment for data field (in bytes).
92841 + @Param[in] address - The required base address.
92842 +
92843 + @Return E_OK - success, E_NO_MEMORY - out of memory.
92844 + *//***************************************************************************/
92845 +t_Error MEM_InitByAddress(char name[],
92846 + t_Handle *p_Handle,
92847 + uint32_t num,
92848 + uint16_t dataSize,
92849 + uint16_t prefixSize,
92850 + uint16_t postfixSize,
92851 + uint16_t alignment,
92852 + uint8_t *address);
92853 +
92854 +/**************************************************************************//**
92855 + @Function MEM_Free
92856 +
92857 + @Description Free a specific memory segment.
92858 +
92859 + @Param[in] h_Mem - Handle to memory segment.
92860 +
92861 + @Return None.
92862 +*//***************************************************************************/
92863 +void MEM_Free(t_Handle h_Mem);
92864 +
92865 +/**************************************************************************//**
92866 + @Function MEM_Get
92867 +
92868 + @Description Get a block of memory from a segment.
92869 +
92870 + @Param[in] h_Mem - Handle to memory segment.
92871 +
92872 + @Return Pointer to new memory block on success,0 otherwise.
92873 +*//***************************************************************************/
92874 +void * MEM_Get(t_Handle h_Mem);
92875 +
92876 +/**************************************************************************//**
92877 + @Function MEM_GetN
92878 +
92879 + @Description Get up to N blocks of memory from a segment.
92880 +
92881 + The blocks are assumed to be of a fixed size (one size per segment).
92882 +
92883 + @Param[in] h_Mem - Handle to memory segment.
92884 + @Param[in] num - Number of blocks to allocate.
92885 + @Param[out] array - Array of at least num pointers to which the addresses
92886 + of the allocated blocks are written.
92887 +
92888 + @Return The number of blocks actually allocated.
92889 +
92890 + @Cautions Interrupts are disabled for all of the allocation loop.
92891 + Although this loop is very short for each block (several machine
92892 + instructions), you should not allocate a very large number
92893 + of blocks via this routine.
92894 +*//***************************************************************************/
92895 +uint16_t MEM_GetN(t_Handle h_Mem, uint32_t num, void *array[]);
92896 +
92897 +/**************************************************************************//**
92898 + @Function MEM_Put
92899 +
92900 + @Description Put a block of memory back to a segment.
92901 +
92902 + @Param[in] h_Mem - Handle to memory segment.
92903 + @Param[in] p_Block - The block to return.
92904 +
92905 + @Return Pointer to new memory block on success,0 otherwise.
92906 +*//***************************************************************************/
92907 +t_Error MEM_Put(t_Handle h_Mem, void *p_Block);
92908 +
92909 +/**************************************************************************//**
92910 + @Function MEM_ComputePartitionSize
92911 +
92912 + @Description calculate a tight upper boundary of the size of a partition with
92913 + given attributes.
92914 +
92915 + The returned value is suitable if one wants to use MEM_InitByAddress().
92916 +
92917 + @Param[in] num - The number of blocks in the segment.
92918 + @Param[in] dataSize - Size of block to get.
92919 + @Param[in] prefixSize - The prefix size
92920 + @Param postfixSize - The postfix size
92921 + @Param[in] alignment - The requested alignment value (in bytes)
92922 +
92923 + @Return The memory block size a segment with the given attributes needs.
92924 +*//***************************************************************************/
92925 +uint32_t MEM_ComputePartitionSize(uint32_t num,
92926 + uint16_t dataSize,
92927 + uint16_t prefixSize,
92928 + uint16_t postfixSize,
92929 + uint16_t alignment);
92930 +
92931 +#ifdef DEBUG_MEM_LEAKS
92932 +#if !((defined(__MWERKS__) || defined(__GNUC__)) && (__dest_os == __ppc_eabi))
92933 +#error "Memory-Leaks-Debug option is supported only for freescale CodeWarrior"
92934 +#endif /* !(defined(__MWERKS__) && ... */
92935 +
92936 +/**************************************************************************//**
92937 + @Function MEM_CheckLeaks
92938 +
92939 + @Description Report MEM object leaks.
92940 +
92941 + This routine is automatically called by the MEM_Free() routine,
92942 + but it can also be invoked while the MEM object is alive.
92943 +
92944 + @Param[in] h_Mem - Handle to memory segment.
92945 +
92946 + @Return None.
92947 +*//***************************************************************************/
92948 +void MEM_CheckLeaks(t_Handle h_Mem);
92949 +
92950 +#else /* not DEBUG_MEM_LEAKS */
92951 +#define MEM_CheckLeaks(h_Mem)
92952 +#endif /* not DEBUG_MEM_LEAKS */
92953 +
92954 +/**************************************************************************//**
92955 + @Description Get base of MEM
92956 +*//***************************************************************************/
92957 +#define MEM_GetBase(h_Mem) ((t_MemorySegment *)(h_Mem))->p_Bases[0]
92958 +
92959 +/**************************************************************************//**
92960 + @Description Get size of MEM block
92961 +*//***************************************************************************/
92962 +#define MEM_GetSize(h_Mem) ((t_MemorySegment *)(h_Mem))->dataSize
92963 +
92964 +/**************************************************************************//**
92965 + @Description Get prefix size of MEM block
92966 +*//***************************************************************************/
92967 +#define MEM_GetPrefixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->prefixSize
92968 +
92969 +/**************************************************************************//**
92970 + @Description Get postfix size of MEM block
92971 +*//***************************************************************************/
92972 +#define MEM_GetPostfixSize(h_Mem) ((t_MemorySegment *)(h_Mem))->postfixSize
92973 +
92974 +/**************************************************************************//**
92975 + @Description Get alignment of MEM block (in bytes)
92976 +*//***************************************************************************/
92977 +#define MEM_GetAlignment(h_Mem) ((t_MemorySegment *)(h_Mem))->alignment
92978 +
92979 +/**************************************************************************//**
92980 + @Description Get the number of blocks in the segment
92981 +*//***************************************************************************/
92982 +#define MEM_GetNumOfBlocks(h_Mem) ((t_MemorySegment *)(h_Mem))->num
92983 +
92984 +/** @} */ /* end of MEM group */
92985 +/** @} */ /* end of etc_id group */
92986 +
92987 +
92988 +#endif /* __MEM_EXT_H */
92989 --- /dev/null
92990 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/memcpy_ext.h
92991 @@ -0,0 +1,208 @@
92992 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
92993 + * All rights reserved.
92994 + *
92995 + * Redistribution and use in source and binary forms, with or without
92996 + * modification, are permitted provided that the following conditions are met:
92997 + * * Redistributions of source code must retain the above copyright
92998 + * notice, this list of conditions and the following disclaimer.
92999 + * * Redistributions in binary form must reproduce the above copyright
93000 + * notice, this list of conditions and the following disclaimer in the
93001 + * documentation and/or other materials provided with the distribution.
93002 + * * Neither the name of Freescale Semiconductor nor the
93003 + * names of its contributors may be used to endorse or promote products
93004 + * derived from this software without specific prior written permission.
93005 + *
93006 + *
93007 + * ALTERNATIVELY, this software may be distributed under the terms of the
93008 + * GNU General Public License ("GPL") as published by the Free Software
93009 + * Foundation, either version 2 of that License or (at your option) any
93010 + * later version.
93011 + *
93012 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93013 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93014 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93015 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93016 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93017 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93018 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93019 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93020 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93021 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93022 + */
93023 +
93024 +
93025 +/**************************************************************************//**
93026 +
93027 + @File memcpy_ext.h
93028 +
93029 + @Description Efficient functions for copying and setting blocks of memory.
93030 +*//***************************************************************************/
93031 +
93032 +#ifndef __MEMCPY_EXT_H
93033 +#define __MEMCPY_EXT_H
93034 +
93035 +#include "std_ext.h"
93036 +
93037 +
93038 +/**************************************************************************//**
93039 + @Group etc_id Utility Library Application Programming Interface
93040 +
93041 + @Description External routines.
93042 +
93043 + @{
93044 +*//***************************************************************************/
93045 +
93046 +/**************************************************************************//**
93047 + @Group mem_cpy Memory Copy
93048 +
93049 + @Description Memory Copy module functions,definitions and enums.
93050 +
93051 + @{
93052 +*//***************************************************************************/
93053 +
93054 +/**************************************************************************//**
93055 + @Function MemCpy32
93056 +
93057 + @Description Copies one memory buffer into another one in 4-byte chunks!
93058 + Which should be more efficient than byte by byte.
93059 +
93060 + For large buffers (over 60 bytes) this function is about 4 times
93061 + more efficient than the trivial memory copy. For short buffers
93062 + it is reduced to the trivial copy and may be a bit worse.
93063 +
93064 + @Param[in] pDst - The address of the destination buffer.
93065 + @Param[in] pSrc - The address of the source buffer.
93066 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
93067 +
93068 + @Return pDst (the address of the destination buffer).
93069 +
93070 + @Cautions There is no parameter or boundary checking! It is up to the user
93071 + to supply non-null parameters as source & destination and size
93072 + that actually fits into the destination buffer.
93073 +*//***************************************************************************/
93074 +void * MemCpy32(void* pDst,void* pSrc, uint32_t size);
93075 +void * IO2IOCpy32(void* pDst,void* pSrc, uint32_t size);
93076 +void * IO2MemCpy32(void* pDst,void* pSrc, uint32_t size);
93077 +void * Mem2IOCpy32(void* pDst,void* pSrc, uint32_t size);
93078 +
93079 +/**************************************************************************//**
93080 + @Function MemCpy64
93081 +
93082 + @Description Copies one memory buffer into another one in 8-byte chunks!
93083 + Which should be more efficient than byte by byte.
93084 +
93085 + For large buffers (over 60 bytes) this function is about 8 times
93086 + more efficient than the trivial memory copy. For short buffers
93087 + it is reduced to the trivial copy and may be a bit worse.
93088 +
93089 + Some testing suggests that MemCpy32() preforms better than
93090 + MemCpy64() over small buffers. On average they break even at
93091 + 100 byte buffers. For buffers larger than that MemCpy64 is
93092 + superior.
93093 +
93094 + @Param[in] pDst - The address of the destination buffer.
93095 + @Param[in] pSrc - The address of the source buffer.
93096 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
93097 +
93098 + @Return pDst (the address of the destination buffer).
93099 +
93100 + @Cautions There is no parameter or boundary checking! It is up to the user
93101 + to supply non null parameters as source & destination and size
93102 + that actually fits into their buffer.
93103 +
93104 + Do not use under Linux.
93105 +*//***************************************************************************/
93106 +void * MemCpy64(void* pDst,void* pSrc, uint32_t size);
93107 +
93108 +/**************************************************************************//**
93109 + @Function MemSet32
93110 +
93111 + @Description Sets all bytes of a memory buffer to a specific value, in
93112 + 4-byte chunks.
93113 +
93114 + @Param[in] pDst - The address of the destination buffer.
93115 + @Param[in] val - Value to set destination bytes to.
93116 + @Param[in] size - The number of bytes that will be set to val.
93117 +
93118 + @Return pDst (the address of the destination buffer).
93119 +
93120 + @Cautions There is no parameter or boundary checking! It is up to the user
93121 + to supply non null parameter as destination and size
93122 + that actually fits into the destination buffer.
93123 +*//***************************************************************************/
93124 +void * MemSet32(void* pDst, uint8_t val, uint32_t size);
93125 +void * IOMemSet32(void* pDst, uint8_t val, uint32_t size);
93126 +
93127 +/**************************************************************************//**
93128 + @Function MemSet64
93129 +
93130 + @Description Sets all bytes of a memory buffer to a specific value, in
93131 + 8-byte chunks.
93132 +
93133 + @Param[in] pDst - The address of the destination buffer.
93134 + @Param[in] val - Value to set destination bytes to.
93135 + @Param[in] size - The number of bytes that will be set to val.
93136 +
93137 + @Return pDst (the address of the destination buffer).
93138 +
93139 + @Cautions There is no parameter or boundary checking! It is up to the user
93140 + to supply non null parameter as destination and size
93141 + that actually fits into the destination buffer.
93142 +*//***************************************************************************/
93143 +void * MemSet64(void* pDst, uint8_t val, uint32_t size);
93144 +
93145 +/**************************************************************************//**
93146 + @Function MemDisp
93147 +
93148 + @Description Displays a block of memory in chunks of 32 bits.
93149 +
93150 + @Param[in] addr - The address of the memory to display.
93151 + @Param[in] size - The number of bytes that will be displayed.
93152 +
93153 + @Return None.
93154 +
93155 + @Cautions There is no parameter or boundary checking! It is up to the user
93156 + to supply non null parameter as destination and size
93157 + that actually fits into the destination buffer.
93158 +*//***************************************************************************/
93159 +void MemDisp(uint8_t *addr, int size);
93160 +
93161 +/**************************************************************************//**
93162 + @Function MemCpy8
93163 +
93164 + @Description Trivial copy one memory buffer into another byte by byte
93165 +
93166 + @Param[in] pDst - The address of the destination buffer.
93167 + @Param[in] pSrc - The address of the source buffer.
93168 + @Param[in] size - The number of bytes that will be copied from pSrc to pDst.
93169 +
93170 + @Return pDst (the address of the destination buffer).
93171 +
93172 + @Cautions There is no parameter or boundary checking! It is up to the user
93173 + to supply non-null parameters as source & destination and size
93174 + that actually fits into the destination buffer.
93175 +*//***************************************************************************/
93176 +void * MemCpy8(void* pDst,void* pSrc, uint32_t size);
93177 +
93178 +/**************************************************************************//**
93179 + @Function MemSet8
93180 +
93181 + @Description Sets all bytes of a memory buffer to a specific value byte by byte.
93182 +
93183 + @Param[in] pDst - The address of the destination buffer.
93184 + @Param[in] c - Value to set destination bytes to.
93185 + @Param[in] size - The number of bytes that will be set to val.
93186 +
93187 + @Return pDst (the address of the destination buffer).
93188 +
93189 + @Cautions There is no parameter or boundary checking! It is up to the user
93190 + to supply non null parameter as destination and size
93191 + that actually fits into the destination buffer.
93192 +*//***************************************************************************/
93193 +void * MemSet8(void* pDst, int c, uint32_t size);
93194 +
93195 +/** @} */ /* end of mem_cpy group */
93196 +/** @} */ /* end of etc_id group */
93197 +
93198 +
93199 +#endif /* __MEMCPY_EXT_H */
93200 --- /dev/null
93201 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/mm_ext.h
93202 @@ -0,0 +1,310 @@
93203 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
93204 + * All rights reserved.
93205 + *
93206 + * Redistribution and use in source and binary forms, with or without
93207 + * modification, are permitted provided that the following conditions are met:
93208 + * * Redistributions of source code must retain the above copyright
93209 + * notice, this list of conditions and the following disclaimer.
93210 + * * Redistributions in binary form must reproduce the above copyright
93211 + * notice, this list of conditions and the following disclaimer in the
93212 + * documentation and/or other materials provided with the distribution.
93213 + * * Neither the name of Freescale Semiconductor nor the
93214 + * names of its contributors may be used to endorse or promote products
93215 + * derived from this software without specific prior written permission.
93216 + *
93217 + *
93218 + * ALTERNATIVELY, this software may be distributed under the terms of the
93219 + * GNU General Public License ("GPL") as published by the Free Software
93220 + * Foundation, either version 2 of that License or (at your option) any
93221 + * later version.
93222 + *
93223 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93224 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93225 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93226 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93227 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93228 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93229 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93230 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93231 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93232 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93233 + */
93234 +
93235 +
93236 +/**************************************************************************//**
93237 + @File mm_ext.h
93238 +
93239 + @Description Memory Manager Application Programming Interface
93240 +*//***************************************************************************/
93241 +#ifndef __MM_EXT
93242 +#define __MM_EXT
93243 +
93244 +#include "std_ext.h"
93245 +
93246 +#define MM_MAX_ALIGNMENT 20 /* Alignments from 2 to 128 are available
93247 + where maximum alignment defined as
93248 + MM_MAX_ALIGNMENT power of 2 */
93249 +
93250 +#define MM_MAX_NAME_LEN 32
93251 +
93252 +/**************************************************************************//**
93253 + @Group etc_id Utility Library Application Programming Interface
93254 +
93255 + @Description External routines.
93256 +
93257 + @{
93258 +*//***************************************************************************/
93259 +
93260 +/**************************************************************************//**
93261 + @Group mm_grp Flexible Memory Manager
93262 +
93263 + @Description Flexible Memory Manager module functions,definitions and enums.
93264 + (All of the following functions,definitions and enums can be found in mm_ext.h)
93265 +
93266 + @{
93267 +*//***************************************************************************/
93268 +
93269 +
93270 +/**************************************************************************//**
93271 + @Function MM_Init
93272 +
93273 + @Description Initializes a new MM object.
93274 +
93275 + It initializes a new memory block consisting of base address
93276 + and size of the available memory by calling to MemBlock_Init
93277 + routine. It is also initializes a new free block for each
93278 + by calling FreeBlock_Init routine, which is pointed to
93279 + the almost all memory started from the required alignment
93280 + from the base address and to the end of the memory.
93281 + The handle to the new MM object is returned via "MM"
93282 + argument (passed by reference).
93283 +
93284 + @Param[in] h_MM - Handle to the MM object.
93285 + @Param[in] base - Base address of the MM.
93286 + @Param[in] size - Size of the MM.
93287 +
93288 + @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.
93289 +*//***************************************************************************/
93290 +t_Error MM_Init(t_Handle *h_MM, uint64_t base, uint64_t size);
93291 +
93292 +/**************************************************************************//**
93293 + @Function MM_Get
93294 +
93295 + @Description Allocates a block of memory according to the given size and the alignment.
93296 +
93297 + The Alignment argument tells from which
93298 + free list allocate a block of memory. 2^alignment indicates
93299 + the alignment that the base address of the allocated block
93300 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
93301 + are available for the alignment argument.
93302 + The routine passes through the specific free list of free
93303 + blocks and seeks for a first block that have anough memory
93304 + that is required (best fit).
93305 + After the block is found and data is allocated, it calls
93306 + the internal MM_CutFree routine to update all free lists
93307 + do not include a just allocated block. Of course, each
93308 + free list contains a free blocks with the same alignment.
93309 + It is also creates a busy block that holds
93310 + information about an allocated block.
93311 +
93312 + @Param[in] h_MM - Handle to the MM object.
93313 + @Param[in] size - Size of the MM.
93314 + @Param[in] alignment - Index as a power of two defines a required
93315 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
93316 + @Param[in] name - The name that specifies an allocated block.
93317 +
93318 + @Return base address of an allocated block ILLEGAL_BASE if can't allocate a block
93319 +*//***************************************************************************/
93320 +uint64_t MM_Get(t_Handle h_MM, uint64_t size, uint64_t alignment, char *name);
93321 +
93322 +/**************************************************************************//**
93323 + @Function MM_GetBase
93324 +
93325 + @Description Gets the base address of the required MM objects.
93326 +
93327 + @Param[in] h_MM - Handle to the MM object.
93328 +
93329 + @Return base address of the block.
93330 +*//***************************************************************************/
93331 +uint64_t MM_GetBase(t_Handle h_MM);
93332 +
93333 +/**************************************************************************//**
93334 + @Function MM_GetForce
93335 +
93336 + @Description Force memory allocation.
93337 +
93338 + It means to allocate a block of memory of the given
93339 + size from the given base address.
93340 + The routine checks if the required block can be allocated
93341 + (that is it is free) and then, calls the internal MM_CutFree
93342 + routine to update all free lists do not include that block.
93343 +
93344 + @Param[in] h_MM - Handle to the MM object.
93345 + @Param[in] base - Base address of the MM.
93346 + @Param[in] size - Size of the MM.
93347 + @Param[in] name - Name that specifies an allocated block.
93348 +
93349 + @Return base address of an allocated block, ILLEGAL_BASE if can't allocate a block.
93350 +*//***************************************************************************/
93351 +uint64_t MM_GetForce(t_Handle h_MM, uint64_t base, uint64_t size, char *name);
93352 +
93353 +/**************************************************************************//**
93354 + @Function MM_GetForceMin
93355 +
93356 + @Description Allocates a block of memory according to the given size, the alignment and minimum base address.
93357 +
93358 + The Alignment argument tells from which
93359 + free list allocate a block of memory. 2^alignment indicates
93360 + the alignment that the base address of the allocated block
93361 + should have. So, the only values 1, 2, 4, 8, 16, 32 and 64
93362 + are available for the alignment argument.
93363 + The minimum baser address forces the location of the block
93364 + to be from a given address onward.
93365 + The routine passes through the specific free list of free
93366 + blocks and seeks for the first base address equal or smaller
93367 + than the required minimum address and end address larger than
93368 + than the required base + its size - i.e. that may contain
93369 + the required block.
93370 + After the block is found and data is allocated, it calls
93371 + the internal MM_CutFree routine to update all free lists
93372 + do not include a just allocated block. Of course, each
93373 + free list contains a free blocks with the same alignment.
93374 + It is also creates a busy block that holds
93375 + information about an allocated block.
93376 +
93377 + @Param[in] h_MM - Handle to the MM object.
93378 + @Param[in] size - Size of the MM.
93379 + @Param[in] alignment - Index as a power of two defines a required
93380 + alignment (in bytes); Should be 1, 2, 4, 8, 16, 32 or 64
93381 + @Param[in] min - The minimum base address of the block.
93382 + @Param[in] name - Name that specifies an allocated block.
93383 +
93384 + @Return base address of an allocated block,ILLEGAL_BASE if can't allocate a block.
93385 +*//***************************************************************************/
93386 +uint64_t MM_GetForceMin(t_Handle h_MM,
93387 + uint64_t size,
93388 + uint64_t alignment,
93389 + uint64_t min,
93390 + char *name);
93391 +
93392 +/**************************************************************************//**
93393 + @Function MM_Put
93394 +
93395 + @Description Puts a block of memory of the given base address back to the memory.
93396 +
93397 + It checks if there is a busy block with the
93398 + given base address. If not, it returns 0, that
93399 + means can't free a block. Otherwise, it gets parameters of
93400 + the busy block and after it updates lists of free blocks,
93401 + removes that busy block from the list by calling to MM_CutBusy
93402 + routine.
93403 + After that it calls to MM_AddFree routine to add a new free
93404 + block to the free lists.
93405 +
93406 + @Param[in] h_MM - Handle to the MM object.
93407 + @Param[in] base - Base address of the MM.
93408 +
93409 + @Return The size of bytes released, 0 if failed.
93410 +*//***************************************************************************/
93411 +uint64_t MM_Put(t_Handle h_MM, uint64_t base);
93412 +
93413 +/**************************************************************************//**
93414 + @Function MM_PutForce
93415 +
93416 + @Description Releases a block of memory of the required size from the required base address.
93417 +
93418 + First, it calls to MM_CutBusy routine
93419 + to cut a free block from the busy list. And then, calls to
93420 + MM_AddFree routine to add the free block to the free lists.
93421 +
93422 + @Param[in] h_MM - Handle to the MM object.
93423 + @Param[in] base - Base address of of a block to free.
93424 + @Param[in] size - Size of a block to free.
93425 +
93426 + @Return The number of bytes released, 0 on failure.
93427 +*//***************************************************************************/
93428 +uint64_t MM_PutForce(t_Handle h_MM, uint64_t base, uint64_t size);
93429 +
93430 +/**************************************************************************//**
93431 + @Function MM_Add
93432 +
93433 + @Description Adds a new memory block for memory allocation.
93434 +
93435 + When a new memory block is initialized and added to the
93436 + memory list, it calls to MM_AddFree routine to add the
93437 + new free block to the free lists.
93438 +
93439 + @Param[in] h_MM - Handle to the MM object.
93440 + @Param[in] base - Base address of the memory block.
93441 + @Param[in] size - Size of the memory block.
93442 +
93443 + @Return E_OK on success, otherwise returns an error code.
93444 +*//***************************************************************************/
93445 +t_Error MM_Add(t_Handle h_MM, uint64_t base, uint64_t size);
93446 +
93447 +/**************************************************************************//**
93448 + @Function MM_Dump
93449 +
93450 + @Description Prints results of free and busy lists.
93451 +
93452 + @Param[in] h_MM - Handle to the MM object.
93453 +*//***************************************************************************/
93454 +void MM_Dump(t_Handle h_MM);
93455 +
93456 +/**************************************************************************//**
93457 + @Function MM_Free
93458 +
93459 + @Description Releases memory allocated for MM object.
93460 +
93461 + @Param[in] h_MM - Handle of the MM object.
93462 +*//***************************************************************************/
93463 +void MM_Free(t_Handle h_MM);
93464 +
93465 +/**************************************************************************//**
93466 + @Function MM_GetMemBlock
93467 +
93468 + @Description Returns base address of the memory block specified by the index.
93469 +
93470 + If index is 0, returns base address
93471 + of the first memory block, 1 - returns base address
93472 + of the second memory block, etc.
93473 + Note, those memory blocks are allocated by the
93474 + application before MM_Init or MM_Add and have to
93475 + be released by the application before or after invoking
93476 + the MM_Free routine.
93477 +
93478 + @Param[in] h_MM - Handle to the MM object.
93479 + @Param[in] index - Index of the memory block.
93480 +
93481 + @Return valid base address or ILLEGAL_BASE if no memory block specified by the index.
93482 +*//***************************************************************************/
93483 +uint64_t MM_GetMemBlock(t_Handle h_MM, int index);
93484 +
93485 +/**************************************************************************//**
93486 + @Function MM_InRange
93487 +
93488 + @Description Checks if a specific address is in the memory range of the passed MM object.
93489 +
93490 + @Param[in] h_MM - Handle to the MM object.
93491 + @Param[in] addr - The address to be checked.
93492 +
93493 + @Return TRUE if the address is in the address range of the block, FALSE otherwise.
93494 +*//***************************************************************************/
93495 +bool MM_InRange(t_Handle h_MM, uint64_t addr);
93496 +
93497 +/**************************************************************************//**
93498 + @Function MM_GetFreeMemSize
93499 +
93500 + @Description Returns the size (in bytes) of free memory.
93501 +
93502 + @Param[in] h_MM - Handle to the MM object.
93503 +
93504 + @Return Free memory size in bytes.
93505 +*//***************************************************************************/
93506 +uint64_t MM_GetFreeMemSize(t_Handle h_MM);
93507 +
93508 +
93509 +/** @} */ /* end of mm_grp group */
93510 +/** @} */ /* end of etc_id group */
93511 +
93512 +#endif /* __MM_EXT_H */
93513 --- /dev/null
93514 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/etc/sprint_ext.h
93515 @@ -0,0 +1,118 @@
93516 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
93517 + * All rights reserved.
93518 + *
93519 + * Redistribution and use in source and binary forms, with or without
93520 + * modification, are permitted provided that the following conditions are met:
93521 + * * Redistributions of source code must retain the above copyright
93522 + * notice, this list of conditions and the following disclaimer.
93523 + * * Redistributions in binary form must reproduce the above copyright
93524 + * notice, this list of conditions and the following disclaimer in the
93525 + * documentation and/or other materials provided with the distribution.
93526 + * * Neither the name of Freescale Semiconductor nor the
93527 + * names of its contributors may be used to endorse or promote products
93528 + * derived from this software without specific prior written permission.
93529 + *
93530 + *
93531 + * ALTERNATIVELY, this software may be distributed under the terms of the
93532 + * GNU General Public License ("GPL") as published by the Free Software
93533 + * Foundation, either version 2 of that License or (at your option) any
93534 + * later version.
93535 + *
93536 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93537 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93538 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93539 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93540 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93541 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93542 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93543 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93544 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93545 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93546 + */
93547 +
93548 +
93549 +/**************************************************************************//**
93550 + @File sprint_ext.h
93551 +
93552 + @Description Debug routines (externals).
93553 +
93554 +*//***************************************************************************/
93555 +
93556 +#ifndef __SPRINT_EXT_H
93557 +#define __SPRINT_EXT_H
93558 +
93559 +
93560 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
93561 +#include <linux/kernel.h>
93562 +
93563 +#elif defined(NCSW_VXWORKS)
93564 +#include "private/stdioP.h"
93565 +
93566 +#else
93567 +#include <stdio.h>
93568 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
93569 +
93570 +#include "std_ext.h"
93571 +
93572 +
93573 +/**************************************************************************//**
93574 + @Group etc_id Utility Library Application Programming Interface
93575 +
93576 + @Description External routines.
93577 +
93578 + @{
93579 +*//***************************************************************************/
93580 +
93581 +/**************************************************************************//**
93582 + @Group sprint_id Sprint
93583 +
93584 + @Description Sprint & Sscan module functions,definitions and enums.
93585 +
93586 + @{
93587 +*//***************************************************************************/
93588 +
93589 +/**************************************************************************//**
93590 + @Function Sprint
93591 +
93592 + @Description Format a string and place it in a buffer.
93593 +
93594 + @Param[in] buff - The buffer to place the result into.
93595 + @Param[in] str - The format string to use.
93596 + @Param[in] ... - Arguments for the format string.
93597 +
93598 + @Return Number of bytes formatted.
93599 +*//***************************************************************************/
93600 +int Sprint(char *buff, const char *str, ...);
93601 +
93602 +/**************************************************************************//**
93603 + @Function Snprint
93604 +
93605 + @Description Format a string and place it in a buffer.
93606 +
93607 + @Param[in] buf - The buffer to place the result into.
93608 + @Param[in] size - The size of the buffer, including the trailing null space.
93609 + @Param[in] fmt - The format string to use.
93610 + @Param[in] ... - Arguments for the format string.
93611 +
93612 + @Return Number of bytes formatted.
93613 +*//***************************************************************************/
93614 +int Snprint(char * buf, uint32_t size, const char *fmt, ...);
93615 +
93616 +/**************************************************************************//**
93617 + @Function Sscan
93618 +
93619 + @Description Unformat a buffer into a list of arguments.
93620 +
93621 + @Param[in] buf - input buffer.
93622 + @Param[in] fmt - formatting of buffer.
93623 + @Param[out] ... - resulting arguments.
93624 +
93625 + @Return Number of bytes unformatted.
93626 +*//***************************************************************************/
93627 +int Sscan(const char * buf, const char * fmt, ...);
93628 +
93629 +/** @} */ /* end of sprint_id group */
93630 +/** @} */ /* end of etc_id group */
93631 +
93632 +
93633 +#endif /* __SPRINT_EXT_H */
93634 --- /dev/null
93635 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/arch/ppc_access.h
93636 @@ -0,0 +1,37 @@
93637 +/*
93638 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93639 + *
93640 + * Redistribution and use in source and binary forms, with or without
93641 + * modification, are permitted provided that the following conditions are met:
93642 + * * Redistributions of source code must retain the above copyright
93643 + * notice, this list of conditions and the following disclaimer.
93644 + * * Redistributions in binary form must reproduce the above copyright
93645 + * notice, this list of conditions and the following disclaimer in the
93646 + * documentation and/or other materials provided with the distribution.
93647 + * * Neither the name of Freescale Semiconductor nor the
93648 + * names of its contributors may be used to endorse or promote products
93649 + * derived from this software without specific prior written permission.
93650 + *
93651 + *
93652 + * ALTERNATIVELY, this software may be distributed under the terms of the
93653 + * GNU General Public License ("GPL") as published by the Free Software
93654 + * Foundation, either version 2 of that License or (at your option) any
93655 + * later version.
93656 + *
93657 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93658 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93659 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93660 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93661 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93662 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93663 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93664 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93665 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93666 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93667 + */
93668 +
93669 +#ifndef FL_E500_MACROS_H
93670 +#define FL_E500_MACROS_H
93671 +
93672 +#endif /* FL_E500_MACROS_H */
93673 +
93674 --- /dev/null
93675 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/common/general.h
93676 @@ -0,0 +1,52 @@
93677 +/*
93678 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93679 + *
93680 + * Redistribution and use in source and binary forms, with or without
93681 + * modification, are permitted provided that the following conditions are met:
93682 + * * Redistributions of source code must retain the above copyright
93683 + * notice, this list of conditions and the following disclaimer.
93684 + * * Redistributions in binary form must reproduce the above copyright
93685 + * notice, this list of conditions and the following disclaimer in the
93686 + * documentation and/or other materials provided with the distribution.
93687 + * * Neither the name of Freescale Semiconductor nor the
93688 + * names of its contributors may be used to endorse or promote products
93689 + * derived from this software without specific prior written permission.
93690 + *
93691 + *
93692 + * ALTERNATIVELY, this software may be distributed under the terms of the
93693 + * GNU General Public License ("GPL") as published by the Free Software
93694 + * Foundation, either version 2 of that License or (at your option) any
93695 + * later version.
93696 + *
93697 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93698 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93699 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93700 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93701 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93702 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93703 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93704 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93705 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93706 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93707 + */
93708 +
93709 +#ifndef __GENERAL_H
93710 +#define __GENERAL_H
93711 +
93712 +#include "std_ext.h"
93713 +#if !defined(NCSW_LINUX)
93714 +#include "errno.h"
93715 +#endif
93716 +
93717 +
93718 +extern uint32_t get_mac_addr_crc(uint64_t _addr);
93719 +
93720 +#ifndef CONFIG_FMAN_ARM
93721 +#define iowrite32be(val, addr) WRITE_UINT32(*addr, val)
93722 +#define ioread32be(addr) GET_UINT32(*addr)
93723 +#endif
93724 +
93725 +#define ether_crc(len, addr) get_mac_addr_crc(*(uint64_t *)(addr)>>16)
93726 +
93727 +
93728 +#endif /* __GENERAL_H */
93729 --- /dev/null
93730 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fman_common.h
93731 @@ -0,0 +1,78 @@
93732 +/*
93733 + * Copyright 2008-2013 Freescale Semiconductor Inc.
93734 + *
93735 + * Redistribution and use in source and binary forms, with or without
93736 + * modification, are permitted provided that the following conditions are met:
93737 + * * Redistributions of source code must retain the above copyright
93738 + * notice, this list of conditions and the following disclaimer.
93739 + * * Redistributions in binary form must reproduce the above copyright
93740 + * notice, this list of conditions and the following disclaimer in the
93741 + * documentation and/or other materials provided with the distribution.
93742 + * * Neither the name of Freescale Semiconductor nor the
93743 + * names of its contributors may be used to endorse or promote products
93744 + * derived from this software without specific prior written permission.
93745 + *
93746 + *
93747 + * ALTERNATIVELY, this software may be distributed under the terms of the
93748 + * GNU General Public License ("GPL") as published by the Free Software
93749 + * Foundation, either version 2 of that License or (at your option) any
93750 + * later version.
93751 + *
93752 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93753 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93754 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93755 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93756 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93757 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93758 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93759 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93760 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93761 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93762 + */
93763 +
93764 +
93765 +#ifndef __FMAN_COMMON_H
93766 +#define __FMAN_COMMON_H
93767 +
93768 +/**************************************************************************//**
93769 + @Description NIA Description
93770 +*//***************************************************************************/
93771 +#define NIA_ORDER_RESTOR 0x00800000
93772 +#define NIA_ENG_FM_CTL 0x00000000
93773 +#define NIA_ENG_PRS 0x00440000
93774 +#define NIA_ENG_KG 0x00480000
93775 +#define NIA_ENG_PLCR 0x004C0000
93776 +#define NIA_ENG_BMI 0x00500000
93777 +#define NIA_ENG_QMI_ENQ 0x00540000
93778 +#define NIA_ENG_QMI_DEQ 0x00580000
93779 +#define NIA_ENG_MASK 0x007C0000
93780 +
93781 +#define NIA_FM_CTL_AC_CC 0x00000006
93782 +#define NIA_FM_CTL_AC_HC 0x0000000C
93783 +#define NIA_FM_CTL_AC_IND_MODE_TX 0x00000008
93784 +#define NIA_FM_CTL_AC_IND_MODE_RX 0x0000000A
93785 +#define NIA_FM_CTL_AC_FRAG 0x0000000e
93786 +#define NIA_FM_CTL_AC_PRE_FETCH 0x00000010
93787 +#define NIA_FM_CTL_AC_POST_FETCH_PCD 0x00000012
93788 +#define NIA_FM_CTL_AC_POST_FETCH_PCD_UDP_LEN 0x00000018
93789 +#define NIA_FM_CTL_AC_POST_FETCH_NO_PCD 0x00000012
93790 +#define NIA_FM_CTL_AC_FRAG_CHECK 0x00000014
93791 +#define NIA_FM_CTL_AC_PRE_CC 0x00000020
93792 +
93793 +
93794 +#define NIA_BMI_AC_ENQ_FRAME 0x00000002
93795 +#define NIA_BMI_AC_TX_RELEASE 0x000002C0
93796 +#define NIA_BMI_AC_RELEASE 0x000000C0
93797 +#define NIA_BMI_AC_DISCARD 0x000000C1
93798 +#define NIA_BMI_AC_TX 0x00000274
93799 +#define NIA_BMI_AC_FETCH 0x00000208
93800 +#define NIA_BMI_AC_MASK 0x000003FF
93801 +
93802 +#define NIA_KG_DIRECT 0x00000100
93803 +#define NIA_KG_CC_EN 0x00000200
93804 +#define NIA_PLCR_ABSOLUTE 0x00008000
93805 +
93806 +#define NIA_BMI_AC_ENQ_FRAME_WITHOUT_DMA 0x00000202
93807 +#define NIA_BMI_AC_FETCH_ALL_FRAME 0x0000020c
93808 +
93809 +#endif /* __FMAN_COMMON_H */
93810 --- /dev/null
93811 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_enet.h
93812 @@ -0,0 +1,273 @@
93813 +/*
93814 + * Copyright 2008-2012 Freescale Semiconductor Inc.
93815 + *
93816 + * Redistribution and use in source and binary forms, with or without
93817 + * modification, are permitted provided that the following conditions are met:
93818 + * * Redistributions of source code must retain the above copyright
93819 + * notice, this list of conditions and the following disclaimer.
93820 + * * Redistributions in binary form must reproduce the above copyright
93821 + * notice, this list of conditions and the following disclaimer in the
93822 + * documentation and/or other materials provided with the distribution.
93823 + * * Neither the name of Freescale Semiconductor nor the
93824 + * names of its contributors may be used to endorse or promote products
93825 + * derived from this software without specific prior written permission.
93826 + *
93827 + *
93828 + * ALTERNATIVELY, this software may be distributed under the terms of the
93829 + * GNU General Public License ("GPL") as published by the Free Software
93830 + * Foundation, either version 2 of that License or (at your option) any
93831 + * later version.
93832 + *
93833 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
93834 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
93835 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
93836 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
93837 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
93838 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
93839 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
93840 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93841 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
93842 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
93843 + */
93844 +
93845 +#ifndef __FSL_ENET_H
93846 +#define __FSL_ENET_H
93847 +
93848 +/**
93849 + @Description Ethernet MAC-PHY Interface
93850 +*/
93851 +
93852 +enum enet_interface {
93853 + E_ENET_IF_MII = 0x00010000, /**< MII interface */
93854 + E_ENET_IF_RMII = 0x00020000, /**< RMII interface */
93855 + E_ENET_IF_SMII = 0x00030000, /**< SMII interface */
93856 + E_ENET_IF_GMII = 0x00040000, /**< GMII interface */
93857 + E_ENET_IF_RGMII = 0x00050000, /**< RGMII interface */
93858 + E_ENET_IF_TBI = 0x00060000, /**< TBI interface */
93859 + E_ENET_IF_RTBI = 0x00070000, /**< RTBI interface */
93860 + E_ENET_IF_SGMII = 0x00080000, /**< SGMII interface */
93861 + E_ENET_IF_XGMII = 0x00090000, /**< XGMII interface */
93862 + E_ENET_IF_QSGMII = 0x000a0000, /**< QSGMII interface */
93863 + E_ENET_IF_XFI = 0x000b0000 /**< XFI interface */
93864 +};
93865 +
93866 +/**
93867 + @Description Ethernet Speed (nominal data rate)
93868 +*/
93869 +enum enet_speed {
93870 + E_ENET_SPEED_10 = 10, /**< 10 Mbps */
93871 + E_ENET_SPEED_100 = 100, /**< 100 Mbps */
93872 + E_ENET_SPEED_1000 = 1000, /**< 1000 Mbps = 1 Gbps */
93873 + E_ENET_SPEED_2500 = 2500, /**< 2500 Mbps = 2.5 Gbps */
93874 + E_ENET_SPEED_10000 = 10000 /**< 10000 Mbps = 10 Gbps */
93875 +};
93876 +
93877 +enum mac_type {
93878 + E_MAC_DTSEC,
93879 + E_MAC_TGEC,
93880 + E_MAC_MEMAC
93881 +};
93882 +
93883 +/**************************************************************************//**
93884 + @Description Enum for inter-module interrupts registration
93885 +*//***************************************************************************/
93886 +enum fman_event_modules {
93887 + E_FMAN_MOD_PRS, /**< Parser event */
93888 + E_FMAN_MOD_KG, /**< Keygen event */
93889 + E_FMAN_MOD_PLCR, /**< Policer event */
93890 + E_FMAN_MOD_10G_MAC, /**< 10G MAC event */
93891 + E_FMAN_MOD_1G_MAC, /**< 1G MAC event */
93892 + E_FMAN_MOD_TMR, /**< Timer event */
93893 + E_FMAN_MOD_FMAN_CTRL, /**< FMAN Controller Timer event */
93894 + E_FMAN_MOD_MACSEC,
93895 + E_FMAN_MOD_DUMMY_LAST
93896 +};
93897 +
93898 +/**************************************************************************//**
93899 + @Description Enum for interrupts types
93900 +*//***************************************************************************/
93901 +enum fman_intr_type {
93902 + E_FMAN_INTR_TYPE_ERR,
93903 + E_FMAN_INTR_TYPE_NORMAL
93904 +};
93905 +
93906 +/**************************************************************************//**
93907 + @Description enum for defining MAC types
93908 +*//***************************************************************************/
93909 +enum fman_mac_type {
93910 + E_FMAN_MAC_10G = 0, /**< 10G MAC */
93911 + E_FMAN_MAC_1G /**< 1G MAC */
93912 +};
93913 +
93914 +enum fman_mac_exceptions {
93915 + E_FMAN_MAC_EX_10G_MDIO_SCAN_EVENTMDIO = 0,
93916 + /**< 10GEC MDIO scan event interrupt */
93917 + E_FMAN_MAC_EX_10G_MDIO_CMD_CMPL,
93918 + /**< 10GEC MDIO command completion interrupt */
93919 + E_FMAN_MAC_EX_10G_REM_FAULT,
93920 + /**< 10GEC, mEMAC Remote fault interrupt */
93921 + E_FMAN_MAC_EX_10G_LOC_FAULT,
93922 + /**< 10GEC, mEMAC Local fault interrupt */
93923 + E_FMAN_MAC_EX_10G_1TX_ECC_ER,
93924 + /**< 10GEC, mEMAC Transmit frame ECC error interrupt */
93925 + E_FMAN_MAC_EX_10G_TX_FIFO_UNFL,
93926 + /**< 10GEC, mEMAC Transmit FIFO underflow interrupt */
93927 + E_FMAN_MAC_EX_10G_TX_FIFO_OVFL,
93928 + /**< 10GEC, mEMAC Transmit FIFO overflow interrupt */
93929 + E_FMAN_MAC_EX_10G_TX_ER,
93930 + /**< 10GEC Transmit frame error interrupt */
93931 + E_FMAN_MAC_EX_10G_RX_FIFO_OVFL,
93932 + /**< 10GEC, mEMAC Receive FIFO overflow interrupt */
93933 + E_FMAN_MAC_EX_10G_RX_ECC_ER,
93934 + /**< 10GEC, mEMAC Receive frame ECC error interrupt */
93935 + E_FMAN_MAC_EX_10G_RX_JAB_FRM,
93936 + /**< 10GEC Receive jabber frame interrupt */
93937 + E_FMAN_MAC_EX_10G_RX_OVRSZ_FRM,
93938 + /**< 10GEC Receive oversized frame interrupt */
93939 + E_FMAN_MAC_EX_10G_RX_RUNT_FRM,
93940 + /**< 10GEC Receive runt frame interrupt */
93941 + E_FMAN_MAC_EX_10G_RX_FRAG_FRM,
93942 + /**< 10GEC Receive fragment frame interrupt */
93943 + E_FMAN_MAC_EX_10G_RX_LEN_ER,
93944 + /**< 10GEC Receive payload length error interrupt */
93945 + E_FMAN_MAC_EX_10G_RX_CRC_ER,
93946 + /**< 10GEC Receive CRC error interrupt */
93947 + E_FMAN_MAC_EX_10G_RX_ALIGN_ER,
93948 + /**< 10GEC Receive alignment error interrupt */
93949 + E_FMAN_MAC_EX_1G_BAB_RX,
93950 + /**< dTSEC Babbling receive error */
93951 + E_FMAN_MAC_EX_1G_RX_CTL,
93952 + /**< dTSEC Receive control (pause frame) interrupt */
93953 + E_FMAN_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET,
93954 + /**< dTSEC Graceful transmit stop complete */
93955 + E_FMAN_MAC_EX_1G_BAB_TX,
93956 + /**< dTSEC Babbling transmit error */
93957 + E_FMAN_MAC_EX_1G_TX_CTL,
93958 + /**< dTSEC Transmit control (pause frame) interrupt */
93959 + E_FMAN_MAC_EX_1G_TX_ERR,
93960 + /**< dTSEC Transmit error */
93961 + E_FMAN_MAC_EX_1G_LATE_COL,
93962 + /**< dTSEC Late collision */
93963 + E_FMAN_MAC_EX_1G_COL_RET_LMT,
93964 + /**< dTSEC Collision retry limit */
93965 + E_FMAN_MAC_EX_1G_TX_FIFO_UNDRN,
93966 + /**< dTSEC Transmit FIFO underrun */
93967 + E_FMAN_MAC_EX_1G_MAG_PCKT,
93968 + /**< dTSEC Magic Packet detection */
93969 + E_FMAN_MAC_EX_1G_MII_MNG_RD_COMPLET,
93970 + /**< dTSEC MII management read completion */
93971 + E_FMAN_MAC_EX_1G_MII_MNG_WR_COMPLET,
93972 + /**< dTSEC MII management write completion */
93973 + E_FMAN_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET,
93974 + /**< dTSEC Graceful receive stop complete */
93975 + E_FMAN_MAC_EX_1G_TX_DATA_ERR,
93976 + /**< dTSEC Internal data error on transmit */
93977 + E_FMAN_MAC_EX_1G_RX_DATA_ERR,
93978 + /**< dTSEC Internal data error on receive */
93979 + E_FMAN_MAC_EX_1G_1588_TS_RX_ERR,
93980 + /**< dTSEC Time-Stamp Receive Error */
93981 + E_FMAN_MAC_EX_1G_RX_MIB_CNT_OVFL,
93982 + /**< dTSEC MIB counter overflow */
93983 + E_FMAN_MAC_EX_TS_FIFO_ECC_ERR,
93984 + /**< mEMAC Time-stamp FIFO ECC error interrupt;
93985 + not supported on T4240/B4860 rev1 chips */
93986 +};
93987 +
93988 +#define ENET_IF_SGMII_BASEX 0x80000000
93989 + /**< SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
93990 + and phy or backplane;
93991 + Note: 1000BaseX auto-negotiation relates only to interface between MAC
93992 + and phy/backplane, SGMII phy can still synchronize with far-end phy at
93993 + 10Mbps, 100Mbps or 1000Mbps */
93994 +
93995 +enum enet_mode {
93996 + E_ENET_MODE_INVALID = 0,
93997 + /**< Invalid Ethernet mode */
93998 + E_ENET_MODE_MII_10 = (E_ENET_IF_MII | E_ENET_SPEED_10),
93999 + /**< 10 Mbps MII */
94000 + E_ENET_MODE_MII_100 = (E_ENET_IF_MII | E_ENET_SPEED_100),
94001 + /**< 100 Mbps MII */
94002 + E_ENET_MODE_RMII_10 = (E_ENET_IF_RMII | E_ENET_SPEED_10),
94003 + /**< 10 Mbps RMII */
94004 + E_ENET_MODE_RMII_100 = (E_ENET_IF_RMII | E_ENET_SPEED_100),
94005 + /**< 100 Mbps RMII */
94006 + E_ENET_MODE_SMII_10 = (E_ENET_IF_SMII | E_ENET_SPEED_10),
94007 + /**< 10 Mbps SMII */
94008 + E_ENET_MODE_SMII_100 = (E_ENET_IF_SMII | E_ENET_SPEED_100),
94009 + /**< 100 Mbps SMII */
94010 + E_ENET_MODE_GMII_1000 = (E_ENET_IF_GMII | E_ENET_SPEED_1000),
94011 + /**< 1000 Mbps GMII */
94012 + E_ENET_MODE_RGMII_10 = (E_ENET_IF_RGMII | E_ENET_SPEED_10),
94013 + /**< 10 Mbps RGMII */
94014 + E_ENET_MODE_RGMII_100 = (E_ENET_IF_RGMII | E_ENET_SPEED_100),
94015 + /**< 100 Mbps RGMII */
94016 + E_ENET_MODE_RGMII_1000 = (E_ENET_IF_RGMII | E_ENET_SPEED_1000),
94017 + /**< 1000 Mbps RGMII */
94018 + E_ENET_MODE_TBI_1000 = (E_ENET_IF_TBI | E_ENET_SPEED_1000),
94019 + /**< 1000 Mbps TBI */
94020 + E_ENET_MODE_RTBI_1000 = (E_ENET_IF_RTBI | E_ENET_SPEED_1000),
94021 + /**< 1000 Mbps RTBI */
94022 + E_ENET_MODE_SGMII_10 = (E_ENET_IF_SGMII | E_ENET_SPEED_10),
94023 + /**< 10 Mbps SGMII with auto-negotiation between MAC and
94024 + SGMII phy according to Cisco SGMII specification */
94025 + E_ENET_MODE_SGMII_100 = (E_ENET_IF_SGMII | E_ENET_SPEED_100),
94026 + /**< 100 Mbps SGMII with auto-negotiation between MAC and
94027 + SGMII phy according to Cisco SGMII specification */
94028 + E_ENET_MODE_SGMII_1000 = (E_ENET_IF_SGMII | E_ENET_SPEED_1000),
94029 + /**< 1000 Mbps SGMII with auto-negotiation between MAC and
94030 + SGMII phy according to Cisco SGMII specification */
94031 + E_ENET_MODE_SGMII_BASEX_10 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
94032 + | E_ENET_SPEED_10),
94033 + /**< 10 Mbps SGMII with 1000BaseX auto-negotiation between
94034 + MAC and SGMII phy or backplane */
94035 + E_ENET_MODE_SGMII_BASEX_100 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
94036 + | E_ENET_SPEED_100),
94037 + /**< 100 Mbps SGMII with 1000BaseX auto-negotiation between
94038 + MAC and SGMII phy or backplane */
94039 + E_ENET_MODE_SGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_SGMII
94040 + | E_ENET_SPEED_1000),
94041 + /**< 1000 Mbps SGMII with 1000BaseX auto-negotiation between
94042 + MAC and SGMII phy or backplane */
94043 + E_ENET_MODE_QSGMII_1000 = (E_ENET_IF_QSGMII | E_ENET_SPEED_1000),
94044 + /**< 1000 Mbps QSGMII with auto-negotiation between MAC and
94045 + QSGMII phy according to Cisco QSGMII specification */
94046 + E_ENET_MODE_QSGMII_BASEX_1000 = (ENET_IF_SGMII_BASEX | E_ENET_IF_QSGMII
94047 + | E_ENET_SPEED_1000),
94048 + /**< 1000 Mbps QSGMII with 1000BaseX auto-negotiation between
94049 + MAC and QSGMII phy or backplane */
94050 + E_ENET_MODE_XGMII_10000 = (E_ENET_IF_XGMII | E_ENET_SPEED_10000),
94051 + /**< 10000 Mbps XGMII */
94052 + E_ENET_MODE_XFI_10000 = (E_ENET_IF_XFI | E_ENET_SPEED_10000)
94053 + /**< 10000 Mbps XFI */
94054 +};
94055 +
94056 +enum fmam_mac_statistics_level {
94057 + E_FMAN_MAC_NONE_STATISTICS, /**< No statistics */
94058 + E_FMAN_MAC_PARTIAL_STATISTICS, /**< Only error counters are available;
94059 + Optimized for performance */
94060 + E_FMAN_MAC_FULL_STATISTICS /**< All counters available; Not
94061 + optimized for performance */
94062 +};
94063 +
94064 +#define _MAKE_ENET_MODE(_interface, _speed) (enum enet_mode)((_interface) \
94065 + | (_speed))
94066 +
94067 +#define _ENET_INTERFACE_FROM_MODE(mode) (enum enet_interface) \
94068 + ((mode) & 0x0FFF0000)
94069 +#define _ENET_SPEED_FROM_MODE(mode) (enum enet_speed)((mode) & 0x0000FFFF)
94070 +#define _ENET_ADDR_TO_UINT64(_enet_addr) \
94071 + (uint64_t)(((uint64_t)(_enet_addr)[0] << 40) | \
94072 + ((uint64_t)(_enet_addr)[1] << 32) | \
94073 + ((uint64_t)(_enet_addr)[2] << 24) | \
94074 + ((uint64_t)(_enet_addr)[3] << 16) | \
94075 + ((uint64_t)(_enet_addr)[4] << 8) | \
94076 + ((uint64_t)(_enet_addr)[5]))
94077 +
94078 +#define _MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
94079 + do { \
94080 + int i; \
94081 + for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++) \
94082 + (_enet_addr)[i] = (uint8_t)((_addr64) >> ((5-i)*8));\
94083 + } while (0)
94084 +
94085 +#endif /* __FSL_ENET_H */
94086 --- /dev/null
94087 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman.h
94088 @@ -0,0 +1,825 @@
94089 +/*
94090 + * Copyright 2013 Freescale Semiconductor Inc.
94091 + *
94092 + * Redistribution and use in source and binary forms, with or without
94093 + * modification, are permitted provided that the following conditions are met:
94094 + * * Redistributions of source code must retain the above copyright
94095 + * notice, this list of conditions and the following disclaimer.
94096 + * * Redistributions in binary form must reproduce the above copyright
94097 + * notice, this list of conditions and the following disclaimer in the
94098 + * documentation and/or other materials provided with the distribution.
94099 + * * Neither the name of Freescale Semiconductor nor the
94100 + * names of its contributors may be used to endorse or promote products
94101 + * derived from this software without specific prior written permission.
94102 + *
94103 + *
94104 + * ALTERNATIVELY, this software may be distributed under the terms of the
94105 + * GNU General Public License ("GPL") as published by the Free Software
94106 + * Foundation, either version 2 of that License or (at your option) any
94107 + * later version.
94108 + *
94109 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94110 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94111 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94112 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94113 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94114 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94115 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94116 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94117 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94118 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94119 + */
94120 +
94121 +#ifndef __FSL_FMAN_H
94122 +#define __FSL_FMAN_H
94123 +
94124 +#include "common/general.h"
94125 +
94126 +struct fman_ext_pool_params {
94127 + uint8_t id; /**< External buffer pool id */
94128 + uint16_t size; /**< External buffer pool buffer size */
94129 +};
94130 +
94131 +struct fman_ext_pools {
94132 + uint8_t num_pools_used; /**< Number of pools use by this port */
94133 + struct fman_ext_pool_params *ext_buf_pool;
94134 + /**< Parameters for each port */
94135 +};
94136 +
94137 +struct fman_backup_bm_pools {
94138 + uint8_t num_backup_pools; /**< Number of BM backup pools -
94139 + must be smaller than the total number
94140 + of pools defined for the specified
94141 + port.*/
94142 + uint8_t *pool_ids; /**< numOfBackupPools pool id's,
94143 + specifying which pools should be used
94144 + only as backup. Pool id's specified
94145 + here must be a subset of the pools
94146 + used by the specified port.*/
94147 +};
94148 +
94149 +/**************************************************************************//**
94150 + @Description A structure for defining BM pool depletion criteria
94151 +*//***************************************************************************/
94152 +struct fman_buf_pool_depletion {
94153 + bool buf_pool_depletion_enabled;
94154 + bool pools_grp_mode_enable; /**< select mode in which pause frames
94155 + will be sent after a number of pools
94156 + (all together!) are depleted */
94157 + uint8_t num_pools; /**< the number of depleted pools that
94158 + will invoke pause frames transmission.
94159 + */
94160 + bool *pools_to_consider; /**< For each pool, TRUE if it should be
94161 + considered for depletion (Note - this
94162 + pool must be used by this port!). */
94163 + bool single_pool_mode_enable; /**< select mode in which pause frames
94164 + will be sent after a single-pool
94165 + is depleted; */
94166 + bool *pools_to_consider_for_single_mode;
94167 + /**< For each pool, TRUE if it should be
94168 + considered for depletion (Note - this
94169 + pool must be used by this port!) */
94170 + bool has_pfc_priorities;
94171 + bool *pfc_priorities_en; /**< This field is used by the MAC as
94172 + the Priority Enable Vector in the PFC
94173 + frame which is transmitted */
94174 +};
94175 +
94176 +/**************************************************************************//**
94177 + @Description Enum for defining port DMA swap mode
94178 +*//***************************************************************************/
94179 +enum fman_dma_swap_option {
94180 + FMAN_DMA_NO_SWP, /**< No swap, transfer data as is.*/
94181 + FMAN_DMA_SWP_PPC_LE, /**< The transferred data should be swapped
94182 + in PowerPc Little Endian mode. */
94183 + FMAN_DMA_SWP_BE /**< The transferred data should be swapped
94184 + in Big Endian mode */
94185 +};
94186 +
94187 +/**************************************************************************//**
94188 + @Description Enum for defining port DMA cache attributes
94189 +*//***************************************************************************/
94190 +enum fman_dma_cache_option {
94191 + FMAN_DMA_NO_STASH = 0, /**< Cacheable, no Allocate (No Stashing) */
94192 + FMAN_DMA_STASH = 1 /**< Cacheable and Allocate (Stashing on) */
94193 +};
94194 +
94195 +typedef struct t_FmPrsResult fm_prs_result_t;
94196 +typedef enum e_EnetMode enet_mode_t;
94197 +typedef t_Handle handle_t;
94198 +
94199 +struct fman_revision_info {
94200 + uint8_t majorRev; /**< Major revision */
94201 + uint8_t minorRev; /**< Minor revision */
94202 +};
94203 +
94204 +/* sizes */
94205 +#define CAPWAP_FRAG_EXTRA_SPACE 32
94206 +#define OFFSET_UNITS 16
94207 +#define MAX_INT_OFFSET 240
94208 +#define MAX_IC_SIZE 256
94209 +#define MAX_EXT_OFFSET 496
94210 +#define MAX_EXT_BUFFER_OFFSET 511
94211 +
94212 +/**************************************************************************
94213 + @Description Memory Mapped Registers
94214 +***************************************************************************/
94215 +#define FMAN_LIODN_TBL 64 /* size of LIODN table */
94216 +
94217 +struct fman_fpm_regs {
94218 + uint32_t fmfp_tnc; /**< FPM TNUM Control 0x00 */
94219 + uint32_t fmfp_prc; /**< FPM Port_ID FmCtl Association 0x04 */
94220 + uint32_t fmfp_brkc; /**< FPM Breakpoint Control 0x08 */
94221 + uint32_t fmfp_mxd; /**< FPM Flush Control 0x0c */
94222 + uint32_t fmfp_dist1; /**< FPM Dispatch Thresholds1 0x10 */
94223 + uint32_t fmfp_dist2; /**< FPM Dispatch Thresholds2 0x14 */
94224 + uint32_t fm_epi; /**< FM Error Pending Interrupts 0x18 */
94225 + uint32_t fm_rie; /**< FM Error Interrupt Enable 0x1c */
94226 + uint32_t fmfp_fcev[4]; /**< FPM FMan-Controller Event 1-4 0x20-0x2f */
94227 + uint32_t res0030[4]; /**< res 0x30 - 0x3f */
94228 + uint32_t fmfp_cee[4]; /**< PM FMan-Controller Event 1-4 0x40-0x4f */
94229 + uint32_t res0050[4]; /**< res 0x50-0x5f */
94230 + uint32_t fmfp_tsc1; /**< FPM TimeStamp Control1 0x60 */
94231 + uint32_t fmfp_tsc2; /**< FPM TimeStamp Control2 0x64 */
94232 + uint32_t fmfp_tsp; /**< FPM Time Stamp 0x68 */
94233 + uint32_t fmfp_tsf; /**< FPM Time Stamp Fraction 0x6c */
94234 + uint32_t fm_rcr; /**< FM Rams Control 0x70 */
94235 + uint32_t fmfp_extc; /**< FPM External Requests Control 0x74 */
94236 + uint32_t fmfp_ext1; /**< FPM External Requests Config1 0x78 */
94237 + uint32_t fmfp_ext2; /**< FPM External Requests Config2 0x7c */
94238 + uint32_t fmfp_drd[16]; /**< FPM Data_Ram Data 0-15 0x80 - 0xbf */
94239 + uint32_t fmfp_dra; /**< FPM Data Ram Access 0xc0 */
94240 + uint32_t fm_ip_rev_1; /**< FM IP Block Revision 1 0xc4 */
94241 + uint32_t fm_ip_rev_2; /**< FM IP Block Revision 2 0xc8 */
94242 + uint32_t fm_rstc; /**< FM Reset Command 0xcc */
94243 + uint32_t fm_cld; /**< FM Classifier Debug 0xd0 */
94244 + uint32_t fm_npi; /**< FM Normal Pending Interrupts 0xd4 */
94245 + uint32_t fmfp_exte; /**< FPM External Requests Enable 0xd8 */
94246 + uint32_t fmfp_ee; /**< FPM Event & Mask 0xdc */
94247 + uint32_t fmfp_cev[4]; /**< FPM CPU Event 1-4 0xe0-0xef */
94248 + uint32_t res00f0[4]; /**< res 0xf0-0xff */
94249 + uint32_t fmfp_ps[64]; /**< FPM Port Status 0x100-0x1ff */
94250 + uint32_t fmfp_clfabc; /**< FPM CLFABC 0x200 */
94251 + uint32_t fmfp_clfcc; /**< FPM CLFCC 0x204 */
94252 + uint32_t fmfp_clfaval; /**< FPM CLFAVAL 0x208 */
94253 + uint32_t fmfp_clfbval; /**< FPM CLFBVAL 0x20c */
94254 + uint32_t fmfp_clfcval; /**< FPM CLFCVAL 0x210 */
94255 + uint32_t fmfp_clfamsk; /**< FPM CLFAMSK 0x214 */
94256 + uint32_t fmfp_clfbmsk; /**< FPM CLFBMSK 0x218 */
94257 + uint32_t fmfp_clfcmsk; /**< FPM CLFCMSK 0x21c */
94258 + uint32_t fmfp_clfamc; /**< FPM CLFAMC 0x220 */
94259 + uint32_t fmfp_clfbmc; /**< FPM CLFBMC 0x224 */
94260 + uint32_t fmfp_clfcmc; /**< FPM CLFCMC 0x228 */
94261 + uint32_t fmfp_decceh; /**< FPM DECCEH 0x22c */
94262 + uint32_t res0230[116]; /**< res 0x230 - 0x3ff */
94263 + uint32_t fmfp_ts[128]; /**< 0x400: FPM Task Status 0x400 - 0x5ff */
94264 + uint32_t res0600[0x400 - 384];
94265 +};
94266 +
94267 +struct fman_bmi_regs {
94268 + uint32_t fmbm_init; /**< BMI Initialization 0x00 */
94269 + uint32_t fmbm_cfg1; /**< BMI Configuration 1 0x04 */
94270 + uint32_t fmbm_cfg2; /**< BMI Configuration 2 0x08 */
94271 + uint32_t res000c[5]; /**< 0x0c - 0x1f */
94272 + uint32_t fmbm_ievr; /**< Interrupt Event Register 0x20 */
94273 + uint32_t fmbm_ier; /**< Interrupt Enable Register 0x24 */
94274 + uint32_t fmbm_ifr; /**< Interrupt Force Register 0x28 */
94275 + uint32_t res002c[5]; /**< 0x2c - 0x3f */
94276 + uint32_t fmbm_arb[8]; /**< BMI Arbitration 0x40 - 0x5f */
94277 + uint32_t res0060[12]; /**<0x60 - 0x8f */
94278 + uint32_t fmbm_dtc[3]; /**< Debug Trap Counter 0x90 - 0x9b */
94279 + uint32_t res009c; /**< 0x9c */
94280 + uint32_t fmbm_dcv[3][4]; /**< Debug Compare val 0xa0-0xcf */
94281 + uint32_t fmbm_dcm[3][4]; /**< Debug Compare Mask 0xd0-0xff */
94282 + uint32_t fmbm_gde; /**< BMI Global Debug Enable 0x100 */
94283 + uint32_t fmbm_pp[63]; /**< BMI Port Parameters 0x104 - 0x1ff */
94284 + uint32_t res0200; /**< 0x200 */
94285 + uint32_t fmbm_pfs[63]; /**< BMI Port FIFO Size 0x204 - 0x2ff */
94286 + uint32_t res0300; /**< 0x300 */
94287 + uint32_t fmbm_spliodn[63]; /**< Port Partition ID 0x304 - 0x3ff */
94288 +};
94289 +
94290 +struct fman_qmi_regs {
94291 + uint32_t fmqm_gc; /**< General Configuration Register 0x00 */
94292 + uint32_t res0004; /**< 0x04 */
94293 + uint32_t fmqm_eie; /**< Error Interrupt Event Register 0x08 */
94294 + uint32_t fmqm_eien; /**< Error Interrupt Enable Register 0x0c */
94295 + uint32_t fmqm_eif; /**< Error Interrupt Force Register 0x10 */
94296 + uint32_t fmqm_ie; /**< Interrupt Event Register 0x14 */
94297 + uint32_t fmqm_ien; /**< Interrupt Enable Register 0x18 */
94298 + uint32_t fmqm_if; /**< Interrupt Force Register 0x1c */
94299 + uint32_t fmqm_gs; /**< Global Status Register 0x20 */
94300 + uint32_t fmqm_ts; /**< Task Status Register 0x24 */
94301 + uint32_t fmqm_etfc; /**< Enqueue Total Frame Counter 0x28 */
94302 + uint32_t fmqm_dtfc; /**< Dequeue Total Frame Counter 0x2c */
94303 + uint32_t fmqm_dc0; /**< Dequeue Counter 0 0x30 */
94304 + uint32_t fmqm_dc1; /**< Dequeue Counter 1 0x34 */
94305 + uint32_t fmqm_dc2; /**< Dequeue Counter 2 0x38 */
94306 + uint32_t fmqm_dc3; /**< Dequeue Counter 3 0x3c */
94307 + uint32_t fmqm_dfdc; /**< Dequeue FQID from Default Counter 0x40 */
94308 + uint32_t fmqm_dfcc; /**< Dequeue FQID from Context Counter 0x44 */
94309 + uint32_t fmqm_dffc; /**< Dequeue FQID from FD Counter 0x48 */
94310 + uint32_t fmqm_dcc; /**< Dequeue Confirm Counter 0x4c */
94311 + uint32_t res0050[7]; /**< 0x50 - 0x6b */
94312 + uint32_t fmqm_tapc; /**< Tnum Aging Period Control 0x6c */
94313 + uint32_t fmqm_dmcvc; /**< Dequeue MAC Command Valid Counter 0x70 */
94314 + uint32_t fmqm_difdcc; /**< Dequeue Invalid FD Command Counter 0x74 */
94315 + uint32_t fmqm_da1v; /**< Dequeue A1 Valid Counter 0x78 */
94316 + uint32_t res007c; /**< 0x7c */
94317 + uint32_t fmqm_dtc; /**< 0x80 Debug Trap Counter 0x80 */
94318 + uint32_t fmqm_efddd; /**< 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
94319 + uint32_t res0088[2]; /**< 0x88 - 0x8f */
94320 + struct {
94321 + uint32_t fmqm_dtcfg1; /**< 0x90 dbg trap cfg 1 Register 0x00 */
94322 + uint32_t fmqm_dtval1; /**< Debug Trap Value 1 Register 0x04 */
94323 + uint32_t fmqm_dtm1; /**< Debug Trap Mask 1 Register 0x08 */
94324 + uint32_t fmqm_dtc1; /**< Debug Trap Counter 1 Register 0x0c */
94325 + uint32_t fmqm_dtcfg2; /**< dbg Trap cfg 2 Register 0x10 */
94326 + uint32_t fmqm_dtval2; /**< Debug Trap Value 2 Register 0x14 */
94327 + uint32_t fmqm_dtm2; /**< Debug Trap Mask 2 Register 0x18 */
94328 + uint32_t res001c; /**< 0x1c */
94329 + } dbg_traps[3]; /**< 0x90 - 0xef */
94330 + uint8_t res00f0[0x400 - 0xf0]; /**< 0xf0 - 0x3ff */
94331 +};
94332 +
94333 +struct fman_dma_regs {
94334 + uint32_t fmdmsr; /**< FM DMA status register 0x00 */
94335 + uint32_t fmdmmr; /**< FM DMA mode register 0x04 */
94336 + uint32_t fmdmtr; /**< FM DMA bus threshold register 0x08 */
94337 + uint32_t fmdmhy; /**< FM DMA bus hysteresis register 0x0c */
94338 + uint32_t fmdmsetr; /**< FM DMA SOS emergency Threshold Register 0x10 */
94339 + uint32_t fmdmtah; /**< FM DMA transfer bus address high reg 0x14 */
94340 + uint32_t fmdmtal; /**< FM DMA transfer bus address low reg 0x18 */
94341 + uint32_t fmdmtcid; /**< FM DMA transfer bus communication ID reg 0x1c */
94342 + uint32_t fmdmra; /**< FM DMA bus internal ram address register 0x20 */
94343 + uint32_t fmdmrd; /**< FM DMA bus internal ram data register 0x24 */
94344 + uint32_t fmdmwcr; /**< FM DMA CAM watchdog counter value 0x28 */
94345 + uint32_t fmdmebcr; /**< FM DMA CAM base in MURAM register 0x2c */
94346 + uint32_t fmdmccqdr; /**< FM DMA CAM and CMD Queue Debug reg 0x30 */
94347 + uint32_t fmdmccqvr1; /**< FM DMA CAM and CMD Queue Value reg #1 0x34 */
94348 + uint32_t fmdmccqvr2; /**< FM DMA CAM and CMD Queue Value reg #2 0x38 */
94349 + uint32_t fmdmcqvr3; /**< FM DMA CMD Queue Value register #3 0x3c */
94350 + uint32_t fmdmcqvr4; /**< FM DMA CMD Queue Value register #4 0x40 */
94351 + uint32_t fmdmcqvr5; /**< FM DMA CMD Queue Value register #5 0x44 */
94352 + uint32_t fmdmsefrc; /**< FM DMA Semaphore Entry Full Reject Cntr 0x48 */
94353 + uint32_t fmdmsqfrc; /**< FM DMA Semaphore Queue Full Reject Cntr 0x4c */
94354 + uint32_t fmdmssrc; /**< FM DMA Semaphore SYNC Reject Counter 0x50 */
94355 + uint32_t fmdmdcr; /**< FM DMA Debug Counter 0x54 */
94356 + uint32_t fmdmemsr; /**< FM DMA Emergency Smoother Register 0x58 */
94357 + uint32_t res005c; /**< 0x5c */
94358 + uint32_t fmdmplr[FMAN_LIODN_TBL / 2]; /**< DMA LIODN regs 0x60-0xdf */
94359 + uint32_t res00e0[0x400 - 56];
94360 +};
94361 +
94362 +struct fman_rg {
94363 + struct fman_fpm_regs *fpm_rg;
94364 + struct fman_dma_regs *dma_rg;
94365 + struct fman_bmi_regs *bmi_rg;
94366 + struct fman_qmi_regs *qmi_rg;
94367 +};
94368 +
94369 +enum fman_dma_cache_override {
94370 + E_FMAN_DMA_NO_CACHE_OR = 0, /**< No override of the Cache field */
94371 + E_FMAN_DMA_NO_STASH_DATA, /**< No data stashing in system level cache */
94372 + E_FMAN_DMA_MAY_STASH_DATA, /**< Stashing allowed in sys level cache */
94373 + E_FMAN_DMA_STASH_DATA /**< Stashing performed in system level cache */
94374 +};
94375 +
94376 +enum fman_dma_aid_mode {
94377 + E_FMAN_DMA_AID_OUT_PORT_ID = 0, /**< 4 LSB of PORT_ID */
94378 + E_FMAN_DMA_AID_OUT_TNUM /**< 4 LSB of TNUM */
94379 +};
94380 +
94381 +enum fman_dma_dbg_cnt_mode {
94382 + E_FMAN_DMA_DBG_NO_CNT = 0, /**< No counting */
94383 + E_FMAN_DMA_DBG_CNT_DONE, /**< Count DONE commands */
94384 + E_FMAN_DMA_DBG_CNT_COMM_Q_EM, /**< command Q emergency signal */
94385 + E_FMAN_DMA_DBG_CNT_INT_READ_EM, /**< Read buf emergency signal */
94386 + E_FMAN_DMA_DBG_CNT_INT_WRITE_EM, /**< Write buf emergency signal */
94387 + E_FMAN_DMA_DBG_CNT_FPM_WAIT, /**< FPM WAIT signal */
94388 + E_FMAN_DMA_DBG_CNT_SIGLE_BIT_ECC, /**< Single bit ECC errors */
94389 + E_FMAN_DMA_DBG_CNT_RAW_WAR_PROT /**< RAW & WAR protection counter */
94390 +};
94391 +
94392 +enum fman_dma_emergency_level {
94393 + E_FMAN_DMA_EM_EBS = 0, /**< EBS emergency */
94394 + E_FMAN_DMA_EM_SOS /**< SOS emergency */
94395 +};
94396 +
94397 +enum fman_catastrophic_err {
94398 + E_FMAN_CATAST_ERR_STALL_PORT = 0, /**< Port_ID stalled reset required */
94399 + E_FMAN_CATAST_ERR_STALL_TASK /**< Only erroneous task is stalled */
94400 +};
94401 +
94402 +enum fman_dma_err {
94403 + E_FMAN_DMA_ERR_CATASTROPHIC = 0, /**< Catastrophic DMA error */
94404 + E_FMAN_DMA_ERR_REPORT /**< Reported DMA error */
94405 +};
94406 +
94407 +struct fman_cfg {
94408 + uint16_t liodn_bs_pr_port[FMAN_LIODN_TBL];/* base per port */
94409 + bool en_counters;
94410 + uint8_t disp_limit_tsh;
94411 + uint8_t prs_disp_tsh;
94412 + uint8_t plcr_disp_tsh;
94413 + uint8_t kg_disp_tsh;
94414 + uint8_t bmi_disp_tsh;
94415 + uint8_t qmi_enq_disp_tsh;
94416 + uint8_t qmi_deq_disp_tsh;
94417 + uint8_t fm_ctl1_disp_tsh;
94418 + uint8_t fm_ctl2_disp_tsh;
94419 + enum fman_dma_cache_override dma_cache_override;
94420 + enum fman_dma_aid_mode dma_aid_mode;
94421 + bool dma_aid_override;
94422 + uint8_t dma_axi_dbg_num_of_beats;
94423 + uint8_t dma_cam_num_of_entries;
94424 + uint32_t dma_watchdog;
94425 + uint8_t dma_comm_qtsh_asrt_emer;
94426 + uint8_t dma_write_buf_tsh_asrt_emer;
94427 + uint8_t dma_read_buf_tsh_asrt_emer;
94428 + uint8_t dma_comm_qtsh_clr_emer;
94429 + uint8_t dma_write_buf_tsh_clr_emer;
94430 + uint8_t dma_read_buf_tsh_clr_emer;
94431 + uint32_t dma_sos_emergency;
94432 + enum fman_dma_dbg_cnt_mode dma_dbg_cnt_mode;
94433 + bool dma_stop_on_bus_error;
94434 + bool dma_en_emergency;
94435 + uint32_t dma_emergency_bus_select;
94436 + enum fman_dma_emergency_level dma_emergency_level;
94437 + bool dma_en_emergency_smoother;
94438 + uint32_t dma_emergency_switch_counter;
94439 + bool halt_on_external_activ;
94440 + bool halt_on_unrecov_ecc_err;
94441 + enum fman_catastrophic_err catastrophic_err;
94442 + enum fman_dma_err dma_err;
94443 + bool en_muram_test_mode;
94444 + bool en_iram_test_mode;
94445 + bool external_ecc_rams_enable;
94446 + uint16_t tnum_aging_period;
94447 + uint32_t exceptions;
94448 + uint16_t clk_freq;
94449 + bool pedantic_dma;
94450 + uint32_t cam_base_addr;
94451 + uint32_t fifo_base_addr;
94452 + uint32_t total_fifo_size;
94453 + uint8_t total_num_of_tasks;
94454 + bool qmi_deq_option_support;
94455 + uint32_t qmi_def_tnums_thresh;
94456 + bool fman_partition_array;
94457 + uint8_t num_of_fman_ctrl_evnt_regs;
94458 +};
94459 +
94460 +/**************************************************************************//**
94461 + @Description Exceptions
94462 +*//***************************************************************************/
94463 +#define FMAN_EX_DMA_BUS_ERROR 0x80000000
94464 +#define FMAN_EX_DMA_READ_ECC 0x40000000
94465 +#define FMAN_EX_DMA_SYSTEM_WRITE_ECC 0x20000000
94466 +#define FMAN_EX_DMA_FM_WRITE_ECC 0x10000000
94467 +#define FMAN_EX_FPM_STALL_ON_TASKS 0x08000000
94468 +#define FMAN_EX_FPM_SINGLE_ECC 0x04000000
94469 +#define FMAN_EX_FPM_DOUBLE_ECC 0x02000000
94470 +#define FMAN_EX_QMI_SINGLE_ECC 0x01000000
94471 +#define FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID 0x00800000
94472 +#define FMAN_EX_QMI_DOUBLE_ECC 0x00400000
94473 +#define FMAN_EX_BMI_LIST_RAM_ECC 0x00200000
94474 +#define FMAN_EX_BMI_PIPELINE_ECC 0x00100000
94475 +#define FMAN_EX_BMI_STATISTICS_RAM_ECC 0x00080000
94476 +#define FMAN_EX_IRAM_ECC 0x00040000
94477 +#define FMAN_EX_NURAM_ECC 0x00020000
94478 +#define FMAN_EX_BMI_DISPATCH_RAM_ECC 0x00010000
94479 +
94480 +enum fman_exceptions {
94481 + E_FMAN_EX_DMA_BUS_ERROR = 0, /**< DMA bus error. */
94482 + E_FMAN_EX_DMA_READ_ECC, /**< Read Buffer ECC error */
94483 + E_FMAN_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC err on sys side */
94484 + E_FMAN_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side */
94485 + E_FMAN_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
94486 + E_FMAN_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
94487 + E_FMAN_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
94488 + E_FMAN_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
94489 + E_FMAN_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
94490 + E_FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< DeQ from unknown port id */
94491 + E_FMAN_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
94492 + E_FMAN_EX_BMI_STORAGE_PROFILE_ECC, /**< storage profile */
94493 + E_FMAN_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics RAM ECC Err Enable */
94494 + E_FMAN_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
94495 + E_FMAN_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
94496 + E_FMAN_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
94497 +};
94498 +
94499 +enum fman_counters {
94500 + E_FMAN_COUNTERS_ENQ_TOTAL_FRAME = 0, /**< QMI tot enQ frames counter */
94501 + E_FMAN_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI tot deQ frames counter */
94502 + E_FMAN_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
94503 + E_FMAN_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
94504 + E_FMAN_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
94505 + E_FMAN_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
94506 + E_FMAN_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI deQ from dflt queue cntr */
94507 + E_FMAN_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI deQ from FQ context cntr */
94508 + E_FMAN_COUNTERS_DEQ_FROM_FD, /**< QMI deQ from FD command field cntr */
94509 + E_FMAN_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
94510 + E_FMAN_COUNTERS_SEMAPHOR_ENTRY_FULL_REJECT, /**< DMA full entry cntr */
94511 + E_FMAN_COUNTERS_SEMAPHOR_QUEUE_FULL_REJECT, /**< DMA full CAM Q cntr */
94512 + E_FMAN_COUNTERS_SEMAPHOR_SYNC_REJECT /**< DMA sync counter */
94513 +};
94514 +
94515 +#define FPM_PRT_FM_CTL1 0x00000001
94516 +#define FPM_PRT_FM_CTL2 0x00000002
94517 +
94518 +/**************************************************************************//**
94519 + @Description DMA definitions
94520 +*//***************************************************************************/
94521 +
94522 +/* masks */
94523 +#define DMA_MODE_AID_OR 0x20000000
94524 +#define DMA_MODE_SBER 0x10000000
94525 +#define DMA_MODE_BER 0x00200000
94526 +#define DMA_MODE_EB 0x00100000
94527 +#define DMA_MODE_ECC 0x00000020
94528 +#define DMA_MODE_PRIVILEGE_PROT 0x00001000
94529 +#define DMA_MODE_SECURE_PROT 0x00000800
94530 +#define DMA_MODE_EMER_READ 0x00080000
94531 +#define DMA_MODE_EMER_WRITE 0x00040000
94532 +#define DMA_MODE_CACHE_OR_MASK 0xC0000000
94533 +#define DMA_MODE_CEN_MASK 0x0000E000
94534 +#define DMA_MODE_DBG_MASK 0x00000380
94535 +#define DMA_MODE_AXI_DBG_MASK 0x0F000000
94536 +
94537 +#define DMA_EMSR_EMSTR_MASK 0x0000FFFF
94538 +
94539 +#define DMA_TRANSFER_PORTID_MASK 0xFF000000
94540 +#define DMA_TRANSFER_TNUM_MASK 0x00FF0000
94541 +#define DMA_TRANSFER_LIODN_MASK 0x00000FFF
94542 +
94543 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
94544 +#define DMA_LOW_LIODN_MASK 0x00000FFF
94545 +
94546 +#define DMA_STATUS_CMD_QUEUE_NOT_EMPTY 0x10000000
94547 +#define DMA_STATUS_BUS_ERR 0x08000000
94548 +#define DMA_STATUS_READ_ECC 0x04000000
94549 +#define DMA_STATUS_SYSTEM_WRITE_ECC 0x02000000
94550 +#define DMA_STATUS_FM_WRITE_ECC 0x01000000
94551 +#define DMA_STATUS_SYSTEM_DPEXT_ECC 0x00800000
94552 +#define DMA_STATUS_FM_DPEXT_ECC 0x00400000
94553 +#define DMA_STATUS_SYSTEM_DPDAT_ECC 0x00200000
94554 +#define DMA_STATUS_FM_DPDAT_ECC 0x00100000
94555 +#define DMA_STATUS_FM_SPDAT_ECC 0x00080000
94556 +
94557 +#define FM_LIODN_BASE_MASK 0x00000FFF
94558 +
94559 +/* shifts */
94560 +#define DMA_MODE_CACHE_OR_SHIFT 30
94561 +#define DMA_MODE_BUS_PRI_SHIFT 16
94562 +#define DMA_MODE_AXI_DBG_SHIFT 24
94563 +#define DMA_MODE_CEN_SHIFT 13
94564 +#define DMA_MODE_BUS_PROT_SHIFT 10
94565 +#define DMA_MODE_DBG_SHIFT 7
94566 +#define DMA_MODE_EMER_LVL_SHIFT 6
94567 +#define DMA_MODE_AID_MODE_SHIFT 4
94568 +#define DMA_MODE_MAX_AXI_DBG_NUM_OF_BEATS 16
94569 +#define DMA_MODE_MAX_CAM_NUM_OF_ENTRIES 32
94570 +
94571 +#define DMA_THRESH_COMMQ_SHIFT 24
94572 +#define DMA_THRESH_READ_INT_BUF_SHIFT 16
94573 +
94574 +#define DMA_LIODN_SHIFT 16
94575 +
94576 +#define DMA_TRANSFER_PORTID_SHIFT 24
94577 +#define DMA_TRANSFER_TNUM_SHIFT 16
94578 +
94579 +/* sizes */
94580 +#define DMA_MAX_WATCHDOG 0xffffffff
94581 +
94582 +/* others */
94583 +#define DMA_CAM_SIZEOF_ENTRY 0x40
94584 +#define DMA_CAM_ALIGN 0x1000
94585 +#define DMA_CAM_UNITS 8
94586 +
94587 +/**************************************************************************//**
94588 + @Description General defines
94589 +*//***************************************************************************/
94590 +
94591 +#define FM_DEBUG_STATUS_REGISTER_OFFSET 0x000d1084UL
94592 +#define FM_UCODE_DEBUG_INSTRUCTION 0x6ffff805UL
94593 +
94594 +/**************************************************************************//**
94595 + @Description FPM defines
94596 +*//***************************************************************************/
94597 +
94598 +/* masks */
94599 +#define FPM_EV_MASK_DOUBLE_ECC 0x80000000
94600 +#define FPM_EV_MASK_STALL 0x40000000
94601 +#define FPM_EV_MASK_SINGLE_ECC 0x20000000
94602 +#define FPM_EV_MASK_RELEASE_FM 0x00010000
94603 +#define FPM_EV_MASK_DOUBLE_ECC_EN 0x00008000
94604 +#define FPM_EV_MASK_STALL_EN 0x00004000
94605 +#define FPM_EV_MASK_SINGLE_ECC_EN 0x00002000
94606 +#define FPM_EV_MASK_EXTERNAL_HALT 0x00000008
94607 +#define FPM_EV_MASK_ECC_ERR_HALT 0x00000004
94608 +
94609 +#define FPM_RAM_RAMS_ECC_EN 0x80000000
94610 +#define FPM_RAM_IRAM_ECC_EN 0x40000000
94611 +#define FPM_RAM_MURAM_ECC 0x00008000
94612 +#define FPM_RAM_IRAM_ECC 0x00004000
94613 +#define FPM_RAM_MURAM_TEST_ECC 0x20000000
94614 +#define FPM_RAM_IRAM_TEST_ECC 0x10000000
94615 +#define FPM_RAM_RAMS_ECC_EN_SRC_SEL 0x08000000
94616 +
94617 +#define FPM_IRAM_ECC_ERR_EX_EN 0x00020000
94618 +#define FPM_MURAM_ECC_ERR_EX_EN 0x00040000
94619 +
94620 +#define FPM_REV1_MAJOR_MASK 0x0000FF00
94621 +#define FPM_REV1_MINOR_MASK 0x000000FF
94622 +
94623 +#define FPM_REV2_INTEG_MASK 0x00FF0000
94624 +#define FPM_REV2_ERR_MASK 0x0000FF00
94625 +#define FPM_REV2_CFG_MASK 0x000000FF
94626 +
94627 +#define FPM_TS_FRACTION_MASK 0x0000FFFF
94628 +#define FPM_TS_CTL_EN 0x80000000
94629 +
94630 +#define FPM_PRC_REALSE_STALLED 0x00800000
94631 +
94632 +#define FPM_PS_STALLED 0x00800000
94633 +#define FPM_PS_FM_CTL1_SEL 0x80000000
94634 +#define FPM_PS_FM_CTL2_SEL 0x40000000
94635 +#define FPM_PS_FM_CTL_SEL_MASK (FPM_PS_FM_CTL1_SEL | FPM_PS_FM_CTL2_SEL)
94636 +
94637 +#define FPM_RSTC_FM_RESET 0x80000000
94638 +#define FPM_RSTC_10G0_RESET 0x04000000
94639 +#define FPM_RSTC_1G0_RESET 0x40000000
94640 +#define FPM_RSTC_1G1_RESET 0x20000000
94641 +#define FPM_RSTC_1G2_RESET 0x10000000
94642 +#define FPM_RSTC_1G3_RESET 0x08000000
94643 +#define FPM_RSTC_1G4_RESET 0x02000000
94644 +
94645 +
94646 +#define FPM_DISP_LIMIT_MASK 0x1F000000
94647 +#define FPM_THR1_PRS_MASK 0xFF000000
94648 +#define FPM_THR1_KG_MASK 0x00FF0000
94649 +#define FPM_THR1_PLCR_MASK 0x0000FF00
94650 +#define FPM_THR1_BMI_MASK 0x000000FF
94651 +
94652 +#define FPM_THR2_QMI_ENQ_MASK 0xFF000000
94653 +#define FPM_THR2_QMI_DEQ_MASK 0x000000FF
94654 +#define FPM_THR2_FM_CTL1_MASK 0x00FF0000
94655 +#define FPM_THR2_FM_CTL2_MASK 0x0000FF00
94656 +
94657 +/* shifts */
94658 +#define FPM_DISP_LIMIT_SHIFT 24
94659 +
94660 +#define FPM_THR1_PRS_SHIFT 24
94661 +#define FPM_THR1_KG_SHIFT 16
94662 +#define FPM_THR1_PLCR_SHIFT 8
94663 +#define FPM_THR1_BMI_SHIFT 0
94664 +
94665 +#define FPM_THR2_QMI_ENQ_SHIFT 24
94666 +#define FPM_THR2_QMI_DEQ_SHIFT 0
94667 +#define FPM_THR2_FM_CTL1_SHIFT 16
94668 +#define FPM_THR2_FM_CTL2_SHIFT 8
94669 +
94670 +#define FPM_EV_MASK_CAT_ERR_SHIFT 1
94671 +#define FPM_EV_MASK_DMA_ERR_SHIFT 0
94672 +
94673 +#define FPM_REV1_MAJOR_SHIFT 8
94674 +#define FPM_REV1_MINOR_SHIFT 0
94675 +
94676 +#define FPM_REV2_INTEG_SHIFT 16
94677 +#define FPM_REV2_ERR_SHIFT 8
94678 +#define FPM_REV2_CFG_SHIFT 0
94679 +
94680 +#define FPM_TS_INT_SHIFT 16
94681 +
94682 +#define FPM_PORT_FM_CTL_PORTID_SHIFT 24
94683 +
94684 +#define FPM_PS_FM_CTL_SEL_SHIFT 30
94685 +#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT 16
94686 +
94687 +#define FPM_DISP_LIMIT_SHIFT 24
94688 +
94689 +/* Interrupts defines */
94690 +#define FPM_EVENT_FM_CTL_0 0x00008000
94691 +#define FPM_EVENT_FM_CTL 0x0000FF00
94692 +#define FPM_EVENT_FM_CTL_BRK 0x00000080
94693 +
94694 +/* others */
94695 +#define FPM_MAX_DISP_LIMIT 31
94696 +#define FPM_RSTC_FM_RESET 0x80000000
94697 +#define FPM_RSTC_1G0_RESET 0x40000000
94698 +#define FPM_RSTC_1G1_RESET 0x20000000
94699 +#define FPM_RSTC_1G2_RESET 0x10000000
94700 +#define FPM_RSTC_1G3_RESET 0x08000000
94701 +#define FPM_RSTC_10G0_RESET 0x04000000
94702 +#define FPM_RSTC_1G4_RESET 0x02000000
94703 +#define FPM_RSTC_1G5_RESET 0x01000000
94704 +#define FPM_RSTC_1G6_RESET 0x00800000
94705 +#define FPM_RSTC_1G7_RESET 0x00400000
94706 +#define FPM_RSTC_10G1_RESET 0x00200000
94707 +/**************************************************************************//**
94708 + @Description BMI defines
94709 +*//***************************************************************************/
94710 +/* masks */
94711 +#define BMI_INIT_START 0x80000000
94712 +#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC 0x80000000
94713 +#define BMI_ERR_INTR_EN_LIST_RAM_ECC 0x40000000
94714 +#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC 0x20000000
94715 +#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC 0x10000000
94716 +#define BMI_NUM_OF_TASKS_MASK 0x3F000000
94717 +#define BMI_NUM_OF_EXTRA_TASKS_MASK 0x000F0000
94718 +#define BMI_NUM_OF_DMAS_MASK 0x00000F00
94719 +#define BMI_NUM_OF_EXTRA_DMAS_MASK 0x0000000F
94720 +#define BMI_FIFO_SIZE_MASK 0x000003FF
94721 +#define BMI_EXTRA_FIFO_SIZE_MASK 0x03FF0000
94722 +#define BMI_CFG2_DMAS_MASK 0x0000003F
94723 +#define BMI_TOTAL_FIFO_SIZE_MASK 0x07FF0000
94724 +#define BMI_TOTAL_NUM_OF_TASKS_MASK 0x007F0000
94725 +
94726 +/* shifts */
94727 +#define BMI_CFG2_TASKS_SHIFT 16
94728 +#define BMI_CFG2_DMAS_SHIFT 0
94729 +#define BMI_CFG1_FIFO_SIZE_SHIFT 16
94730 +#define BMI_FIFO_SIZE_SHIFT 0
94731 +#define BMI_EXTRA_FIFO_SIZE_SHIFT 16
94732 +#define BMI_NUM_OF_TASKS_SHIFT 24
94733 +#define BMI_EXTRA_NUM_OF_TASKS_SHIFT 16
94734 +#define BMI_NUM_OF_DMAS_SHIFT 8
94735 +#define BMI_EXTRA_NUM_OF_DMAS_SHIFT 0
94736 +
94737 +/* others */
94738 +#define BMI_FIFO_ALIGN 0x100
94739 +#define FMAN_BMI_FIFO_UNITS 0x100
94740 +
94741 +
94742 +/**************************************************************************//**
94743 + @Description QMI defines
94744 +*//***************************************************************************/
94745 +/* masks */
94746 +#define QMI_CFG_ENQ_EN 0x80000000
94747 +#define QMI_CFG_DEQ_EN 0x40000000
94748 +#define QMI_CFG_EN_COUNTERS 0x10000000
94749 +#define QMI_CFG_SOFT_RESET 0x01000000
94750 +#define QMI_CFG_DEQ_MASK 0x0000003F
94751 +#define QMI_CFG_ENQ_MASK 0x00003F00
94752 +
94753 +#define QMI_ERR_INTR_EN_DOUBLE_ECC 0x80000000
94754 +#define QMI_ERR_INTR_EN_DEQ_FROM_DEF 0x40000000
94755 +#define QMI_INTR_EN_SINGLE_ECC 0x80000000
94756 +
94757 +/* shifts */
94758 +#define QMI_CFG_ENQ_SHIFT 8
94759 +#define QMI_TAPC_TAP 22
94760 +
94761 +#define QMI_GS_HALT_NOT_BUSY 0x00000002
94762 +
94763 +/**************************************************************************//**
94764 + @Description IRAM defines
94765 +*//***************************************************************************/
94766 +/* masks */
94767 +#define IRAM_IADD_AIE 0x80000000
94768 +#define IRAM_READY 0x80000000
94769 +
94770 +uint32_t fman_get_bmi_err_event(struct fman_bmi_regs *bmi_rg);
94771 +uint32_t fman_get_qmi_err_event(struct fman_qmi_regs *qmi_rg);
94772 +uint32_t fman_get_dma_com_id(struct fman_dma_regs *dma_rg);
94773 +uint64_t fman_get_dma_addr(struct fman_dma_regs *dma_rg);
94774 +uint32_t fman_get_dma_err_event(struct fman_dma_regs *dma_rg);
94775 +uint32_t fman_get_fpm_err_event(struct fman_fpm_regs *fpm_rg);
94776 +uint32_t fman_get_muram_err_event(struct fman_fpm_regs *fpm_rg);
94777 +uint32_t fman_get_iram_err_event(struct fman_fpm_regs *fpm_rg);
94778 +uint32_t fman_get_qmi_event(struct fman_qmi_regs *qmi_rg);
94779 +uint32_t fman_get_fpm_error_interrupts(struct fman_fpm_regs *fpm_rg);
94780 +uint32_t fman_get_ctrl_intr(struct fman_fpm_regs *fpm_rg,
94781 + uint8_t event_reg_id);
94782 +uint8_t fman_get_qmi_deq_th(struct fman_qmi_regs *qmi_rg);
94783 +uint8_t fman_get_qmi_enq_th(struct fman_qmi_regs *qmi_rg);
94784 +uint16_t fman_get_size_of_fifo(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
94785 +uint32_t fman_get_total_fifo_size(struct fman_bmi_regs *bmi_rg);
94786 +uint16_t fman_get_size_of_extra_fifo(struct fman_bmi_regs *bmi_rg,
94787 + uint8_t port_id);
94788 +uint8_t fman_get_num_of_tasks(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
94789 +uint8_t fman_get_num_extra_tasks(struct fman_bmi_regs *bmi_rg,
94790 + uint8_t port_id);
94791 +uint8_t fman_get_num_of_dmas(struct fman_bmi_regs *bmi_rg, uint8_t port_id);
94792 +uint8_t fman_get_num_extra_dmas(struct fman_bmi_regs *bmi_rg,
94793 + uint8_t port_id);
94794 +uint32_t fman_get_normal_pending(struct fman_fpm_regs *fpm_rg);
94795 +uint32_t fman_get_controller_event(struct fman_fpm_regs *fpm_rg,
94796 + uint8_t reg_id);
94797 +uint32_t fman_get_error_pending(struct fman_fpm_regs *fpm_rg);
94798 +void fman_get_revision(struct fman_fpm_regs *fpm_rg, uint8_t *major,
94799 + uint8_t *minor);
94800 +uint32_t fman_get_counter(struct fman_rg *fman_rg,
94801 + enum fman_counters reg_name);
94802 +uint32_t fman_get_dma_status(struct fman_dma_regs *dma_rg);
94803 +
94804 +
94805 +int fman_set_erratum_10gmac_a004_wa(struct fman_fpm_regs *fpm_rg);
94806 +void fman_set_ctrl_intr(struct fman_fpm_regs *fpm_rg, uint8_t event_reg_id,
94807 + uint32_t enable_events);
94808 +void fman_set_num_of_riscs_per_port(struct fman_fpm_regs *fpm_rg,
94809 + uint8_t port_id,
94810 + uint8_t num_fman_ctrls,
94811 + uint32_t or_fman_ctrl);
94812 +void fman_set_order_restoration_per_port(struct fman_fpm_regs *fpm_rg,
94813 + uint8_t port_id,
94814 + bool independent_mode,
94815 + bool is_rx_port);
94816 +void fman_set_qmi_enq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
94817 +void fman_set_qmi_deq_th(struct fman_qmi_regs *qmi_rg, uint8_t val);
94818 +void fman_set_liodn_per_port(struct fman_rg *fman_rg,
94819 + uint8_t port_id,
94820 + uint16_t liodn_base,
94821 + uint16_t liodn_offset);
94822 +void fman_set_size_of_fifo(struct fman_bmi_regs *bmi_rg,
94823 + uint8_t port_id,
94824 + uint32_t size_of_fifo,
94825 + uint32_t extra_size_of_fifo);
94826 +void fman_set_num_of_tasks(struct fman_bmi_regs *bmi_rg,
94827 + uint8_t port_id,
94828 + uint8_t num_of_tasks,
94829 + uint8_t num_of_extra_tasks);
94830 +void fman_set_num_of_open_dmas(struct fman_bmi_regs *bmi_rg,
94831 + uint8_t port_id,
94832 + uint8_t num_of_open_dmas,
94833 + uint8_t num_of_extra_open_dmas,
94834 + uint8_t total_num_of_dmas);
94835 +void fman_set_ports_bandwidth(struct fman_bmi_regs *bmi_rg, uint8_t *weights);
94836 +int fman_set_exception(struct fman_rg *fman_rg,
94837 + enum fman_exceptions exception,
94838 + bool enable);
94839 +void fman_set_dma_emergency(struct fman_dma_regs *dma_rg, bool is_write,
94840 + bool enable);
94841 +void fman_set_dma_ext_bus_pri(struct fman_dma_regs *dma_rg, uint32_t pri);
94842 +void fman_set_congestion_group_pfc_priority(uint32_t *cpg_rg,
94843 + uint32_t congestion_group_id,
94844 + uint8_t piority_bit_map,
94845 + uint32_t reg_num);
94846 +
94847 +
94848 +void fman_defconfig(struct fman_cfg *cfg, bool is_master);
94849 +void fman_regconfig(struct fman_rg *fman_rg, struct fman_cfg *cfg);
94850 +int fman_fpm_init(struct fman_fpm_regs *fpm_rg, struct fman_cfg *cfg);
94851 +int fman_bmi_init(struct fman_bmi_regs *bmi_rg, struct fman_cfg *cfg);
94852 +int fman_qmi_init(struct fman_qmi_regs *qmi_rg, struct fman_cfg *cfg);
94853 +int fman_dma_init(struct fman_dma_regs *dma_rg, struct fman_cfg *cfg);
94854 +void fman_free_resources(struct fman_rg *fman_rg);
94855 +int fman_enable(struct fman_rg *fman_rg, struct fman_cfg *cfg);
94856 +void fman_reset(struct fman_fpm_regs *fpm_rg);
94857 +void fman_resume(struct fman_fpm_regs *fpm_rg);
94858 +
94859 +
94860 +void fman_enable_time_stamp(struct fman_fpm_regs *fpm_rg,
94861 + uint8_t count1ubit,
94862 + uint16_t fm_clk_freq);
94863 +void fman_enable_rams_ecc(struct fman_fpm_regs *fpm_rg);
94864 +void fman_qmi_disable_dispatch_limit(struct fman_fpm_regs *fpm_rg);
94865 +void fman_disable_rams_ecc(struct fman_fpm_regs *fpm_rg);
94866 +void fman_resume_stalled_port(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
94867 +int fman_reset_mac(struct fman_fpm_regs *fpm_rg, uint8_t macId, bool is_10g);
94868 +bool fman_is_port_stalled(struct fman_fpm_regs *fpm_rg, uint8_t port_id);
94869 +bool fman_rams_ecc_is_external_ctl(struct fman_fpm_regs *fpm_rg);
94870 +bool fman_is_qmi_halt_not_busy_state(struct fman_qmi_regs *qmi_rg);
94871 +int fman_modify_counter(struct fman_rg *fman_rg,
94872 + enum fman_counters reg_name,
94873 + uint32_t val);
94874 +void fman_force_intr(struct fman_rg *fman_rg,
94875 + enum fman_exceptions exception);
94876 +void fman_set_vsp_window(struct fman_bmi_regs *bmi_rg,
94877 + uint8_t port_id,
94878 + uint8_t base_storage_profile,
94879 + uint8_t log2_num_of_profiles);
94880 +
94881 +/**************************************************************************//**
94882 + @Description default values
94883 +*//***************************************************************************/
94884 +#define DEFAULT_CATASTROPHIC_ERR E_FMAN_CATAST_ERR_STALL_PORT
94885 +#define DEFAULT_DMA_ERR E_FMAN_DMA_ERR_CATASTROPHIC
94886 +#define DEFAULT_HALT_ON_EXTERNAL_ACTIVATION FALSE /* do not change! if changed, must be disabled for rev1 ! */
94887 +#define DEFAULT_HALT_ON_UNRECOVERABLE_ECC_ERROR FALSE /* do not change! if changed, must be disabled for rev1 ! */
94888 +#define DEFAULT_EXTERNAL_ECC_RAMS_ENABLE FALSE
94889 +#define DEFAULT_AID_OVERRIDE FALSE
94890 +#define DEFAULT_AID_MODE E_FMAN_DMA_AID_OUT_TNUM
94891 +#define DEFAULT_DMA_COMM_Q_LOW 0x2A
94892 +#define DEFAULT_DMA_COMM_Q_HIGH 0x3F
94893 +#define DEFAULT_CACHE_OVERRIDE E_FMAN_DMA_NO_CACHE_OR
94894 +#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES 64
94895 +#define DEFAULT_DMA_DBG_CNT_MODE E_FMAN_DMA_DBG_NO_CNT
94896 +#define DEFAULT_DMA_EN_EMERGENCY FALSE
94897 +#define DEFAULT_DMA_SOS_EMERGENCY 0
94898 +#define DEFAULT_DMA_WATCHDOG 0 /* disabled */
94899 +#define DEFAULT_DMA_EN_EMERGENCY_SMOOTHER FALSE
94900 +#define DEFAULT_DMA_EMERGENCY_SWITCH_COUNTER 0
94901 +#define DEFAULT_DISP_LIMIT 0
94902 +#define DEFAULT_PRS_DISP_TH 16
94903 +#define DEFAULT_PLCR_DISP_TH 16
94904 +#define DEFAULT_KG_DISP_TH 16
94905 +#define DEFAULT_BMI_DISP_TH 16
94906 +#define DEFAULT_QMI_ENQ_DISP_TH 16
94907 +#define DEFAULT_QMI_DEQ_DISP_TH 16
94908 +#define DEFAULT_FM_CTL1_DISP_TH 16
94909 +#define DEFAULT_FM_CTL2_DISP_TH 16
94910 +#define DEFAULT_TNUM_AGING_PERIOD 4
94911 +
94912 +
94913 +#endif /* __FSL_FMAN_H */
94914 --- /dev/null
94915 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec.h
94916 @@ -0,0 +1,1096 @@
94917 +/*
94918 + * Copyright 2008-2012 Freescale Semiconductor Inc.
94919 + *
94920 + * Redistribution and use in source and binary forms, with or without
94921 + * modification, are permitted provided that the following conditions are met:
94922 + * * Redistributions of source code must retain the above copyright
94923 + * notice, this list of conditions and the following disclaimer.
94924 + * * Redistributions in binary form must reproduce the above copyright
94925 + * notice, this list of conditions and the following disclaimer in the
94926 + * documentation and/or other materials provided with the distribution.
94927 + * * Neither the name of Freescale Semiconductor nor the
94928 + * names of its contributors may be used to endorse or promote products
94929 + * derived from this software without specific prior written permission.
94930 + *
94931 + *
94932 + * ALTERNATIVELY, this software may be distributed under the terms of the
94933 + * GNU General Public License ("GPL") as published by the Free Software
94934 + * Foundation, either version 2 of that License or (at your option) any
94935 + * later version.
94936 + *
94937 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
94938 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
94939 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
94940 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
94941 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94942 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
94943 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
94944 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
94945 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
94946 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
94947 + */
94948 +
94949 +#ifndef __FSL_FMAN_DTSEC_H
94950 +#define __FSL_FMAN_DTSEC_H
94951 +
94952 +#include "common/general.h"
94953 +#include "fsl_enet.h"
94954 +
94955 +/**
94956 + * DOC: dTSEC Init sequence
94957 + *
94958 + * To prepare dTSEC block for transfer use the following call sequence:
94959 + *
94960 + * - fman_dtsec_defconfig() - This step is optional and yet recommended. Its
94961 + * use is to obtain the default dTSEC configuration parameters.
94962 + *
94963 + * - Change dtsec configuration in &dtsec_cfg. This structure will be used
94964 + * to customize the dTSEC behavior.
94965 + *
94966 + * - fman_dtsec_init() - Applies the configuration on dTSEC hardware. Note that
94967 + * dTSEC is initialized while both Tx and Rx are disabled.
94968 + *
94969 + * - fman_dtsec_set_mac_address() - Set the station address (mac address).
94970 + * This is used by dTSEC to match against received packets.
94971 + *
94972 + * - fman_dtsec_adjust_link() - Set the link speed and duplex parameters
94973 + * after the PHY establishes the link.
94974 + *
94975 + * - dtsec_enable_tx() and dtsec_enable_rx() to enable transmission and
94976 + * reception.
94977 + */
94978 +
94979 +/**
94980 + * DOC: dTSEC Graceful stop
94981 + *
94982 + * To temporary stop dTSEC activity use fman_dtsec_stop_tx() and
94983 + * fman_dtsec_stop_rx(). Note that these functions request dTSEC graceful stop
94984 + * but return before this stop is complete. To query for graceful stop
94985 + * completion use fman_dtsec_get_event() and check DTSEC_IEVENT_GTSC and
94986 + * DTSEC_IEVENT_GRSC bits. Alternatively the dTSEC interrupt mask can be set to
94987 + * enable graceful stop interrupts.
94988 + *
94989 + * To resume operation after graceful stop use fman_dtsec_start_tx() and
94990 + * fman_dtsec_start_rx().
94991 + */
94992 +
94993 +/**
94994 + * DOC: dTSEC interrupt handling
94995 + *
94996 + * This code does not provide an interrupt handler for dTSEC. Instead this
94997 + * handler should be implemented and registered to the operating system by the
94998 + * caller. Some primitives for accessing the event status and mask registers
94999 + * are provided.
95000 + *
95001 + * See "dTSEC Events" section for a list of events that dTSEC can generate.
95002 + */
95003 +
95004 +/**
95005 + * DOC: dTSEC Events
95006 + *
95007 + * Interrupt events cause dTSEC event bits to be set. Software may poll the
95008 + * event register at any time to check for pending interrupts. If an event
95009 + * occurs and its corresponding enable bit is set in the interrupt mask
95010 + * register, the event also causes a hardware interrupt at the PIC.
95011 + *
95012 + * To poll for event status use the fman_dtsec_get_event() function.
95013 + * To configure the interrupt mask use fman_dtsec_enable_interrupt() and
95014 + * fman_dtsec_disable_interrupt() functions.
95015 + * After servicing a dTSEC interrupt use fman_dtsec_ack_event to reset the
95016 + * serviced event bit.
95017 + *
95018 + * The following events may be signaled by dTSEC hardware:
95019 + *
95020 + * %DTSEC_IEVENT_BABR - Babbling receive error. This bit indicates that
95021 + * a frame was received with length in excess of the MAC's maximum frame length
95022 + * register.
95023 + *
95024 + * %DTSEC_IEVENT_RXC - Receive control (pause frame) interrupt. A pause
95025 + * control frame was received while Rx pause frame handling is enabled.
95026 + * Also see fman_dtsec_handle_rx_pause().
95027 + *
95028 + * %DTSEC_IEVENT_MSRO - MIB counter overflow. The count for one of the MIB
95029 + * counters has exceeded the size of its register.
95030 + *
95031 + * %DTSEC_IEVENT_GTSC - Graceful transmit stop complete. Graceful stop is now
95032 + * complete. The transmitter is in a stopped state, in which only pause frames
95033 + * can be transmitted.
95034 + * Also see fman_dtsec_stop_tx().
95035 + *
95036 + * %DTSEC_IEVENT_BABT - Babbling transmit error. The transmitted frame length
95037 + * has exceeded the value in the MAC's Maximum Frame Length register.
95038 + *
95039 + * %DTSEC_IEVENT_TXC - Transmit control (pause frame) interrupt. his bit
95040 + * indicates that a control frame was transmitted.
95041 + *
95042 + * %DTSEC_IEVENT_TXE - Transmit error. This bit indicates that an error
95043 + * occurred on the transmitted channel. This bit is set whenever any transmit
95044 + * error occurs which causes the dTSEC to discard all or part of a frame
95045 + * (LC, CRL, XFUN).
95046 + *
95047 + * %DTSEC_IEVENT_LC - Late collision. This bit indicates that a collision
95048 + * occurred beyond the collision window (slot time) in half-duplex mode.
95049 + * The frame is truncated with a bad CRC and the remainder of the frame
95050 + * is discarded.
95051 + *
95052 + * %DTSEC_IEVENT_CRL - Collision retry limit. is bit indicates that the number
95053 + * of successive transmission collisions has exceeded the MAC's half-duplex
95054 + * register's retransmission maximum count. The frame is discarded without
95055 + * being transmitted and transmission of the next frame commences. This only
95056 + * occurs while in half-duplex mode.
95057 + * The number of retransmit attempts can be set in
95058 + * &dtsec_halfdup_cfg.@retransmit before calling fman_dtsec_init().
95059 + *
95060 + * %DTSEC_IEVENT_XFUN - Transmit FIFO underrun. This bit indicates that the
95061 + * transmit FIFO became empty before the complete frame was transmitted.
95062 + * The frame is truncated with a bad CRC and the remainder of the frame is
95063 + * discarded.
95064 + *
95065 + * %DTSEC_IEVENT_MAG - TBD
95066 + *
95067 + * %DTSEC_IEVENT_MMRD - MII management read completion.
95068 + *
95069 + * %DTSEC_IEVENT_MMWR - MII management write completion.
95070 + *
95071 + * %DTSEC_IEVENT_GRSC - Graceful receive stop complete. It allows the user to
95072 + * know if the system has completed the stop and it is safe to write to receive
95073 + * registers (status, control or configuration registers) that are used by the
95074 + * system during normal operation.
95075 + *
95076 + * %DTSEC_IEVENT_TDPE - Internal data error on transmit. This bit indicates
95077 + * that the dTSEC has detected a parity error on its stored transmit data, which
95078 + * is likely to compromise the validity of recently transferred frames.
95079 + *
95080 + * %DTSEC_IEVENT_RDPE - Internal data error on receive. This bit indicates that
95081 + * the dTSEC has detected a parity error on its stored receive data, which is
95082 + * likely to compromise the validity of recently transferred frames.
95083 + */
95084 +/* Interrupt Mask Register (IMASK) */
95085 +#define DTSEC_IMASK_BREN 0x80000000
95086 +#define DTSEC_IMASK_RXCEN 0x40000000
95087 +#define DTSEC_IMASK_MSROEN 0x04000000
95088 +#define DTSEC_IMASK_GTSCEN 0x02000000
95089 +#define DTSEC_IMASK_BTEN 0x01000000
95090 +#define DTSEC_IMASK_TXCEN 0x00800000
95091 +#define DTSEC_IMASK_TXEEN 0x00400000
95092 +#define DTSEC_IMASK_LCEN 0x00040000
95093 +#define DTSEC_IMASK_CRLEN 0x00020000
95094 +#define DTSEC_IMASK_XFUNEN 0x00010000
95095 +#define DTSEC_IMASK_ABRTEN 0x00008000
95096 +#define DTSEC_IMASK_IFERREN 0x00004000
95097 +#define DTSEC_IMASK_MAGEN 0x00000800
95098 +#define DTSEC_IMASK_MMRDEN 0x00000400
95099 +#define DTSEC_IMASK_MMWREN 0x00000200
95100 +#define DTSEC_IMASK_GRSCEN 0x00000100
95101 +#define DTSEC_IMASK_TDPEEN 0x00000002
95102 +#define DTSEC_IMASK_RDPEEN 0x00000001
95103 +
95104 +#define DTSEC_EVENTS_MASK \
95105 + ((uint32_t)(DTSEC_IMASK_BREN | \
95106 + DTSEC_IMASK_RXCEN | \
95107 + DTSEC_IMASK_BTEN | \
95108 + DTSEC_IMASK_TXCEN | \
95109 + DTSEC_IMASK_TXEEN | \
95110 + DTSEC_IMASK_ABRTEN | \
95111 + DTSEC_IMASK_LCEN | \
95112 + DTSEC_IMASK_CRLEN | \
95113 + DTSEC_IMASK_XFUNEN | \
95114 + DTSEC_IMASK_IFERREN | \
95115 + DTSEC_IMASK_MAGEN | \
95116 + DTSEC_IMASK_TDPEEN | \
95117 + DTSEC_IMASK_RDPEEN))
95118 +
95119 +/* dtsec timestamp event bits */
95120 +#define TMR_PEMASK_TSREEN 0x00010000
95121 +#define TMR_PEVENT_TSRE 0x00010000
95122 +
95123 +/* Group address bit indication */
95124 +#define MAC_GROUP_ADDRESS 0x0000010000000000ULL
95125 +/* size in bytes of L2 address */
95126 +#define MAC_ADDRLEN 6
95127 +
95128 +#define DEFAULT_HALFDUP_ON FALSE
95129 +#define DEFAULT_HALFDUP_RETRANSMIT 0xf
95130 +#define DEFAULT_HALFDUP_COLL_WINDOW 0x37
95131 +#define DEFAULT_HALFDUP_EXCESS_DEFER TRUE
95132 +#define DEFAULT_HALFDUP_NO_BACKOFF FALSE
95133 +#define DEFAULT_HALFDUP_BP_NO_BACKOFF FALSE
95134 +#define DEFAULT_HALFDUP_ALT_BACKOFF_VAL 0x0A
95135 +#define DEFAULT_HALFDUP_ALT_BACKOFF_EN FALSE
95136 +#define DEFAULT_RX_DROP_BCAST FALSE
95137 +#define DEFAULT_RX_SHORT_FRM TRUE
95138 +#define DEFAULT_RX_LEN_CHECK FALSE
95139 +#define DEFAULT_TX_PAD_CRC TRUE
95140 +#define DEFAULT_TX_CRC FALSE
95141 +#define DEFAULT_RX_CTRL_ACC FALSE
95142 +#define DEFAULT_TX_PAUSE_TIME 0xf000
95143 +#define DEFAULT_TBIPA 5
95144 +#define DEFAULT_RX_PREPEND 0
95145 +#define DEFAULT_PTP_TSU_EN TRUE
95146 +#define DEFAULT_PTP_EXCEPTION_EN TRUE
95147 +#define DEFAULT_PREAMBLE_LEN 7
95148 +#define DEFAULT_RX_PREAMBLE FALSE
95149 +#define DEFAULT_TX_PREAMBLE FALSE
95150 +#define DEFAULT_LOOPBACK FALSE
95151 +#define DEFAULT_RX_TIME_STAMP_EN FALSE
95152 +#define DEFAULT_TX_TIME_STAMP_EN FALSE
95153 +#define DEFAULT_RX_FLOW TRUE
95154 +#define DEFAULT_TX_FLOW TRUE
95155 +#define DEFAULT_RX_GROUP_HASH_EXD FALSE
95156 +#define DEFAULT_TX_PAUSE_TIME_EXTD 0
95157 +#define DEFAULT_RX_PROMISC FALSE
95158 +#define DEFAULT_NON_BACK_TO_BACK_IPG1 0x40
95159 +#define DEFAULT_NON_BACK_TO_BACK_IPG2 0x60
95160 +#define DEFAULT_MIN_IFG_ENFORCEMENT 0x50
95161 +#define DEFAULT_BACK_TO_BACK_IPG 0x60
95162 +#define DEFAULT_MAXIMUM_FRAME 0x600
95163 +#define DEFAULT_TBI_PHY_ADDR 5
95164 +#define DEFAULT_WAKE_ON_LAN FALSE
95165 +
95166 +/* register related defines (bits, field offsets..) */
95167 +#define DTSEC_ID1_ID 0xffff0000
95168 +#define DTSEC_ID1_REV_MJ 0x0000FF00
95169 +#define DTSEC_ID1_REV_MN 0x000000ff
95170 +
95171 +#define DTSEC_ID2_INT_REDUCED_OFF 0x00010000
95172 +#define DTSEC_ID2_INT_NORMAL_OFF 0x00020000
95173 +
95174 +#define DTSEC_ECNTRL_CLRCNT 0x00004000
95175 +#define DTSEC_ECNTRL_AUTOZ 0x00002000
95176 +#define DTSEC_ECNTRL_STEN 0x00001000
95177 +#define DTSEC_ECNTRL_CFG_RO 0x80000000
95178 +#define DTSEC_ECNTRL_GMIIM 0x00000040
95179 +#define DTSEC_ECNTRL_TBIM 0x00000020
95180 +#define DTSEC_ECNTRL_SGMIIM 0x00000002
95181 +#define DTSEC_ECNTRL_RPM 0x00000010
95182 +#define DTSEC_ECNTRL_R100M 0x00000008
95183 +#define DTSEC_ECNTRL_RMM 0x00000004
95184 +#define DTSEC_ECNTRL_QSGMIIM 0x00000001
95185 +
95186 +#define DTSEC_TCTRL_THDF 0x00000800
95187 +#define DTSEC_TCTRL_TTSE 0x00000040
95188 +#define DTSEC_TCTRL_GTS 0x00000020
95189 +#define DTSEC_TCTRL_TFC_PAUSE 0x00000010
95190 +
95191 +/* PTV offsets */
95192 +#define PTV_PTE_OFST 16
95193 +
95194 +#define RCTRL_CFA 0x00008000
95195 +#define RCTRL_GHTX 0x00000400
95196 +#define RCTRL_RTSE 0x00000040
95197 +#define RCTRL_GRS 0x00000020
95198 +#define RCTRL_BC_REJ 0x00000010
95199 +#define RCTRL_MPROM 0x00000008
95200 +#define RCTRL_RSF 0x00000004
95201 +#define RCTRL_UPROM 0x00000001
95202 +#define RCTRL_PROM (RCTRL_UPROM | RCTRL_MPROM)
95203 +
95204 +#define TMR_CTL_ESFDP 0x00000800
95205 +#define TMR_CTL_ESFDE 0x00000400
95206 +
95207 +#define MACCFG1_SOFT_RESET 0x80000000
95208 +#define MACCFG1_LOOPBACK 0x00000100
95209 +#define MACCFG1_RX_FLOW 0x00000020
95210 +#define MACCFG1_TX_FLOW 0x00000010
95211 +#define MACCFG1_TX_EN 0x00000001
95212 +#define MACCFG1_RX_EN 0x00000004
95213 +#define MACCFG1_RESET_RxMC 0x00080000
95214 +#define MACCFG1_RESET_TxMC 0x00040000
95215 +#define MACCFG1_RESET_RxFUN 0x00020000
95216 +#define MACCFG1_RESET_TxFUN 0x00010000
95217 +
95218 +#define MACCFG2_NIBBLE_MODE 0x00000100
95219 +#define MACCFG2_BYTE_MODE 0x00000200
95220 +#define MACCFG2_PRE_AM_Rx_EN 0x00000080
95221 +#define MACCFG2_PRE_AM_Tx_EN 0x00000040
95222 +#define MACCFG2_LENGTH_CHECK 0x00000010
95223 +#define MACCFG2_MAGIC_PACKET_EN 0x00000008
95224 +#define MACCFG2_PAD_CRC_EN 0x00000004
95225 +#define MACCFG2_CRC_EN 0x00000002
95226 +#define MACCFG2_FULL_DUPLEX 0x00000001
95227 +
95228 +#define PREAMBLE_LENGTH_SHIFT 12
95229 +
95230 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT 24
95231 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT 16
95232 +#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT 8
95233 +
95234 +#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
95235 +#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
95236 +#define IPGIFG_MIN_IFG_ENFORCEMENT 0x0000FF00
95237 +#define IPGIFG_BACK_TO_BACK_IPG 0x0000007F
95238 +
95239 +#define HAFDUP_ALT_BEB 0x00080000
95240 +#define HAFDUP_BP_NO_BACKOFF 0x00040000
95241 +#define HAFDUP_NO_BACKOFF 0x00020000
95242 +#define HAFDUP_EXCESS_DEFER 0x00010000
95243 +#define HAFDUP_COLLISION_WINDOW 0x000003ff
95244 +
95245 +#define HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT 20
95246 +#define HAFDUP_RETRANSMISSION_MAX_SHIFT 12
95247 +#define HAFDUP_RETRANSMISSION_MAX 0x0000f000
95248 +
95249 +#define NUM_OF_HASH_REGS 8 /* Number of hash table registers */
95250 +
95251 +/* CAR1/2 bits */
95252 +#define DTSEC_CAR1_TR64 0x80000000
95253 +#define DTSEC_CAR1_TR127 0x40000000
95254 +#define DTSEC_CAR1_TR255 0x20000000
95255 +#define DTSEC_CAR1_TR511 0x10000000
95256 +#define DTSEC_CAR1_TRK1 0x08000000
95257 +#define DTSEC_CAR1_TRMAX 0x04000000
95258 +#define DTSEC_CAR1_TRMGV 0x02000000
95259 +
95260 +#define DTSEC_CAR1_RBYT 0x00010000
95261 +#define DTSEC_CAR1_RPKT 0x00008000
95262 +#define DTSEC_CAR1_RFCS 0x00004000
95263 +#define DTSEC_CAR1_RMCA 0x00002000
95264 +#define DTSEC_CAR1_RBCA 0x00001000
95265 +#define DTSEC_CAR1_RXCF 0x00000800
95266 +#define DTSEC_CAR1_RXPF 0x00000400
95267 +#define DTSEC_CAR1_RXUO 0x00000200
95268 +#define DTSEC_CAR1_RALN 0x00000100
95269 +#define DTSEC_CAR1_RFLR 0x00000080
95270 +#define DTSEC_CAR1_RCDE 0x00000040
95271 +#define DTSEC_CAR1_RCSE 0x00000020
95272 +#define DTSEC_CAR1_RUND 0x00000010
95273 +#define DTSEC_CAR1_ROVR 0x00000008
95274 +#define DTSEC_CAR1_RFRG 0x00000004
95275 +#define DTSEC_CAR1_RJBR 0x00000002
95276 +#define DTSEC_CAR1_RDRP 0x00000001
95277 +
95278 +#define DTSEC_CAR2_TJBR 0x00080000
95279 +#define DTSEC_CAR2_TFCS 0x00040000
95280 +#define DTSEC_CAR2_TXCF 0x00020000
95281 +#define DTSEC_CAR2_TOVR 0x00010000
95282 +#define DTSEC_CAR2_TUND 0x00008000
95283 +#define DTSEC_CAR2_TFRG 0x00004000
95284 +#define DTSEC_CAR2_TBYT 0x00002000
95285 +#define DTSEC_CAR2_TPKT 0x00001000
95286 +#define DTSEC_CAR2_TMCA 0x00000800
95287 +#define DTSEC_CAR2_TBCA 0x00000400
95288 +#define DTSEC_CAR2_TXPF 0x00000200
95289 +#define DTSEC_CAR2_TDFR 0x00000100
95290 +#define DTSEC_CAR2_TEDF 0x00000080
95291 +#define DTSEC_CAR2_TSCL 0x00000040
95292 +#define DTSEC_CAR2_TMCL 0x00000020
95293 +#define DTSEC_CAR2_TLCL 0x00000010
95294 +#define DTSEC_CAR2_TXCL 0x00000008
95295 +#define DTSEC_CAR2_TNCL 0x00000004
95296 +#define DTSEC_CAR2_TDRP 0x00000001
95297 +
95298 +#define CAM1_ERRORS_ONLY \
95299 + (DTSEC_CAR1_RXPF | DTSEC_CAR1_RALN | DTSEC_CAR1_RFLR \
95300 + | DTSEC_CAR1_RCDE | DTSEC_CAR1_RCSE | DTSEC_CAR1_RUND \
95301 + | DTSEC_CAR1_ROVR | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
95302 + | DTSEC_CAR1_RDRP)
95303 +
95304 +#define CAM2_ERRORS_ONLY (DTSEC_CAR2_TFCS | DTSEC_CAR2_TXPF | DTSEC_CAR2_TDRP)
95305 +
95306 +/*
95307 + * Group of dTSEC specific counters relating to the standard RMON MIB Group 1
95308 + * (or Ethernet) statistics.
95309 + */
95310 +#define CAM1_MIB_GRP_1 \
95311 + (DTSEC_CAR1_RDRP | DTSEC_CAR1_RBYT | DTSEC_CAR1_RPKT | DTSEC_CAR1_RMCA\
95312 + | DTSEC_CAR1_RBCA | DTSEC_CAR1_RALN | DTSEC_CAR1_RUND | DTSEC_CAR1_ROVR\
95313 + | DTSEC_CAR1_RFRG | DTSEC_CAR1_RJBR \
95314 + | DTSEC_CAR1_TR64 | DTSEC_CAR1_TR127 | DTSEC_CAR1_TR255 \
95315 + | DTSEC_CAR1_TR511 | DTSEC_CAR1_TRMAX)
95316 +
95317 +#define CAM2_MIB_GRP_1 (DTSEC_CAR2_TNCL | DTSEC_CAR2_TDRP)
95318 +
95319 +/* memory map */
95320 +
95321 +struct dtsec_regs {
95322 + /* dTSEC General Control and Status Registers */
95323 + uint32_t tsec_id; /* 0x000 ETSEC_ID register */
95324 + uint32_t tsec_id2; /* 0x004 ETSEC_ID2 register */
95325 + uint32_t ievent; /* 0x008 Interrupt event register */
95326 + uint32_t imask; /* 0x00C Interrupt mask register */
95327 + uint32_t reserved0010[1];
95328 + uint32_t ecntrl; /* 0x014 E control register */
95329 + uint32_t ptv; /* 0x018 Pause time value register */
95330 + uint32_t tbipa; /* 0x01C TBI PHY address register */
95331 + uint32_t tmr_ctrl; /* 0x020 Time-stamp Control register */
95332 + uint32_t tmr_pevent; /* 0x024 Time-stamp event register */
95333 + uint32_t tmr_pemask; /* 0x028 Timer event mask register */
95334 + uint32_t reserved002c[5];
95335 + uint32_t tctrl; /* 0x040 Transmit control register */
95336 + uint32_t reserved0044[3];
95337 + uint32_t rctrl; /* 0x050 Receive control register */
95338 + uint32_t reserved0054[11];
95339 + uint32_t igaddr[8]; /* 0x080-0x09C Individual/group address */
95340 + uint32_t gaddr[8]; /* 0x0A0-0x0BC Group address registers 0-7 */
95341 + uint32_t reserved00c0[16];
95342 + uint32_t maccfg1; /* 0x100 MAC configuration #1 */
95343 + uint32_t maccfg2; /* 0x104 MAC configuration #2 */
95344 + uint32_t ipgifg; /* 0x108 IPG/IFG */
95345 + uint32_t hafdup; /* 0x10C Half-duplex */
95346 + uint32_t maxfrm; /* 0x110 Maximum frame */
95347 + uint32_t reserved0114[10];
95348 + uint32_t ifstat; /* 0x13C Interface status */
95349 + uint32_t macstnaddr1; /* 0x140 Station Address,part 1 */
95350 + uint32_t macstnaddr2; /* 0x144 Station Address,part 2 */
95351 + struct {
95352 + uint32_t exact_match1; /* octets 1-4 */
95353 + uint32_t exact_match2; /* octets 5-6 */
95354 + } macaddr[15]; /* 0x148-0x1BC mac exact match addresses 1-15 */
95355 + uint32_t reserved01c0[16];
95356 + uint32_t tr64; /* 0x200 transmit and receive 64 byte frame counter */
95357 + uint32_t tr127; /* 0x204 transmit and receive 65 to 127 byte frame
95358 + * counter */
95359 + uint32_t tr255; /* 0x208 transmit and receive 128 to 255 byte frame
95360 + * counter */
95361 + uint32_t tr511; /* 0x20C transmit and receive 256 to 511 byte frame
95362 + * counter */
95363 + uint32_t tr1k; /* 0x210 transmit and receive 512 to 1023 byte frame
95364 + * counter */
95365 + uint32_t trmax; /* 0x214 transmit and receive 1024 to 1518 byte frame
95366 + * counter */
95367 + uint32_t trmgv; /* 0x218 transmit and receive 1519 to 1522 byte good
95368 + * VLAN frame count */
95369 + uint32_t rbyt; /* 0x21C receive byte counter */
95370 + uint32_t rpkt; /* 0x220 receive packet counter */
95371 + uint32_t rfcs; /* 0x224 receive FCS error counter */
95372 + uint32_t rmca; /* 0x228 RMCA receive multicast packet counter */
95373 + uint32_t rbca; /* 0x22C receive broadcast packet counter */
95374 + uint32_t rxcf; /* 0x230 receive control frame packet counter */
95375 + uint32_t rxpf; /* 0x234 receive pause frame packet counter */
95376 + uint32_t rxuo; /* 0x238 receive unknown OP code counter */
95377 + uint32_t raln; /* 0x23C receive alignment error counter */
95378 + uint32_t rflr; /* 0x240 receive frame length error counter */
95379 + uint32_t rcde; /* 0x244 receive code error counter */
95380 + uint32_t rcse; /* 0x248 receive carrier sense error counter */
95381 + uint32_t rund; /* 0x24C receive undersize packet counter */
95382 + uint32_t rovr; /* 0x250 receive oversize packet counter */
95383 + uint32_t rfrg; /* 0x254 receive fragments counter */
95384 + uint32_t rjbr; /* 0x258 receive jabber counter */
95385 + uint32_t rdrp; /* 0x25C receive drop */
95386 + uint32_t tbyt; /* 0x260 transmit byte counter */
95387 + uint32_t tpkt; /* 0x264 transmit packet counter */
95388 + uint32_t tmca; /* 0x268 transmit multicast packet counter */
95389 + uint32_t tbca; /* 0x26C transmit broadcast packet counter */
95390 + uint32_t txpf; /* 0x270 transmit pause control frame counter */
95391 + uint32_t tdfr; /* 0x274 transmit deferral packet counter */
95392 + uint32_t tedf; /* 0x278 transmit excessive deferral packet counter */
95393 + uint32_t tscl; /* 0x27C transmit single collision packet counter */
95394 + uint32_t tmcl; /* 0x280 transmit multiple collision packet counter */
95395 + uint32_t tlcl; /* 0x284 transmit late collision packet counter */
95396 + uint32_t txcl; /* 0x288 transmit excessive collision packet counter */
95397 + uint32_t tncl; /* 0x28C transmit total collision counter */
95398 + uint32_t reserved0290[1];
95399 + uint32_t tdrp; /* 0x294 transmit drop frame counter */
95400 + uint32_t tjbr; /* 0x298 transmit jabber frame counter */
95401 + uint32_t tfcs; /* 0x29C transmit FCS error counter */
95402 + uint32_t txcf; /* 0x2A0 transmit control frame counter */
95403 + uint32_t tovr; /* 0x2A4 transmit oversize frame counter */
95404 + uint32_t tund; /* 0x2A8 transmit undersize frame counter */
95405 + uint32_t tfrg; /* 0x2AC transmit fragments frame counter */
95406 + uint32_t car1; /* 0x2B0 carry register one register* */
95407 + uint32_t car2; /* 0x2B4 carry register two register* */
95408 + uint32_t cam1; /* 0x2B8 carry register one mask register */
95409 + uint32_t cam2; /* 0x2BC carry register two mask register */
95410 + uint32_t reserved02c0[848];
95411 +};
95412 +
95413 +/**
95414 + * struct dtsec_mib_grp_1_counters - MIB counter overflows
95415 + *
95416 + * @tr64: Transmit and Receive 64 byte frame count. Increment for each
95417 + * good or bad frame, of any type, transmitted or received, which
95418 + * is 64 bytes in length.
95419 + * @tr127: Transmit and Receive 65 to 127 byte frame count. Increments for
95420 + * each good or bad frame of any type, transmitted or received,
95421 + * which is 65-127 bytes in length.
95422 + * @tr255: Transmit and Receive 128 to 255 byte frame count. Increments
95423 + * for each good or bad frame, of any type, transmitted or
95424 + * received, which is 128-255 bytes in length.
95425 + * @tr511: Transmit and Receive 256 to 511 byte frame count. Increments
95426 + * for each good or bad frame, of any type, transmitted or
95427 + * received, which is 256-511 bytes in length.
95428 + * @tr1k: Transmit and Receive 512 to 1023 byte frame count. Increments
95429 + * for each good or bad frame, of any type, transmitted or
95430 + * received, which is 512-1023 bytes in length.
95431 + * @trmax: Transmit and Receive 1024 to 1518 byte frame count. Increments
95432 + * for each good or bad frame, of any type, transmitted or
95433 + * received, which is 1024-1518 bytes in length.
95434 + * @rfrg: Receive fragments count. Increments for each received frame
95435 + * which is less than 64 bytes in length and contains an invalid
95436 + * FCS. This includes integral and non-integral lengths.
95437 + * @rjbr: Receive jabber count. Increments for received frames which
95438 + * exceed 1518 (non VLAN) or 1522 (VLAN) bytes and contain an
95439 + * invalid FCS. This includes alignment errors.
95440 + * @rdrp: Receive dropped packets count. Increments for received frames
95441 + * which are streamed to system but are later dropped due to lack
95442 + * of system resources. Does not increment for frames rejected due
95443 + * to address filtering.
95444 + * @raln: Receive alignment error count. Increments for each received
95445 + * frame from 64 to 1518 (non VLAN) or 1522 (VLAN) which contains
95446 + * an invalid FCS and is not an integral number of bytes.
95447 + * @rund: Receive undersize packet count. Increments each time a frame is
95448 + * received which is less than 64 bytes in length and contains a
95449 + * valid FCS and is otherwise well formed. This count does not
95450 + * include range length errors.
95451 + * @rovr: Receive oversize packet count. Increments each time a frame is
95452 + * received which exceeded 1518 (non VLAN) or 1522 (VLAN) and
95453 + * contains a valid FCS and is otherwise well formed.
95454 + * @rbyt: Receive byte count. Increments by the byte count of frames
95455 + * received, including those in bad packets, excluding preamble and
95456 + * SFD but including FCS bytes.
95457 + * @rpkt: Receive packet count. Increments for each received frame
95458 + * (including bad packets, all unicast, broadcast, and multicast
95459 + * packets).
95460 + * @rmca: Receive multicast packet count. Increments for each multicast
95461 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
95462 + * 1522 (VLAN), excluding broadcast frames. This count does not
95463 + * include range/length errors.
95464 + * @rbca: Receive broadcast packet count. Increments for each broadcast
95465 + * frame with valid CRC and of lengths 64 to 1518 (non VLAN) or
95466 + * 1522 (VLAN), excluding multicast frames. Does not include
95467 + * range/length errors.
95468 + * @tdrp: Transmit drop frame count. Increments each time a memory error
95469 + * or an underrun has occurred.
95470 + * @tncl: Transmit total collision counter. Increments by the number of
95471 + * collisions experienced during the transmission of a frame. Does
95472 + * not increment for aborted frames.
95473 + *
95474 + * The structure contains a group of dTSEC HW specific counters relating to the
95475 + * standard RMON MIB Group 1 (or Ethernet statistics) counters. This structure
95476 + * is counting only the carry events of the corresponding HW counters.
95477 + *
95478 + * tr64 to trmax notes: Frame sizes specified are considered excluding preamble
95479 + * and SFD but including FCS bytes.
95480 + */
95481 +struct dtsec_mib_grp_1_counters {
95482 + uint64_t rdrp;
95483 + uint64_t tdrp;
95484 + uint64_t rbyt;
95485 + uint64_t rpkt;
95486 + uint64_t rbca;
95487 + uint64_t rmca;
95488 + uint64_t raln;
95489 + uint64_t rund;
95490 + uint64_t rovr;
95491 + uint64_t rfrg;
95492 + uint64_t rjbr;
95493 + uint64_t tncl;
95494 + uint64_t tr64;
95495 + uint64_t tr127;
95496 + uint64_t tr255;
95497 + uint64_t tr511;
95498 + uint64_t tr1k;
95499 + uint64_t trmax;
95500 +};
95501 +
95502 +enum dtsec_stat_counters {
95503 + E_DTSEC_STAT_TR64,
95504 + E_DTSEC_STAT_TR127,
95505 + E_DTSEC_STAT_TR255,
95506 + E_DTSEC_STAT_TR511,
95507 + E_DTSEC_STAT_TR1K,
95508 + E_DTSEC_STAT_TRMAX,
95509 + E_DTSEC_STAT_TRMGV,
95510 + E_DTSEC_STAT_RBYT,
95511 + E_DTSEC_STAT_RPKT,
95512 + E_DTSEC_STAT_RMCA,
95513 + E_DTSEC_STAT_RBCA,
95514 + E_DTSEC_STAT_RXPF,
95515 + E_DTSEC_STAT_RALN,
95516 + E_DTSEC_STAT_RFLR,
95517 + E_DTSEC_STAT_RCDE,
95518 + E_DTSEC_STAT_RCSE,
95519 + E_DTSEC_STAT_RUND,
95520 + E_DTSEC_STAT_ROVR,
95521 + E_DTSEC_STAT_RFRG,
95522 + E_DTSEC_STAT_RJBR,
95523 + E_DTSEC_STAT_RDRP,
95524 + E_DTSEC_STAT_TFCS,
95525 + E_DTSEC_STAT_TBYT,
95526 + E_DTSEC_STAT_TPKT,
95527 + E_DTSEC_STAT_TMCA,
95528 + E_DTSEC_STAT_TBCA,
95529 + E_DTSEC_STAT_TXPF,
95530 + E_DTSEC_STAT_TNCL,
95531 + E_DTSEC_STAT_TDRP
95532 +};
95533 +
95534 +enum dtsec_stat_level {
95535 + /* No statistics */
95536 + E_MAC_STAT_NONE = 0,
95537 + /* Only RMON MIB group 1 (ether stats). Optimized for performance */
95538 + E_MAC_STAT_MIB_GRP1,
95539 + /* Only error counters are available. Optimized for performance */
95540 + E_MAC_STAT_PARTIAL,
95541 + /* All counters available. Not optimized for performance */
95542 + E_MAC_STAT_FULL
95543 +};
95544 +
95545 +
95546 +/**
95547 + * struct dtsec_cfg - dTSEC configuration
95548 + *
95549 + * @halfdup_on: Transmit half-duplex flow control, under software
95550 + * control for 10/100-Mbps half-duplex media. If set,
95551 + * back pressure is applied to media by raising carrier.
95552 + * @halfdup_retransmit: Number of retransmission attempts following a collision.
95553 + * If this is exceeded dTSEC aborts transmission due to
95554 + * excessive collisions. The standard specifies the
95555 + * attempt limit to be 15.
95556 + * @halfdup_coll_window:The number of bytes of the frame during which
95557 + * collisions may occur. The default value of 55
95558 + * corresponds to the frame byte at the end of the
95559 + * standard 512-bit slot time window. If collisions are
95560 + * detected after this byte, the late collision event is
95561 + * asserted and transmission of current frame is aborted.
95562 + * @rx_drop_bcast: Discard broadcast frames. If set, all broadcast frames
95563 + * will be discarded by dTSEC.
95564 + * @rx_short_frm: Accept short frames. If set, dTSEC will accept frames
95565 + * of length 14..63 bytes.
95566 + * @rx_len_check: Length check for received frames. If set, the MAC
95567 + * checks the frame's length field on receive to ensure it
95568 + * matches the actual data field length. This only works
95569 + * for received frames with length field less than 1500.
95570 + * No check is performed for larger frames.
95571 + * @tx_pad_crc: Pad and append CRC. If set, the MAC pads all
95572 + * transmitted short frames and appends a CRC to every
95573 + * frame regardless of padding requirement.
95574 + * @tx_crc: Transmission CRC enable. If set, the MAC appends a CRC
95575 + * to all frames. If frames presented to the MAC have a
95576 + * valid length and contain a valid CRC, @tx_crc should be
95577 + * reset.
95578 + * This field is ignored if @tx_pad_crc is set.
95579 + * @rx_ctrl_acc: Control frame accept. If set, this overrides 802.3
95580 + * standard control frame behavior, and all Ethernet frames
95581 + * that have an ethertype of 0x8808 are treated as normal
95582 + * Ethernet frames and passed up to the packet interface on
95583 + * a DA match. Received pause control frames are passed to
95584 + * the packet interface only if Rx flow control is also
95585 + * disabled. See fman_dtsec_handle_rx_pause() function.
95586 + * @tx_pause_time: Transmit pause time value. This pause value is used as
95587 + * part of the pause frame to be sent when a transmit pause
95588 + * frame is initiated. If set to 0 this disables
95589 + * transmission of pause frames.
95590 + * @rx_preamble: Receive preamble enable. If set, the MAC recovers the
95591 + * received Ethernet 7-byte preamble and passes it to the
95592 + * packet interface at the start of each received frame.
95593 + * This field should be reset for internal MAC loop-back
95594 + * mode.
95595 + * @tx_preamble: User defined preamble enable for transmitted frames.
95596 + * If set, a user-defined preamble must passed to the MAC
95597 + * and it is transmitted instead of the standard preamble.
95598 + * @preamble_len: Length, in bytes, of the preamble field preceding each
95599 + * Ethernet start-of-frame delimiter byte. The default
95600 + * value of 0x7 should be used in order to guarantee
95601 + * reliable operation with IEEE 802.3 compliant hardware.
95602 + * @rx_prepend: Packet alignment padding length. The specified number
95603 + * of bytes (1-31) of zero padding are inserted before the
95604 + * start of each received frame. For Ethernet, where
95605 + * optional preamble extraction is enabled, the padding
95606 + * appears before the preamble, otherwise the padding
95607 + * precedes the layer 2 header.
95608 + *
95609 + * This structure contains basic dTSEC configuration and must be passed to
95610 + * fman_dtsec_init() function. A default set of configuration values can be
95611 + * obtained by calling fman_dtsec_defconfig().
95612 + */
95613 +struct dtsec_cfg {
95614 + bool halfdup_on;
95615 + bool halfdup_alt_backoff_en;
95616 + bool halfdup_excess_defer;
95617 + bool halfdup_no_backoff;
95618 + bool halfdup_bp_no_backoff;
95619 + uint8_t halfdup_alt_backoff_val;
95620 + uint16_t halfdup_retransmit;
95621 + uint16_t halfdup_coll_window;
95622 + bool rx_drop_bcast;
95623 + bool rx_short_frm;
95624 + bool rx_len_check;
95625 + bool tx_pad_crc;
95626 + bool tx_crc;
95627 + bool rx_ctrl_acc;
95628 + unsigned short tx_pause_time;
95629 + unsigned short tbipa;
95630 + bool ptp_tsu_en;
95631 + bool ptp_exception_en;
95632 + bool rx_preamble;
95633 + bool tx_preamble;
95634 + unsigned char preamble_len;
95635 + unsigned char rx_prepend;
95636 + bool loopback;
95637 + bool rx_time_stamp_en;
95638 + bool tx_time_stamp_en;
95639 + bool rx_flow;
95640 + bool tx_flow;
95641 + bool rx_group_hash_exd;
95642 + bool rx_promisc;
95643 + uint8_t tbi_phy_addr;
95644 + uint16_t tx_pause_time_extd;
95645 + uint16_t maximum_frame;
95646 + uint32_t non_back_to_back_ipg1;
95647 + uint32_t non_back_to_back_ipg2;
95648 + uint32_t min_ifg_enforcement;
95649 + uint32_t back_to_back_ipg;
95650 + bool wake_on_lan;
95651 +};
95652 +
95653 +
95654 +/**
95655 + * fman_dtsec_defconfig() - Get default dTSEC configuration
95656 + * @cfg: pointer to configuration structure.
95657 + *
95658 + * Call this function to obtain a default set of configuration values for
95659 + * initializing dTSEC. The user can overwrite any of the values before calling
95660 + * fman_dtsec_init(), if specific configuration needs to be applied.
95661 + */
95662 +void fman_dtsec_defconfig(struct dtsec_cfg *cfg);
95663 +
95664 +/**
95665 + * fman_dtsec_init() - Init dTSEC hardware block
95666 + * @regs: Pointer to dTSEC register block
95667 + * @cfg: dTSEC configuration data
95668 + * @iface_mode: dTSEC interface mode, the type of MAC - PHY interface.
95669 + * @iface_speed: 1G or 10G
95670 + * @macaddr: MAC station address to be assigned to the device
95671 + * @fm_rev_maj: major rev number
95672 + * @fm_rev_min: minor rev number
95673 + * @exceptions_mask: initial exceptions mask
95674 + *
95675 + * This function initializes dTSEC and applies basic configuration.
95676 + *
95677 + * dTSEC initialization sequence:
95678 + * Before enabling Rx/Tx call dtsec_set_address() to set MAC address,
95679 + * fman_dtsec_adjust_link() to configure interface speed and duplex and finally
95680 + * dtsec_enable_tx()/dtsec_enable_rx() to start transmission and reception.
95681 + *
95682 + * Returns: 0 if successful, an error code otherwise.
95683 + */
95684 +int fman_dtsec_init(struct dtsec_regs *regs, struct dtsec_cfg *cfg,
95685 + enum enet_interface iface_mode,
95686 + enum enet_speed iface_speed,
95687 + uint8_t *macaddr, uint8_t fm_rev_maj,
95688 + uint8_t fm_rev_min,
95689 + uint32_t exception_mask);
95690 +
95691 +/**
95692 + * fman_dtsec_enable() - Enable dTSEC Tx and Tx
95693 + * @regs: Pointer to dTSEC register block
95694 + * @apply_rx: enable rx side
95695 + * @apply_tx: enable tx side
95696 + *
95697 + * This function resets Tx and Rx graceful stop bit and enables dTSEC Tx and Rx.
95698 + */
95699 +void fman_dtsec_enable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
95700 +
95701 +/**
95702 + * fman_dtsec_disable() - Disable dTSEC Tx and Rx
95703 + * @regs: Pointer to dTSEC register block
95704 + * @apply_rx: disable rx side
95705 + * @apply_tx: disable tx side
95706 + *
95707 + * This function disables Tx and Rx in dTSEC.
95708 + */
95709 +void fman_dtsec_disable(struct dtsec_regs *regs, bool apply_rx, bool apply_tx);
95710 +
95711 +/**
95712 + * fman_dtsec_get_revision() - Get dTSEC hardware revision
95713 + * @regs: Pointer to dTSEC register block
95714 + *
95715 + * Returns dtsec_id content
95716 + *
95717 + * Call this function to obtain the dTSEC hardware version.
95718 + */
95719 +uint32_t fman_dtsec_get_revision(struct dtsec_regs *regs);
95720 +
95721 +/**
95722 + * fman_dtsec_set_mac_address() - Set MAC station address
95723 + * @regs: Pointer to dTSEC register block
95724 + * @macaddr: MAC address array
95725 + *
95726 + * This function sets MAC station address. To enable unicast reception call
95727 + * this after fman_dtsec_init(). While promiscuous mode is disabled dTSEC will
95728 + * match the destination address of received unicast frames against this
95729 + * address.
95730 + */
95731 +void fman_dtsec_set_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
95732 +
95733 +/**
95734 + * fman_dtsec_get_mac_address() - Query MAC station address
95735 + * @regs: Pointer to dTSEC register block
95736 + * @macaddr: MAC address array
95737 + */
95738 +void fman_dtsec_get_mac_address(struct dtsec_regs *regs, uint8_t *macaddr);
95739 +
95740 +/**
95741 + * fman_dtsec_set_uc_promisc() - Sets unicast promiscuous mode
95742 + * @regs: Pointer to dTSEC register block
95743 + * @enable: Enable unicast promiscuous mode
95744 + *
95745 + * Use this function to enable/disable dTSEC L2 address filtering. If the
95746 + * address filtering is disabled all unicast packets are accepted.
95747 + * To set dTSEC in promiscuous mode call both fman_dtsec_set_uc_promisc() and
95748 + * fman_dtsec_set_mc_promisc() to disable filtering for both unicast and
95749 + * multicast addresses.
95750 + */
95751 +void fman_dtsec_set_uc_promisc(struct dtsec_regs *regs, bool enable);
95752 +
95753 +/**
95754 + * fman_dtsec_set_wol() - Enable/Disable wake on lan
95755 + * (magic packet support)
95756 + * @regs: Pointer to dTSEC register block
95757 + * @en: Enable Wake On Lan support in dTSEC
95758 + *
95759 + */
95760 +void fman_dtsec_set_wol(struct dtsec_regs *regs, bool en);
95761 +
95762 +/**
95763 + * fman_dtsec_adjust_link() - Adjust dTSEC speed/duplex settings
95764 + * @regs: Pointer to dTSEC register block
95765 + * @iface_mode: dTSEC interface mode
95766 + * @speed: Link speed
95767 + * @full_dx: True for full-duplex, false for half-duplex.
95768 + *
95769 + * This function configures the MAC to function and the desired rates. Use it
95770 + * to configure dTSEC after fman_dtsec_init() and whenever the link speed
95771 + * changes (for instance following PHY auto-negociation).
95772 + *
95773 + * Returns: 0 if successful, an error code otherwise.
95774 + */
95775 +int fman_dtsec_adjust_link(struct dtsec_regs *regs,
95776 + enum enet_interface iface_mode,
95777 + enum enet_speed speed, bool full_dx);
95778 +
95779 +/**
95780 + * fman_dtsec_set_tbi_phy_addr() - Updates TBI address field
95781 + * @regs: Pointer to dTSEC register block
95782 + * @address: Valid PHY address in the range of 1 to 31. 0 is reserved.
95783 + *
95784 + * In SGMII mode, the dTSEC's TBIPA field must contain a valid TBI PHY address
95785 + * so that the associated TBI PHY (i.e. the link) may be initialized.
95786 + *
95787 + * Returns: 0 if successful, an error code otherwise.
95788 + */
95789 +int fman_dtsec_set_tbi_phy_addr(struct dtsec_regs *regs,
95790 + uint8_t addr);
95791 +
95792 +/**
95793 + * fman_dtsec_set_max_frame_len() - Set max frame length
95794 + * @regs: Pointer to dTSEC register block
95795 + * @length: Max frame length.
95796 + *
95797 + * Sets maximum frame length for received and transmitted frames. Frames that
95798 + * exceeds this length are truncated.
95799 + */
95800 +void fman_dtsec_set_max_frame_len(struct dtsec_regs *regs, uint16_t length);
95801 +
95802 +/**
95803 + * fman_dtsec_get_max_frame_len() - Query max frame length
95804 + * @regs: Pointer to dTSEC register block
95805 + *
95806 + * Returns: the current value of the maximum frame length.
95807 + */
95808 +uint16_t fman_dtsec_get_max_frame_len(struct dtsec_regs *regs);
95809 +
95810 +/**
95811 + * fman_dtsec_handle_rx_pause() - Configure pause frame handling
95812 + * @regs: Pointer to dTSEC register block
95813 + * @en: Enable pause frame handling in dTSEC
95814 + *
95815 + * If enabled, dTSEC will handle pause frames internally. This must be disabled
95816 + * if dTSEC is set in half-duplex mode.
95817 + * If pause frame handling is disabled and &dtsec_cfg.rx_ctrl_acc is set, pause
95818 + * frames will be transferred to the packet interface just like regular Ethernet
95819 + * frames.
95820 + */
95821 +void fman_dtsec_handle_rx_pause(struct dtsec_regs *regs, bool en);
95822 +
95823 +/**
95824 + * fman_dtsec_set_tx_pause_frames() - Configure Tx pause time
95825 + * @regs: Pointer to dTSEC register block
95826 + * @time: Time value included in pause frames
95827 + *
95828 + * Call this function to set the time value used in transmitted pause frames.
95829 + * If time is 0, transmission of pause frames is disabled
95830 + */
95831 +void fman_dtsec_set_tx_pause_frames(struct dtsec_regs *regs, uint16_t time);
95832 +
95833 +/**
95834 + * fman_dtsec_ack_event() - Acknowledge handled events
95835 + * @regs: Pointer to dTSEC register block
95836 + * @ev_mask: Events to acknowledge
95837 + *
95838 + * After handling events signaled by dTSEC in either polling or interrupt mode,
95839 + * call this function to reset the associated status bits in dTSEC event
95840 + * register.
95841 + */
95842 +void fman_dtsec_ack_event(struct dtsec_regs *regs, uint32_t ev_mask);
95843 +
95844 +/**
95845 + * fman_dtsec_get_event() - Returns currently asserted events
95846 + * @regs: Pointer to dTSEC register block
95847 + * @ev_mask: Mask of relevant events
95848 + *
95849 + * Call this function to obtain a bit-mask of events that are currently asserted
95850 + * in dTSEC, taken from IEVENT register.
95851 + *
95852 + * Returns: a bit-mask of events asserted in dTSEC.
95853 + */
95854 +uint32_t fman_dtsec_get_event(struct dtsec_regs *regs, uint32_t ev_mask);
95855 +
95856 +/**
95857 + * fman_dtsec_get_interrupt_mask() - Returns a bit-mask of enabled interrupts
95858 + * @regs: Pointer to dTSEC register block
95859 + *
95860 + * Call this function to obtain a bit-mask of enabled interrupts
95861 + * in dTSEC, taken from IMASK register.
95862 + *
95863 + * Returns: a bit-mask of enabled interrupts in dTSEC.
95864 + */
95865 +uint32_t fman_dtsec_get_interrupt_mask(struct dtsec_regs *regs);
95866 +
95867 +void fman_dtsec_clear_addr_in_paddr(struct dtsec_regs *regs,
95868 + uint8_t paddr_num);
95869 +
95870 +void fman_dtsec_add_addr_in_paddr(struct dtsec_regs *regs,
95871 + uint64_t addr,
95872 + uint8_t paddr_num);
95873 +
95874 +void fman_dtsec_enable_tmr_interrupt (struct dtsec_regs *regs);
95875 +
95876 +void fman_dtsec_disable_tmr_interrupt(struct dtsec_regs *regs);
95877 +
95878 +/**
95879 + * fman_dtsec_disable_interrupt() - Disables interrupts for the specified events
95880 + * @regs: Pointer to dTSEC register block
95881 + * @ev_mask: Mask of relevant events
95882 + *
95883 + * Call this function to disable interrupts in dTSEC for the specified events.
95884 + * To enable interrupts use fman_dtsec_enable_interrupt().
95885 + */
95886 +void fman_dtsec_disable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
95887 +
95888 +/**
95889 + * fman_dtsec_enable_interrupt() - Enable interrupts for the specified events
95890 + * @regs: Pointer to dTSEC register block
95891 + * @ev_mask: Mask of relevant events
95892 + *
95893 + * Call this function to enable interrupts in dTSEC for the specified events.
95894 + * To disable interrupts use fman_dtsec_disable_interrupt().
95895 + */
95896 +void fman_dtsec_enable_interrupt(struct dtsec_regs *regs, uint32_t ev_mask);
95897 +
95898 +/**
95899 + * fman_dtsec_set_ts() - Enables dTSEC timestamps
95900 + * @regs: Pointer to dTSEC register block
95901 + * @en: true to enable timestamps, false to disable them
95902 + *
95903 + * Call this function to enable/disable dTSEC timestamps. This affects both
95904 + * Tx and Rx.
95905 + */
95906 +void fman_dtsec_set_ts(struct dtsec_regs *regs, bool en);
95907 +
95908 +/**
95909 + * fman_dtsec_set_bucket() - Enables/disables a filter bucket
95910 + * @regs: Pointer to dTSEC register block
95911 + * @bucket: Bucket index
95912 + * @enable: true/false to enable/disable this bucket
95913 + *
95914 + * This function enables or disables the specified bucket. Enabling a bucket
95915 + * associated with an address configures dTSEC to accept received packets
95916 + * with that destination address.
95917 + * Multiple addresses may be associated with the same bucket. Disabling a
95918 + * bucket will affect all addresses associated with that bucket. A bucket that
95919 + * is enabled requires further filtering and verification in the upper layers
95920 + *
95921 + */
95922 +void fman_dtsec_set_bucket(struct dtsec_regs *regs, int bucket, bool enable);
95923 +
95924 +/**
95925 + * dtsec_set_hash_table() - insert a crc code into thr filter table
95926 + * @regs: Pointer to dTSEC register block
95927 + * @crc: crc to insert
95928 + * @mcast: true is this is a multicast address
95929 + * @ghtx: true if we are in ghtx mode
95930 + *
95931 + * This function inserts a crc code into the filter table.
95932 + */
95933 +void fman_dtsec_set_hash_table(struct dtsec_regs *regs, uint32_t crc,
95934 + bool mcast, bool ghtx);
95935 +
95936 +/**
95937 + * fman_dtsec_reset_filter_table() - Resets the address filtering table
95938 + * @regs: Pointer to dTSEC register block
95939 + * @mcast: Reset multicast entries
95940 + * @ucast: Reset unicast entries
95941 + *
95942 + * Resets all entries in L2 address filter table. After calling this function
95943 + * all buckets enabled using fman_dtsec_set_bucket() will be disabled.
95944 + * If dtsec_init_filter_table() was called with @unicast_hash set to false,
95945 + * @ucast argument is ignored.
95946 + * This does not affect the primary nor the 15 additional addresses configured
95947 + * using dtsec_set_address() or dtsec_set_match_address().
95948 + */
95949 +void fman_dtsec_reset_filter_table(struct dtsec_regs *regs, bool mcast,
95950 + bool ucast);
95951 +
95952 +/**
95953 + * fman_dtsec_set_mc_promisc() - Set multicast promiscuous mode
95954 + * @regs: Pointer to dTSEC register block
95955 + * @enable: Enable multicast promiscuous mode
95956 + *
95957 + * Call this to enable/disable L2 address filtering for multicast packets.
95958 + */
95959 +void fman_dtsec_set_mc_promisc(struct dtsec_regs *regs, bool enable);
95960 +
95961 +/* statistics APIs */
95962 +
95963 +/**
95964 + * fman_dtsec_set_stat_level() - Enable a group of MIB statistics counters
95965 + * @regs: Pointer to dTSEC register block
95966 + * @level: Specifies a certain group of dTSEC MIB HW counters or _all_,
95967 + * to specify all the existing counters.
95968 + * If set to _none_, it disables all the counters.
95969 + *
95970 + * Enables the MIB statistics hw counters and sets up the carry interrupt
95971 + * masks for the counters corresponding to the @level input parameter.
95972 + *
95973 + * Returns: error if invalid @level value given.
95974 + */
95975 +int fman_dtsec_set_stat_level(struct dtsec_regs *regs,
95976 + enum dtsec_stat_level level);
95977 +
95978 +/**
95979 + * fman_dtsec_reset_stat() - Completely resets all dTSEC HW counters
95980 + * @regs: Pointer to dTSEC register block
95981 + */
95982 +void fman_dtsec_reset_stat(struct dtsec_regs *regs);
95983 +
95984 +/**
95985 + * fman_dtsec_get_clear_carry_regs() - Read and clear carry bits (CAR1-2 registers)
95986 + * @regs: Pointer to dTSEC register block
95987 + * @car1: car1 register value
95988 + * @car2: car2 register value
95989 + *
95990 + * When set, the carry bits signal that an overflow occurred on the
95991 + * corresponding counters.
95992 + * Note that the carry bits (CAR1-2 registers) will assert the
95993 + * %DTSEC_IEVENT_MSRO interrupt if unmasked (via CAM1-2 regs).
95994 + *
95995 + * Returns: true if overflow occurred, otherwise - false
95996 + */
95997 +bool fman_dtsec_get_clear_carry_regs(struct dtsec_regs *regs,
95998 + uint32_t *car1, uint32_t *car2);
95999 +
96000 +uint32_t fman_dtsec_check_and_clear_tmr_event(struct dtsec_regs *regs);
96001 +
96002 +uint32_t fman_dtsec_get_stat_counter(struct dtsec_regs *regs,
96003 + enum dtsec_stat_counters reg_name);
96004 +
96005 +void fman_dtsec_start_tx(struct dtsec_regs *regs);
96006 +void fman_dtsec_start_rx(struct dtsec_regs *regs);
96007 +void fman_dtsec_stop_tx(struct dtsec_regs *regs);
96008 +void fman_dtsec_stop_rx(struct dtsec_regs *regs);
96009 +uint32_t fman_dtsec_get_rctrl(struct dtsec_regs *regs);
96010 +
96011 +
96012 +#endif /* __FSL_FMAN_DTSEC_H */
96013 --- /dev/null
96014 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_dtsec_mii_acc.h
96015 @@ -0,0 +1,107 @@
96016 +/*
96017 + * Copyright 2008-2013 Freescale Semiconductor Inc.
96018 + *
96019 + * Redistribution and use in source and binary forms, with or without
96020 + * modification, are permitted provided that the following conditions are met:
96021 + * * Redistributions of source code must retain the above copyright
96022 + * notice, this list of conditions and the following disclaimer.
96023 + * * Redistributions in binary form must reproduce the above copyright
96024 + * notice, this list of conditions and the following disclaimer in the
96025 + * documentation and/or other materials provided with the distribution.
96026 + * * Neither the name of Freescale Semiconductor nor the
96027 + * names of its contributors may be used to endorse or promote products
96028 + * derived from this software without specific prior written permission.
96029 + *
96030 + *
96031 + * ALTERNATIVELY, this software may be distributed under the terms of the
96032 + * GNU General Public License ("GPL") as published by the Free Software
96033 + * Foundation, either version 2 of that License or (at your option) any
96034 + * later version.
96035 + *
96036 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96037 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96038 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96039 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96040 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96041 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96042 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96043 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96044 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96045 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96046 + */
96047 +
96048 +#ifndef __FSL_FMAN_DTSEC_MII_ACC_H
96049 +#define __FSL_FMAN_DTSEC_MII_ACC_H
96050 +
96051 +#include "common/general.h"
96052 +
96053 +
96054 +/* MII Management Configuration Register */
96055 +#define MIIMCFG_RESET_MGMT 0x80000000
96056 +#define MIIMCFG_MGNTCLK_MASK 0x00000007
96057 +#define MIIMCFG_MGNTCLK_SHIFT 0
96058 +
96059 +/* MII Management Command Register */
96060 +#define MIIMCOM_SCAN_CYCLE 0x00000002
96061 +#define MIIMCOM_READ_CYCLE 0x00000001
96062 +
96063 +/* MII Management Address Register */
96064 +#define MIIMADD_PHY_ADDR_SHIFT 8
96065 +#define MIIMADD_PHY_ADDR_MASK 0x00001f00
96066 +
96067 +#define MIIMADD_REG_ADDR_SHIFT 0
96068 +#define MIIMADD_REG_ADDR_MASK 0x0000001f
96069 +
96070 +/* MII Management Indicator Register */
96071 +#define MIIMIND_BUSY 0x00000001
96072 +
96073 +
96074 +/* PHY Control Register */
96075 +#define PHY_CR_PHY_RESET 0x8000
96076 +#define PHY_CR_LOOPBACK 0x4000
96077 +#define PHY_CR_SPEED0 0x2000
96078 +#define PHY_CR_ANE 0x1000
96079 +#define PHY_CR_RESET_AN 0x0200
96080 +#define PHY_CR_FULLDUPLEX 0x0100
96081 +#define PHY_CR_SPEED1 0x0040
96082 +
96083 +#define PHY_TBICON_SRESET 0x8000
96084 +#define PHY_TBICON_SPEED2 0x0020
96085 +#define PHY_TBICON_CLK_SEL 0x0020
96086 +#define PHY_TBIANA_SGMII 0x4001
96087 +#define PHY_TBIANA_1000X 0x01a0
96088 +/* register map */
96089 +
96090 +/* MII Configuration Control Memory Map Registers */
96091 +struct dtsec_mii_reg {
96092 + uint32_t reserved1[72];
96093 + uint32_t miimcfg; /* MII Mgmt:configuration */
96094 + uint32_t miimcom; /* MII Mgmt:command */
96095 + uint32_t miimadd; /* MII Mgmt:address */
96096 + uint32_t miimcon; /* MII Mgmt:control 3 */
96097 + uint32_t miimstat; /* MII Mgmt:status */
96098 + uint32_t miimind; /* MII Mgmt:indicators */
96099 +};
96100 +
96101 +/* dTSEC MII API */
96102 +
96103 +/* functions to access the mii registers for phy configuration.
96104 + * this functionality may not be available for all dtsecs in the system.
96105 + * consult the reference manual for details */
96106 +void fman_dtsec_mii_reset(struct dtsec_mii_reg *regs);
96107 +/* frequency is in MHz.
96108 + * note that dtsec clock is 1/2 of fman clock */
96109 +void fman_dtsec_mii_init(struct dtsec_mii_reg *regs, uint16_t dtsec_freq);
96110 +int fman_dtsec_mii_write_reg(struct dtsec_mii_reg *regs,
96111 + uint8_t addr,
96112 + uint8_t reg,
96113 + uint16_t data,
96114 + uint16_t dtsec_freq);
96115 +
96116 +int fman_dtsec_mii_read_reg(struct dtsec_mii_reg *regs,
96117 + uint8_t addr,
96118 + uint8_t reg,
96119 + uint16_t *data,
96120 + uint16_t dtsec_freq);
96121 +
96122 +#endif /* __FSL_FMAN_DTSEC_MII_ACC_H */
96123 --- /dev/null
96124 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_kg.h
96125 @@ -0,0 +1,514 @@
96126 +/*
96127 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96128 + *
96129 + * Redistribution and use in source and binary forms, with or without
96130 + * modification, are permitted provided that the following conditions are met:
96131 + * * Redistributions of source code must retain the above copyright
96132 + * notice, this list of conditions and the following disclaimer.
96133 + * * Redistributions in binary form must reproduce the above copyright
96134 + * notice, this list of conditions and the following disclaimer in the
96135 + * documentation and/or other materials provided with the distribution.
96136 + * * Neither the name of Freescale Semiconductor nor the
96137 + * names of its contributors may be used to endorse or promote products
96138 + * derived from this software without specific prior written permission.
96139 + *
96140 + *
96141 + * ALTERNATIVELY, this software may be distributed under the terms of the
96142 + * GNU General Public License ("GPL") as published by the Free Software
96143 + * Foundation, either version 2 of that License or (at your option) any
96144 + * later version.
96145 + *
96146 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96147 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96148 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96149 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96150 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96151 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96152 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96153 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96154 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96155 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96156 + */
96157 +
96158 +#ifndef __FSL_FMAN_KG_H
96159 +#define __FSL_FMAN_KG_H
96160 +
96161 +#include "common/general.h"
96162 +
96163 +#define FM_KG_NUM_OF_GENERIC_REGS 8 /**< Num of generic KeyGen regs */
96164 +#define FMAN_MAX_NUM_OF_HW_PORTS 64
96165 +/**< Total num of masks allowed on KG extractions */
96166 +#define FM_KG_EXTRACT_MASKS_NUM 4
96167 +#define FM_KG_NUM_CLS_PLAN_ENTR 8 /**< Num of class. plan regs */
96168 +#define FM_KG_CLS_PLAN_GRPS_NUM 32 /**< Max num of class. groups */
96169 +
96170 +struct fman_kg_regs {
96171 + uint32_t fmkg_gcr;
96172 + uint32_t res004;
96173 + uint32_t res008;
96174 + uint32_t fmkg_eer;
96175 + uint32_t fmkg_eeer;
96176 + uint32_t res014;
96177 + uint32_t res018;
96178 + uint32_t fmkg_seer;
96179 + uint32_t fmkg_seeer;
96180 + uint32_t fmkg_gsr;
96181 + uint32_t fmkg_tpc;
96182 + uint32_t fmkg_serc;
96183 + uint32_t res030[4];
96184 + uint32_t fmkg_fdor;
96185 + uint32_t fmkg_gdv0r;
96186 + uint32_t fmkg_gdv1r;
96187 + uint32_t res04c[6];
96188 + uint32_t fmkg_feer;
96189 + uint32_t res068[38];
96190 + uint32_t fmkg_indirect[63];
96191 + uint32_t fmkg_ar;
96192 +};
96193 +
96194 +struct fman_kg_scheme_regs {
96195 + uint32_t kgse_mode; /**< MODE */
96196 + uint32_t kgse_ekfc; /**< Extract Known Fields Command */
96197 + uint32_t kgse_ekdv; /**< Extract Known Default Value */
96198 + uint32_t kgse_bmch; /**< Bit Mask Command High */
96199 + uint32_t kgse_bmcl; /**< Bit Mask Command Low */
96200 + uint32_t kgse_fqb; /**< Frame Queue Base */
96201 + uint32_t kgse_hc; /**< Hash Command */
96202 + uint32_t kgse_ppc; /**< Policer Profile Command */
96203 + uint32_t kgse_gec[FM_KG_NUM_OF_GENERIC_REGS];
96204 + /**< Generic Extract Command */
96205 + uint32_t kgse_spc; /**< KeyGen Scheme Entry Statistic Packet Counter */
96206 + uint32_t kgse_dv0; /**< KeyGen Scheme Entry Default Value 0 */
96207 + uint32_t kgse_dv1; /**< KeyGen Scheme Entry Default Value 1 */
96208 + uint32_t kgse_ccbs; /**< KeyGen Scheme Entry Coarse Classification Bit*/
96209 + uint32_t kgse_mv; /**< KeyGen Scheme Entry Match vector */
96210 + uint32_t kgse_om; /**< KeyGen Scheme Entry Operation Mode bits */
96211 + uint32_t kgse_vsp; /**< KeyGen Scheme Entry Virtual Storage Profile */
96212 +};
96213 +
96214 +struct fman_kg_pe_regs{
96215 + uint32_t fmkg_pe_sp;
96216 + uint32_t fmkg_pe_cpp;
96217 +};
96218 +
96219 +struct fman_kg_cp_regs {
96220 + uint32_t kgcpe[FM_KG_NUM_CLS_PLAN_ENTR];
96221 +};
96222 +
96223 +
96224 +#define FM_KG_KGAR_GO 0x80000000
96225 +#define FM_KG_KGAR_READ 0x40000000
96226 +#define FM_KG_KGAR_WRITE 0x00000000
96227 +#define FM_KG_KGAR_SEL_SCHEME_ENTRY 0x00000000
96228 +#define FM_KG_KGAR_SCM_WSEL_UPDATE_CNT 0x00008000
96229 +
96230 +#define KG_SCH_PP_SHIFT_HIGH 0x80000000
96231 +#define KG_SCH_PP_NO_GEN 0x10000000
96232 +#define KG_SCH_PP_SHIFT_LOW 0x0000F000
96233 +#define KG_SCH_MODE_NIA_PLCR 0x40000000
96234 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
96235 +#define KG_SCH_BITMASK_MASK 0x000000FF
96236 +#define KG_SCH_GEN_VALID 0x80000000
96237 +#define KG_SCH_GEN_MASK 0x00FF0000
96238 +#define FM_PCD_KG_KGAR_ERR 0x20000000
96239 +#define FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY 0x01000000
96240 +#define FM_PCD_KG_KGAR_SEL_PORT_ENTRY 0x02000000
96241 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_SP 0x00008000
96242 +#define FM_PCD_KG_KGAR_SEL_PORT_WSEL_CPP 0x00004000
96243 +#define FM_PCD_KG_KGAR_WSEL_MASK 0x0000FF00
96244 +#define KG_SCH_HASH_CONFIG_NO_FQID 0x80000000
96245 +#define KG_SCH_HASH_CONFIG_SYM 0x40000000
96246 +
96247 +#define FM_EX_KG_DOUBLE_ECC 0x80000000
96248 +#define FM_EX_KG_KEYSIZE_OVERFLOW 0x40000000
96249 +
96250 +/* ECC capture register */
96251 +#define KG_FMKG_SERC_CAP 0x80000000
96252 +#define KG_FMKG_SERC_CET 0x40000000
96253 +#define KG_FMKG_SERC_CNT_MSK 0x00FF0000
96254 +#define KG_FMKG_SERC_CNT_SHIFT 16
96255 +#define KG_FMKG_SERC_ADDR_MSK 0x000003FF
96256 +
96257 +/* Masks */
96258 +#define FM_KG_KGGCR_EN 0x80000000
96259 +#define KG_SCH_GEN_VALID 0x80000000
96260 +#define KG_SCH_GEN_EXTRACT_TYPE 0x00008000
96261 +#define KG_ERR_TYPE_DOUBLE 0x40000000
96262 +#define KG_ERR_ADDR_MASK 0x00000FFF
96263 +#define KG_SCH_MODE_EN 0x80000000
96264 +
96265 +/* shifts */
96266 +#define FM_KG_KGAR_NUM_SHIFT 16
96267 +#define FM_KG_PE_CPP_MASK_SHIFT 16
96268 +#define FM_KG_KGAR_WSEL_SHIFT 8
96269 +
96270 +#define FM_KG_SCH_GEN_HT_INVALID 0
96271 +
96272 +#define FM_KG_MASK_SEL_GEN_BASE 0x20
96273 +
96274 +#define KG_GET_MASK_SEL_SHIFT(shift, i) \
96275 +switch (i) \
96276 +{ \
96277 + case 0: (shift) = 26; break; \
96278 + case 1: (shift) = 20; break; \
96279 + case 2: (shift) = 10; break; \
96280 + case 3: (shift) = 4; break; \
96281 + default: (shift) = 0; \
96282 +}
96283 +
96284 +#define KG_GET_MASK_OFFSET_SHIFT(shift, i) \
96285 +switch (i) \
96286 +{ \
96287 + case 0: (shift) = 16; break; \
96288 + case 1: (shift) = 0; break; \
96289 + case 2: (shift) = 28; break; \
96290 + case 3: (shift) = 24; break; \
96291 + default: (shift) = 0; \
96292 +}
96293 +
96294 +#define KG_GET_MASK_SHIFT(shift, i) \
96295 +switch (i) \
96296 +{ \
96297 + case 0: shift = 24; break; \
96298 + case 1: shift = 16; break; \
96299 + case 2: shift = 8; break; \
96300 + case 3: shift = 0; break; \
96301 + default: shift = 0; \
96302 +}
96303 +
96304 +/* Port entry CPP register */
96305 +#define FMAN_KG_PE_CPP_MASK_SHIFT 16
96306 +
96307 +/* Scheme registers */
96308 +#define FMAN_KG_SCH_MODE_EN 0x80000000
96309 +#define FMAN_KG_SCH_MODE_NIA_PLCR 0x40000000
96310 +#define FMAN_KG_SCH_MODE_CCOBASE_SHIFT 24
96311 +
96312 +#define FMAN_KG_SCH_DEF_MAC_ADDR_SHIFT 30
96313 +#define FMAN_KG_SCH_DEF_VLAN_TCI_SHIFT 28
96314 +#define FMAN_KG_SCH_DEF_ETYPE_SHIFT 26
96315 +#define FMAN_KG_SCH_DEF_PPP_SID_SHIFT 24
96316 +#define FMAN_KG_SCH_DEF_PPP_PID_SHIFT 22
96317 +#define FMAN_KG_SCH_DEF_MPLS_SHIFT 20
96318 +#define FMAN_KG_SCH_DEF_IP_ADDR_SHIFT 18
96319 +#define FMAN_KG_SCH_DEF_PTYPE_SHIFT 16
96320 +#define FMAN_KG_SCH_DEF_IP_TOS_TC_SHIFT 14
96321 +#define FMAN_KG_SCH_DEF_IPv6_FL_SHIFT 12
96322 +#define FMAN_KG_SCH_DEF_IPSEC_SPI_SHIFT 10
96323 +#define FMAN_KG_SCH_DEF_L4_PORT_SHIFT 8
96324 +#define FMAN_KG_SCH_DEF_TCP_FLG_SHIFT 6
96325 +
96326 +#define FMAN_KG_SCH_GEN_VALID 0x80000000
96327 +#define FMAN_KG_SCH_GEN_SIZE_MAX 16
96328 +#define FMAN_KG_SCH_GEN_OR 0x00008000
96329 +
96330 +#define FMAN_KG_SCH_GEN_DEF_SHIFT 29
96331 +#define FMAN_KG_SCH_GEN_SIZE_SHIFT 24
96332 +#define FMAN_KG_SCH_GEN_MASK_SHIFT 16
96333 +#define FMAN_KG_SCH_GEN_HT_SHIFT 8
96334 +
96335 +#define FMAN_KG_SCH_HASH_HSHIFT_SHIFT 24
96336 +#define FMAN_KG_SCH_HASH_HSHIFT_MAX 0x28
96337 +#define FMAN_KG_SCH_HASH_SYM 0x40000000
96338 +#define FMAN_KG_SCH_HASH_NO_FQID_GEN 0x80000000
96339 +
96340 +#define FMAN_KG_SCH_PP_SH_SHIFT 27
96341 +#define FMAN_KG_SCH_PP_SL_SHIFT 12
96342 +#define FMAN_KG_SCH_PP_SH_MASK 0x80000000
96343 +#define FMAN_KG_SCH_PP_SL_MASK 0x0000F000
96344 +#define FMAN_KG_SCH_PP_SHIFT_MAX 0x17
96345 +#define FMAN_KG_SCH_PP_MASK_SHIFT 16
96346 +#define FMAN_KG_SCH_PP_NO_GEN 0x10000000
96347 +
96348 +enum fman_kg_gen_extract_src {
96349 + E_FMAN_KG_GEN_EXTRACT_ETH,
96350 + E_FMAN_KG_GEN_EXTRACT_ETYPE,
96351 + E_FMAN_KG_GEN_EXTRACT_SNAP,
96352 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_1,
96353 + E_FMAN_KG_GEN_EXTRACT_VLAN_TCI_N,
96354 + E_FMAN_KG_GEN_EXTRACT_PPPoE,
96355 + E_FMAN_KG_GEN_EXTRACT_MPLS_1,
96356 + E_FMAN_KG_GEN_EXTRACT_MPLS_2,
96357 + E_FMAN_KG_GEN_EXTRACT_MPLS_3,
96358 + E_FMAN_KG_GEN_EXTRACT_MPLS_N,
96359 + E_FMAN_KG_GEN_EXTRACT_IPv4_1,
96360 + E_FMAN_KG_GEN_EXTRACT_IPv6_1,
96361 + E_FMAN_KG_GEN_EXTRACT_IPv4_2,
96362 + E_FMAN_KG_GEN_EXTRACT_IPv6_2,
96363 + E_FMAN_KG_GEN_EXTRACT_MINENCAP,
96364 + E_FMAN_KG_GEN_EXTRACT_IP_PID,
96365 + E_FMAN_KG_GEN_EXTRACT_GRE,
96366 + E_FMAN_KG_GEN_EXTRACT_TCP,
96367 + E_FMAN_KG_GEN_EXTRACT_UDP,
96368 + E_FMAN_KG_GEN_EXTRACT_SCTP,
96369 + E_FMAN_KG_GEN_EXTRACT_DCCP,
96370 + E_FMAN_KG_GEN_EXTRACT_IPSEC_AH,
96371 + E_FMAN_KG_GEN_EXTRACT_IPSEC_ESP,
96372 + E_FMAN_KG_GEN_EXTRACT_SHIM_1,
96373 + E_FMAN_KG_GEN_EXTRACT_SHIM_2,
96374 + E_FMAN_KG_GEN_EXTRACT_FROM_DFLT,
96375 + E_FMAN_KG_GEN_EXTRACT_FROM_FRAME_START,
96376 + E_FMAN_KG_GEN_EXTRACT_FROM_PARSE_RESULT,
96377 + E_FMAN_KG_GEN_EXTRACT_FROM_END_OF_PARSE,
96378 + E_FMAN_KG_GEN_EXTRACT_FROM_FQID
96379 +};
96380 +
96381 +struct fman_kg_ex_ecc_attr
96382 +{
96383 + bool valid;
96384 + bool double_ecc;
96385 + uint16_t addr;
96386 + uint8_t single_ecc_count;
96387 +};
96388 +
96389 +enum fman_kg_def_select
96390 +{
96391 + E_FMAN_KG_DEF_GLOBAL_0,
96392 + E_FMAN_KG_DEF_GLOBAL_1,
96393 + E_FMAN_KG_DEF_SCHEME_0,
96394 + E_FMAN_KG_DEF_SCHEME_1
96395 +};
96396 +
96397 +struct fman_kg_extract_def
96398 +{
96399 + enum fman_kg_def_select mac_addr;
96400 + enum fman_kg_def_select vlan_tci;
96401 + enum fman_kg_def_select etype;
96402 + enum fman_kg_def_select ppp_sid;
96403 + enum fman_kg_def_select ppp_pid;
96404 + enum fman_kg_def_select mpls;
96405 + enum fman_kg_def_select ip_addr;
96406 + enum fman_kg_def_select ptype;
96407 + enum fman_kg_def_select ip_tos_tc;
96408 + enum fman_kg_def_select ipv6_fl;
96409 + enum fman_kg_def_select ipsec_spi;
96410 + enum fman_kg_def_select l4_port;
96411 + enum fman_kg_def_select tcp_flg;
96412 +};
96413 +
96414 +enum fman_kg_gen_extract_type
96415 +{
96416 + E_FMAN_KG_HASH_EXTRACT,
96417 + E_FMAN_KG_OR_EXTRACT
96418 +};
96419 +
96420 +struct fman_kg_gen_extract_params
96421 +{
96422 + /* Hash or Or-ed extract */
96423 + enum fman_kg_gen_extract_type type;
96424 + enum fman_kg_gen_extract_src src;
96425 + bool no_validation;
96426 + /* Extraction offset from the header location specified above */
96427 + uint8_t offset;
96428 + /* Size of extraction for FMAN_KG_HASH_EXTRACT,
96429 + * hash result shift for FMAN_KG_OR_EXTRACT */
96430 + uint8_t extract;
96431 + uint8_t mask;
96432 + /* Default value to use when header specified
96433 + * by fman_kg_gen_extract_src doesn't present */
96434 + enum fman_kg_def_select def_val;
96435 +};
96436 +
96437 +struct fman_kg_extract_mask
96438 +{
96439 + /**< Indication if mask is on known field extraction or
96440 + * on general extraction; TRUE for known field */
96441 + bool is_known;
96442 + /**< One of FMAN_KG_EXTRACT_xxx defines for known fields mask and
96443 + * generic register index for generic extracts mask */
96444 + uint32_t field_or_gen_idx;
96445 + /**< Byte offset from start of the extracted data specified
96446 + * by field_or_gen_idx */
96447 + uint8_t offset;
96448 + /**< Byte mask (selected bits will be used) */
96449 + uint8_t mask;
96450 +};
96451 +
96452 +struct fman_kg_extract_params
96453 +{
96454 + /* Or-ed mask of FMAN_KG_EXTRACT_xxx defines */
96455 + uint32_t known_fields;
96456 + struct fman_kg_extract_def known_fields_def;
96457 + /* Number of entries in gen_extract */
96458 + uint8_t gen_extract_num;
96459 + struct fman_kg_gen_extract_params gen_extract[FM_KG_NUM_OF_GENERIC_REGS];
96460 + /* Number of entries in masks */
96461 + uint8_t masks_num;
96462 + struct fman_kg_extract_mask masks[FM_KG_EXTRACT_MASKS_NUM];
96463 + uint32_t def_scheme_0;
96464 + uint32_t def_scheme_1;
96465 +};
96466 +
96467 +struct fman_kg_hash_params
96468 +{
96469 + bool use_hash;
96470 + uint8_t shift_r;
96471 + uint32_t mask; /**< 24-bit mask */
96472 + bool sym; /**< Symmetric hash for src and dest pairs */
96473 +};
96474 +
96475 +struct fman_kg_pp_params
96476 +{
96477 + uint8_t base;
96478 + uint8_t shift;
96479 + uint8_t mask;
96480 + bool bypass_pp_gen;
96481 +};
96482 +
96483 +struct fman_kg_cc_params
96484 +{
96485 + uint8_t base_offset;
96486 + uint32_t qlcv_bits_sel;
96487 +};
96488 +
96489 +enum fman_pcd_engine
96490 +{
96491 + E_FMAN_PCD_INVALID = 0, /**< Invalid PCD engine indicated*/
96492 + E_FMAN_PCD_DONE, /**< No PCD Engine indicated */
96493 + E_FMAN_PCD_KG, /**< Keygen indicated */
96494 + E_FMAN_PCD_CC, /**< Coarse classification indicated */
96495 + E_FMAN_PCD_PLCR, /**< Policer indicated */
96496 + E_FMAN_PCD_PRS /**< Parser indicated */
96497 +};
96498 +
96499 +struct fman_kg_cls_plan_params
96500 +{
96501 + uint8_t entries_mask;
96502 + uint32_t mask_vector[FM_KG_NUM_CLS_PLAN_ENTR];
96503 +};
96504 +
96505 +struct fman_kg_scheme_params
96506 +{
96507 + uint32_t match_vector;
96508 + struct fman_kg_extract_params extract_params;
96509 + struct fman_kg_hash_params hash_params;
96510 + uint32_t base_fqid;
96511 + /* What we do w/features supported per FM version ?? */
96512 + bool bypass_fqid_gen;
96513 + struct fman_kg_pp_params policer_params;
96514 + struct fman_kg_cc_params cc_params;
96515 + bool update_counter;
96516 + /**< counter_value: Set scheme counter to the specified value;
96517 + * relevant only when update_counter = TRUE. */
96518 + uint32_t counter_value;
96519 + enum fman_pcd_engine next_engine;
96520 + /**< Next engine action code */
96521 + uint32_t next_engine_action;
96522 +};
96523 +
96524 +
96525 +
96526 +int fman_kg_write_ar_wait(struct fman_kg_regs *regs, uint32_t fmkg_ar);
96527 +void fman_kg_write_sp(struct fman_kg_regs *regs, uint32_t sp, bool add);
96528 +void fman_kg_write_cpp(struct fman_kg_regs *regs, uint32_t cpp);
96529 +void fman_kg_get_event(struct fman_kg_regs *regs,
96530 + uint32_t *event,
96531 + uint32_t *scheme_idx);
96532 +void fman_kg_init(struct fman_kg_regs *regs,
96533 + uint32_t exceptions,
96534 + uint32_t dflt_nia);
96535 +void fman_kg_enable_scheme_interrupts(struct fman_kg_regs *regs);
96536 +void fman_kg_enable(struct fman_kg_regs *regs);
96537 +void fman_kg_disable(struct fman_kg_regs *regs);
96538 +int fman_kg_write_bind_cls_plans(struct fman_kg_regs *regs,
96539 + uint8_t hwport_id,
96540 + uint32_t bind_cls_plans);
96541 +int fman_kg_build_bind_cls_plans(uint8_t grp_base,
96542 + uint8_t grp_mask,
96543 + uint32_t *bind_cls_plans);
96544 +int fman_kg_write_bind_schemes(struct fman_kg_regs *regs,
96545 + uint8_t hwport_id,
96546 + uint32_t schemes);
96547 +int fman_kg_write_cls_plan(struct fman_kg_regs *regs,
96548 + uint8_t grp_id,
96549 + uint8_t entries_mask,
96550 + uint8_t hwport_id,
96551 + struct fman_kg_cp_regs *cls_plan_regs);
96552 +int fman_kg_build_cls_plan(struct fman_kg_cls_plan_params *params,
96553 + struct fman_kg_cp_regs *cls_plan_regs);
96554 +uint32_t fman_kg_get_schemes_total_counter(struct fman_kg_regs *regs);
96555 +int fman_kg_set_scheme_counter(struct fman_kg_regs *regs,
96556 + uint8_t scheme_id,
96557 + uint8_t hwport_id,
96558 + uint32_t counter);
96559 +int fman_kg_get_scheme_counter(struct fman_kg_regs *regs,
96560 + uint8_t scheme_id,
96561 + uint8_t hwport_id,
96562 + uint32_t *counter);
96563 +int fman_kg_delete_scheme(struct fman_kg_regs *regs,
96564 + uint8_t scheme_id,
96565 + uint8_t hwport_id);
96566 +int fman_kg_write_scheme(struct fman_kg_regs *regs,
96567 + uint8_t scheme_id,
96568 + uint8_t hwport_id,
96569 + struct fman_kg_scheme_regs *scheme_regs,
96570 + bool update_counter);
96571 +int fman_kg_build_scheme(struct fman_kg_scheme_params *params,
96572 + struct fman_kg_scheme_regs *scheme_regs);
96573 +void fman_kg_get_capture(struct fman_kg_regs *regs,
96574 + struct fman_kg_ex_ecc_attr *ecc_attr,
96575 + bool clear);
96576 +void fman_kg_get_exception(struct fman_kg_regs *regs,
96577 + uint32_t *events,
96578 + uint32_t *scheme_ids,
96579 + bool clear);
96580 +void fman_kg_set_exception(struct fman_kg_regs *regs,
96581 + uint32_t exception,
96582 + bool enable);
96583 +void fman_kg_set_dflt_val(struct fman_kg_regs *regs,
96584 + uint8_t def_id,
96585 + uint32_t val);
96586 +void fman_kg_set_data_after_prs(struct fman_kg_regs *regs, uint8_t offset);
96587 +
96588 +
96589 +
96590 +/**************************************************************************//**
96591 + @Description NIA Description
96592 +*//***************************************************************************/
96593 +#define KG_NIA_ORDER_RESTOR 0x00800000
96594 +#define KG_NIA_ENG_FM_CTL 0x00000000
96595 +#define KG_NIA_ENG_PRS 0x00440000
96596 +#define KG_NIA_ENG_KG 0x00480000
96597 +#define KG_NIA_ENG_PLCR 0x004C0000
96598 +#define KG_NIA_ENG_BMI 0x00500000
96599 +#define KG_NIA_ENG_QMI_ENQ 0x00540000
96600 +#define KG_NIA_ENG_QMI_DEQ 0x00580000
96601 +#define KG_NIA_ENG_MASK 0x007C0000
96602 +
96603 +#define KG_NIA_AC_MASK 0x0003FFFF
96604 +
96605 +#define KG_NIA_INVALID 0xFFFFFFFF
96606 +
96607 +static __inline__ uint32_t fm_kg_build_nia(enum fman_pcd_engine next_engine,
96608 + uint32_t next_engine_action)
96609 +{
96610 + uint32_t nia;
96611 +
96612 + if (next_engine_action & ~KG_NIA_AC_MASK)
96613 + return KG_NIA_INVALID;
96614 +
96615 + switch (next_engine) {
96616 + case E_FMAN_PCD_DONE:
96617 + nia = KG_NIA_ENG_BMI | next_engine_action;
96618 + break;
96619 +
96620 + case E_FMAN_PCD_KG:
96621 + nia = KG_NIA_ENG_KG | next_engine_action;
96622 + break;
96623 +
96624 + case E_FMAN_PCD_CC:
96625 + nia = KG_NIA_ENG_FM_CTL | next_engine_action;
96626 + break;
96627 +
96628 + case E_FMAN_PCD_PLCR:
96629 + nia = KG_NIA_ENG_PLCR | next_engine_action;
96630 + break;
96631 +
96632 + default:
96633 + nia = KG_NIA_INVALID;
96634 + }
96635 +
96636 + return nia;
96637 +}
96638 +
96639 +#endif /* __FSL_FMAN_KG_H */
96640 --- /dev/null
96641 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac.h
96642 @@ -0,0 +1,434 @@
96643 +/*
96644 + * Copyright 2008-2012 Freescale Semiconductor Inc.
96645 + *
96646 + * Redistribution and use in source and binary forms, with or without
96647 + * modification, are permitted provided that the following conditions are met:
96648 + * * Redistributions of source code must retain the above copyright
96649 + * notice, this list of conditions and the following disclaimer.
96650 + * * Redistributions in binary form must reproduce the above copyright
96651 + * notice, this list of conditions and the following disclaimer in the
96652 + * documentation and/or other materials provided with the distribution.
96653 + * * Neither the name of Freescale Semiconductor nor the
96654 + * names of its contributors may be used to endorse or promote products
96655 + * derived from this software without specific prior written permission.
96656 + *
96657 + *
96658 + * ALTERNATIVELY, this software may be distributed under the terms of the
96659 + * GNU General Public License ("GPL") as published by the Free Software
96660 + * Foundation, either version 2 of that License or (at your option) any
96661 + * later version.
96662 + *
96663 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
96664 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
96665 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
96666 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
96667 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
96668 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
96669 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
96670 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
96671 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
96672 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
96673 + */
96674 +
96675 +
96676 +#ifndef __FSL_FMAN_MEMAC_H
96677 +#define __FSL_FMAN_MEMAC_H
96678 +
96679 +#include "common/general.h"
96680 +#include "fsl_enet.h"
96681 +
96682 +
96683 +#define MEMAC_NUM_OF_PADDRS 7 /* Num of additional exact match MAC adr regs */
96684 +
96685 +/* Control and Configuration Register (COMMAND_CONFIG) */
96686 +#define CMD_CFG_MG 0x80000000 /* 00 Magic Packet detection */
96687 +#define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */
96688 +#define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */
96689 +#define CMD_CFG_SFD_ANY 0x00200000 /* 10 Disable SFD check */
96690 +#define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */
96691 +#define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */
96692 +#define CMD_CFG_SEND_IDLE 0x00010000 /* 15 Force idle generation */
96693 +#define CMD_CFG_CNT_FRM_EN 0x00002000 /* 18 Control frame rx enable */
96694 +#define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */
96695 +#define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */
96696 +#define CMD_CFG_LOOPBACK_EN 0x00000400 /* 21 XGMII/GMII loopback enable */
96697 +#define CMD_CFG_TX_ADDR_INS 0x00000200 /* 22 Tx source MAC addr insertion */
96698 +#define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */
96699 +#define CMD_CFG_PAUSE_FWD 0x00000080 /* 24 Terminate/frwd Pause frames */
96700 +#define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */
96701 +#define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */
96702 +#define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */
96703 +#define CMD_CFG_WAN_MODE 0x00000008 /* 28 WAN mode enable */
96704 +#define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */
96705 +#define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */
96706 +
96707 +/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
96708 +#define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000
96709 +#define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF
96710 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000
96711 +#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000
96712 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G 0x00360000
96713 +#define TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G 0x00040000
96714 +#define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019
96715 +#define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020
96716 +#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060
96717 +
96718 +#define GET_TX_EMPTY_DEFAULT_VALUE(_val) \
96719 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
96720 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
96721 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) : \
96722 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));
96723 +
96724 +#define GET_TX_EMPTY_PFC_VALUE(_val) \
96725 +_val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \
96726 +((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \
96727 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_10G) : \
96728 + (_val |= TX_FIFO_SECTIONS_TX_EMPTY_PFC_1G));
96729 +
96730 +/* Interface Mode Register (IF_MODE) */
96731 +#define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */
96732 +#define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */
96733 +#define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */
96734 +#define IF_MODE_RGMII 0x00000004
96735 +#define IF_MODE_RGMII_AUTO 0x00008000
96736 +#define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */
96737 +#define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */
96738 +#define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */
96739 +#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
96740 +#define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */
96741 +#define IF_MODE_HD 0x00000040 /* Half duplex operation */
96742 +
96743 +/* Hash table Control Register (HASHTABLE_CTRL) */
96744 +#define HASH_CTRL_MCAST_SHIFT 26
96745 +#define HASH_CTRL_MCAST_EN 0x00000100 /* 23 Mcast frame rx for hash */
96746 +#define HASH_CTRL_ADDR_MASK 0x0000003F /* 26-31 Hash table address code */
96747 +
96748 +#define GROUP_ADDRESS 0x0000010000000000LL /* MAC mcast indication */
96749 +#define HASH_TABLE_SIZE 64 /* Hash tbl size */
96750 +
96751 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
96752 +#define MEMAC_TX_IPG_LENGTH_MASK 0x0000003F
96753 +
96754 +/* Statistics Configuration Register (STATN_CONFIG) */
96755 +#define STATS_CFG_CLR 0x00000004 /* 29 Reset all counters */
96756 +#define STATS_CFG_CLR_ON_RD 0x00000002 /* 30 Clear on read */
96757 +#define STATS_CFG_SATURATE 0x00000001 /* 31 Saturate at the maximum val */
96758 +
96759 +/* Interrupt Mask Register (IMASK) */
96760 +#define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */
96761 +#define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */
96762 +#define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */
96763 +#define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */
96764 +
96765 +#define MEMAC_ALL_ERRS_IMASK \
96766 + ((uint32_t)(MEMAC_IMASK_TSECC_ER | \
96767 + MEMAC_IMASK_TECC_ER | \
96768 + MEMAC_IMASK_RECC_ER | \
96769 + MEMAC_IMASK_MGI))
96770 +
96771 +#define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */
96772 +#define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */
96773 +#define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */
96774 +#define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */
96775 +#define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error */
96776 +#define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */
96777 +#define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */
96778 +#define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */
96779 +#define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */
96780 +#define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */
96781 +#define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */
96782 +#define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */
96783 +#define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */
96784 +#define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */
96785 +#define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */
96786 +#define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */
96787 +#define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */
96788 +
96789 +enum memac_counters {
96790 + E_MEMAC_COUNTER_R64,
96791 + E_MEMAC_COUNTER_T64,
96792 + E_MEMAC_COUNTER_R127,
96793 + E_MEMAC_COUNTER_T127,
96794 + E_MEMAC_COUNTER_R255,
96795 + E_MEMAC_COUNTER_T255,
96796 + E_MEMAC_COUNTER_R511,
96797 + E_MEMAC_COUNTER_T511,
96798 + E_MEMAC_COUNTER_R1023,
96799 + E_MEMAC_COUNTER_T1023,
96800 + E_MEMAC_COUNTER_R1518,
96801 + E_MEMAC_COUNTER_T1518,
96802 + E_MEMAC_COUNTER_R1519X,
96803 + E_MEMAC_COUNTER_T1519X,
96804 + E_MEMAC_COUNTER_RFRG,
96805 + E_MEMAC_COUNTER_RJBR,
96806 + E_MEMAC_COUNTER_RDRP,
96807 + E_MEMAC_COUNTER_RALN,
96808 + E_MEMAC_COUNTER_TUND,
96809 + E_MEMAC_COUNTER_ROVR,
96810 + E_MEMAC_COUNTER_RXPF,
96811 + E_MEMAC_COUNTER_TXPF,
96812 + E_MEMAC_COUNTER_ROCT,
96813 + E_MEMAC_COUNTER_RMCA,
96814 + E_MEMAC_COUNTER_RBCA,
96815 + E_MEMAC_COUNTER_RPKT,
96816 + E_MEMAC_COUNTER_RUCA,
96817 + E_MEMAC_COUNTER_RERR,
96818 + E_MEMAC_COUNTER_TOCT,
96819 + E_MEMAC_COUNTER_TMCA,
96820 + E_MEMAC_COUNTER_TBCA,
96821 + E_MEMAC_COUNTER_TUCA,
96822 + E_MEMAC_COUNTER_TERR
96823 +};
96824 +
96825 +#define DEFAULT_PAUSE_QUANTA 0xf000
96826 +#define DEFAULT_FRAME_LENGTH 0x600
96827 +#define DEFAULT_TX_IPG_LENGTH 12
96828 +
96829 +/*
96830 + * memory map
96831 + */
96832 +
96833 +struct mac_addr {
96834 + uint32_t mac_addr_l; /* Lower 32 bits of 48-bit MAC address */
96835 + uint32_t mac_addr_u; /* Upper 16 bits of 48-bit MAC address */
96836 +};
96837 +
96838 +struct memac_regs {
96839 + /* General Control and Status */
96840 + uint32_t res0000[2];
96841 + uint32_t command_config; /* 0x008 Ctrl and cfg */
96842 + struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */
96843 + uint32_t maxfrm; /* 0x014 Max frame length */
96844 + uint32_t res0018[1];
96845 + uint32_t rx_fifo_sections; /* Receive FIFO configuration reg */
96846 + uint32_t tx_fifo_sections; /* Transmit FIFO configuration reg */
96847 + uint32_t res0024[2];
96848 + uint32_t hashtable_ctrl; /* 0x02C Hash table control */
96849 + uint32_t res0030[4];
96850 + uint32_t ievent; /* 0x040 Interrupt event */
96851 + uint32_t tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */
96852 + uint32_t res0048;
96853 + uint32_t imask; /* 0x04C Interrupt mask */
96854 + uint32_t res0050;
96855 + uint32_t pause_quanta[4]; /* 0x054 Pause quanta */
96856 + uint32_t pause_thresh[4]; /* 0x064 Pause quanta threshold */
96857 + uint32_t rx_pause_status; /* 0x074 Receive pause status */
96858 + uint32_t res0078[2];
96859 + struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS]; /* 0x80-0x0B4 mac padr */
96860 + uint32_t lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */
96861 + uint32_t sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */
96862 + uint32_t res00c0[8];
96863 + uint32_t statn_config; /* 0x0E0 Statistics configuration */
96864 + uint32_t res00e4[7];
96865 + /* Rx Statistics Counter */
96866 + uint32_t reoct_l;
96867 + uint32_t reoct_u;
96868 + uint32_t roct_l;
96869 + uint32_t roct_u;
96870 + uint32_t raln_l;
96871 + uint32_t raln_u;
96872 + uint32_t rxpf_l;
96873 + uint32_t rxpf_u;
96874 + uint32_t rfrm_l;
96875 + uint32_t rfrm_u;
96876 + uint32_t rfcs_l;
96877 + uint32_t rfcs_u;
96878 + uint32_t rvlan_l;
96879 + uint32_t rvlan_u;
96880 + uint32_t rerr_l;
96881 + uint32_t rerr_u;
96882 + uint32_t ruca_l;
96883 + uint32_t ruca_u;
96884 + uint32_t rmca_l;
96885 + uint32_t rmca_u;
96886 + uint32_t rbca_l;
96887 + uint32_t rbca_u;
96888 + uint32_t rdrp_l;
96889 + uint32_t rdrp_u;
96890 + uint32_t rpkt_l;
96891 + uint32_t rpkt_u;
96892 + uint32_t rund_l;
96893 + uint32_t rund_u;
96894 + uint32_t r64_l;
96895 + uint32_t r64_u;
96896 + uint32_t r127_l;
96897 + uint32_t r127_u;
96898 + uint32_t r255_l;
96899 + uint32_t r255_u;
96900 + uint32_t r511_l;
96901 + uint32_t r511_u;
96902 + uint32_t r1023_l;
96903 + uint32_t r1023_u;
96904 + uint32_t r1518_l;
96905 + uint32_t r1518_u;
96906 + uint32_t r1519x_l;
96907 + uint32_t r1519x_u;
96908 + uint32_t rovr_l;
96909 + uint32_t rovr_u;
96910 + uint32_t rjbr_l;
96911 + uint32_t rjbr_u;
96912 + uint32_t rfrg_l;
96913 + uint32_t rfrg_u;
96914 + uint32_t rcnp_l;
96915 + uint32_t rcnp_u;
96916 + uint32_t rdrntp_l;
96917 + uint32_t rdrntp_u;
96918 + uint32_t res01d0[12];
96919 + /* Tx Statistics Counter */
96920 + uint32_t teoct_l;
96921 + uint32_t teoct_u;
96922 + uint32_t toct_l;
96923 + uint32_t toct_u;
96924 + uint32_t res0210[2];
96925 + uint32_t txpf_l;
96926 + uint32_t txpf_u;
96927 + uint32_t tfrm_l;
96928 + uint32_t tfrm_u;
96929 + uint32_t tfcs_l;
96930 + uint32_t tfcs_u;
96931 + uint32_t tvlan_l;
96932 + uint32_t tvlan_u;
96933 + uint32_t terr_l;
96934 + uint32_t terr_u;
96935 + uint32_t tuca_l;
96936 + uint32_t tuca_u;
96937 + uint32_t tmca_l;
96938 + uint32_t tmca_u;
96939 + uint32_t tbca_l;
96940 + uint32_t tbca_u;
96941 + uint32_t res0258[2];
96942 + uint32_t tpkt_l;
96943 + uint32_t tpkt_u;
96944 + uint32_t tund_l;
96945 + uint32_t tund_u;
96946 + uint32_t t64_l;
96947 + uint32_t t64_u;
96948 + uint32_t t127_l;
96949 + uint32_t t127_u;
96950 + uint32_t t255_l;
96951 + uint32_t t255_u;
96952 + uint32_t t511_l;
96953 + uint32_t t511_u;
96954 + uint32_t t1023_l;
96955 + uint32_t t1023_u;
96956 + uint32_t t1518_l;
96957 + uint32_t t1518_u;
96958 + uint32_t t1519x_l;
96959 + uint32_t t1519x_u;
96960 + uint32_t res02a8[6];
96961 + uint32_t tcnp_l;
96962 + uint32_t tcnp_u;
96963 + uint32_t res02c8[14];
96964 + /* Line Interface Control */
96965 + uint32_t if_mode; /* 0x300 Interface Mode Control */
96966 + uint32_t if_status; /* 0x304 Interface Status */
96967 + uint32_t res0308[14];
96968 + /* HiGig/2 */
96969 + uint32_t hg_config; /* 0x340 Control and cfg */
96970 + uint32_t res0344[3];
96971 + uint32_t hg_pause_quanta; /* 0x350 Pause quanta */
96972 + uint32_t res0354[3];
96973 + uint32_t hg_pause_thresh; /* 0x360 Pause quanta threshold */
96974 + uint32_t res0364[3];
96975 + uint32_t hgrx_pause_status; /* 0x370 Receive pause status */
96976 + uint32_t hg_fifos_status; /* 0x374 fifos status */
96977 + uint32_t rhm; /* 0x378 rx messages counter */
96978 + uint32_t thm; /* 0x37C tx messages counter */
96979 +};
96980 +
96981 +struct memac_cfg {
96982 + bool reset_on_init;
96983 + bool rx_error_discard;
96984 + bool pause_ignore;
96985 + bool pause_forward_enable;
96986 + bool no_length_check_enable;
96987 + bool cmd_frame_enable;
96988 + bool send_idle_enable;
96989 + bool wan_mode_enable;
96990 + bool promiscuous_mode_enable;
96991 + bool tx_addr_ins_enable;
96992 + bool loopback_enable;
96993 + bool lgth_check_nostdr;
96994 + bool time_stamp_enable;
96995 + bool pad_enable;
96996 + bool phy_tx_ena_on;
96997 + bool rx_sfd_any;
96998 + bool rx_pbl_fwd;
96999 + bool tx_pbl_fwd;
97000 + bool debug_mode;
97001 + bool wake_on_lan;
97002 + uint16_t max_frame_length;
97003 + uint16_t pause_quanta;
97004 + uint32_t tx_ipg_length;
97005 +};
97006 +
97007 +
97008 +/**
97009 + * fman_memac_defconfig() - Get default MEMAC configuration
97010 + * @cfg: pointer to configuration structure.
97011 + *
97012 + * Call this function to obtain a default set of configuration values for
97013 + * initializing MEMAC. The user can overwrite any of the values before calling
97014 + * fman_memac_init(), if specific configuration needs to be applied.
97015 + */
97016 +void fman_memac_defconfig(struct memac_cfg *cfg);
97017 +
97018 +int fman_memac_init(struct memac_regs *regs,
97019 + struct memac_cfg *cfg,
97020 + enum enet_interface enet_interface,
97021 + enum enet_speed enet_speed,
97022 + bool slow_10g_if,
97023 + uint32_t exceptions);
97024 +
97025 +void fman_memac_enable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
97026 +
97027 +void fman_memac_disable(struct memac_regs *regs, bool apply_rx, bool apply_tx);
97028 +
97029 +void fman_memac_set_promiscuous(struct memac_regs *regs, bool val);
97030 +
97031 +void fman_memac_add_addr_in_paddr(struct memac_regs *regs,
97032 + uint8_t *adr,
97033 + uint8_t paddr_num);
97034 +
97035 +void fman_memac_clear_addr_in_paddr(struct memac_regs *regs,
97036 + uint8_t paddr_num);
97037 +
97038 +uint64_t fman_memac_get_counter(struct memac_regs *regs,
97039 + enum memac_counters reg_name);
97040 +
97041 +void fman_memac_set_tx_pause_frames(struct memac_regs *regs,
97042 + uint8_t priority, uint16_t pauseTime, uint16_t threshTime);
97043 +
97044 +uint16_t fman_memac_get_max_frame_len(struct memac_regs *regs);
97045 +
97046 +void fman_memac_set_exception(struct memac_regs *regs, uint32_t val,
97047 + bool enable);
97048 +
97049 +void fman_memac_reset_stat(struct memac_regs *regs);
97050 +
97051 +void fman_memac_reset(struct memac_regs *regs);
97052 +
97053 +void fman_memac_reset_filter_table(struct memac_regs *regs);
97054 +
97055 +void fman_memac_set_hash_table_entry(struct memac_regs *regs, uint32_t crc);
97056 +
97057 +void fman_memac_set_hash_table(struct memac_regs *regs, uint32_t val);
97058 +
97059 +void fman_memac_set_rx_ignore_pause_frames(struct memac_regs *regs,
97060 + bool enable);
97061 +
97062 +void fman_memac_set_wol(struct memac_regs *regs, bool enable);
97063 +
97064 +uint32_t fman_memac_get_event(struct memac_regs *regs, uint32_t ev_mask);
97065 +
97066 +void fman_memac_ack_event(struct memac_regs *regs, uint32_t ev_mask);
97067 +
97068 +uint32_t fman_memac_get_interrupt_mask(struct memac_regs *regs);
97069 +
97070 +void fman_memac_adjust_link(struct memac_regs *regs,
97071 + enum enet_interface iface_mode,
97072 + enum enet_speed speed, bool full_dx);
97073 +
97074 +
97075 +
97076 +#endif /*__FSL_FMAN_MEMAC_H*/
97077 --- /dev/null
97078 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_memac_mii_acc.h
97079 @@ -0,0 +1,78 @@
97080 +/*
97081 + * Copyright 2008-2013 Freescale Semiconductor Inc.
97082 + *
97083 + * Redistribution and use in source and binary forms, with or without
97084 + * modification, are permitted provided that the following conditions are met:
97085 + * * Redistributions of source code must retain the above copyright
97086 + * notice, this list of conditions and the following disclaimer.
97087 + * * Redistributions in binary form must reproduce the above copyright
97088 + * notice, this list of conditions and the following disclaimer in the
97089 + * documentation and/or other materials provided with the distribution.
97090 + * * Neither the name of Freescale Semiconductor nor the
97091 + * names of its contributors may be used to endorse or promote products
97092 + * derived from this software without specific prior written permission.
97093 + *
97094 + *
97095 + * ALTERNATIVELY, this software may be distributed under the terms of the
97096 + * GNU General Public License ("GPL") as published by the Free Software
97097 + * Foundation, either version 2 of that License or (at your option) any
97098 + * later version.
97099 + *
97100 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97101 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97102 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97103 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97104 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97105 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97106 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97107 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97108 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97109 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97110 + */
97111 +
97112 +#ifndef __FSL_FMAN_MEMAC_MII_ACC_H
97113 +#define __FSL_FMAN_MEMAC_MII_ACC_H
97114 +
97115 +#include "common/general.h"
97116 +#include "fsl_enet.h"
97117 +/* MII Management Registers */
97118 +#define MDIO_CFG_CLK_DIV_MASK 0x0080ff80
97119 +#define MDIO_CFG_CLK_DIV_SHIFT 7
97120 +#define MDIO_CFG_HOLD_MASK 0x0000001c
97121 +#define MDIO_CFG_ENC45 0x00000040
97122 +#define MDIO_CFG_READ_ERR 0x00000002
97123 +#define MDIO_CFG_BSY 0x00000001
97124 +
97125 +#define MDIO_CTL_PHY_ADDR_SHIFT 5
97126 +#define MDIO_CTL_READ 0x00008000
97127 +
97128 +#define MDIO_DATA_BSY 0x80000000
97129 +
97130 +/*MEMAC Internal PHY Registers - SGMII */
97131 +#define PHY_SGMII_CR_PHY_RESET 0x8000
97132 +#define PHY_SGMII_CR_RESET_AN 0x0200
97133 +#define PHY_SGMII_CR_DEF_VAL 0x1140
97134 +#define PHY_SGMII_DEV_ABILITY_SGMII 0x4001
97135 +#define PHY_SGMII_DEV_ABILITY_1000X 0x01A0
97136 +#define PHY_SGMII_IF_MODE_AN 0x0002
97137 +#define PHY_SGMII_IF_MODE_SGMII 0x0001
97138 +#define PHY_SGMII_IF_MODE_1000X 0x0000
97139 +
97140 +/*----------------------------------------------------*/
97141 +/* MII Configuration Control Memory Map Registers */
97142 +/*----------------------------------------------------*/
97143 +struct memac_mii_access_mem_map {
97144 + uint32_t mdio_cfg; /* 0x030 */
97145 + uint32_t mdio_ctrl; /* 0x034 */
97146 + uint32_t mdio_data; /* 0x038 */
97147 + uint32_t mdio_addr; /* 0x03c */
97148 +};
97149 +
97150 +int fman_memac_mii_read_phy_reg(struct memac_mii_access_mem_map *mii_regs,
97151 + uint8_t phy_addr, uint8_t reg, uint16_t *data,
97152 + enum enet_speed enet_speed);
97153 +int fman_memac_mii_write_phy_reg(struct memac_mii_access_mem_map *mii_regs,
97154 + uint8_t phy_addr, uint8_t reg, uint16_t data,
97155 + enum enet_speed enet_speed);
97156 +
97157 +#endif /* __MAC_API_MEMAC_MII_ACC_H */
97158 --- /dev/null
97159 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_port.h
97160 @@ -0,0 +1,593 @@
97161 +/*
97162 + * Copyright 2008-2013 Freescale Semiconductor Inc.
97163 + *
97164 + * Redistribution and use in source and binary forms, with or without
97165 + * modification, are permitted provided that the following conditions are met:
97166 + * * Redistributions of source code must retain the above copyright
97167 + * notice, this list of conditions and the following disclaimer.
97168 + * * Redistributions in binary form must reproduce the above copyright
97169 + * notice, this list of conditions and the following disclaimer in the
97170 + * documentation and/or other materials provided with the distribution.
97171 + * * Neither the name of Freescale Semiconductor nor the
97172 + * names of its contributors may be used to endorse or promote products
97173 + * derived from this software without specific prior written permission.
97174 + *
97175 + *
97176 + * ALTERNATIVELY, this software may be distributed under the terms of the
97177 + * GNU General Public License ("GPL") as published by the Free Software
97178 + * Foundation, either version 2 of that License or (at your option) any
97179 + * later version.
97180 + *
97181 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97182 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97183 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97184 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97185 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97186 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97187 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97188 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97189 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97190 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97191 + */
97192 +
97193 +#ifndef __FSL_FMAN_PORT_H
97194 +#define __FSL_FMAN_PORT_H
97195 +
97196 +#include "fsl_fman_sp.h"
97197 +
97198 +/** @Collection Registers bit fields */
97199 +
97200 +/** @Description BMI defines */
97201 +#define BMI_EBD_EN 0x80000000
97202 +
97203 +#define BMI_PORT_CFG_EN 0x80000000
97204 +#define BMI_PORT_CFG_FDOVR 0x02000000
97205 +#define BMI_PORT_CFG_IM 0x01000000
97206 +
97207 +#define BMI_PORT_STATUS_BSY 0x80000000
97208 +
97209 +#define BMI_DMA_ATTR_SWP_SHIFT FMAN_SP_DMA_ATTR_SWP_SHIFT
97210 +#define BMI_DMA_ATTR_IC_STASH_ON 0x10000000
97211 +#define BMI_DMA_ATTR_HDR_STASH_ON 0x04000000
97212 +#define BMI_DMA_ATTR_SG_STASH_ON 0x01000000
97213 +#define BMI_DMA_ATTR_WRITE_OPTIMIZE FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
97214 +
97215 +#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT 16
97216 +#define BMI_RX_FIFO_THRESHOLD_ETHE 0x80000000
97217 +
97218 +#define BMI_TX_FRAME_END_CS_IGNORE_SHIFT 24
97219 +#define BMI_RX_FRAME_END_CS_IGNORE_SHIFT 24
97220 +#define BMI_RX_FRAME_END_CUT_SHIFT 16
97221 +
97222 +#define BMI_IC_TO_EXT_SHIFT FMAN_SP_IC_TO_EXT_SHIFT
97223 +#define BMI_IC_FROM_INT_SHIFT FMAN_SP_IC_FROM_INT_SHIFT
97224 +
97225 +#define BMI_INT_BUF_MARG_SHIFT 28
97226 +#define BMI_EXT_BUF_MARG_START_SHIFT FMAN_SP_EXT_BUF_MARG_START_SHIFT
97227 +
97228 +#define BMI_CMD_MR_LEAC 0x00200000
97229 +#define BMI_CMD_MR_SLEAC 0x00100000
97230 +#define BMI_CMD_MR_MA 0x00080000
97231 +#define BMI_CMD_MR_DEAS 0x00040000
97232 +#define BMI_CMD_RX_MR_DEF (BMI_CMD_MR_LEAC | \
97233 + BMI_CMD_MR_SLEAC | \
97234 + BMI_CMD_MR_MA | \
97235 + BMI_CMD_MR_DEAS)
97236 +#define BMI_CMD_TX_MR_DEF 0
97237 +#define BMI_CMD_OP_MR_DEF (BMI_CMD_MR_DEAS | \
97238 + BMI_CMD_MR_MA)
97239 +
97240 +#define BMI_CMD_ATTR_ORDER 0x80000000
97241 +#define BMI_CMD_ATTR_SYNC 0x02000000
97242 +#define BMI_CMD_ATTR_COLOR_SHIFT 26
97243 +
97244 +#define BMI_FIFO_PIPELINE_DEPTH_SHIFT 12
97245 +#define BMI_NEXT_ENG_FD_BITS_SHIFT 24
97246 +#define BMI_FRAME_END_CS_IGNORE_SHIFT 24
97247 +
97248 +#define BMI_COUNTERS_EN 0x80000000
97249 +
97250 +#define BMI_EXT_BUF_POOL_VALID FMAN_SP_EXT_BUF_POOL_VALID
97251 +#define BMI_EXT_BUF_POOL_EN_COUNTER FMAN_SP_EXT_BUF_POOL_EN_COUNTER
97252 +#define BMI_EXT_BUF_POOL_BACKUP FMAN_SP_EXT_BUF_POOL_BACKUP
97253 +#define BMI_EXT_BUF_POOL_ID_SHIFT 16
97254 +#define BMI_EXT_BUF_POOL_ID_MASK 0x003F0000
97255 +#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT 16
97256 +
97257 +#define BMI_TX_FIFO_MIN_FILL_SHIFT 16
97258 +#define BMI_TX_FIFO_PIPELINE_DEPTH_SHIFT 12
97259 +
97260 +#define MAX_PERFORMANCE_TASK_COMP 64
97261 +#define MAX_PERFORMANCE_RX_QUEUE_COMP 64
97262 +#define MAX_PERFORMANCE_TX_QUEUE_COMP 8
97263 +#define MAX_PERFORMANCE_DMA_COMP 16
97264 +#define MAX_PERFORMANCE_FIFO_COMP 1024
97265 +
97266 +#define BMI_PERFORMANCE_TASK_COMP_SHIFT 24
97267 +#define BMI_PERFORMANCE_QUEUE_COMP_SHIFT 16
97268 +#define BMI_PERFORMANCE_DMA_COMP_SHIFT 12
97269 +
97270 +#define BMI_RATE_LIMIT_GRAN_TX 16000 /* In Kbps */
97271 +#define BMI_RATE_LIMIT_GRAN_OP 10000 /* In frames */
97272 +#define BMI_RATE_LIMIT_MAX_RATE_IN_GRAN_UNITS 1024
97273 +#define BMI_RATE_LIMIT_MAX_BURST_SIZE 1024 /* In KBytes */
97274 +#define BMI_RATE_LIMIT_MAX_BURST_SHIFT 16
97275 +#define BMI_RATE_LIMIT_HIGH_BURST_SIZE_GRAN 0x80000000
97276 +#define BMI_RATE_LIMIT_SCALE_TSBS_SHIFT 16
97277 +#define BMI_RATE_LIMIT_SCALE_EN 0x80000000
97278 +#define BMI_SG_DISABLE FMAN_SP_SG_DISABLE
97279 +
97280 +/** @Description QMI defines */
97281 +#define QMI_PORT_CFG_EN 0x80000000
97282 +#define QMI_PORT_CFG_EN_COUNTERS 0x10000000
97283 +
97284 +#define QMI_PORT_STATUS_DEQ_TNUM_BSY 0x80000000
97285 +#define QMI_PORT_STATUS_DEQ_FD_BSY 0x20000000
97286 +
97287 +#define QMI_DEQ_CFG_PRI 0x80000000
97288 +#define QMI_DEQ_CFG_TYPE1 0x10000000
97289 +#define QMI_DEQ_CFG_TYPE2 0x20000000
97290 +#define QMI_DEQ_CFG_TYPE3 0x30000000
97291 +#define QMI_DEQ_CFG_PREFETCH_PARTIAL 0x01000000
97292 +#define QMI_DEQ_CFG_PREFETCH_FULL 0x03000000
97293 +#define QMI_DEQ_CFG_SP_MASK 0xf
97294 +#define QMI_DEQ_CFG_SP_SHIFT 20
97295 +
97296 +
97297 +/** @Description General port defines */
97298 +#define FMAN_PORT_EXT_POOLS_NUM(fm_rev_maj) \
97299 + (((fm_rev_maj) == 4) ? 4 : 8)
97300 +#define FMAN_PORT_MAX_EXT_POOLS_NUM 8
97301 +#define FMAN_PORT_OBS_EXT_POOLS_NUM 2
97302 +#define FMAN_PORT_CG_MAP_NUM 8
97303 +#define FMAN_PORT_PRS_RESULT_WORDS_NUM 8
97304 +#define FMAN_PORT_BMI_FIFO_UNITS 0x100
97305 +#define FMAN_PORT_IC_OFFSET_UNITS 0x10
97306 +
97307 +
97308 +/** @Collection FM Port Register Map */
97309 +
97310 +/** @Description BMI Rx port register map */
97311 +struct fman_port_rx_bmi_regs {
97312 + uint32_t fmbm_rcfg; /**< Rx Configuration */
97313 + uint32_t fmbm_rst; /**< Rx Status */
97314 + uint32_t fmbm_rda; /**< Rx DMA attributes*/
97315 + uint32_t fmbm_rfp; /**< Rx FIFO Parameters*/
97316 + uint32_t fmbm_rfed; /**< Rx Frame End Data*/
97317 + uint32_t fmbm_ricp; /**< Rx Internal Context Parameters*/
97318 + uint32_t fmbm_rim; /**< Rx Internal Buffer Margins*/
97319 + uint32_t fmbm_rebm; /**< Rx External Buffer Margins*/
97320 + uint32_t fmbm_rfne; /**< Rx Frame Next Engine*/
97321 + uint32_t fmbm_rfca; /**< Rx Frame Command Attributes.*/
97322 + uint32_t fmbm_rfpne; /**< Rx Frame Parser Next Engine*/
97323 + uint32_t fmbm_rpso; /**< Rx Parse Start Offset*/
97324 + uint32_t fmbm_rpp; /**< Rx Policer Profile */
97325 + uint32_t fmbm_rccb; /**< Rx Coarse Classification Base */
97326 + uint32_t fmbm_reth; /**< Rx Excessive Threshold */
97327 + uint32_t reserved003c[1]; /**< (0x03C 0x03F) */
97328 + uint32_t fmbm_rprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
97329 + /**< Rx Parse Results Array Init*/
97330 + uint32_t fmbm_rfqid; /**< Rx Frame Queue ID*/
97331 + uint32_t fmbm_refqid; /**< Rx Error Frame Queue ID*/
97332 + uint32_t fmbm_rfsdm; /**< Rx Frame Status Discard Mask*/
97333 + uint32_t fmbm_rfsem; /**< Rx Frame Status Error Mask*/
97334 + uint32_t fmbm_rfene; /**< Rx Frame Enqueue Next Engine */
97335 + uint32_t reserved0074[0x2]; /**< (0x074-0x07C) */
97336 + uint32_t fmbm_rcmne; /**< Rx Frame Continuous Mode Next Engine */
97337 + uint32_t reserved0080[0x20];/**< (0x080 0x0FF) */
97338 + uint32_t fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
97339 + /**< Buffer Manager pool Information-*/
97340 + uint32_t fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];
97341 + /**< Allocate Counter-*/
97342 + uint32_t reserved0130[8];
97343 + /**< 0x130/0x140 - 0x15F reserved -*/
97344 + uint32_t fmbm_rcgm[FMAN_PORT_CG_MAP_NUM];
97345 + /**< Congestion Group Map*/
97346 + uint32_t fmbm_mpd; /**< BM Pool Depletion */
97347 + uint32_t reserved0184[0x1F]; /**< (0x184 0x1FF) */
97348 + uint32_t fmbm_rstc; /**< Rx Statistics Counters*/
97349 + uint32_t fmbm_rfrc; /**< Rx Frame Counter*/
97350 + uint32_t fmbm_rfbc; /**< Rx Bad Frames Counter*/
97351 + uint32_t fmbm_rlfc; /**< Rx Large Frames Counter*/
97352 + uint32_t fmbm_rffc; /**< Rx Filter Frames Counter*/
97353 + uint32_t fmbm_rfdc; /**< Rx Frame Discard Counter*/
97354 + uint32_t fmbm_rfldec; /**< Rx Frames List DMA Error Counter*/
97355 + uint32_t fmbm_rodc; /**< Rx Out of Buffers Discard nntr*/
97356 + uint32_t fmbm_rbdc; /**< Rx Buffers Deallocate Counter*/
97357 + uint32_t reserved0224[0x17]; /**< (0x224 0x27F) */
97358 + uint32_t fmbm_rpc; /**< Rx Performance Counters*/
97359 + uint32_t fmbm_rpcp; /**< Rx Performance Count Parameters*/
97360 + uint32_t fmbm_rccn; /**< Rx Cycle Counter*/
97361 + uint32_t fmbm_rtuc; /**< Rx Tasks Utilization Counter*/
97362 + uint32_t fmbm_rrquc; /**< Rx Receive Queue Utilization cntr*/
97363 + uint32_t fmbm_rduc; /**< Rx DMA Utilization Counter*/
97364 + uint32_t fmbm_rfuc; /**< Rx FIFO Utilization Counter*/
97365 + uint32_t fmbm_rpac; /**< Rx Pause Activation Counter*/
97366 + uint32_t reserved02a0[0x18]; /**< (0x2A0 0x2FF) */
97367 + uint32_t fmbm_rdbg; /**< Rx Debug-*/
97368 +};
97369 +
97370 +/** @Description BMI Tx port register map */
97371 +struct fman_port_tx_bmi_regs {
97372 + uint32_t fmbm_tcfg; /**< Tx Configuration */
97373 + uint32_t fmbm_tst; /**< Tx Status */
97374 + uint32_t fmbm_tda; /**< Tx DMA attributes */
97375 + uint32_t fmbm_tfp; /**< Tx FIFO Parameters */
97376 + uint32_t fmbm_tfed; /**< Tx Frame End Data */
97377 + uint32_t fmbm_ticp; /**< Tx Internal Context Parameters */
97378 + uint32_t fmbm_tfdne; /**< Tx Frame Dequeue Next Engine. */
97379 + uint32_t fmbm_tfca; /**< Tx Frame Command attribute. */
97380 + uint32_t fmbm_tcfqid; /**< Tx Confirmation Frame Queue ID. */
97381 + uint32_t fmbm_tefqid; /**< Tx Frame Error Queue ID */
97382 + uint32_t fmbm_tfene; /**< Tx Frame Enqueue Next Engine */
97383 + uint32_t fmbm_trlmts; /**< Tx Rate Limiter Scale */
97384 + uint32_t fmbm_trlmt; /**< Tx Rate Limiter */
97385 + uint32_t reserved0034[0x0e]; /**< (0x034-0x6c) */
97386 + uint32_t fmbm_tccb; /**< Tx Coarse Classification base */
97387 + uint32_t fmbm_tfne; /**< Tx Frame Next Engine */
97388 + uint32_t fmbm_tpfcm[0x02]; /**< Tx Priority based Flow Control (PFC) Mapping */
97389 + uint32_t fmbm_tcmne; /**< Tx Frame Continuous Mode Next Engine */
97390 + uint32_t reserved0080[0x60]; /**< (0x080-0x200) */
97391 + uint32_t fmbm_tstc; /**< Tx Statistics Counters */
97392 + uint32_t fmbm_tfrc; /**< Tx Frame Counter */
97393 + uint32_t fmbm_tfdc; /**< Tx Frames Discard Counter */
97394 + uint32_t fmbm_tfledc; /**< Tx Frame len error discard cntr */
97395 + uint32_t fmbm_tfufdc; /**< Tx Frame unsprt frmt discard cntr*/
97396 + uint32_t fmbm_tbdc; /**< Tx Buffers Deallocate Counter */
97397 + uint32_t reserved0218[0x1A]; /**< (0x218-0x280) */
97398 + uint32_t fmbm_tpc; /**< Tx Performance Counters*/
97399 + uint32_t fmbm_tpcp; /**< Tx Performance Count Parameters*/
97400 + uint32_t fmbm_tccn; /**< Tx Cycle Counter*/
97401 + uint32_t fmbm_ttuc; /**< Tx Tasks Utilization Counter*/
97402 + uint32_t fmbm_ttcquc; /**< Tx Transmit conf Q util Counter*/
97403 + uint32_t fmbm_tduc; /**< Tx DMA Utilization Counter*/
97404 + uint32_t fmbm_tfuc; /**< Tx FIFO Utilization Counter*/
97405 +};
97406 +
97407 +/** @Description BMI O/H port register map */
97408 +struct fman_port_oh_bmi_regs {
97409 + uint32_t fmbm_ocfg; /**< O/H Configuration */
97410 + uint32_t fmbm_ost; /**< O/H Status */
97411 + uint32_t fmbm_oda; /**< O/H DMA attributes */
97412 + uint32_t fmbm_oicp; /**< O/H Internal Context Parameters */
97413 + uint32_t fmbm_ofdne; /**< O/H Frame Dequeue Next Engine */
97414 + uint32_t fmbm_ofne; /**< O/H Frame Next Engine */
97415 + uint32_t fmbm_ofca; /**< O/H Frame Command Attributes. */
97416 + uint32_t fmbm_ofpne; /**< O/H Frame Parser Next Engine */
97417 + uint32_t fmbm_opso; /**< O/H Parse Start Offset */
97418 + uint32_t fmbm_opp; /**< O/H Policer Profile */
97419 + uint32_t fmbm_occb; /**< O/H Coarse Classification base */
97420 + uint32_t fmbm_oim; /**< O/H Internal margins*/
97421 + uint32_t fmbm_ofp; /**< O/H Fifo Parameters*/
97422 + uint32_t fmbm_ofed; /**< O/H Frame End Data*/
97423 + uint32_t reserved0030[2]; /**< (0x038 - 0x03F) */
97424 + uint32_t fmbm_oprai[FMAN_PORT_PRS_RESULT_WORDS_NUM];
97425 + /**< O/H Parse Results Array Initialization */
97426 + uint32_t fmbm_ofqid; /**< O/H Frame Queue ID */
97427 + uint32_t fmbm_oefqid; /**< O/H Error Frame Queue ID */
97428 + uint32_t fmbm_ofsdm; /**< O/H Frame Status Discard Mask */
97429 + uint32_t fmbm_ofsem; /**< O/H Frame Status Error Mask */
97430 + uint32_t fmbm_ofene; /**< O/H Frame Enqueue Next Engine */
97431 + uint32_t fmbm_orlmts; /**< O/H Rate Limiter Scale */
97432 + uint32_t fmbm_orlmt; /**< O/H Rate Limiter */
97433 + uint32_t fmbm_ocmne; /**< O/H Continuous Mode Next Engine */
97434 + uint32_t reserved0080[0x20]; /**< 0x080 - 0x0FF Reserved */
97435 + uint32_t fmbm_oebmpi[2]; /**< Buf Mngr Observed Pool Info */
97436 + uint32_t reserved0108[0x16]; /**< 0x108 - 0x15F Reserved */
97437 + uint32_t fmbm_ocgm[FMAN_PORT_CG_MAP_NUM]; /**< Observed Congestion Group Map */
97438 + uint32_t fmbm_ompd; /**< Observed BMan Pool Depletion */
97439 + uint32_t reserved0184[0x1F]; /**< 0x184 - 0x1FF Reserved */
97440 + uint32_t fmbm_ostc; /**< O/H Statistics Counters */
97441 + uint32_t fmbm_ofrc; /**< O/H Frame Counter */
97442 + uint32_t fmbm_ofdc; /**< O/H Frames Discard Counter */
97443 + uint32_t fmbm_ofledc; /**< O/H Frames Len Err Discard Cntr */
97444 + uint32_t fmbm_ofufdc; /**< O/H Frames Unsprtd Discard Cutr */
97445 + uint32_t fmbm_offc; /**< O/H Filter Frames Counter */
97446 + uint32_t fmbm_ofwdc; /**< Rx Frames WRED Discard Counter */
97447 + uint32_t fmbm_ofldec; /**< O/H Frames List DMA Error Cntr */
97448 + uint32_t fmbm_obdc; /**< O/H Buffers Deallocate Counter */
97449 + uint32_t reserved0218[0x17]; /**< (0x218 - 0x27F) */
97450 + uint32_t fmbm_opc; /**< O/H Performance Counters */
97451 + uint32_t fmbm_opcp; /**< O/H Performance Count Parameters */
97452 + uint32_t fmbm_occn; /**< O/H Cycle Counter */
97453 + uint32_t fmbm_otuc; /**< O/H Tasks Utilization Counter */
97454 + uint32_t fmbm_oduc; /**< O/H DMA Utilization Counter */
97455 + uint32_t fmbm_ofuc; /**< O/H FIFO Utilization Counter */
97456 +};
97457 +
97458 +/** @Description BMI port register map */
97459 +union fman_port_bmi_regs {
97460 + struct fman_port_rx_bmi_regs rx;
97461 + struct fman_port_tx_bmi_regs tx;
97462 + struct fman_port_oh_bmi_regs oh;
97463 +};
97464 +
97465 +/** @Description QMI port register map */
97466 +struct fman_port_qmi_regs {
97467 + uint32_t fmqm_pnc; /**< PortID n Configuration Register */
97468 + uint32_t fmqm_pns; /**< PortID n Status Register */
97469 + uint32_t fmqm_pnts; /**< PortID n Task Status Register */
97470 + uint32_t reserved00c[4]; /**< 0xn00C - 0xn01B */
97471 + uint32_t fmqm_pnen; /**< PortID n Enqueue NIA Register */
97472 + uint32_t fmqm_pnetfc; /**< PortID n Enq Total Frame Counter */
97473 + uint32_t reserved024[2]; /**< 0xn024 - 0x02B */
97474 + uint32_t fmqm_pndn; /**< PortID n Dequeue NIA Register */
97475 + uint32_t fmqm_pndc; /**< PortID n Dequeue Config Register */
97476 + uint32_t fmqm_pndtfc; /**< PortID n Dequeue tot Frame cntr */
97477 + uint32_t fmqm_pndfdc; /**< PortID n Dequeue FQID Dflt Cntr */
97478 + uint32_t fmqm_pndcc; /**< PortID n Dequeue Confirm Counter */
97479 +};
97480 +
97481 +
97482 +enum fman_port_dma_swap {
97483 + E_FMAN_PORT_DMA_NO_SWAP, /**< No swap, transfer data as is */
97484 + E_FMAN_PORT_DMA_SWAP_LE,
97485 + /**< The transferred data should be swapped in PPC Little Endian mode */
97486 + E_FMAN_PORT_DMA_SWAP_BE
97487 + /**< The transferred data should be swapped in Big Endian mode */
97488 +};
97489 +
97490 +/* Default port color */
97491 +enum fman_port_color {
97492 + E_FMAN_PORT_COLOR_GREEN, /**< Default port color is green */
97493 + E_FMAN_PORT_COLOR_YELLOW, /**< Default port color is yellow */
97494 + E_FMAN_PORT_COLOR_RED, /**< Default port color is red */
97495 + E_FMAN_PORT_COLOR_OVERRIDE /**< Ignore color */
97496 +};
97497 +
97498 +/* QMI dequeue from the SP channel - types */
97499 +enum fman_port_deq_type {
97500 + E_FMAN_PORT_DEQ_BY_PRI,
97501 + /**< Priority precedence and Intra-Class scheduling */
97502 + E_FMAN_PORT_DEQ_ACTIVE_FQ,
97503 + /**< Active FQ precedence and Intra-Class scheduling */
97504 + E_FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
97505 + /**< Active FQ precedence and override Intra-Class scheduling */
97506 +};
97507 +
97508 +/* QMI dequeue prefetch modes */
97509 +enum fman_port_deq_prefetch {
97510 + E_FMAN_PORT_DEQ_NO_PREFETCH, /**< No prefetch mode */
97511 + E_FMAN_PORT_DEQ_PART_PREFETCH, /**< Partial prefetch mode */
97512 + E_FMAN_PORT_DEQ_FULL_PREFETCH /**< Full prefetch mode */
97513 +};
97514 +
97515 +/* Parameters for defining performance counters behavior */
97516 +struct fman_port_perf_cnt_params {
97517 + uint8_t task_val; /**< Task compare value */
97518 + uint8_t queue_val;
97519 + /**< Rx or Tx conf queue compare value (unused for O/H ports) */
97520 + uint8_t dma_val; /**< Dma compare value */
97521 + uint32_t fifo_val; /**< Fifo compare value (in bytes) */
97522 +};
97523 +
97524 +/** @Description FM Port configuration structure, used at init */
97525 +struct fman_port_cfg {
97526 + struct fman_port_perf_cnt_params perf_cnt_params;
97527 + /* BMI parameters */
97528 + enum fman_port_dma_swap dma_swap_data;
97529 + bool dma_ic_stash_on;
97530 + bool dma_header_stash_on;
97531 + bool dma_sg_stash_on;
97532 + bool dma_write_optimize;
97533 + uint16_t ic_ext_offset;
97534 + uint8_t ic_int_offset;
97535 + uint16_t ic_size;
97536 + enum fman_port_color color;
97537 + bool sync_req;
97538 + bool discard_override;
97539 + uint8_t checksum_bytes_ignore;
97540 + uint8_t rx_cut_end_bytes;
97541 + uint32_t rx_pri_elevation;
97542 + uint32_t rx_fifo_thr;
97543 + uint8_t rx_fd_bits;
97544 + uint8_t int_buf_start_margin;
97545 + uint16_t ext_buf_start_margin;
97546 + uint16_t ext_buf_end_margin;
97547 + uint32_t tx_fifo_min_level;
97548 + uint32_t tx_fifo_low_comf_level;
97549 + uint8_t tx_fifo_deq_pipeline_depth;
97550 + bool stats_counters_enable;
97551 + bool perf_counters_enable;
97552 + /* QMI parameters */
97553 + bool deq_high_pri;
97554 + enum fman_port_deq_type deq_type;
97555 + enum fman_port_deq_prefetch deq_prefetch_opt;
97556 + uint16_t deq_byte_cnt;
97557 + bool queue_counters_enable;
97558 + bool no_scatter_gather;
97559 + int errata_A006675;
97560 + int errata_A006320;
97561 + int excessive_threshold_register;
97562 + int fmbm_rebm_has_sgd;
97563 + int fmbm_tfne_has_features;
97564 + int qmi_deq_options_support;
97565 +};
97566 +
97567 +enum fman_port_type {
97568 + E_FMAN_PORT_TYPE_OP = 0,
97569 + /**< Offline parsing port, shares id-s with
97570 + * host command, so must have exclusive id-s */
97571 + E_FMAN_PORT_TYPE_RX, /**< 1G Rx port */
97572 + E_FMAN_PORT_TYPE_RX_10G, /**< 10G Rx port */
97573 + E_FMAN_PORT_TYPE_TX, /**< 1G Tx port */
97574 + E_FMAN_PORT_TYPE_TX_10G, /**< 10G Tx port */
97575 + E_FMAN_PORT_TYPE_DUMMY,
97576 + E_FMAN_PORT_TYPE_HC = E_FMAN_PORT_TYPE_DUMMY
97577 + /**< Host command port, shares id-s with
97578 + * offline parsing ports, so must have exclusive id-s */
97579 +};
97580 +
97581 +struct fman_port_params {
97582 + uint32_t discard_mask;
97583 + uint32_t err_mask;
97584 + uint32_t dflt_fqid;
97585 + uint32_t err_fqid;
97586 + uint8_t deq_sp;
97587 + bool dont_release_buf;
97588 +};
97589 +
97590 +/* Port context - used by most API functions */
97591 +struct fman_port {
97592 + enum fman_port_type type;
97593 + uint8_t fm_rev_maj;
97594 + uint8_t fm_rev_min;
97595 + union fman_port_bmi_regs *bmi_regs;
97596 + struct fman_port_qmi_regs *qmi_regs;
97597 + bool im_en;
97598 + uint8_t ext_pools_num;
97599 +};
97600 +
97601 +/** @Description External buffer pools configuration */
97602 +struct fman_port_bpools {
97603 + uint8_t count; /**< Num of pools to set up */
97604 + bool counters_enable; /**< Enable allocate counters */
97605 + uint8_t grp_bp_depleted_num;
97606 + /**< Number of depleted pools - if reached the BMI indicates
97607 + * the MAC to send a pause frame */
97608 + struct {
97609 + uint8_t bpid; /**< BM pool ID */
97610 + uint16_t size;
97611 + /**< Pool's size - must be in ascending order */
97612 + bool is_backup;
97613 + /**< If this is a backup pool */
97614 + bool grp_bp_depleted;
97615 + /**< Consider this buffer in multiple pools depletion criteria*/
97616 + bool single_bp_depleted;
97617 + /**< Consider this buffer in single pool depletion criteria */
97618 + bool pfc_priorities_en;
97619 + } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
97620 +};
97621 +
97622 +enum fman_port_rate_limiter_scale_down {
97623 + E_FMAN_PORT_RATE_DOWN_NONE,
97624 + E_FMAN_PORT_RATE_DOWN_BY_2,
97625 + E_FMAN_PORT_RATE_DOWN_BY_4,
97626 + E_FMAN_PORT_RATE_DOWN_BY_8
97627 +};
97628 +
97629 +/* Rate limiter configuration */
97630 +struct fman_port_rate_limiter {
97631 + uint8_t count_1micro_bit;
97632 + bool high_burst_size_gran;
97633 + /**< Defines burst_size granularity for OP ports; when TRUE,
97634 + * burst_size below counts in frames, otherwise in 10^3 frames */
97635 + uint16_t burst_size;
97636 + /**< Max burst size, in KBytes for Tx port, according to
97637 + * high_burst_size_gran definition for OP port */
97638 + uint32_t rate;
97639 + /**< In Kbps for Tx port, in frames/sec for OP port */
97640 + enum fman_port_rate_limiter_scale_down rate_factor;
97641 +};
97642 +
97643 +/* BMI statistics counters */
97644 +enum fman_port_stats_counters {
97645 + E_FMAN_PORT_STATS_CNT_FRAME,
97646 + /**< Number of processed frames; valid for all ports */
97647 + E_FMAN_PORT_STATS_CNT_DISCARD,
97648 + /**< For Rx ports - frames discarded by QMAN, for Tx or O/H ports -
97649 + * frames discarded due to DMA error; valid for all ports */
97650 + E_FMAN_PORT_STATS_CNT_DEALLOC_BUF,
97651 + /**< Number of buffer deallocate operations; valid for all ports */
97652 + E_FMAN_PORT_STATS_CNT_RX_BAD_FRAME,
97653 + /**< Number of bad Rx frames, like CRC error, Rx FIFO overflow etc;
97654 + * valid for Rx ports only */
97655 + E_FMAN_PORT_STATS_CNT_RX_LARGE_FRAME,
97656 + /**< Number of Rx oversized frames, that is frames exceeding max frame
97657 + * size configured for the corresponding ETH controller;
97658 + * valid for Rx ports only */
97659 + E_FMAN_PORT_STATS_CNT_RX_OUT_OF_BUF,
97660 + /**< Frames discarded due to lack of external buffers; valid for
97661 + * Rx ports only */
97662 + E_FMAN_PORT_STATS_CNT_LEN_ERR,
97663 + /**< Frames discarded due to frame length error; valid for Tx and
97664 + * O/H ports only */
97665 + E_FMAN_PORT_STATS_CNT_UNSUPPORTED_FORMAT,
97666 + /**< Frames discarded due to unsupported FD format; valid for Tx
97667 + * and O/H ports only */
97668 + E_FMAN_PORT_STATS_CNT_FILTERED_FRAME,
97669 + /**< Number of frames filtered out by PCD module; valid for
97670 + * Rx and OP ports only */
97671 + E_FMAN_PORT_STATS_CNT_DMA_ERR,
97672 + /**< Frames rejected by QMAN that were not able to release their
97673 + * buffers due to DMA error; valid for Rx and O/H ports only */
97674 + E_FMAN_PORT_STATS_CNT_WRED_DISCARD
97675 + /**< Frames going through O/H port that were not able to to enter the
97676 + * return queue due to WRED algorithm; valid for O/H ports only */
97677 +};
97678 +
97679 +/* BMI performance counters */
97680 +enum fman_port_perf_counters {
97681 + E_FMAN_PORT_PERF_CNT_CYCLE, /**< Cycle counter */
97682 + E_FMAN_PORT_PERF_CNT_TASK_UTIL, /**< Tasks utilization counter */
97683 + E_FMAN_PORT_PERF_CNT_QUEUE_UTIL,
97684 + /**< For Rx ports - Rx queue utilization, for Tx ports - Tx conf queue
97685 + * utilization; not valid for O/H ports */
97686 + E_FMAN_PORT_PERF_CNT_DMA_UTIL, /**< DMA utilization counter */
97687 + E_FMAN_PORT_PERF_CNT_FIFO_UTIL, /**< FIFO utilization counter */
97688 + E_FMAN_PORT_PERF_CNT_RX_PAUSE
97689 + /**< Number of cycles in which Rx pause activation control is on;
97690 + * valid for Rx ports only */
97691 +};
97692 +
97693 +/* QMI counters */
97694 +enum fman_port_qmi_counters {
97695 + E_FMAN_PORT_ENQ_TOTAL, /**< EnQ tot frame cntr */
97696 + E_FMAN_PORT_DEQ_TOTAL, /**< DeQ tot frame cntr; invalid for Rx ports */
97697 + E_FMAN_PORT_DEQ_FROM_DFLT,
97698 + /**< Dequeue from default FQID counter not valid for Rx ports */
97699 + E_FMAN_PORT_DEQ_CONFIRM /**< DeQ confirm cntr invalid for Rx ports */
97700 +};
97701 +
97702 +
97703 +/** @Collection FM Port API */
97704 +void fman_port_defconfig(struct fman_port_cfg *cfg, enum fman_port_type type);
97705 +int fman_port_init(struct fman_port *port,
97706 + struct fman_port_cfg *cfg,
97707 + struct fman_port_params *params);
97708 +int fman_port_enable(struct fman_port *port);
97709 +int fman_port_disable(const struct fman_port *port);
97710 +int fman_port_set_bpools(const struct fman_port *port,
97711 + const struct fman_port_bpools *bp);
97712 +int fman_port_set_rate_limiter(struct fman_port *port,
97713 + struct fman_port_rate_limiter *rate_limiter);
97714 +int fman_port_delete_rate_limiter(struct fman_port *port);
97715 +int fman_port_set_err_mask(struct fman_port *port, uint32_t err_mask);
97716 +int fman_port_set_discard_mask(struct fman_port *port, uint32_t discard_mask);
97717 +int fman_port_modify_rx_fd_bits(struct fman_port *port,
97718 + uint8_t rx_fd_bits,
97719 + bool add);
97720 +int fman_port_set_perf_cnt_params(struct fman_port *port,
97721 + struct fman_port_perf_cnt_params *params);
97722 +int fman_port_set_stats_cnt_mode(struct fman_port *port, bool enable);
97723 +int fman_port_set_perf_cnt_mode(struct fman_port *port, bool enable);
97724 +int fman_port_set_queue_cnt_mode(struct fman_port *port, bool enable);
97725 +int fman_port_set_bpool_cnt_mode(struct fman_port *port,
97726 + uint8_t bpid,
97727 + bool enable);
97728 +uint32_t fman_port_get_stats_counter(struct fman_port *port,
97729 + enum fman_port_stats_counters counter);
97730 +void fman_port_set_stats_counter(struct fman_port *port,
97731 + enum fman_port_stats_counters counter,
97732 + uint32_t value);
97733 +uint32_t fman_port_get_perf_counter(struct fman_port *port,
97734 + enum fman_port_perf_counters counter);
97735 +void fman_port_set_perf_counter(struct fman_port *port,
97736 + enum fman_port_perf_counters counter,
97737 + uint32_t value);
97738 +uint32_t fman_port_get_qmi_counter(struct fman_port *port,
97739 + enum fman_port_qmi_counters counter);
97740 +void fman_port_set_qmi_counter(struct fman_port *port,
97741 + enum fman_port_qmi_counters counter,
97742 + uint32_t value);
97743 +uint32_t fman_port_get_bpool_counter(struct fman_port *port, uint8_t bpid);
97744 +void fman_port_set_bpool_counter(struct fman_port *port,
97745 + uint8_t bpid,
97746 + uint32_t value);
97747 +int fman_port_add_congestion_grps(struct fman_port *port,
97748 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
97749 +int fman_port_remove_congestion_grps(struct fman_port *port,
97750 + uint32_t grps_map[FMAN_PORT_CG_MAP_NUM]);
97751 +
97752 +
97753 +#endif /* __FSL_FMAN_PORT_H */
97754 --- /dev/null
97755 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_prs.h
97756 @@ -0,0 +1,102 @@
97757 +/*
97758 + * Copyright 2008-2012 Freescale Semiconductor Inc.
97759 + *
97760 + * Redistribution and use in source and binary forms, with or without
97761 + * modification, are permitted provided that the following conditions are met:
97762 + * * Redistributions of source code must retain the above copyright
97763 + * notice, this list of conditions and the following disclaimer.
97764 + * * Redistributions in binary form must reproduce the above copyright
97765 + * notice, this list of conditions and the following disclaimer in the
97766 + * documentation and/or other materials provided with the distribution.
97767 + * * Neither the name of Freescale Semiconductor nor the
97768 + * names of its contributors may be used to endorse or promote products
97769 + * derived from this software without specific prior written permission.
97770 + *
97771 + *
97772 + * ALTERNATIVELY, this software may be distributed under the terms of the
97773 + * GNU General Public License ("GPL") as published by the Free Software
97774 + * Foundation, either version 2 of that License or (at your option) any
97775 + * later version.
97776 + *
97777 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97778 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97779 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97780 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97781 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97782 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97783 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97784 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97785 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97786 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97787 + */
97788 +
97789 +#ifndef __FSL_FMAN_PRS_H
97790 +#define __FSL_FMAN_PRS_H
97791 +
97792 +#include "common/general.h"
97793 +
97794 +#define FM_PCD_EX_PRS_DOUBLE_ECC 0x02000000
97795 +#define FM_PCD_EX_PRS_SINGLE_ECC 0x01000000
97796 +
97797 +#define FM_PCD_PRS_PPSC_ALL_PORTS 0xffff0000
97798 +#define FM_PCD_PRS_RPIMAC_EN 0x00000001
97799 +#define FM_PCD_PRS_PORT_IDLE_STS 0xffff0000
97800 +#define FM_PCD_PRS_SINGLE_ECC 0x00004000
97801 +#define FM_PCD_PRS_DOUBLE_ECC 0x00004000
97802 +#define PRS_MAX_CYCLE_LIMIT 8191
97803 +
97804 +#define DEFAULT_MAX_PRS_CYC_LIM 0
97805 +
97806 +struct fman_prs_regs {
97807 + uint32_t fmpr_rpclim;
97808 + uint32_t fmpr_rpimac;
97809 + uint32_t pmeec;
97810 + uint32_t res00c[5];
97811 + uint32_t fmpr_pevr;
97812 + uint32_t fmpr_pever;
97813 + uint32_t res028;
97814 + uint32_t fmpr_perr;
97815 + uint32_t fmpr_perer;
97816 + uint32_t res034;
97817 + uint32_t res038[10];
97818 + uint32_t fmpr_ppsc;
97819 + uint32_t res064;
97820 + uint32_t fmpr_pds;
97821 + uint32_t fmpr_l2rrs;
97822 + uint32_t fmpr_l3rrs;
97823 + uint32_t fmpr_l4rrs;
97824 + uint32_t fmpr_srrs;
97825 + uint32_t fmpr_l2rres;
97826 + uint32_t fmpr_l3rres;
97827 + uint32_t fmpr_l4rres;
97828 + uint32_t fmpr_srres;
97829 + uint32_t fmpr_spcs;
97830 + uint32_t fmpr_spscs;
97831 + uint32_t fmpr_hxscs;
97832 + uint32_t fmpr_mrcs;
97833 + uint32_t fmpr_mwcs;
97834 + uint32_t fmpr_mrscs;
97835 + uint32_t fmpr_mwscs;
97836 + uint32_t fmpr_fcscs;
97837 +};
97838 +
97839 +struct fman_prs_cfg {
97840 + uint32_t port_id_stat;
97841 + uint16_t max_prs_cyc_lim;
97842 + uint32_t prs_exceptions;
97843 +};
97844 +
97845 +uint32_t fman_prs_get_err_event(struct fman_prs_regs *regs, uint32_t ev_mask);
97846 +uint32_t fman_prs_get_err_ev_mask(struct fman_prs_regs *regs);
97847 +void fman_prs_ack_err_event(struct fman_prs_regs *regs, uint32_t event);
97848 +uint32_t fman_prs_get_expt_event(struct fman_prs_regs *regs, uint32_t ev_mask);
97849 +uint32_t fman_prs_get_expt_ev_mask(struct fman_prs_regs *regs);
97850 +void fman_prs_ack_expt_event(struct fman_prs_regs *regs, uint32_t event);
97851 +void fman_prs_defconfig(struct fman_prs_cfg *cfg);
97852 +int fman_prs_init(struct fman_prs_regs *regs, struct fman_prs_cfg *cfg);
97853 +void fman_prs_enable(struct fman_prs_regs *regs);
97854 +void fman_prs_disable(struct fman_prs_regs *regs);
97855 +int fman_prs_is_enabled(struct fman_prs_regs *regs);
97856 +void fman_prs_set_stst_port_msk(struct fman_prs_regs *regs, uint32_t pid_msk);
97857 +void fman_prs_set_stst(struct fman_prs_regs *regs, bool enable);
97858 +#endif /* __FSL_FMAN_PRS_H */
97859 --- /dev/null
97860 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_rtc.h
97861 @@ -0,0 +1,449 @@
97862 +/*
97863 + * Copyright 2013 Freescale Semiconductor Inc.
97864 + *
97865 + * Redistribution and use in source and binary forms, with or without
97866 + * modification, are permitted provided that the following conditions are met:
97867 + * * Redistributions of source code must retain the above copyright
97868 + * notice, this list of conditions and the following disclaimer.
97869 + * * Redistributions in binary form must reproduce the above copyright
97870 + * notice, this list of conditions and the following disclaimer in the
97871 + * documentation and/or other materials provided with the distribution.
97872 + * * Neither the name of Freescale Semiconductor nor the
97873 + * names of its contributors may be used to endorse or promote products
97874 + * derived from this software without specific prior written permission.
97875 + *
97876 + *
97877 + * ALTERNATIVELY, this software may be distributed under the terms of the
97878 + * GNU General Public License ("GPL") as published by the Free Software
97879 + * Foundation, either version 2 of that License or (at your option) any
97880 + * later version.
97881 + *
97882 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
97883 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
97884 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
97885 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
97886 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
97887 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
97888 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
97889 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
97890 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
97891 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
97892 + */
97893 +
97894 +#ifndef __FSL_FMAN_RTC_H
97895 +#define __FSL_FMAN_RTC_H
97896 +
97897 +#include "common/general.h"
97898 +
97899 +/* FM RTC Registers definitions */
97900 +#define FMAN_RTC_TMR_CTRL_ALMP1 0x80000000
97901 +#define FMAN_RTC_TMR_CTRL_ALMP2 0x40000000
97902 +#define FMAN_RTC_TMR_CTRL_FS 0x10000000
97903 +#define FMAN_RTC_TMR_CTRL_PP1L 0x08000000
97904 +#define FMAN_RTC_TMR_CTRL_PP2L 0x04000000
97905 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_MASK 0x03FF0000
97906 +#define FMAN_RTC_TMR_CTRL_FRD 0x00004000
97907 +#define FMAN_RTC_TMR_CTRL_SLV 0x00002000
97908 +#define FMAN_RTC_TMR_CTRL_ETEP1 0x00000100
97909 +#define FMAN_RTC_TMR_CTRL_COPH 0x00000080
97910 +#define FMAN_RTC_TMR_CTRL_CIPH 0x00000040
97911 +#define FMAN_RTC_TMR_CTRL_TMSR 0x00000020
97912 +#define FMAN_RTC_TMR_CTRL_DBG 0x00000010
97913 +#define FMAN_RTC_TMR_CTRL_BYP 0x00000008
97914 +#define FMAN_RTC_TMR_CTRL_TE 0x00000004
97915 +#define FMAN_RTC_TMR_CTRL_CKSEL_OSC_CLK 0x00000003
97916 +#define FMAN_RTC_TMR_CTRL_CKSEL_MAC_CLK 0x00000001
97917 +#define FMAN_RTC_TMR_CTRL_CKSEL_EXT_CLK 0x00000000
97918 +#define FMAN_RTC_TMR_CTRL_TCLK_PERIOD_SHIFT 16
97919 +
97920 +#define FMAN_RTC_TMR_TEVENT_ETS2 0x02000000
97921 +#define FMAN_RTC_TMR_TEVENT_ETS1 0x01000000
97922 +#define FMAN_RTC_TMR_TEVENT_ALM2 0x00020000
97923 +#define FMAN_RTC_TMR_TEVENT_ALM1 0x00010000
97924 +#define FMAN_RTC_TMR_TEVENT_PP1 0x00000080
97925 +#define FMAN_RTC_TMR_TEVENT_PP2 0x00000040
97926 +#define FMAN_RTC_TMR_TEVENT_PP3 0x00000020
97927 +#define FMAN_RTC_TMR_TEVENT_ALL (FMAN_RTC_TMR_TEVENT_ETS2 |\
97928 + FMAN_RTC_TMR_TEVENT_ETS1 |\
97929 + FMAN_RTC_TMR_TEVENT_ALM2 |\
97930 + FMAN_RTC_TMR_TEVENT_ALM1 |\
97931 + FMAN_RTC_TMR_TEVENT_PP1 |\
97932 + FMAN_RTC_TMR_TEVENT_PP2 |\
97933 + FMAN_RTC_TMR_TEVENT_PP3)
97934 +
97935 +#define FMAN_RTC_TMR_PRSC_OCK_MASK 0x0000FFFF
97936 +
97937 +/**************************************************************************//**
97938 + @Description FM RTC Alarm Polarity Options.
97939 +*//***************************************************************************/
97940 +enum fman_rtc_alarm_polarity {
97941 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH, /**< Active-high output polarity */
97942 + E_FMAN_RTC_ALARM_POLARITY_ACTIVE_LOW /**< Active-low output polarity */
97943 +};
97944 +
97945 +/**************************************************************************//**
97946 + @Description FM RTC Trigger Polarity Options.
97947 +*//***************************************************************************/
97948 +enum fman_rtc_trigger_polarity {
97949 + E_FMAN_RTC_TRIGGER_ON_RISING_EDGE, /**< Trigger on rising edge */
97950 + E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE /**< Trigger on falling edge */
97951 +};
97952 +
97953 +/**************************************************************************//**
97954 + @Description IEEE1588 Timer Module FM RTC Optional Clock Sources.
97955 +*//***************************************************************************/
97956 +enum fman_src_clock {
97957 + E_FMAN_RTC_SOURCE_CLOCK_EXTERNAL, /**< external high precision timer
97958 + reference clock */
97959 + E_FMAN_RTC_SOURCE_CLOCK_SYSTEM, /**< MAC system clock */
97960 + E_FMAN_RTC_SOURCE_CLOCK_OSCILATOR /**< RTC clock oscilator */
97961 +};
97962 +
97963 +/* RTC default values */
97964 +#define DEFAULT_SRC_CLOCK E_FMAN_RTC_SOURCE_CLOCK_SYSTEM
97965 +#define DEFAULT_INVERT_INPUT_CLK_PHASE FALSE
97966 +#define DEFAULT_INVERT_OUTPUT_CLK_PHASE FALSE
97967 +#define DEFAULT_ALARM_POLARITY E_FMAN_RTC_ALARM_POLARITY_ACTIVE_HIGH
97968 +#define DEFAULT_TRIGGER_POLARITY E_FMAN_RTC_TRIGGER_ON_FALLING_EDGE
97969 +#define DEFAULT_PULSE_REALIGN FALSE
97970 +
97971 +#define FMAN_RTC_MAX_NUM_OF_ALARMS 3
97972 +#define FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES 4
97973 +#define FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS 3
97974 +
97975 +/**************************************************************************//**
97976 + @Description FM RTC timer alarm
97977 +*//***************************************************************************/
97978 +struct t_tmr_alarm{
97979 + uint32_t tmr_alarm_h; /**< */
97980 + uint32_t tmr_alarm_l; /**< */
97981 +};
97982 +
97983 +/**************************************************************************//**
97984 + @Description FM RTC timer Ex trigger
97985 +*//***************************************************************************/
97986 +struct t_tmr_ext_trigger{
97987 + uint32_t tmr_etts_h; /**< */
97988 + uint32_t tmr_etts_l; /**< */
97989 +};
97990 +
97991 +struct rtc_regs {
97992 + uint32_t tmr_id; /* 0x000 Module ID register */
97993 + uint32_t tmr_id2; /* 0x004 Controller ID register */
97994 + uint32_t reserved0008[30];
97995 + uint32_t tmr_ctrl; /* 0x0080 timer control register */
97996 + uint32_t tmr_tevent; /* 0x0084 timer event register */
97997 + uint32_t tmr_temask; /* 0x0088 timer event mask register */
97998 + uint32_t reserved008c[3];
97999 + uint32_t tmr_cnt_h; /* 0x0098 timer counter high register */
98000 + uint32_t tmr_cnt_l; /* 0x009c timer counter low register */
98001 + uint32_t tmr_add; /* 0x00a0 timer drift compensation addend register */
98002 + uint32_t tmr_acc; /* 0x00a4 timer accumulator register */
98003 + uint32_t tmr_prsc; /* 0x00a8 timer prescale */
98004 + uint32_t reserved00ac;
98005 + uint32_t tmr_off_h; /* 0x00b0 timer offset high */
98006 + uint32_t tmr_off_l; /* 0x00b4 timer offset low */
98007 + struct t_tmr_alarm tmr_alarm[FMAN_RTC_MAX_NUM_OF_ALARMS]; /* 0x00b8 timer
98008 + alarm */
98009 + uint32_t tmr_fiper[FMAN_RTC_MAX_NUM_OF_PERIODIC_PULSES]; /* 0x00d0 timer
98010 + fixed period interval */
98011 + struct t_tmr_ext_trigger tmr_etts[FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
98012 + /* 0x00e0 time stamp general purpose external */
98013 + uint32_t reserved00f0[4];
98014 +};
98015 +
98016 +struct rtc_cfg {
98017 + enum fman_src_clock src_clk;
98018 + uint32_t ext_src_clk_freq;
98019 + uint32_t rtc_freq_hz;
98020 + bool timer_slave_mode;
98021 + bool invert_input_clk_phase;
98022 + bool invert_output_clk_phase;
98023 + uint32_t events_mask;
98024 + bool bypass; /**< Indicates if frequency compensation
98025 + is bypassed */
98026 + bool pulse_realign;
98027 + enum fman_rtc_alarm_polarity alarm_polarity[FMAN_RTC_MAX_NUM_OF_ALARMS];
98028 + enum fman_rtc_trigger_polarity trigger_polarity
98029 + [FMAN_RTC_MAX_NUM_OF_EXT_TRIGGERS];
98030 +};
98031 +
98032 +/**
98033 + * fman_rtc_defconfig() - Get default RTC configuration
98034 + * @cfg: pointer to configuration structure.
98035 + *
98036 + * Call this function to obtain a default set of configuration values for
98037 + * initializing RTC. The user can overwrite any of the values before calling
98038 + * fman_rtc_init(), if specific configuration needs to be applied.
98039 + */
98040 +void fman_rtc_defconfig(struct rtc_cfg *cfg);
98041 +
98042 +/**
98043 + * fman_rtc_get_events() - Get the events
98044 + * @regs: Pointer to RTC register block
98045 + *
98046 + * Returns: The events
98047 + */
98048 +uint32_t fman_rtc_get_events(struct rtc_regs *regs);
98049 +
98050 +/**
98051 + * fman_rtc_get_interrupt_mask() - Get the events mask
98052 + * @regs: Pointer to RTC register block
98053 + *
98054 + * Returns: The events mask
98055 + */
98056 +uint32_t fman_rtc_get_interrupt_mask(struct rtc_regs *regs);
98057 +
98058 +
98059 +/**
98060 + * fman_rtc_set_interrupt_mask() - Set the events mask
98061 + * @regs: Pointer to RTC register block
98062 + * @mask: The mask to set
98063 + */
98064 +void fman_rtc_set_interrupt_mask(struct rtc_regs *regs, uint32_t mask);
98065 +
98066 +/**
98067 + * fman_rtc_get_event() - Check if specific events occurred
98068 + * @regs: Pointer to RTC register block
98069 + * @ev_mask: a mask of the events to check
98070 + *
98071 + * Returns: 0 if the events did not occur. Non zero if one of the events occurred
98072 + */
98073 +uint32_t fman_rtc_get_event(struct rtc_regs *regs, uint32_t ev_mask);
98074 +
98075 +/**
98076 + * fman_rtc_check_and_clear_event() - Clear events which are on
98077 + * @regs: Pointer to RTC register block
98078 + *
98079 + * Returns: A mask of the events which were cleared
98080 + */
98081 +uint32_t fman_rtc_check_and_clear_event(struct rtc_regs *regs);
98082 +
98083 +/**
98084 + * fman_rtc_ack_event() - Clear events
98085 + * @regs: Pointer to RTC register block
98086 + * @events: The events to disable
98087 + */
98088 +void fman_rtc_ack_event(struct rtc_regs *regs, uint32_t events);
98089 +
98090 +/**
98091 + * fman_rtc_enable_interupt() - Enable events interrupts
98092 + * @regs: Pointer to RTC register block
98093 + * @mask: The events to disable
98094 + */
98095 +void fman_rtc_enable_interupt(struct rtc_regs *regs, uint32_t mask);
98096 +
98097 +/**
98098 + * fman_rtc_disable_interupt() - Disable events interrupts
98099 + * @regs: Pointer to RTC register block
98100 + * @mask: The events to disable
98101 + */
98102 +void fman_rtc_disable_interupt(struct rtc_regs *regs, uint32_t mask);
98103 +
98104 +/**
98105 + * fman_rtc_get_timer_ctrl() - Get the control register
98106 + * @regs: Pointer to RTC register block
98107 + *
98108 + * Returns: The control register value
98109 + */
98110 +uint32_t fman_rtc_get_timer_ctrl(struct rtc_regs *regs);
98111 +
98112 +/**
98113 + * fman_rtc_set_timer_ctrl() - Set timer control register
98114 + * @regs: Pointer to RTC register block
98115 + * @val: The value to set
98116 + */
98117 +void fman_rtc_set_timer_ctrl(struct rtc_regs *regs, uint32_t val);
98118 +
98119 +/**
98120 + * fman_rtc_get_frequency_compensation() - Get the frequency compensation
98121 + * @regs: Pointer to RTC register block
98122 + *
98123 + * Returns: The timer counter
98124 + */
98125 +uint32_t fman_rtc_get_frequency_compensation(struct rtc_regs *regs);
98126 +
98127 +/**
98128 + * fman_rtc_set_frequency_compensation() - Set frequency compensation
98129 + * @regs: Pointer to RTC register block
98130 + * @val: The value to set
98131 + */
98132 +void fman_rtc_set_frequency_compensation(struct rtc_regs *regs, uint32_t val);
98133 +
98134 +/**
98135 + * fman_rtc_get_trigger_stamp() - Get a trigger stamp
98136 + * @regs: Pointer to RTC register block
98137 + * @id: The id of the trigger stamp
98138 + *
98139 + * Returns: The time stamp
98140 + */
98141 +uint64_t fman_rtc_get_trigger_stamp(struct rtc_regs *regs, int id);
98142 +
98143 +/**
98144 + * fman_rtc_set_timer_alarm_l() - Set timer alarm low register
98145 + * @regs: Pointer to RTC register block
98146 + * @index: The index of alarm to set
98147 + * @val: The value to set
98148 + */
98149 +void fman_rtc_set_timer_alarm_l(struct rtc_regs *regs, int index,
98150 + uint32_t val);
98151 +
98152 +/**
98153 + * fman_rtc_set_timer_alarm() - Set timer alarm
98154 + * @regs: Pointer to RTC register block
98155 + * @index: The index of alarm to set
98156 + * @val: The value to set
98157 + */
98158 +void fman_rtc_set_timer_alarm(struct rtc_regs *regs, int index, int64_t val);
98159 +
98160 +/**
98161 + * fman_rtc_set_timer_fiper() - Set timer fiper
98162 + * @regs: Pointer to RTC register block
98163 + * @index: The index of fiper to set
98164 + * @val: The value to set
98165 + */
98166 +void fman_rtc_set_timer_fiper(struct rtc_regs *regs, int index, uint32_t val);
98167 +
98168 +/**
98169 + * fman_rtc_set_timer_offset() - Set timer offset
98170 + * @regs: Pointer to RTC register block
98171 + * @val: The value to set
98172 + */
98173 +void fman_rtc_set_timer_offset(struct rtc_regs *regs, int64_t val);
98174 +
98175 +/**
98176 + * fman_rtc_get_timer() - Get the timer counter
98177 + * @regs: Pointer to RTC register block
98178 + *
98179 + * Returns: The timer counter
98180 + */
98181 +static inline uint64_t fman_rtc_get_timer(struct rtc_regs *regs)
98182 +{
98183 + uint64_t time;
98184 + /* TMR_CNT_L must be read first to get an accurate value */
98185 + time = (uint64_t)ioread32be(&regs->tmr_cnt_l);
98186 + time |= ((uint64_t)ioread32be(&regs->tmr_cnt_h) << 32);
98187 +
98188 + return time;
98189 +}
98190 +
98191 +/**
98192 + * fman_rtc_set_timer() - Set timer counter
98193 + * @regs: Pointer to RTC register block
98194 + * @val: The value to set
98195 + */
98196 +static inline void fman_rtc_set_timer(struct rtc_regs *regs, int64_t val)
98197 +{
98198 + iowrite32be((uint32_t)val, &regs->tmr_cnt_l);
98199 + iowrite32be((uint32_t)(val >> 32), &regs->tmr_cnt_h);
98200 +}
98201 +
98202 +/**
98203 + * fman_rtc_timers_soft_reset() - Soft reset
98204 + * @regs: Pointer to RTC register block
98205 + *
98206 + * Resets all the timer registers and state machines for the 1588 IP and
98207 + * the attached client 1588
98208 + */
98209 +void fman_rtc_timers_soft_reset(struct rtc_regs *regs);
98210 +
98211 +/**
98212 + * fman_rtc_clear_external_trigger() - Clear an external trigger
98213 + * @regs: Pointer to RTC register block
98214 + * @id: The id of the trigger to clear
98215 + */
98216 +void fman_rtc_clear_external_trigger(struct rtc_regs *regs, int id);
98217 +
98218 +/**
98219 + * fman_rtc_clear_periodic_pulse() - Clear periodic pulse
98220 + * @regs: Pointer to RTC register block
98221 + * @id: The id of the fiper to clear
98222 + */
98223 +void fman_rtc_clear_periodic_pulse(struct rtc_regs *regs, int id);
98224 +
98225 +/**
98226 + * fman_rtc_enable() - Enable RTC hardware block
98227 + * @regs: Pointer to RTC register block
98228 + */
98229 +void fman_rtc_enable(struct rtc_regs *regs, bool reset_clock);
98230 +
98231 +/**
98232 + * fman_rtc_is_enabled() - Is RTC hardware block enabled
98233 + * @regs: Pointer to RTC register block
98234 + *
98235 + * Return: TRUE if enabled
98236 + */
98237 +bool fman_rtc_is_enabled(struct rtc_regs *regs);
98238 +
98239 +/**
98240 + * fman_rtc_disable() - Disable RTC hardware block
98241 + * @regs: Pointer to RTC register block
98242 + */
98243 +void fman_rtc_disable(struct rtc_regs *regs);
98244 +
98245 +/**
98246 + * fman_rtc_init() - Init RTC hardware block
98247 + * @cfg: RTC configuration data
98248 + * @regs: Pointer to RTC register block
98249 + * @num_alarms: Number of alarms in RTC
98250 + * @num_fipers: Number of fipers in RTC
98251 + * @num_ext_triggers: Number of external triggers in RTC
98252 + * @freq_compensation: Frequency compensation
98253 + * @output_clock_divisor: Output clock divisor
98254 + *
98255 + * This function initializes RTC and applies basic configuration.
98256 + */
98257 +void fman_rtc_init(struct rtc_cfg *cfg, struct rtc_regs *regs, int num_alarms,
98258 + int num_fipers, int num_ext_triggers, bool init_freq_comp,
98259 + uint32_t freq_compensation, uint32_t output_clock_divisor);
98260 +
98261 +/**
98262 + * fman_rtc_set_alarm() - Set an alarm
98263 + * @regs: Pointer to RTC register block
98264 + * @id: id of alarm
98265 + * @val: value to write
98266 + * @enable: should interrupt be enabled
98267 + */
98268 +void fman_rtc_set_alarm(struct rtc_regs *regs, int id, uint32_t val, bool enable);
98269 +
98270 +/**
98271 + * fman_rtc_set_periodic_pulse() - Set an alarm
98272 + * @regs: Pointer to RTC register block
98273 + * @id: id of fiper
98274 + * @val: value to write
98275 + * @enable: should interrupt be enabled
98276 + */
98277 +void fman_rtc_set_periodic_pulse(struct rtc_regs *regs, int id, uint32_t val,
98278 + bool enable);
98279 +
98280 +/**
98281 + * fman_rtc_set_ext_trigger() - Set an external trigger
98282 + * @regs: Pointer to RTC register block
98283 + * @id: id of trigger
98284 + * @enable: should interrupt be enabled
98285 + * @use_pulse_as_input: use the pulse as input
98286 + */
98287 +void fman_rtc_set_ext_trigger(struct rtc_regs *regs, int id, bool enable,
98288 + bool use_pulse_as_input);
98289 +
98290 +struct fm_rtc_alarm_params {
98291 + uint8_t alarm_id; /**< 0 or 1 */
98292 + uint64_t alarm_time; /**< In nanoseconds, the time when the
98293 + alarm should go off - must be a
98294 + multiple of the RTC period */
98295 + void (*f_alarm_callback)(void* app, uint8_t id); /**< This routine will
98296 + be called when RTC reaches alarmTime */
98297 + bool clear_on_expiration; /**< TRUE to turn off the alarm once
98298 + expired.*/
98299 +};
98300 +
98301 +struct fm_rtc_periodic_pulse_params {
98302 + uint8_t periodic_pulse_id; /**< 0 or 1 */
98303 + uint64_t periodic_pulse_period; /**< In Nanoseconds. Must be a multiple
98304 + of the RTC period */
98305 + void (*f_periodic_pulse_callback)(void* app, uint8_t id); /**< This
98306 + routine will be called every
98307 + periodicPulsePeriod. */
98308 +};
98309 +
98310 +#endif /* __FSL_FMAN_RTC_H */
98311 --- /dev/null
98312 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_sp.h
98313 @@ -0,0 +1,138 @@
98314 +/*
98315 + * Copyright 2013 Freescale Semiconductor Inc.
98316 + *
98317 + * Redistribution and use in source and binary forms, with or without
98318 + * modification, are permitted provided that the following conditions are met:
98319 + * * Redistributions of source code must retain the above copyright
98320 + * notice, this list of conditions and the following disclaimer.
98321 + * * Redistributions in binary form must reproduce the above copyright
98322 + * notice, this list of conditions and the following disclaimer in the
98323 + * documentation and/or other materials provided with the distribution.
98324 + * * Neither the name of Freescale Semiconductor nor the
98325 + * names of its contributors may be used to endorse or promote products
98326 + * derived from this software without specific prior written permission.
98327 + *
98328 + *
98329 + * ALTERNATIVELY, this software may be distributed under the terms of the
98330 + * GNU General Public License ("GPL") as published by the Free Software
98331 + * Foundation, either version 2 of that License or (at your option) any
98332 + * later version.
98333 + *
98334 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98335 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98336 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98337 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98338 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98339 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98340 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98341 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98342 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98343 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98344 + */
98345 +
98346 +#ifndef __FSL_FMAN_SP_H
98347 +#define __FSL_FMAN_SP_H
98348 +
98349 +#include "common/general.h"
98350 +#include "fsl_fman.h"
98351 +
98352 +
98353 +struct fm_pcd_storage_profile_regs{
98354 + uint32_t fm_sp_ebmpi[8];
98355 + /*offset 0 - 0xc*/
98356 + /**< Buffer Manager pool Information */
98357 +
98358 + uint32_t fm_sp_acnt; /*offset 0x20*/
98359 + uint32_t fm_sp_ebm; /*offset 0x24*/
98360 + uint32_t fm_sp_da; /*offset 0x28*/
98361 + uint32_t fm_sp_icp; /*offset 0x2c*/
98362 + uint32_t fm_sp_mpd; /*offset 0x30*/
98363 + uint32_t res1[2]; /*offset 0x34 - 0x38*/
98364 + uint32_t fm_sp_spliodn; /*offset 0x3c*/
98365 +};
98366 +
98367 +/**************************************************************************//**
98368 + @Description structure for defining internal context copying
98369 +*//***************************************************************************/
98370 +struct fman_sp_int_context_data_copy{
98371 + uint16_t ext_buf_offset; /**< Offset in External buffer to which
98372 + internal context is copied to (Rx)
98373 + or taken from (Tx, Op). */
98374 + uint8_t int_context_offset; /**< Offset within internal context to copy
98375 + from (Rx) or to copy to (Tx, Op).*/
98376 + uint16_t size; /**< Internal offset size to be copied */
98377 +};
98378 +
98379 +/**************************************************************************//**
98380 + @Description struct for defining external buffer margins
98381 +*//***************************************************************************/
98382 +struct fman_sp_buf_margins{
98383 + uint16_t start_margins; /**< Number of bytes to be left at the
98384 + beginning of the external buffer (must be
98385 + divisible by 16) */
98386 + uint16_t end_margins; /**< number of bytes to be left at the end of
98387 + the external buffer(must be divisible by 16)*/
98388 +};
98389 +
98390 +struct fm_storage_profile_params {
98391 + struct fman_ext_pools fm_ext_pools;
98392 + struct fman_backup_bm_pools backup_pools;
98393 + struct fman_sp_int_context_data_copy *int_context;
98394 + struct fman_sp_buf_margins *buf_margins;
98395 + enum fman_dma_swap_option dma_swap_data;
98396 + enum fman_dma_cache_option int_context_cache_attr;
98397 + enum fman_dma_cache_option header_cache_attr;
98398 + enum fman_dma_cache_option scatter_gather_cache_attr;
98399 + bool dma_write_optimize;
98400 + uint16_t liodn_offset;
98401 + bool no_scather_gather;
98402 + struct fman_buf_pool_depletion buf_pool_depletion;
98403 +};
98404 +
98405 +/**************************************************************************//**
98406 + @Description Registers bit fields
98407 +*//***************************************************************************/
98408 +#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER 0x40000000
98409 +#define FMAN_SP_EXT_BUF_POOL_VALID 0x80000000
98410 +#define FMAN_SP_EXT_BUF_POOL_BACKUP 0x20000000
98411 +#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE 0x00100000
98412 +#define FMAN_SP_SG_DISABLE 0x80000000
98413 +
98414 +/* shifts */
98415 +#define FMAN_SP_EXT_BUF_POOL_ID_SHIFT 16
98416 +#define FMAN_SP_POOL_DEP_NUM_OF_POOLS_SHIFT 16
98417 +#define FMAN_SP_EXT_BUF_MARG_START_SHIFT 16
98418 +#define FMAN_SP_EXT_BUF_MARG_END_SHIFT 0
98419 +#define FMAN_SP_DMA_ATTR_SWP_SHIFT 30
98420 +#define FMAN_SP_DMA_ATTR_IC_CACHE_SHIFT 28
98421 +#define FMAN_SP_DMA_ATTR_HDR_CACHE_SHIFT 26
98422 +#define FMAN_SP_DMA_ATTR_SG_CACHE_SHIFT 24
98423 +#define FMAN_SP_IC_TO_EXT_SHIFT 16
98424 +#define FMAN_SP_IC_FROM_INT_SHIFT 8
98425 +#define FMAN_SP_IC_SIZE_SHIFT 0
98426 +
98427 +/**************************************************************************//**
98428 + @Description defaults
98429 +*//***************************************************************************/
98430 +#define DEFAULT_FMAN_SP_DMA_SWAP_DATA FMAN_DMA_NO_SWP
98431 +#define DEFAULT_FMAN_SP_DMA_INT_CONTEXT_CACHE_ATTR FMAN_DMA_NO_STASH
98432 +#define DEFAULT_FMAN_SP_DMA_HEADER_CACHE_ATTR FMAN_DMA_NO_STASH
98433 +#define DEFAULT_FMAN_SP_DMA_SCATTER_GATHER_CACHE_ATTR FMAN_DMA_NO_STASH
98434 +#define DEFAULT_FMAN_SP_DMA_WRITE_OPTIMIZE TRUE
98435 +#define DEFAULT_FMAN_SP_NO_SCATTER_GATHER FALSE
98436 +
98437 +void fman_vsp_defconfig(struct fm_storage_profile_params *cfg);
98438 +
98439 +void fman_vsp_init(struct fm_pcd_storage_profile_regs *regs,
98440 + uint16_t index, struct fm_storage_profile_params *fm_vsp_params,
98441 + int port_max_num_of_ext_pools, int bm_max_num_of_pools,
98442 + int max_num_of_pfc_priorities);
98443 +
98444 +uint32_t fman_vsp_get_statistics(struct fm_pcd_storage_profile_regs *regs,
98445 + uint16_t index);
98446 +
98447 +void fman_vsp_set_statistics(struct fm_pcd_storage_profile_regs *regs,
98448 + uint16_t index, uint32_t value);
98449 +
98450 +
98451 +#endif /* __FSL_FMAN_SP_H */
98452 --- /dev/null
98453 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/flib/fsl_fman_tgec.h
98454 @@ -0,0 +1,479 @@
98455 +/*
98456 + * Copyright 2008-2012 Freescale Semiconductor Inc.
98457 + *
98458 + * Redistribution and use in source and binary forms, with or without
98459 + * modification, are permitted provided that the following conditions are met:
98460 + * * Redistributions of source code must retain the above copyright
98461 + * notice, this list of conditions and the following disclaimer.
98462 + * * Redistributions in binary form must reproduce the above copyright
98463 + * notice, this list of conditions and the following disclaimer in the
98464 + * documentation and/or other materials provided with the distribution.
98465 + * * Neither the name of Freescale Semiconductor nor the
98466 + * names of its contributors may be used to endorse or promote products
98467 + * derived from this software without specific prior written permission.
98468 + *
98469 + *
98470 + * ALTERNATIVELY, this software may be distributed under the terms of the
98471 + * GNU General Public License ("GPL") as published by the Free Software
98472 + * Foundation, either version 2 of that License or (at your option) any
98473 + * later version.
98474 + *
98475 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98476 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98477 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98478 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98479 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98480 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98481 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98482 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98483 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98484 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98485 + */
98486 +
98487 +#ifndef __FSL_FMAN_TGEC_H
98488 +#define __FSL_FMAN_TGEC_H
98489 +
98490 +#include "common/general.h"
98491 +#include "fsl_enet.h"
98492 +
98493 +
98494 +/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
98495 +#define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
98496 +
98497 +enum tgec_counters {
98498 + E_TGEC_COUNTER_R64,
98499 + E_TGEC_COUNTER_R127,
98500 + E_TGEC_COUNTER_R255,
98501 + E_TGEC_COUNTER_R511,
98502 + E_TGEC_COUNTER_R1023,
98503 + E_TGEC_COUNTER_R1518,
98504 + E_TGEC_COUNTER_R1519X,
98505 + E_TGEC_COUNTER_TRFRG,
98506 + E_TGEC_COUNTER_TRJBR,
98507 + E_TGEC_COUNTER_RDRP,
98508 + E_TGEC_COUNTER_RALN,
98509 + E_TGEC_COUNTER_TRUND,
98510 + E_TGEC_COUNTER_TROVR,
98511 + E_TGEC_COUNTER_RXPF,
98512 + E_TGEC_COUNTER_TXPF,
98513 + E_TGEC_COUNTER_ROCT,
98514 + E_TGEC_COUNTER_RMCA,
98515 + E_TGEC_COUNTER_RBCA,
98516 + E_TGEC_COUNTER_RPKT,
98517 + E_TGEC_COUNTER_RUCA,
98518 + E_TGEC_COUNTER_RERR,
98519 + E_TGEC_COUNTER_TOCT,
98520 + E_TGEC_COUNTER_TMCA,
98521 + E_TGEC_COUNTER_TBCA,
98522 + E_TGEC_COUNTER_TUCA,
98523 + E_TGEC_COUNTER_TERR
98524 +};
98525 +
98526 +/* Command and Configuration Register (COMMAND_CONFIG) */
98527 +#define CMD_CFG_EN_TIMESTAMP 0x00100000
98528 +#define CMD_CFG_TX_ADDR_INS_SEL 0x00080000
98529 +#define CMD_CFG_NO_LEN_CHK 0x00020000
98530 +#define CMD_CFG_SEND_IDLE 0x00010000
98531 +#define CMD_CFG_RX_ER_DISC 0x00004000
98532 +#define CMD_CFG_CMD_FRM_EN 0x00002000
98533 +#define CMD_CFG_STAT_CLR 0x00001000
98534 +#define CMD_CFG_LOOPBACK_EN 0x00000400
98535 +#define CMD_CFG_TX_ADDR_INS 0x00000200
98536 +#define CMD_CFG_PAUSE_IGNORE 0x00000100
98537 +#define CMD_CFG_PAUSE_FWD 0x00000080
98538 +#define CMD_CFG_PROMIS_EN 0x00000010
98539 +#define CMD_CFG_WAN_MODE 0x00000008
98540 +#define CMD_CFG_RX_EN 0x00000002
98541 +#define CMD_CFG_TX_EN 0x00000001
98542 +
98543 +/* Interrupt Mask Register (IMASK) */
98544 +#define TGEC_IMASK_MDIO_SCAN_EVENT 0x00010000
98545 +#define TGEC_IMASK_MDIO_CMD_CMPL 0x00008000
98546 +#define TGEC_IMASK_REM_FAULT 0x00004000
98547 +#define TGEC_IMASK_LOC_FAULT 0x00002000
98548 +#define TGEC_IMASK_TX_ECC_ER 0x00001000
98549 +#define TGEC_IMASK_TX_FIFO_UNFL 0x00000800
98550 +#define TGEC_IMASK_TX_FIFO_OVFL 0x00000400
98551 +#define TGEC_IMASK_TX_ER 0x00000200
98552 +#define TGEC_IMASK_RX_FIFO_OVFL 0x00000100
98553 +#define TGEC_IMASK_RX_ECC_ER 0x00000080
98554 +#define TGEC_IMASK_RX_JAB_FRM 0x00000040
98555 +#define TGEC_IMASK_RX_OVRSZ_FRM 0x00000020
98556 +#define TGEC_IMASK_RX_RUNT_FRM 0x00000010
98557 +#define TGEC_IMASK_RX_FRAG_FRM 0x00000008
98558 +#define TGEC_IMASK_RX_LEN_ER 0x00000004
98559 +#define TGEC_IMASK_RX_CRC_ER 0x00000002
98560 +#define TGEC_IMASK_RX_ALIGN_ER 0x00000001
98561 +
98562 +#define TGEC_EVENTS_MASK \
98563 + ((uint32_t)(TGEC_IMASK_MDIO_SCAN_EVENT | \
98564 + TGEC_IMASK_MDIO_CMD_CMPL | \
98565 + TGEC_IMASK_REM_FAULT | \
98566 + TGEC_IMASK_LOC_FAULT | \
98567 + TGEC_IMASK_TX_ECC_ER | \
98568 + TGEC_IMASK_TX_FIFO_UNFL | \
98569 + TGEC_IMASK_TX_FIFO_OVFL | \
98570 + TGEC_IMASK_TX_ER | \
98571 + TGEC_IMASK_RX_FIFO_OVFL | \
98572 + TGEC_IMASK_RX_ECC_ER | \
98573 + TGEC_IMASK_RX_JAB_FRM | \
98574 + TGEC_IMASK_RX_OVRSZ_FRM | \
98575 + TGEC_IMASK_RX_RUNT_FRM | \
98576 + TGEC_IMASK_RX_FRAG_FRM | \
98577 + TGEC_IMASK_RX_LEN_ER | \
98578 + TGEC_IMASK_RX_CRC_ER | \
98579 + TGEC_IMASK_RX_ALIGN_ER))
98580 +
98581 +/* Hashtable Control Register (HASHTABLE_CTRL) */
98582 +#define TGEC_HASH_MCAST_SHIFT 23
98583 +#define TGEC_HASH_MCAST_EN 0x00000200
98584 +#define TGEC_HASH_ADR_MSK 0x000001ff
98585 +
98586 +#define DEFAULT_WAN_MODE_ENABLE FALSE
98587 +#define DEFAULT_PROMISCUOUS_MODE_ENABLE FALSE
98588 +#define DEFAULT_PAUSE_FORWARD_ENABLE FALSE
98589 +#define DEFAULT_PAUSE_IGNORE FALSE
98590 +#define DEFAULT_TX_ADDR_INS_ENABLE FALSE
98591 +#define DEFAULT_LOOPBACK_ENABLE FALSE
98592 +#define DEFAULT_CMD_FRAME_ENABLE FALSE
98593 +#define DEFAULT_RX_ERROR_DISCARD FALSE
98594 +#define DEFAULT_SEND_IDLE_ENABLE FALSE
98595 +#define DEFAULT_NO_LENGTH_CHECK_ENABLE TRUE
98596 +#define DEFAULT_LGTH_CHECK_NOSTDR FALSE
98597 +#define DEFAULT_TIME_STAMP_ENABLE FALSE
98598 +#define DEFAULT_TX_IPG_LENGTH 12
98599 +#define DEFAULT_MAX_FRAME_LENGTH 0x600
98600 +#define DEFAULT_PAUSE_QUANT 0xf000
98601 +
98602 +/*
98603 + * 10G memory map
98604 + */
98605 +struct tgec_regs {
98606 + uint32_t tgec_id; /* 0x000 Controller ID */
98607 + uint32_t reserved001[1]; /* 0x004 */
98608 + uint32_t command_config; /* 0x008 Control and configuration */
98609 + uint32_t mac_addr_0; /* 0x00c Lower 32 bits of the MAC adr */
98610 + uint32_t mac_addr_1; /* 0x010 Upper 16 bits of the MAC adr */
98611 + uint32_t maxfrm; /* 0x014 Maximum frame length */
98612 + uint32_t pause_quant; /* 0x018 Pause quanta */
98613 + uint32_t rx_fifo_sections; /* 0x01c */
98614 + uint32_t tx_fifo_sections; /* 0x020 */
98615 + uint32_t rx_fifo_almost_f_e; /* 0x024 */
98616 + uint32_t tx_fifo_almost_f_e; /* 0x028 */
98617 + uint32_t hashtable_ctrl; /* 0x02c Hash table control*/
98618 + uint32_t mdio_cfg_status; /* 0x030 */
98619 + uint32_t mdio_command; /* 0x034 */
98620 + uint32_t mdio_data; /* 0x038 */
98621 + uint32_t mdio_regaddr; /* 0x03c */
98622 + uint32_t status; /* 0x040 */
98623 + uint32_t tx_ipg_len; /* 0x044 Transmitter inter-packet-gap */
98624 + uint32_t mac_addr_2; /* 0x048 Lower 32 bits of 2nd MAC adr */
98625 + uint32_t mac_addr_3; /* 0x04c Upper 16 bits of 2nd MAC adr */
98626 + uint32_t rx_fifo_ptr_rd; /* 0x050 */
98627 + uint32_t rx_fifo_ptr_wr; /* 0x054 */
98628 + uint32_t tx_fifo_ptr_rd; /* 0x058 */
98629 + uint32_t tx_fifo_ptr_wr; /* 0x05c */
98630 + uint32_t imask; /* 0x060 Interrupt mask */
98631 + uint32_t ievent; /* 0x064 Interrupt event */
98632 + uint32_t udp_port; /* 0x068 Defines a UDP Port number */
98633 + uint32_t type_1588v2; /* 0x06c Type field for 1588v2 */
98634 + uint32_t reserved070[4]; /* 0x070 */
98635 + /*10Ge Statistics Counter */
98636 + uint32_t tfrm_u; /* 80 aFramesTransmittedOK */
98637 + uint32_t tfrm_l; /* 84 aFramesTransmittedOK */
98638 + uint32_t rfrm_u; /* 88 aFramesReceivedOK */
98639 + uint32_t rfrm_l; /* 8c aFramesReceivedOK */
98640 + uint32_t rfcs_u; /* 90 aFrameCheckSequenceErrors */
98641 + uint32_t rfcs_l; /* 94 aFrameCheckSequenceErrors */
98642 + uint32_t raln_u; /* 98 aAlignmentErrors */
98643 + uint32_t raln_l; /* 9c aAlignmentErrors */
98644 + uint32_t txpf_u; /* A0 aPAUSEMACCtrlFramesTransmitted */
98645 + uint32_t txpf_l; /* A4 aPAUSEMACCtrlFramesTransmitted */
98646 + uint32_t rxpf_u; /* A8 aPAUSEMACCtrlFramesReceived */
98647 + uint32_t rxpf_l; /* Ac aPAUSEMACCtrlFramesReceived */
98648 + uint32_t rlong_u; /* B0 aFrameTooLongErrors */
98649 + uint32_t rlong_l; /* B4 aFrameTooLongErrors */
98650 + uint32_t rflr_u; /* B8 aInRangeLengthErrors */
98651 + uint32_t rflr_l; /* Bc aInRangeLengthErrors */
98652 + uint32_t tvlan_u; /* C0 VLANTransmittedOK */
98653 + uint32_t tvlan_l; /* C4 VLANTransmittedOK */
98654 + uint32_t rvlan_u; /* C8 VLANReceivedOK */
98655 + uint32_t rvlan_l; /* Cc VLANReceivedOK */
98656 + uint32_t toct_u; /* D0 ifOutOctets */
98657 + uint32_t toct_l; /* D4 ifOutOctets */
98658 + uint32_t roct_u; /* D8 ifInOctets */
98659 + uint32_t roct_l; /* Dc ifInOctets */
98660 + uint32_t ruca_u; /* E0 ifInUcastPkts */
98661 + uint32_t ruca_l; /* E4 ifInUcastPkts */
98662 + uint32_t rmca_u; /* E8 ifInMulticastPkts */
98663 + uint32_t rmca_l; /* Ec ifInMulticastPkts */
98664 + uint32_t rbca_u; /* F0 ifInBroadcastPkts */
98665 + uint32_t rbca_l; /* F4 ifInBroadcastPkts */
98666 + uint32_t terr_u; /* F8 ifOutErrors */
98667 + uint32_t terr_l; /* Fc ifOutErrors */
98668 + uint32_t reserved100[2]; /* 100-108*/
98669 + uint32_t tuca_u; /* 108 ifOutUcastPkts */
98670 + uint32_t tuca_l; /* 10c ifOutUcastPkts */
98671 + uint32_t tmca_u; /* 110 ifOutMulticastPkts */
98672 + uint32_t tmca_l; /* 114 ifOutMulticastPkts */
98673 + uint32_t tbca_u; /* 118 ifOutBroadcastPkts */
98674 + uint32_t tbca_l; /* 11c ifOutBroadcastPkts */
98675 + uint32_t rdrp_u; /* 120 etherStatsDropEvents */
98676 + uint32_t rdrp_l; /* 124 etherStatsDropEvents */
98677 + uint32_t reoct_u; /* 128 etherStatsOctets */
98678 + uint32_t reoct_l; /* 12c etherStatsOctets */
98679 + uint32_t rpkt_u; /* 130 etherStatsPkts */
98680 + uint32_t rpkt_l; /* 134 etherStatsPkts */
98681 + uint32_t trund_u; /* 138 etherStatsUndersizePkts */
98682 + uint32_t trund_l; /* 13c etherStatsUndersizePkts */
98683 + uint32_t r64_u; /* 140 etherStatsPkts64Octets */
98684 + uint32_t r64_l; /* 144 etherStatsPkts64Octets */
98685 + uint32_t r127_u; /* 148 etherStatsPkts65to127Octets */
98686 + uint32_t r127_l; /* 14c etherStatsPkts65to127Octets */
98687 + uint32_t r255_u; /* 150 etherStatsPkts128to255Octets */
98688 + uint32_t r255_l; /* 154 etherStatsPkts128to255Octets */
98689 + uint32_t r511_u; /* 158 etherStatsPkts256to511Octets */
98690 + uint32_t r511_l; /* 15c etherStatsPkts256to511Octets */
98691 + uint32_t r1023_u; /* 160 etherStatsPkts512to1023Octets */
98692 + uint32_t r1023_l; /* 164 etherStatsPkts512to1023Octets */
98693 + uint32_t r1518_u; /* 168 etherStatsPkts1024to1518Octets */
98694 + uint32_t r1518_l; /* 16c etherStatsPkts1024to1518Octets */
98695 + uint32_t r1519x_u; /* 170 etherStatsPkts1519toX */
98696 + uint32_t r1519x_l; /* 174 etherStatsPkts1519toX */
98697 + uint32_t trovr_u; /* 178 etherStatsOversizePkts */
98698 + uint32_t trovr_l; /* 17c etherStatsOversizePkts */
98699 + uint32_t trjbr_u; /* 180 etherStatsJabbers */
98700 + uint32_t trjbr_l; /* 184 etherStatsJabbers */
98701 + uint32_t trfrg_u; /* 188 etherStatsFragments */
98702 + uint32_t trfrg_l; /* 18C etherStatsFragments */
98703 + uint32_t rerr_u; /* 190 ifInErrors */
98704 + uint32_t rerr_l; /* 194 ifInErrors */
98705 +};
98706 +
98707 +/**
98708 + * struct tgec_cfg - TGEC configuration
98709 + *
98710 + * @rx_error_discard: Receive Erroneous Frame Discard Enable. When set to 1
98711 + * any frame received with an error is discarded in the
98712 + * Core and not forwarded to the Client interface.
98713 + * When set to 0 (Reset value), erroneous Frames are
98714 + * forwarded to the Client interface with ff_rx_err
98715 + * asserted.
98716 + * @pause_ignore: Ignore Pause Frame Quanta. If set to 1 received pause
98717 + * frames are ignored by the MAC. When set to 0
98718 + * (Reset value) the transmit process is stopped for the
98719 + * amount of time specified in the pause quanta received
98720 + * within a pause frame.
98721 + * @pause_forward_enable:
98722 + * Terminate / Forward Pause Frames. If set to 1 pause
98723 + * frames are forwarded to the user application. When set
98724 + * to 0 (Reset value) pause frames are terminated and
98725 + * discarded within the MAC.
98726 + * @no_length_check_enable:
98727 + * Payload Length Check Disable. When set to 0
98728 + * (Reset value), the Core checks the frame's payload
98729 + * length with the Frame Length/Type field, when set to 1
98730 + * the payload length check is disabled.
98731 + * @cmd_frame_enable: Enables reception of all command frames. When set to 1
98732 + * all Command Frames are accepted, when set to 0
98733 + * (Reset Value) only Pause Frames are accepted and all
98734 + * other Command Frames are rejected.
98735 + * @send_idle_enable: Force Idle Generation. When set to 1, the MAC
98736 + * permanently sends XGMII Idle sequences even when faults
98737 + * are received.
98738 + * @wan_mode_enable: WAN Mode Enable. Sets WAN mode (1) or LAN mode
98739 + * (0, default) of operation.
98740 + * @promiscuous_mode_enable:
98741 + * Enables MAC promiscuous operation. When set to 1, all
98742 + * frames are received without any MAC address filtering,
98743 + * when set to 0 (Reset value) Unicast Frames with a
98744 + * destination address not matching the Core MAC Address
98745 + * (MAC Address programmed in Registers MAC_ADDR_0 and
98746 + * MAC_ADDR_1 or the MAC address programmed in Registers
98747 + * MAC_ADDR_2 and MAC_ADDR_3) are rejected.
98748 + * @tx_addr_ins_enable: Set Source MAC Address on Transmit. If set to 1 the
98749 + * MAC overwrites the source MAC address received from the
98750 + * Client Interface with one of the MAC addresses. If set
98751 + * to 0 (Reset value), the source MAC address from the
98752 + * Client Interface is transmitted unmodified to the line.
98753 + * @loopback_enable: PHY Interface Loopback. When set to 1, the signal
98754 + * loop_ena is set to '1', when set to 0 (Reset value)
98755 + * the signal loop_ena is set to 0.
98756 + * @lgth_check_nostdr: The Core interprets the Length/Type field differently
98757 + * depending on the value of this Bit
98758 + * @time_stamp_enable: This bit selects between enabling and disabling the
98759 + * IEEE 1588 functionality. 1: IEEE 1588 is enabled
98760 + * 0: IEEE 1588 is disabled
98761 + * @max_frame_length: Maximum supported received frame length.
98762 + * The 10GEC MAC supports reception of any frame size up
98763 + * to 16,352 bytes (0x3FE0). Typical settings are
98764 + * 0x05EE (1,518 bytes) for standard frames.
98765 + * Default setting is 0x0600 (1,536 bytes).
98766 + * Received frames that exceed this stated maximum
98767 + * are truncated.
98768 + * @pause_quant: Pause quanta value used with transmitted pause frames.
98769 + * Each quanta represents a 512 bit-times.
98770 + * @tx_ipg_length: Transmit Inter-Packet-Gap (IPG) value. A 6-bit value:
98771 + * Depending on LAN or WAN mode of operation the value has
98772 + * the following meaning: - LAN Mode: Number of octets in
98773 + * steps of 4. Valid values are 8, 12, 16, ... 100. DIC is
98774 + * fully supported (see 10.6.1 page 49) for any setting. A
98775 + * default of 12 (reset value) must be set to conform to
98776 + * IEEE802.3ae. Warning: When set to 8, PCS layers may not
98777 + * be able to perform clock rate compensation. - WAN Mode:
98778 + * Stretch factor. Valid values are 4..15. The stretch
98779 + * factor is calculated as (value+1)*8. A default of 12
98780 + * (reset value) must be set to conform to IEEE 802.3ae
98781 + * (i.e. 13*8=104). A larger value shrinks the IPG
98782 + * (increasing bandwidth).
98783 + *
98784 + * This structure contains basic TGEC configuration and must be passed to
98785 + * fman_tgec_init() function. A default set of configuration values can be
98786 + * obtained by calling fman_tgec_defconfig().
98787 + */
98788 +struct tgec_cfg {
98789 + bool rx_error_discard;
98790 + bool pause_ignore;
98791 + bool pause_forward_enable;
98792 + bool no_length_check_enable;
98793 + bool cmd_frame_enable;
98794 + bool send_idle_enable;
98795 + bool wan_mode_enable;
98796 + bool promiscuous_mode_enable;
98797 + bool tx_addr_ins_enable;
98798 + bool loopback_enable;
98799 + bool lgth_check_nostdr;
98800 + bool time_stamp_enable;
98801 + uint16_t max_frame_length;
98802 + uint16_t pause_quant;
98803 + uint32_t tx_ipg_length;
98804 + bool skip_fman11_workaround;
98805 +};
98806 +
98807 +
98808 +void fman_tgec_defconfig(struct tgec_cfg *cfg);
98809 +
98810 +/**
98811 + * fman_tgec_init() - Init tgec hardware block
98812 + * @regs: Pointer to tgec register block
98813 + * @cfg: tgec configuration data
98814 + * @exceptions_mask: initial exceptions mask
98815 + *
98816 + * This function initializes the tgec controller and applies its
98817 + * basic configuration.
98818 + *
98819 + * Returns: 0 if successful, an error code otherwise.
98820 + */
98821 +
98822 +int fman_tgec_init(struct tgec_regs *regs, struct tgec_cfg *cfg,
98823 + uint32_t exception_mask);
98824 +
98825 +void fman_tgec_enable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
98826 +
98827 +void fman_tgec_disable(struct tgec_regs *regs, bool apply_rx, bool apply_tx);
98828 +
98829 +uint32_t fman_tgec_get_revision(struct tgec_regs *regs);
98830 +
98831 +void fman_tgec_set_mac_address(struct tgec_regs *regs, uint8_t *macaddr);
98832 +
98833 +void fman_tgec_set_promiscuous(struct tgec_regs *regs, bool val);
98834 +
98835 +/**
98836 + * fman_tgec_reset_stat() - Completely resets all TGEC HW counters
98837 + * @regs: Pointer to TGEC register block
98838 + */
98839 +void fman_tgec_reset_stat(struct tgec_regs *regs);
98840 +
98841 +/**
98842 + * fman_tgec_get_counter() - Reads TGEC HW counters
98843 + * @regs: Pointer to TGEC register block
98844 + * @reg_name: Counter name according to the appropriate enum
98845 + *
98846 + * Returns: Required counter value
98847 + */
98848 +uint64_t fman_tgec_get_counter(struct tgec_regs *regs,
98849 + enum tgec_counters reg_name);
98850 +
98851 +/**
98852 + * fman_tgec_set_hash_table() - Sets the Hashtable Control Register
98853 + * @regs: Pointer to TGEC register block
98854 + * @value: Value to be written in Hashtable Control Register
98855 + */
98856 +void fman_tgec_set_hash_table(struct tgec_regs *regs, uint32_t value);
98857 +
98858 +/**
98859 + * fman_tgec_set_tx_pause_frames() - Sets the Pause Quanta Register
98860 + * @regs: Pointer to TGEC register block
98861 + * @pause_time: Pause quanta value used with transmitted pause frames.
98862 + * Each quanta represents a 512 bit-times
98863 + */
98864 +void fman_tgec_set_tx_pause_frames(struct tgec_regs *regs, uint16_t pause_time);
98865 +
98866 +/**
98867 + * fman_tgec_set_rx_ignore_pause_frames() - Changes the policy WRT pause frames
98868 + * @regs: Pointer to TGEC register block
98869 + * @en: Ignore/Respond to pause frame quanta
98870 + *
98871 + * Sets the value of PAUSE_IGNORE field in the COMMAND_CONFIG Register
98872 + * 0 - MAC stops transmit process for the duration specified
98873 + * in the Pause frame quanta of a received Pause frame.
98874 + * 1 - MAC ignores received Pause frames.
98875 + */
98876 +void fman_tgec_set_rx_ignore_pause_frames(struct tgec_regs *regs, bool en);
98877 +
98878 +/**
98879 + * fman_tgec_enable_1588_time_stamp() - change timestamp functionality
98880 + * @regs: Pointer to TGEC register block
98881 + * @en: enable/disable timestamp functionality
98882 + *
98883 + * Sets the value of EN_TIMESTAMP field in the COMMAND_CONFIG Register
98884 + * IEEE 1588 timestamp functionality control:
98885 + * 0 disabled, 1 enabled
98886 + */
98887 +
98888 +void fman_tgec_enable_1588_time_stamp(struct tgec_regs *regs, bool en);
98889 +
98890 +uint32_t fman_tgec_get_event(struct tgec_regs *regs, uint32_t ev_mask);
98891 +
98892 +void fman_tgec_ack_event(struct tgec_regs *regs, uint32_t ev_mask);
98893 +
98894 +uint32_t fman_tgec_get_interrupt_mask(struct tgec_regs *regs);
98895 +
98896 +/**
98897 + * fman_tgec_add_addr_in_paddr() - Sets additional exact match MAC address
98898 + * @regs: Pointer to TGEC register block
98899 + * @addr_ptr: Pointer to 6-byte array containing the MAC address
98900 + *
98901 + * Sets the additional station MAC address
98902 + */
98903 +void fman_tgec_add_addr_in_paddr(struct tgec_regs *regs, uint8_t *addr_ptr);
98904 +
98905 +void fman_tgec_clear_addr_in_paddr(struct tgec_regs *regs);
98906 +
98907 +void fman_tgec_enable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
98908 +
98909 +void fman_tgec_disable_interrupt(struct tgec_regs *regs, uint32_t ev_mask);
98910 +
98911 +void fman_tgec_reset_filter_table(struct tgec_regs *regs);
98912 +
98913 +void fman_tgec_set_hash_table_entry(struct tgec_regs *regs, uint32_t crc);
98914 +
98915 +
98916 +/**
98917 + * fman_tgec_get_max_frame_len() - Returns the maximum frame length value
98918 + * @regs: Pointer to TGEC register block
98919 + */
98920 +uint16_t fman_tgec_get_max_frame_len(struct tgec_regs *regs);
98921 +
98922 +/**
98923 + * fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007() - Initialize the
98924 + * main tgec configuration parameters
98925 + * @regs: Pointer to TGEC register block
98926 + *
98927 + * TODO
98928 + */
98929 +void fman_tgec_set_erratum_tx_fifo_corruption_10gmac_a007(struct tgec_regs
98930 + *regs);
98931 +
98932 +
98933 +#endif /* __FSL_FMAN_TGEC_H */
98934 --- /dev/null
98935 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/dpaa_integration_ext.h
98936 @@ -0,0 +1,291 @@
98937 +/*
98938 + * Copyright 2012 Freescale Semiconductor Inc.
98939 + *
98940 + * Redistribution and use in source and binary forms, with or without
98941 + * modification, are permitted provided that the following conditions are met:
98942 + * * Redistributions of source code must retain the above copyright
98943 + * notice, this list of conditions and the following disclaimer.
98944 + * * Redistributions in binary form must reproduce the above copyright
98945 + * notice, this list of conditions and the following disclaimer in the
98946 + * documentation and/or other materials provided with the distribution.
98947 + * * Neither the name of Freescale Semiconductor nor the
98948 + * names of its contributors may be used to endorse or promote products
98949 + * derived from this software without specific prior written permission.
98950 + *
98951 + *
98952 + * ALTERNATIVELY, this software may be distributed under the terms of the
98953 + * GNU General Public License ("GPL") as published by the Free Software
98954 + * Foundation, either version 2 of that License or (at your option) any
98955 + * later version.
98956 + *
98957 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
98958 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
98959 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
98960 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
98961 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
98962 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
98963 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
98964 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
98965 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
98966 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
98967 + */
98968 +
98969 +/**
98970 +
98971 + @File dpaa_integration_ext.h
98972 +
98973 + @Description T4240 FM external definitions and structures.
98974 +*//***************************************************************************/
98975 +#ifndef __DPAA_INTEGRATION_EXT_H
98976 +#define __DPAA_INTEGRATION_EXT_H
98977 +
98978 +#include "std_ext.h"
98979 +
98980 +
98981 +#define DPAA_VERSION 11
98982 +
98983 +/**************************************************************************//**
98984 + @Description DPAA SW Portals Enumeration.
98985 +*//***************************************************************************/
98986 +typedef enum
98987 +{
98988 + e_DPAA_SWPORTAL0 = 0,
98989 + e_DPAA_SWPORTAL1,
98990 + e_DPAA_SWPORTAL2,
98991 + e_DPAA_SWPORTAL3,
98992 + e_DPAA_SWPORTAL4,
98993 + e_DPAA_SWPORTAL5,
98994 + e_DPAA_SWPORTAL6,
98995 + e_DPAA_SWPORTAL7,
98996 + e_DPAA_SWPORTAL8,
98997 + e_DPAA_SWPORTAL9,
98998 + e_DPAA_SWPORTAL10,
98999 + e_DPAA_SWPORTAL11,
99000 + e_DPAA_SWPORTAL12,
99001 + e_DPAA_SWPORTAL13,
99002 + e_DPAA_SWPORTAL14,
99003 + e_DPAA_SWPORTAL15,
99004 + e_DPAA_SWPORTAL16,
99005 + e_DPAA_SWPORTAL17,
99006 + e_DPAA_SWPORTAL18,
99007 + e_DPAA_SWPORTAL19,
99008 + e_DPAA_SWPORTAL20,
99009 + e_DPAA_SWPORTAL21,
99010 + e_DPAA_SWPORTAL22,
99011 + e_DPAA_SWPORTAL23,
99012 + e_DPAA_SWPORTAL24,
99013 + e_DPAA_SWPORTAL_DUMMY_LAST
99014 +} e_DpaaSwPortal;
99015 +
99016 +/**************************************************************************//**
99017 + @Description DPAA Direct Connect Portals Enumeration.
99018 +*//***************************************************************************/
99019 +typedef enum
99020 +{
99021 + e_DPAA_DCPORTAL0 = 0,
99022 + e_DPAA_DCPORTAL1,
99023 + e_DPAA_DCPORTAL2,
99024 + e_DPAA_DCPORTAL_DUMMY_LAST
99025 +} e_DpaaDcPortal;
99026 +
99027 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99028 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99029 +
99030 +/*****************************************************************************
99031 + QMan INTEGRATION-SPECIFIC DEFINITIONS
99032 +******************************************************************************/
99033 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
99034 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
99035 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
99036 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
99037 + /**< FQIDs range - 24 bits */
99038 +
99039 +/**************************************************************************//**
99040 + @Description Work Queue Channel assignments in QMan.
99041 +*//***************************************************************************/
99042 +typedef enum
99043 +{
99044 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
99045 + e_QM_FQ_CHANNEL_SWPORTAL1,
99046 + e_QM_FQ_CHANNEL_SWPORTAL2,
99047 + e_QM_FQ_CHANNEL_SWPORTAL3,
99048 + e_QM_FQ_CHANNEL_SWPORTAL4,
99049 + e_QM_FQ_CHANNEL_SWPORTAL5,
99050 + e_QM_FQ_CHANNEL_SWPORTAL6,
99051 + e_QM_FQ_CHANNEL_SWPORTAL7,
99052 + e_QM_FQ_CHANNEL_SWPORTAL8,
99053 + e_QM_FQ_CHANNEL_SWPORTAL9,
99054 + e_QM_FQ_CHANNEL_SWPORTAL10,
99055 + e_QM_FQ_CHANNEL_SWPORTAL11,
99056 + e_QM_FQ_CHANNEL_SWPORTAL12,
99057 + e_QM_FQ_CHANNEL_SWPORTAL13,
99058 + e_QM_FQ_CHANNEL_SWPORTAL14,
99059 + e_QM_FQ_CHANNEL_SWPORTAL15,
99060 + e_QM_FQ_CHANNEL_SWPORTAL16,
99061 + e_QM_FQ_CHANNEL_SWPORTAL17,
99062 + e_QM_FQ_CHANNEL_SWPORTAL18,
99063 + e_QM_FQ_CHANNEL_SWPORTAL19,
99064 + e_QM_FQ_CHANNEL_SWPORTAL20,
99065 + e_QM_FQ_CHANNEL_SWPORTAL21,
99066 + e_QM_FQ_CHANNEL_SWPORTAL22,
99067 + e_QM_FQ_CHANNEL_SWPORTAL23,
99068 + e_QM_FQ_CHANNEL_SWPORTAL24,
99069 +
99070 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
99071 + e_QM_FQ_CHANNEL_POOL2,
99072 + e_QM_FQ_CHANNEL_POOL3,
99073 + e_QM_FQ_CHANNEL_POOL4,
99074 + e_QM_FQ_CHANNEL_POOL5,
99075 + e_QM_FQ_CHANNEL_POOL6,
99076 + e_QM_FQ_CHANNEL_POOL7,
99077 + e_QM_FQ_CHANNEL_POOL8,
99078 + e_QM_FQ_CHANNEL_POOL9,
99079 + e_QM_FQ_CHANNEL_POOL10,
99080 + e_QM_FQ_CHANNEL_POOL11,
99081 + e_QM_FQ_CHANNEL_POOL12,
99082 + e_QM_FQ_CHANNEL_POOL13,
99083 + e_QM_FQ_CHANNEL_POOL14,
99084 + e_QM_FQ_CHANNEL_POOL15,
99085 +
99086 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
99087 + connected to FMan 0; assigned in incrementing order to
99088 + each sub-portal (SP) in the portal */
99089 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99090 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99091 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99092 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99093 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99094 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99095 + e_QM_FQ_CHANNEL_FMAN0_SP7,
99096 + e_QM_FQ_CHANNEL_FMAN0_SP8,
99097 + e_QM_FQ_CHANNEL_FMAN0_SP9,
99098 + e_QM_FQ_CHANNEL_FMAN0_SP10,
99099 + e_QM_FQ_CHANNEL_FMAN0_SP11,
99100 + e_QM_FQ_CHANNEL_FMAN0_SP12,
99101 + e_QM_FQ_CHANNEL_FMAN0_SP13,
99102 + e_QM_FQ_CHANNEL_FMAN0_SP14,
99103 + e_QM_FQ_CHANNEL_FMAN0_SP15,
99104 +
99105 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
99106 + e_QM_FQ_CHANNEL_RMAN_SP1,
99107 +
99108 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
99109 + connected to SEC */
99110 +} e_QmFQChannel;
99111 +
99112 +/*****************************************************************************
99113 + BMan INTEGRATION-SPECIFIC DEFINITIONS
99114 +******************************************************************************/
99115 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
99116 +
99117 +/*****************************************************************************
99118 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99119 +******************************************************************************/
99120 +#define SEC_NUM_OF_DECOS 3
99121 +#define SEC_ALL_DECOS_MASK 0x00000003
99122 +
99123 +
99124 +/*****************************************************************************
99125 + FM INTEGRATION-SPECIFIC DEFINITIONS
99126 +******************************************************************************/
99127 +#define INTG_MAX_NUM_OF_FM 2
99128 +/* Ports defines */
99129 +#define FM_MAX_NUM_OF_1G_MACS 6
99130 +#define FM_MAX_NUM_OF_10G_MACS 2
99131 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99132 +#define FM_MAX_NUM_OF_OH_PORTS 6
99133 +
99134 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99135 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99136 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99137 +
99138 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99139 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99140 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99141 +
99142 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99143 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
99144 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
99145 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
99146 +
99147 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
99148 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
99149 +
99150 +/* RAMs defines */
99151 +#define FM_MURAM_SIZE (384 * KILOBYTE)
99152 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
99153 +#define FM_NUM_OF_CTRL 4
99154 +
99155 +/* PCD defines */
99156 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
99157 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
99158 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
99159 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
99160 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99161 +
99162 +/* RTC defines */
99163 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
99164 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
99165 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
99166 +
99167 +/* QMI defines */
99168 +#define QMI_MAX_NUM_OF_TNUMS 64
99169 +#define QMI_DEF_TNUMS_THRESH 32
99170 +/* FPM defines */
99171 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99172 +
99173 +/* DMA defines */
99174 +#define DMA_THRESH_MAX_COMMQ 83
99175 +#define DMA_THRESH_MAX_BUF 127
99176 +
99177 +/* BMI defines */
99178 +#define BMI_MAX_NUM_OF_TASKS 128
99179 +#define BMI_MAX_NUM_OF_DMAS 84
99180 +
99181 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99182 +#define PORT_MAX_WEIGHT 16
99183 +
99184 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
99185 +
99186 +/* Unique T4240 */
99187 +#define FM_OP_OPEN_DMA_MIN_LIMIT
99188 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
99189 +#define FM_NO_OP_OBSERVED_POOLS
99190 +#define FM_FRAME_END_PARAMS_FOR_OP
99191 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99192 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
99193 +
99194 +#define FM_NO_GUARANTEED_RESET_VALUES
99195 +
99196 +/* FM errata */
99197 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
99198 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
99199 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
99200 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
99201 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
99202 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
99203 +
99204 +#define FM_BCB_ERRATA_BMI_SW001
99205 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
99206 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
99207 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
99208 +
99209 +/*****************************************************************************
99210 + RMan INTEGRATION-SPECIFIC DEFINITIONS
99211 +******************************************************************************/
99212 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
99213 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
99214 +
99215 +/* RMan erratas */
99216 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
99217 +
99218 +/*****************************************************************************
99219 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99220 +******************************************************************************/
99221 +#define NUM_OF_RX_SC 16
99222 +#define NUM_OF_TX_SC 16
99223 +
99224 +#define NUM_OF_SA_PER_RX_SC 2
99225 +#define NUM_OF_SA_PER_TX_SC 2
99226 +
99227 +#endif /* __DPAA_INTEGRATION_EXT_H */
99228 --- /dev/null
99229 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_ext.h
99230 @@ -0,0 +1,71 @@
99231 +/*
99232 + * Copyright 2012 Freescale Semiconductor Inc.
99233 + *
99234 + * Redistribution and use in source and binary forms, with or without
99235 + * modification, are permitted provided that the following conditions are met:
99236 + * * Redistributions of source code must retain the above copyright
99237 + * notice, this list of conditions and the following disclaimer.
99238 + * * Redistributions in binary form must reproduce the above copyright
99239 + * notice, this list of conditions and the following disclaimer in the
99240 + * documentation and/or other materials provided with the distribution.
99241 + * * Neither the name of Freescale Semiconductor nor the
99242 + * names of its contributors may be used to endorse or promote products
99243 + * derived from this software without specific prior written permission.
99244 + *
99245 + *
99246 + * ALTERNATIVELY, this software may be distributed under the terms of the
99247 + * GNU General Public License ("GPL") as published by the Free Software
99248 + * Foundation, either version 2 of that License or (at your option) any
99249 + * later version.
99250 + *
99251 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99252 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99253 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99254 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99255 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99256 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99257 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99258 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99259 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99260 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99261 + */
99262 +
99263 +/**************************************************************************//**
99264 +
99265 + @File part_ext.h
99266 +
99267 + @Description Definitions for the part (integration) module.
99268 +*//***************************************************************************/
99269 +
99270 +#ifndef __PART_EXT_H
99271 +#define __PART_EXT_H
99272 +
99273 +#include "std_ext.h"
99274 +#include "part_integration_ext.h"
99275 +
99276 +#if !(defined(P1023) || \
99277 + defined(P2041) || \
99278 + defined(P3041) || \
99279 + defined(P4080) || \
99280 + defined(P5020) || \
99281 + defined(P5040) || \
99282 + defined(B4860) || \
99283 + defined(T4240))
99284 +#error "unable to proceed without chip-definition"
99285 +#endif
99286 +
99287 +
99288 +/**************************************************************************//*
99289 + @Description Part data structure - must be contained in any integration
99290 + data structure.
99291 +*//***************************************************************************/
99292 +typedef struct t_Part
99293 +{
99294 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99295 + /**< Returns the address of the module's memory map base. */
99296 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
99297 + /**< Returns the module's ID according to its memory map base. */
99298 +} t_Part;
99299 +
99300 +
99301 +#endif /* __PART_EXT_H */
99302 --- /dev/null
99303 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3H/part_integration_ext.h
99304 @@ -0,0 +1,304 @@
99305 +/*
99306 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99307 + *
99308 + * Redistribution and use in source and binary forms, with or without
99309 + * modification, are permitted provided that the following conditions are met:
99310 + * * Redistributions of source code must retain the above copyright
99311 + * notice, this list of conditions and the following disclaimer.
99312 + * * Redistributions in binary form must reproduce the above copyright
99313 + * notice, this list of conditions and the following disclaimer in the
99314 + * documentation and/or other materials provided with the distribution.
99315 + * * Neither the name of Freescale Semiconductor nor the
99316 + * names of its contributors may be used to endorse or promote products
99317 + * derived from this software without specific prior written permission.
99318 + *
99319 + *
99320 + * ALTERNATIVELY, this software may be distributed under the terms of the
99321 + * GNU General Public License ("GPL") as published by the Free Software
99322 + * Foundation, either version 2 of that License or (at your option) any
99323 + * later version.
99324 + *
99325 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99326 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99327 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99328 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99329 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99330 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99331 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99332 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99333 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99334 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99335 + */
99336 +
99337 +/**
99338 +
99339 + @File part_integration_ext.h
99340 +
99341 + @Description T4240 external definitions and structures.
99342 +*//***************************************************************************/
99343 +#ifndef __PART_INTEGRATION_EXT_H
99344 +#define __PART_INTEGRATION_EXT_H
99345 +
99346 +#include "std_ext.h"
99347 +#include "ddr_std_ext.h"
99348 +#include "enet_ext.h"
99349 +#include "dpaa_integration_ext.h"
99350 +
99351 +
99352 +/**************************************************************************//**
99353 + @Group T4240_chip_id T4240 Application Programming Interface
99354 +
99355 + @Description T4240 Chip functions,definitions and enums.
99356 +
99357 + @{
99358 +*//***************************************************************************/
99359 +
99360 +#define CORE_E6500
99361 +
99362 +#define INTG_MAX_NUM_OF_CORES 24
99363 +
99364 +
99365 +/**************************************************************************//**
99366 + @Description Module types.
99367 +*//***************************************************************************/
99368 +typedef enum e_ModuleId
99369 +{
99370 + e_MODULE_ID_DUART_1 = 0,
99371 + e_MODULE_ID_DUART_2,
99372 + e_MODULE_ID_DUART_3,
99373 + e_MODULE_ID_DUART_4,
99374 + e_MODULE_ID_LAW,
99375 + e_MODULE_ID_IFC,
99376 + e_MODULE_ID_PAMU,
99377 + e_MODULE_ID_QM, /**< Queue manager module */
99378 + e_MODULE_ID_BM, /**< Buffer manager module */
99379 + e_MODULE_ID_QM_CE_PORTAL_0,
99380 + e_MODULE_ID_QM_CI_PORTAL_0,
99381 + e_MODULE_ID_QM_CE_PORTAL_1,
99382 + e_MODULE_ID_QM_CI_PORTAL_1,
99383 + e_MODULE_ID_QM_CE_PORTAL_2,
99384 + e_MODULE_ID_QM_CI_PORTAL_2,
99385 + e_MODULE_ID_QM_CE_PORTAL_3,
99386 + e_MODULE_ID_QM_CI_PORTAL_3,
99387 + e_MODULE_ID_QM_CE_PORTAL_4,
99388 + e_MODULE_ID_QM_CI_PORTAL_4,
99389 + e_MODULE_ID_QM_CE_PORTAL_5,
99390 + e_MODULE_ID_QM_CI_PORTAL_5,
99391 + e_MODULE_ID_QM_CE_PORTAL_6,
99392 + e_MODULE_ID_QM_CI_PORTAL_6,
99393 + e_MODULE_ID_QM_CE_PORTAL_7,
99394 + e_MODULE_ID_QM_CI_PORTAL_7,
99395 + e_MODULE_ID_QM_CE_PORTAL_8,
99396 + e_MODULE_ID_QM_CI_PORTAL_8,
99397 + e_MODULE_ID_QM_CE_PORTAL_9,
99398 + e_MODULE_ID_QM_CI_PORTAL_9,
99399 + e_MODULE_ID_BM_CE_PORTAL_0,
99400 + e_MODULE_ID_BM_CI_PORTAL_0,
99401 + e_MODULE_ID_BM_CE_PORTAL_1,
99402 + e_MODULE_ID_BM_CI_PORTAL_1,
99403 + e_MODULE_ID_BM_CE_PORTAL_2,
99404 + e_MODULE_ID_BM_CI_PORTAL_2,
99405 + e_MODULE_ID_BM_CE_PORTAL_3,
99406 + e_MODULE_ID_BM_CI_PORTAL_3,
99407 + e_MODULE_ID_BM_CE_PORTAL_4,
99408 + e_MODULE_ID_BM_CI_PORTAL_4,
99409 + e_MODULE_ID_BM_CE_PORTAL_5,
99410 + e_MODULE_ID_BM_CI_PORTAL_5,
99411 + e_MODULE_ID_BM_CE_PORTAL_6,
99412 + e_MODULE_ID_BM_CI_PORTAL_6,
99413 + e_MODULE_ID_BM_CE_PORTAL_7,
99414 + e_MODULE_ID_BM_CI_PORTAL_7,
99415 + e_MODULE_ID_BM_CE_PORTAL_8,
99416 + e_MODULE_ID_BM_CI_PORTAL_8,
99417 + e_MODULE_ID_BM_CE_PORTAL_9,
99418 + e_MODULE_ID_BM_CI_PORTAL_9,
99419 + e_MODULE_ID_FM, /**< Frame manager module */
99420 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
99421 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
99422 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
99423 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
99424 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
99425 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
99426 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
99427 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
99428 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
99429 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
99430 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
99431 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
99432 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
99433 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
99434 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
99435 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
99436 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
99437 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
99438 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
99439 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
99440 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
99441 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
99442 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
99443 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
99444 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
99445 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
99446 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
99447 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
99448 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
99449 + e_MODULE_ID_FM_KG, /**< FM Keygen */
99450 + e_MODULE_ID_FM_DMA, /**< FM DMA */
99451 + e_MODULE_ID_FM_FPM, /**< FM FPM */
99452 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
99453 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
99454 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
99455 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
99456 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
99457 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
99458 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
99459 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
99460 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
99461 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
99462 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
99463 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
99464 +
99465 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
99466 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
99467 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
99468 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
99469 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
99470 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
99471 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
99472 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
99473 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
99474 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
99475 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
99476 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
99477 +
99478 + e_MODULE_ID_PIC, /**< PIC */
99479 + e_MODULE_ID_GPIO, /**< GPIO */
99480 + e_MODULE_ID_SERDES, /**< SERDES */
99481 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
99482 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
99483 +
99484 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
99485 +
99486 + e_MODULE_ID_DUMMY_LAST
99487 +} e_ModuleId;
99488 +
99489 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
99490 +
99491 +#if 0 /* using unified values */
99492 +/*****************************************************************************
99493 + INTEGRATION-SPECIFIC MODULE CODES
99494 +******************************************************************************/
99495 +#define MODULE_UNKNOWN 0x00000000
99496 +#define MODULE_MEM 0x00010000
99497 +#define MODULE_MM 0x00020000
99498 +#define MODULE_CORE 0x00030000
99499 +#define MODULE_T4240 0x00040000
99500 +#define MODULE_T4240_PLATFORM 0x00050000
99501 +#define MODULE_PM 0x00060000
99502 +#define MODULE_MMU 0x00070000
99503 +#define MODULE_PIC 0x00080000
99504 +#define MODULE_CPC 0x00090000
99505 +#define MODULE_DUART 0x000a0000
99506 +#define MODULE_SERDES 0x000b0000
99507 +#define MODULE_PIO 0x000c0000
99508 +#define MODULE_QM 0x000d0000
99509 +#define MODULE_BM 0x000e0000
99510 +#define MODULE_SEC 0x000f0000
99511 +#define MODULE_LAW 0x00100000
99512 +#define MODULE_LBC 0x00110000
99513 +#define MODULE_PAMU 0x00120000
99514 +#define MODULE_FM 0x00130000
99515 +#define MODULE_FM_MURAM 0x00140000
99516 +#define MODULE_FM_PCD 0x00150000
99517 +#define MODULE_FM_RTC 0x00160000
99518 +#define MODULE_FM_MAC 0x00170000
99519 +#define MODULE_FM_PORT 0x00180000
99520 +#define MODULE_FM_SP 0x00190000
99521 +#define MODULE_DPA_PORT 0x001a0000
99522 +#define MODULE_MII 0x001b0000
99523 +#define MODULE_I2C 0x001c0000
99524 +#define MODULE_DMA 0x001d0000
99525 +#define MODULE_DDR 0x001e0000
99526 +#define MODULE_ESPI 0x001f0000
99527 +#define MODULE_DPAA_IPSEC 0x00200000
99528 +#endif /* using unified values */
99529 +
99530 +/*****************************************************************************
99531 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
99532 +******************************************************************************/
99533 +#define PAMU_NUM_OF_PARTITIONS 4
99534 +
99535 +/*****************************************************************************
99536 + LAW INTEGRATION-SPECIFIC DEFINITIONS
99537 +******************************************************************************/
99538 +#define LAW_NUM_OF_WINDOWS 32
99539 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
99540 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
99541 +
99542 +
99543 +/*****************************************************************************
99544 + LBC INTEGRATION-SPECIFIC DEFINITIONS
99545 +******************************************************************************/
99546 +/**************************************************************************//**
99547 + @Group lbc_exception_grp LBC Exception Unit
99548 +
99549 + @Description LBC Exception unit API functions, definitions and enums
99550 +
99551 + @{
99552 +*//***************************************************************************/
99553 +
99554 +/**************************************************************************//**
99555 + @Anchor lbc_exbm
99556 +
99557 + @Collection LBC Errors Bit Mask
99558 +
99559 + These errors are reported through the exceptions callback..
99560 + The values can be or'ed in any combination in the errors mask
99561 + parameter of the errors report structure.
99562 +
99563 + These errors can also be passed as a bit-mask to
99564 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
99565 + for enabling or disabling error checking.
99566 + @{
99567 +*//***************************************************************************/
99568 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
99569 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
99570 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
99571 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
99572 +
99573 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
99574 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
99575 + /**< All possible errors */
99576 +/* @} */
99577 +/** @} */ /* end of lbc_exception_grp group */
99578 +
99579 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
99580 +
99581 +#define LBC_NUM_OF_BANKS 8
99582 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
99583 +#define LBC_PARITY_SUPPORT
99584 +#define LBC_ADDRESS_HOLD_TIME_CTRL
99585 +#define LBC_HIGH_CLK_DIVIDERS
99586 +#define LBC_FCM_AVAILABLE
99587 +
99588 +/*****************************************************************************
99589 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
99590 +******************************************************************************/
99591 +#define GPIO_PORT_OFFSET_0x1000
99592 +
99593 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
99594 + Each port contains up to 32 I/O pins. */
99595 +
99596 +#define GPIO_VALID_PIN_MASKS \
99597 + { /* Port A */ 0xFFFFFFFF, \
99598 + /* Port B */ 0xFFFFFFFF, \
99599 + /* Port C */ 0xFFFFFFFF }
99600 +
99601 +#define GPIO_VALID_INTR_MASKS \
99602 + { /* Port A */ 0xFFFFFFFF, \
99603 + /* Port B */ 0xFFFFFFFF, \
99604 + /* Port C */ 0xFFFFFFFF }
99605 +
99606 +
99607 +
99608 +#endif /* __PART_INTEGRATION_EXT_H */
99609 --- /dev/null
99610 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/dpaa_integration_ext.h
99611 @@ -0,0 +1,293 @@
99612 +/*
99613 + * Copyright 2012 Freescale Semiconductor Inc.
99614 + *
99615 + * Redistribution and use in source and binary forms, with or without
99616 + * modification, are permitted provided that the following conditions are met:
99617 + * * Redistributions of source code must retain the above copyright
99618 + * notice, this list of conditions and the following disclaimer.
99619 + * * Redistributions in binary form must reproduce the above copyright
99620 + * notice, this list of conditions and the following disclaimer in the
99621 + * documentation and/or other materials provided with the distribution.
99622 + * * Neither the name of Freescale Semiconductor nor the
99623 + * names of its contributors may be used to endorse or promote products
99624 + * derived from this software without specific prior written permission.
99625 + *
99626 + *
99627 + * ALTERNATIVELY, this software may be distributed under the terms of the
99628 + * GNU General Public License ("GPL") as published by the Free Software
99629 + * Foundation, either version 2 of that License or (at your option) any
99630 + * later version.
99631 + *
99632 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99633 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99634 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99635 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99636 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99637 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99638 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99639 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99640 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99641 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99642 + */
99643 +
99644 +/**
99645 +
99646 + @File dpaa_integration_ext.h
99647 +
99648 + @Description T4240 FM external definitions and structures.
99649 +*//***************************************************************************/
99650 +#ifndef __DPAA_INTEGRATION_EXT_H
99651 +#define __DPAA_INTEGRATION_EXT_H
99652 +
99653 +#include "std_ext.h"
99654 +
99655 +
99656 +#define DPAA_VERSION 11
99657 +
99658 +/**************************************************************************//**
99659 + @Description DPAA SW Portals Enumeration.
99660 +*//***************************************************************************/
99661 +typedef enum
99662 +{
99663 + e_DPAA_SWPORTAL0 = 0,
99664 + e_DPAA_SWPORTAL1,
99665 + e_DPAA_SWPORTAL2,
99666 + e_DPAA_SWPORTAL3,
99667 + e_DPAA_SWPORTAL4,
99668 + e_DPAA_SWPORTAL5,
99669 + e_DPAA_SWPORTAL6,
99670 + e_DPAA_SWPORTAL7,
99671 + e_DPAA_SWPORTAL8,
99672 + e_DPAA_SWPORTAL9,
99673 + e_DPAA_SWPORTAL10,
99674 + e_DPAA_SWPORTAL11,
99675 + e_DPAA_SWPORTAL12,
99676 + e_DPAA_SWPORTAL13,
99677 + e_DPAA_SWPORTAL14,
99678 + e_DPAA_SWPORTAL15,
99679 + e_DPAA_SWPORTAL16,
99680 + e_DPAA_SWPORTAL17,
99681 + e_DPAA_SWPORTAL18,
99682 + e_DPAA_SWPORTAL19,
99683 + e_DPAA_SWPORTAL20,
99684 + e_DPAA_SWPORTAL21,
99685 + e_DPAA_SWPORTAL22,
99686 + e_DPAA_SWPORTAL23,
99687 + e_DPAA_SWPORTAL24,
99688 + e_DPAA_SWPORTAL_DUMMY_LAST
99689 +} e_DpaaSwPortal;
99690 +
99691 +/**************************************************************************//**
99692 + @Description DPAA Direct Connect Portals Enumeration.
99693 +*//***************************************************************************/
99694 +typedef enum
99695 +{
99696 + e_DPAA_DCPORTAL0 = 0,
99697 + e_DPAA_DCPORTAL1,
99698 + e_DPAA_DCPORTAL2,
99699 + e_DPAA_DCPORTAL_DUMMY_LAST
99700 +} e_DpaaDcPortal;
99701 +
99702 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
99703 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
99704 +
99705 +/*****************************************************************************
99706 + QMan INTEGRATION-SPECIFIC DEFINITIONS
99707 +******************************************************************************/
99708 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
99709 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
99710 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
99711 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
99712 + /**< FQIDs range - 24 bits */
99713 +
99714 +/**************************************************************************//**
99715 + @Description Work Queue Channel assignments in QMan.
99716 +*//***************************************************************************/
99717 +typedef enum
99718 +{
99719 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
99720 + e_QM_FQ_CHANNEL_SWPORTAL1,
99721 + e_QM_FQ_CHANNEL_SWPORTAL2,
99722 + e_QM_FQ_CHANNEL_SWPORTAL3,
99723 + e_QM_FQ_CHANNEL_SWPORTAL4,
99724 + e_QM_FQ_CHANNEL_SWPORTAL5,
99725 + e_QM_FQ_CHANNEL_SWPORTAL6,
99726 + e_QM_FQ_CHANNEL_SWPORTAL7,
99727 + e_QM_FQ_CHANNEL_SWPORTAL8,
99728 + e_QM_FQ_CHANNEL_SWPORTAL9,
99729 + e_QM_FQ_CHANNEL_SWPORTAL10,
99730 + e_QM_FQ_CHANNEL_SWPORTAL11,
99731 + e_QM_FQ_CHANNEL_SWPORTAL12,
99732 + e_QM_FQ_CHANNEL_SWPORTAL13,
99733 + e_QM_FQ_CHANNEL_SWPORTAL14,
99734 + e_QM_FQ_CHANNEL_SWPORTAL15,
99735 + e_QM_FQ_CHANNEL_SWPORTAL16,
99736 + e_QM_FQ_CHANNEL_SWPORTAL17,
99737 + e_QM_FQ_CHANNEL_SWPORTAL18,
99738 + e_QM_FQ_CHANNEL_SWPORTAL19,
99739 + e_QM_FQ_CHANNEL_SWPORTAL20,
99740 + e_QM_FQ_CHANNEL_SWPORTAL21,
99741 + e_QM_FQ_CHANNEL_SWPORTAL22,
99742 + e_QM_FQ_CHANNEL_SWPORTAL23,
99743 + e_QM_FQ_CHANNEL_SWPORTAL24,
99744 +
99745 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
99746 + e_QM_FQ_CHANNEL_POOL2,
99747 + e_QM_FQ_CHANNEL_POOL3,
99748 + e_QM_FQ_CHANNEL_POOL4,
99749 + e_QM_FQ_CHANNEL_POOL5,
99750 + e_QM_FQ_CHANNEL_POOL6,
99751 + e_QM_FQ_CHANNEL_POOL7,
99752 + e_QM_FQ_CHANNEL_POOL8,
99753 + e_QM_FQ_CHANNEL_POOL9,
99754 + e_QM_FQ_CHANNEL_POOL10,
99755 + e_QM_FQ_CHANNEL_POOL11,
99756 + e_QM_FQ_CHANNEL_POOL12,
99757 + e_QM_FQ_CHANNEL_POOL13,
99758 + e_QM_FQ_CHANNEL_POOL14,
99759 + e_QM_FQ_CHANNEL_POOL15,
99760 +
99761 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
99762 + connected to FMan 0; assigned in incrementing order to
99763 + each sub-portal (SP) in the portal */
99764 + e_QM_FQ_CHANNEL_FMAN0_SP1,
99765 + e_QM_FQ_CHANNEL_FMAN0_SP2,
99766 + e_QM_FQ_CHANNEL_FMAN0_SP3,
99767 + e_QM_FQ_CHANNEL_FMAN0_SP4,
99768 + e_QM_FQ_CHANNEL_FMAN0_SP5,
99769 + e_QM_FQ_CHANNEL_FMAN0_SP6,
99770 + e_QM_FQ_CHANNEL_FMAN0_SP7,
99771 + e_QM_FQ_CHANNEL_FMAN0_SP8,
99772 + e_QM_FQ_CHANNEL_FMAN0_SP9,
99773 + e_QM_FQ_CHANNEL_FMAN0_SP10,
99774 + e_QM_FQ_CHANNEL_FMAN0_SP11,
99775 + e_QM_FQ_CHANNEL_FMAN0_SP12,
99776 + e_QM_FQ_CHANNEL_FMAN0_SP13,
99777 + e_QM_FQ_CHANNEL_FMAN0_SP14,
99778 + e_QM_FQ_CHANNEL_FMAN0_SP15,
99779 +
99780 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
99781 + e_QM_FQ_CHANNEL_RMAN_SP1,
99782 +
99783 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
99784 + connected to SEC */
99785 +} e_QmFQChannel;
99786 +
99787 +/*****************************************************************************
99788 + BMan INTEGRATION-SPECIFIC DEFINITIONS
99789 +******************************************************************************/
99790 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
99791 +
99792 +/*****************************************************************************
99793 + SEC INTEGRATION-SPECIFIC DEFINITIONS
99794 +******************************************************************************/
99795 +#define SEC_NUM_OF_DECOS 3
99796 +#define SEC_ALL_DECOS_MASK 0x00000003
99797 +
99798 +
99799 +/*****************************************************************************
99800 + FM INTEGRATION-SPECIFIC DEFINITIONS
99801 +******************************************************************************/
99802 +#define INTG_MAX_NUM_OF_FM 1
99803 +/* Ports defines */
99804 +#define FM_MAX_NUM_OF_1G_MACS 5
99805 +#define FM_MAX_NUM_OF_10G_MACS 1
99806 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
99807 +#define FM_MAX_NUM_OF_OH_PORTS 4
99808 +
99809 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
99810 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
99811 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
99812 +
99813 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
99814 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
99815 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
99816 +
99817 +#define FM_MAX_NUM_OF_MACSECS 1 /* Should be updated */
99818 +
99819 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
99820 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
99821 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
99822 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
99823 +
99824 +#define FM_VSP_MAX_NUM_OF_ENTRIES 32
99825 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
99826 +
99827 +/* RAMs defines */
99828 +#define FM_MURAM_SIZE (192 * KILOBYTE)
99829 +#define FM_IRAM_SIZE(major, minor) \
99830 + (((major == 6) && ((minor == 4) )) ? (64 * KILOBYTE) : (32 * KILOBYTE))
99831 +#define FM_NUM_OF_CTRL 2
99832 +
99833 +/* PCD defines */
99834 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
99835 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
99836 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
99837 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
99838 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
99839 +
99840 +/* RTC defines */
99841 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
99842 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
99843 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
99844 +
99845 +/* QMI defines */
99846 +#define QMI_MAX_NUM_OF_TNUMS 64
99847 +#define QMI_DEF_TNUMS_THRESH 32
99848 +/* FPM defines */
99849 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
99850 +
99851 +/* DMA defines */
99852 +#define DMA_THRESH_MAX_COMMQ 83
99853 +#define DMA_THRESH_MAX_BUF 127
99854 +
99855 +/* BMI defines */
99856 +#define BMI_MAX_NUM_OF_TASKS 64
99857 +#define BMI_MAX_NUM_OF_DMAS 32
99858 +
99859 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
99860 +#define PORT_MAX_WEIGHT 16
99861 +
99862 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
99863 +
99864 +/* Unique T4240 */
99865 +#define FM_OP_OPEN_DMA_MIN_LIMIT
99866 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
99867 +#define FM_NO_OP_OBSERVED_POOLS
99868 +#define FM_FRAME_END_PARAMS_FOR_OP
99869 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
99870 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
99871 +
99872 +#define FM_NO_GUARANTEED_RESET_VALUES
99873 +
99874 +/* FM errata */
99875 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
99876 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
99877 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
99878 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
99879 +#define FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
99880 +
99881 +#define FM_BCB_ERRATA_BMI_SW001
99882 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
99883 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
99884 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
99885 +
99886 +/*****************************************************************************
99887 + RMan INTEGRATION-SPECIFIC DEFINITIONS
99888 +******************************************************************************/
99889 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
99890 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
99891 +
99892 +/* RMan erratas */
99893 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
99894 +
99895 +/*****************************************************************************
99896 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
99897 +******************************************************************************/
99898 +#define NUM_OF_RX_SC 16
99899 +#define NUM_OF_TX_SC 16
99900 +
99901 +#define NUM_OF_SA_PER_RX_SC 2
99902 +#define NUM_OF_SA_PER_TX_SC 2
99903 +
99904 +#endif /* __DPAA_INTEGRATION_EXT_H */
99905 --- /dev/null
99906 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_ext.h
99907 @@ -0,0 +1,59 @@
99908 +/*
99909 + * Copyright 2012 Freescale Semiconductor Inc.
99910 + *
99911 + * Redistribution and use in source and binary forms, with or without
99912 + * modification, are permitted provided that the following conditions are met:
99913 + * * Redistributions of source code must retain the above copyright
99914 + * notice, this list of conditions and the following disclaimer.
99915 + * * Redistributions in binary form must reproduce the above copyright
99916 + * notice, this list of conditions and the following disclaimer in the
99917 + * documentation and/or other materials provided with the distribution.
99918 + * * Neither the name of Freescale Semiconductor nor the
99919 + * names of its contributors may be used to endorse or promote products
99920 + * derived from this software without specific prior written permission.
99921 + *
99922 + *
99923 + * ALTERNATIVELY, this software may be distributed under the terms of the
99924 + * GNU General Public License ("GPL") as published by the Free Software
99925 + * Foundation, either version 2 of that License or (at your option) any
99926 + * later version.
99927 + *
99928 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99929 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99930 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99931 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99932 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99933 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99934 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99935 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99936 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99937 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
99938 + */
99939 +
99940 +/**************************************************************************//**
99941 +
99942 + @File part_ext.h
99943 +
99944 + @Description Definitions for the part (integration) module.
99945 +*//***************************************************************************/
99946 +
99947 +#ifndef __PART_EXT_H
99948 +#define __PART_EXT_H
99949 +
99950 +#include "std_ext.h"
99951 +#include "part_integration_ext.h"
99952 +
99953 +/**************************************************************************//*
99954 + @Description Part data structure - must be contained in any integration
99955 + data structure.
99956 +*//***************************************************************************/
99957 +typedef struct t_Part
99958 +{
99959 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
99960 + /**< Returns the address of the module's memory map base. */
99961 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
99962 + /**< Returns the module's ID according to its memory map base. */
99963 +} t_Part;
99964 +
99965 +
99966 +#endif /* __PART_EXT_H */
99967 --- /dev/null
99968 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/FMANV3L/part_integration_ext.h
99969 @@ -0,0 +1,304 @@
99970 +/*
99971 + * Copyright 2008-2012 Freescale Semiconductor Inc.
99972 + *
99973 + * Redistribution and use in source and binary forms, with or without
99974 + * modification, are permitted provided that the following conditions are met:
99975 + * * Redistributions of source code must retain the above copyright
99976 + * notice, this list of conditions and the following disclaimer.
99977 + * * Redistributions in binary form must reproduce the above copyright
99978 + * notice, this list of conditions and the following disclaimer in the
99979 + * documentation and/or other materials provided with the distribution.
99980 + * * Neither the name of Freescale Semiconductor nor the
99981 + * names of its contributors may be used to endorse or promote products
99982 + * derived from this software without specific prior written permission.
99983 + *
99984 + *
99985 + * ALTERNATIVELY, this software may be distributed under the terms of the
99986 + * GNU General Public License ("GPL") as published by the Free Software
99987 + * Foundation, either version 2 of that License or (at your option) any
99988 + * later version.
99989 + *
99990 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
99991 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
99992 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
99993 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
99994 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
99995 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99996 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
99997 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
99998 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
99999 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100000 + */
100001 +
100002 +/**
100003 +
100004 + @File part_integration_ext.h
100005 +
100006 + @Description T4240 external definitions and structures.
100007 +*//***************************************************************************/
100008 +#ifndef __PART_INTEGRATION_EXT_H
100009 +#define __PART_INTEGRATION_EXT_H
100010 +
100011 +#include "std_ext.h"
100012 +#include "ddr_std_ext.h"
100013 +#include "enet_ext.h"
100014 +#include "dpaa_integration_ext.h"
100015 +
100016 +
100017 +/**************************************************************************//**
100018 + @Group T4240_chip_id T4240 Application Programming Interface
100019 +
100020 + @Description T4240 Chip functions,definitions and enums.
100021 +
100022 + @{
100023 +*//***************************************************************************/
100024 +
100025 +#define CORE_E6500
100026 +
100027 +#define INTG_MAX_NUM_OF_CORES 24
100028 +
100029 +
100030 +/**************************************************************************//**
100031 + @Description Module types.
100032 +*//***************************************************************************/
100033 +typedef enum e_ModuleId
100034 +{
100035 + e_MODULE_ID_DUART_1 = 0,
100036 + e_MODULE_ID_DUART_2,
100037 + e_MODULE_ID_DUART_3,
100038 + e_MODULE_ID_DUART_4,
100039 + e_MODULE_ID_LAW,
100040 + e_MODULE_ID_IFC,
100041 + e_MODULE_ID_PAMU,
100042 + e_MODULE_ID_QM, /**< Queue manager module */
100043 + e_MODULE_ID_BM, /**< Buffer manager module */
100044 + e_MODULE_ID_QM_CE_PORTAL_0,
100045 + e_MODULE_ID_QM_CI_PORTAL_0,
100046 + e_MODULE_ID_QM_CE_PORTAL_1,
100047 + e_MODULE_ID_QM_CI_PORTAL_1,
100048 + e_MODULE_ID_QM_CE_PORTAL_2,
100049 + e_MODULE_ID_QM_CI_PORTAL_2,
100050 + e_MODULE_ID_QM_CE_PORTAL_3,
100051 + e_MODULE_ID_QM_CI_PORTAL_3,
100052 + e_MODULE_ID_QM_CE_PORTAL_4,
100053 + e_MODULE_ID_QM_CI_PORTAL_4,
100054 + e_MODULE_ID_QM_CE_PORTAL_5,
100055 + e_MODULE_ID_QM_CI_PORTAL_5,
100056 + e_MODULE_ID_QM_CE_PORTAL_6,
100057 + e_MODULE_ID_QM_CI_PORTAL_6,
100058 + e_MODULE_ID_QM_CE_PORTAL_7,
100059 + e_MODULE_ID_QM_CI_PORTAL_7,
100060 + e_MODULE_ID_QM_CE_PORTAL_8,
100061 + e_MODULE_ID_QM_CI_PORTAL_8,
100062 + e_MODULE_ID_QM_CE_PORTAL_9,
100063 + e_MODULE_ID_QM_CI_PORTAL_9,
100064 + e_MODULE_ID_BM_CE_PORTAL_0,
100065 + e_MODULE_ID_BM_CI_PORTAL_0,
100066 + e_MODULE_ID_BM_CE_PORTAL_1,
100067 + e_MODULE_ID_BM_CI_PORTAL_1,
100068 + e_MODULE_ID_BM_CE_PORTAL_2,
100069 + e_MODULE_ID_BM_CI_PORTAL_2,
100070 + e_MODULE_ID_BM_CE_PORTAL_3,
100071 + e_MODULE_ID_BM_CI_PORTAL_3,
100072 + e_MODULE_ID_BM_CE_PORTAL_4,
100073 + e_MODULE_ID_BM_CI_PORTAL_4,
100074 + e_MODULE_ID_BM_CE_PORTAL_5,
100075 + e_MODULE_ID_BM_CI_PORTAL_5,
100076 + e_MODULE_ID_BM_CE_PORTAL_6,
100077 + e_MODULE_ID_BM_CI_PORTAL_6,
100078 + e_MODULE_ID_BM_CE_PORTAL_7,
100079 + e_MODULE_ID_BM_CI_PORTAL_7,
100080 + e_MODULE_ID_BM_CE_PORTAL_8,
100081 + e_MODULE_ID_BM_CI_PORTAL_8,
100082 + e_MODULE_ID_BM_CE_PORTAL_9,
100083 + e_MODULE_ID_BM_CI_PORTAL_9,
100084 + e_MODULE_ID_FM, /**< Frame manager module */
100085 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
100086 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
100087 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
100088 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
100089 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
100090 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100091 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100092 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100093 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100094 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100095 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100096 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
100097 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100098 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100099 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100100 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100101 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
100102 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
100103 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
100104 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
100105 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100106 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100107 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100108 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100109 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
100110 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
100111 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
100112 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
100113 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
100114 + e_MODULE_ID_FM_KG, /**< FM Keygen */
100115 + e_MODULE_ID_FM_DMA, /**< FM DMA */
100116 + e_MODULE_ID_FM_FPM, /**< FM FPM */
100117 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
100118 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
100119 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
100120 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100121 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
100122 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
100123 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
100124 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
100125 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
100126 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
100127 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
100128 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
100129 +
100130 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100131 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100132 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100133 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100134 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100135 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100136 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100137 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100138 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100139 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100140 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100141 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100142 +
100143 + e_MODULE_ID_PIC, /**< PIC */
100144 + e_MODULE_ID_GPIO, /**< GPIO */
100145 + e_MODULE_ID_SERDES, /**< SERDES */
100146 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100147 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100148 +
100149 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100150 +
100151 + e_MODULE_ID_DUMMY_LAST
100152 +} e_ModuleId;
100153 +
100154 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100155 +
100156 +#if 0 /* using unified values */
100157 +/*****************************************************************************
100158 + INTEGRATION-SPECIFIC MODULE CODES
100159 +******************************************************************************/
100160 +#define MODULE_UNKNOWN 0x00000000
100161 +#define MODULE_MEM 0x00010000
100162 +#define MODULE_MM 0x00020000
100163 +#define MODULE_CORE 0x00030000
100164 +#define MODULE_T4240 0x00040000
100165 +#define MODULE_T4240_PLATFORM 0x00050000
100166 +#define MODULE_PM 0x00060000
100167 +#define MODULE_MMU 0x00070000
100168 +#define MODULE_PIC 0x00080000
100169 +#define MODULE_CPC 0x00090000
100170 +#define MODULE_DUART 0x000a0000
100171 +#define MODULE_SERDES 0x000b0000
100172 +#define MODULE_PIO 0x000c0000
100173 +#define MODULE_QM 0x000d0000
100174 +#define MODULE_BM 0x000e0000
100175 +#define MODULE_SEC 0x000f0000
100176 +#define MODULE_LAW 0x00100000
100177 +#define MODULE_LBC 0x00110000
100178 +#define MODULE_PAMU 0x00120000
100179 +#define MODULE_FM 0x00130000
100180 +#define MODULE_FM_MURAM 0x00140000
100181 +#define MODULE_FM_PCD 0x00150000
100182 +#define MODULE_FM_RTC 0x00160000
100183 +#define MODULE_FM_MAC 0x00170000
100184 +#define MODULE_FM_PORT 0x00180000
100185 +#define MODULE_FM_SP 0x00190000
100186 +#define MODULE_DPA_PORT 0x001a0000
100187 +#define MODULE_MII 0x001b0000
100188 +#define MODULE_I2C 0x001c0000
100189 +#define MODULE_DMA 0x001d0000
100190 +#define MODULE_DDR 0x001e0000
100191 +#define MODULE_ESPI 0x001f0000
100192 +#define MODULE_DPAA_IPSEC 0x00200000
100193 +#endif /* using unified values */
100194 +
100195 +/*****************************************************************************
100196 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
100197 +******************************************************************************/
100198 +#define PAMU_NUM_OF_PARTITIONS 4
100199 +
100200 +/*****************************************************************************
100201 + LAW INTEGRATION-SPECIFIC DEFINITIONS
100202 +******************************************************************************/
100203 +#define LAW_NUM_OF_WINDOWS 32
100204 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4 Kbytes */
100205 +#define LAW_MAX_WINDOW_SIZE 0x0000010000000000LL /**< 1 Tbytes for 40-bit address space */
100206 +
100207 +
100208 +/*****************************************************************************
100209 + LBC INTEGRATION-SPECIFIC DEFINITIONS
100210 +******************************************************************************/
100211 +/**************************************************************************//**
100212 + @Group lbc_exception_grp LBC Exception Unit
100213 +
100214 + @Description LBC Exception unit API functions, definitions and enums
100215 +
100216 + @{
100217 +*//***************************************************************************/
100218 +
100219 +/**************************************************************************//**
100220 + @Anchor lbc_exbm
100221 +
100222 + @Collection LBC Errors Bit Mask
100223 +
100224 + These errors are reported through the exceptions callback..
100225 + The values can be or'ed in any combination in the errors mask
100226 + parameter of the errors report structure.
100227 +
100228 + These errors can also be passed as a bit-mask to
100229 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
100230 + for enabling or disabling error checking.
100231 + @{
100232 +*//***************************************************************************/
100233 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
100234 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
100235 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
100236 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
100237 +
100238 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
100239 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
100240 + /**< All possible errors */
100241 +/* @} */
100242 +/** @} */ /* end of lbc_exception_grp group */
100243 +
100244 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
100245 +
100246 +#define LBC_NUM_OF_BANKS 8
100247 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL /* Up to 4G memory block size */
100248 +#define LBC_PARITY_SUPPORT
100249 +#define LBC_ADDRESS_HOLD_TIME_CTRL
100250 +#define LBC_HIGH_CLK_DIVIDERS
100251 +#define LBC_FCM_AVAILABLE
100252 +
100253 +/*****************************************************************************
100254 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
100255 +******************************************************************************/
100256 +#define GPIO_PORT_OFFSET_0x1000
100257 +
100258 +#define GPIO_NUM_OF_PORTS 3 /**< Number of ports in GPIO module;
100259 + Each port contains up to 32 I/O pins. */
100260 +
100261 +#define GPIO_VALID_PIN_MASKS \
100262 + { /* Port A */ 0xFFFFFFFF, \
100263 + /* Port B */ 0xFFFFFFFF, \
100264 + /* Port C */ 0xFFFFFFFF }
100265 +
100266 +#define GPIO_VALID_INTR_MASKS \
100267 + { /* Port A */ 0xFFFFFFFF, \
100268 + /* Port B */ 0xFFFFFFFF, \
100269 + /* Port C */ 0xFFFFFFFF }
100270 +
100271 +
100272 +
100273 +#endif /* __PART_INTEGRATION_EXT_H */
100274 --- /dev/null
100275 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/dpaa_integration_ext.h
100276 @@ -0,0 +1,291 @@
100277 +/*
100278 + * Copyright 2012 Freescale Semiconductor Inc.
100279 + *
100280 + * Redistribution and use in source and binary forms, with or without
100281 + * modification, are permitted provided that the following conditions are met:
100282 + * * Redistributions of source code must retain the above copyright
100283 + * notice, this list of conditions and the following disclaimer.
100284 + * * Redistributions in binary form must reproduce the above copyright
100285 + * notice, this list of conditions and the following disclaimer in the
100286 + * documentation and/or other materials provided with the distribution.
100287 + * * Neither the name of Freescale Semiconductor nor the
100288 + * names of its contributors may be used to endorse or promote products
100289 + * derived from this software without specific prior written permission.
100290 + *
100291 + *
100292 + * ALTERNATIVELY, this software may be distributed under the terms of the
100293 + * GNU General Public License ("GPL") as published by the Free Software
100294 + * Foundation, either version 2 of that License or (at your option) any
100295 + * later version.
100296 + *
100297 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100298 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100299 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100300 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100301 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100302 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100303 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100304 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100305 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100306 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100307 + */
100308 +
100309 +/**
100310 +
100311 + @File dpaa_integration_ext.h
100312 +
100313 + @Description T4240 FM external definitions and structures.
100314 +*//***************************************************************************/
100315 +#ifndef __DPAA_INTEGRATION_EXT_H
100316 +#define __DPAA_INTEGRATION_EXT_H
100317 +
100318 +#include "std_ext.h"
100319 +
100320 +
100321 +#define DPAA_VERSION 11
100322 +
100323 +/**************************************************************************//**
100324 + @Description DPAA SW Portals Enumeration.
100325 +*//***************************************************************************/
100326 +typedef enum
100327 +{
100328 + e_DPAA_SWPORTAL0 = 0,
100329 + e_DPAA_SWPORTAL1,
100330 + e_DPAA_SWPORTAL2,
100331 + e_DPAA_SWPORTAL3,
100332 + e_DPAA_SWPORTAL4,
100333 + e_DPAA_SWPORTAL5,
100334 + e_DPAA_SWPORTAL6,
100335 + e_DPAA_SWPORTAL7,
100336 + e_DPAA_SWPORTAL8,
100337 + e_DPAA_SWPORTAL9,
100338 + e_DPAA_SWPORTAL10,
100339 + e_DPAA_SWPORTAL11,
100340 + e_DPAA_SWPORTAL12,
100341 + e_DPAA_SWPORTAL13,
100342 + e_DPAA_SWPORTAL14,
100343 + e_DPAA_SWPORTAL15,
100344 + e_DPAA_SWPORTAL16,
100345 + e_DPAA_SWPORTAL17,
100346 + e_DPAA_SWPORTAL18,
100347 + e_DPAA_SWPORTAL19,
100348 + e_DPAA_SWPORTAL20,
100349 + e_DPAA_SWPORTAL21,
100350 + e_DPAA_SWPORTAL22,
100351 + e_DPAA_SWPORTAL23,
100352 + e_DPAA_SWPORTAL24,
100353 + e_DPAA_SWPORTAL_DUMMY_LAST
100354 +} e_DpaaSwPortal;
100355 +
100356 +/**************************************************************************//**
100357 + @Description DPAA Direct Connect Portals Enumeration.
100358 +*//***************************************************************************/
100359 +typedef enum
100360 +{
100361 + e_DPAA_DCPORTAL0 = 0,
100362 + e_DPAA_DCPORTAL1,
100363 + e_DPAA_DCPORTAL2,
100364 + e_DPAA_DCPORTAL_DUMMY_LAST
100365 +} e_DpaaDcPortal;
100366 +
100367 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
100368 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
100369 +
100370 +/*****************************************************************************
100371 + QMan INTEGRATION-SPECIFIC DEFINITIONS
100372 +******************************************************************************/
100373 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
100374 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
100375 +#define QM_MAX_NUM_OF_CGS 256 /**< Congestion groups number */
100376 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE)
100377 + /**< FQIDs range - 24 bits */
100378 +
100379 +/**************************************************************************//**
100380 + @Description Work Queue Channel assignments in QMan.
100381 +*//***************************************************************************/
100382 +typedef enum
100383 +{
100384 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0x0, /**< Dedicated channels serviced by software portals 0 to 24 */
100385 + e_QM_FQ_CHANNEL_SWPORTAL1,
100386 + e_QM_FQ_CHANNEL_SWPORTAL2,
100387 + e_QM_FQ_CHANNEL_SWPORTAL3,
100388 + e_QM_FQ_CHANNEL_SWPORTAL4,
100389 + e_QM_FQ_CHANNEL_SWPORTAL5,
100390 + e_QM_FQ_CHANNEL_SWPORTAL6,
100391 + e_QM_FQ_CHANNEL_SWPORTAL7,
100392 + e_QM_FQ_CHANNEL_SWPORTAL8,
100393 + e_QM_FQ_CHANNEL_SWPORTAL9,
100394 + e_QM_FQ_CHANNEL_SWPORTAL10,
100395 + e_QM_FQ_CHANNEL_SWPORTAL11,
100396 + e_QM_FQ_CHANNEL_SWPORTAL12,
100397 + e_QM_FQ_CHANNEL_SWPORTAL13,
100398 + e_QM_FQ_CHANNEL_SWPORTAL14,
100399 + e_QM_FQ_CHANNEL_SWPORTAL15,
100400 + e_QM_FQ_CHANNEL_SWPORTAL16,
100401 + e_QM_FQ_CHANNEL_SWPORTAL17,
100402 + e_QM_FQ_CHANNEL_SWPORTAL18,
100403 + e_QM_FQ_CHANNEL_SWPORTAL19,
100404 + e_QM_FQ_CHANNEL_SWPORTAL20,
100405 + e_QM_FQ_CHANNEL_SWPORTAL21,
100406 + e_QM_FQ_CHANNEL_SWPORTAL22,
100407 + e_QM_FQ_CHANNEL_SWPORTAL23,
100408 + e_QM_FQ_CHANNEL_SWPORTAL24,
100409 +
100410 + e_QM_FQ_CHANNEL_POOL1 = 0x401, /**< Pool channels that can be serviced by any of the software portals */
100411 + e_QM_FQ_CHANNEL_POOL2,
100412 + e_QM_FQ_CHANNEL_POOL3,
100413 + e_QM_FQ_CHANNEL_POOL4,
100414 + e_QM_FQ_CHANNEL_POOL5,
100415 + e_QM_FQ_CHANNEL_POOL6,
100416 + e_QM_FQ_CHANNEL_POOL7,
100417 + e_QM_FQ_CHANNEL_POOL8,
100418 + e_QM_FQ_CHANNEL_POOL9,
100419 + e_QM_FQ_CHANNEL_POOL10,
100420 + e_QM_FQ_CHANNEL_POOL11,
100421 + e_QM_FQ_CHANNEL_POOL12,
100422 + e_QM_FQ_CHANNEL_POOL13,
100423 + e_QM_FQ_CHANNEL_POOL14,
100424 + e_QM_FQ_CHANNEL_POOL15,
100425 +
100426 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x800, /**< Dedicated channels serviced by Direct Connect Portal 0:
100427 + connected to FMan 0; assigned in incrementing order to
100428 + each sub-portal (SP) in the portal */
100429 + e_QM_FQ_CHANNEL_FMAN0_SP1,
100430 + e_QM_FQ_CHANNEL_FMAN0_SP2,
100431 + e_QM_FQ_CHANNEL_FMAN0_SP3,
100432 + e_QM_FQ_CHANNEL_FMAN0_SP4,
100433 + e_QM_FQ_CHANNEL_FMAN0_SP5,
100434 + e_QM_FQ_CHANNEL_FMAN0_SP6,
100435 + e_QM_FQ_CHANNEL_FMAN0_SP7,
100436 + e_QM_FQ_CHANNEL_FMAN0_SP8,
100437 + e_QM_FQ_CHANNEL_FMAN0_SP9,
100438 + e_QM_FQ_CHANNEL_FMAN0_SP10,
100439 + e_QM_FQ_CHANNEL_FMAN0_SP11,
100440 + e_QM_FQ_CHANNEL_FMAN0_SP12,
100441 + e_QM_FQ_CHANNEL_FMAN0_SP13,
100442 + e_QM_FQ_CHANNEL_FMAN0_SP14,
100443 + e_QM_FQ_CHANNEL_FMAN0_SP15,
100444 +
100445 + e_QM_FQ_CHANNEL_RMAN_SP0 = 0x820, /**< Dedicated channels serviced by Direct Connect Portal 1: connected to RMan */
100446 + e_QM_FQ_CHANNEL_RMAN_SP1,
100447 +
100448 + e_QM_FQ_CHANNEL_CAAM = 0x840 /**< Dedicated channel serviced by Direct Connect Portal 2:
100449 + connected to SEC */
100450 +} e_QmFQChannel;
100451 +
100452 +/*****************************************************************************
100453 + BMan INTEGRATION-SPECIFIC DEFINITIONS
100454 +******************************************************************************/
100455 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
100456 +
100457 +/*****************************************************************************
100458 + SEC INTEGRATION-SPECIFIC DEFINITIONS
100459 +******************************************************************************/
100460 +#define SEC_NUM_OF_DECOS 3
100461 +#define SEC_ALL_DECOS_MASK 0x00000003
100462 +
100463 +
100464 +/*****************************************************************************
100465 + FM INTEGRATION-SPECIFIC DEFINITIONS
100466 +******************************************************************************/
100467 +#define INTG_MAX_NUM_OF_FM 2
100468 +
100469 +/* Ports defines */
100470 +#define FM_MAX_NUM_OF_1G_MACS 6
100471 +#define FM_MAX_NUM_OF_10G_MACS 2
100472 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100473 +#define FM_MAX_NUM_OF_OH_PORTS 6
100474 +
100475 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100476 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100477 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100478 +
100479 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100480 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100481 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100482 +
100483 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
100484 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
100485 +#define FM_MAX_NUM_OF_SUB_PORTALS 16
100486 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
100487 +
100488 +#define FM_VSP_MAX_NUM_OF_ENTRIES 64
100489 +#define FM_MAX_NUM_OF_PFC_PRIORITIES 8
100490 +
100491 +/* RAMs defines */
100492 +#define FM_MURAM_SIZE (384 * KILOBYTE)
100493 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
100494 +#define FM_NUM_OF_CTRL 4
100495 +
100496 +/* PCD defines */
100497 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
100498 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
100499 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
100500 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000600 /**< Number of bytes saved for patches */
100501 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100502 +
100503 +/* RTC defines */
100504 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
100505 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 3 /**< RTC number of periodic pulses */
100506 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
100507 +
100508 +/* QMI defines */
100509 +#define QMI_MAX_NUM_OF_TNUMS 64
100510 +#define QMI_DEF_TNUMS_THRESH 32
100511 +/* FPM defines */
100512 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100513 +
100514 +/* DMA defines */
100515 +#define DMA_THRESH_MAX_COMMQ 83
100516 +#define DMA_THRESH_MAX_BUF 127
100517 +
100518 +/* BMI defines */
100519 +#define BMI_MAX_NUM_OF_TASKS 128
100520 +#define BMI_MAX_NUM_OF_DMAS 84
100521 +
100522 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100523 +#define PORT_MAX_WEIGHT 16
100524 +
100525 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
100526 +
100527 +/* Unique T4240 */
100528 +#define FM_OP_OPEN_DMA_MIN_LIMIT
100529 +#define FM_NO_RESTRICT_ON_ACCESS_RSRC
100530 +#define FM_NO_OP_OBSERVED_POOLS
100531 +#define FM_FRAME_END_PARAMS_FOR_OP
100532 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
100533 +#define FM_QMI_NO_SINGLE_ECC_EXCEPTION
100534 +
100535 +#define FM_NO_GUARANTEED_RESET_VALUES
100536 +
100537 +/* FM errata */
100538 +#define FM_HEAVY_TRAFFIC_HANG_ERRATA_FMAN_A005669
100539 +#define FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127
100540 +#define FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320
100541 +#define FM_OP_NO_VSP_NO_RELEASE_ERRATA_FMAN_A006675
100542 +#define FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981
100543 +
100544 +#define FM_BCB_ERRATA_BMI_SW001
100545 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
100546 +#define FM_AID_MODE_NO_TNUM_SW005 /* refer to pdm TKT068794 - only support of port_id on aid */
100547 +#define FM_ERROR_VSP_NO_MATCH_SW006 /* refer to pdm TKT174304 - no match between errorQ and VSP */
100548 +
100549 +/*****************************************************************************
100550 + RMan INTEGRATION-SPECIFIC DEFINITIONS
100551 +******************************************************************************/
100552 +#define RM_MAX_NUM_OF_IB 4 /**< Number of inbound blocks */
100553 +#define RM_NUM_OF_IBCU 8 /**< NUmber of classification units in an inbound block */
100554 +
100555 +/* RMan erratas */
100556 +#define RM_ERRONEOUS_ACK_ERRATA_RMAN_A006756
100557 +
100558 +/*****************************************************************************
100559 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100560 +******************************************************************************/
100561 +#define NUM_OF_RX_SC 16
100562 +#define NUM_OF_TX_SC 16
100563 +
100564 +#define NUM_OF_SA_PER_RX_SC 2
100565 +#define NUM_OF_SA_PER_TX_SC 2
100566 +
100567 +#endif /* __DPAA_INTEGRATION_EXT_H */
100568 --- /dev/null
100569 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_ext.h
100570 @@ -0,0 +1,64 @@
100571 +/*
100572 + * Copyright 2012 Freescale Semiconductor Inc.
100573 + *
100574 + * Redistribution and use in source and binary forms, with or without
100575 + * modification, are permitted provided that the following conditions are met:
100576 + * * Redistributions of source code must retain the above copyright
100577 + * notice, this list of conditions and the following disclaimer.
100578 + * * Redistributions in binary form must reproduce the above copyright
100579 + * notice, this list of conditions and the following disclaimer in the
100580 + * documentation and/or other materials provided with the distribution.
100581 + * * Neither the name of Freescale Semiconductor nor the
100582 + * names of its contributors may be used to endorse or promote products
100583 + * derived from this software without specific prior written permission.
100584 + *
100585 + *
100586 + * ALTERNATIVELY, this software may be distributed under the terms of the
100587 + * GNU General Public License ("GPL") as published by the Free Software
100588 + * Foundation, either version 2 of that License or (at your option) any
100589 + * later version.
100590 + *
100591 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100592 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100593 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100594 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100595 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100596 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100597 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100598 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100599 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100600 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100601 + */
100602 +
100603 +/**************************************************************************//**
100604 +
100605 + @File part_ext.h
100606 +
100607 + @Description Definitions for the part (integration) module.
100608 +*//***************************************************************************/
100609 +
100610 +#ifndef __PART_EXT_H
100611 +#define __PART_EXT_H
100612 +
100613 +#include "std_ext.h"
100614 +#include "part_integration_ext.h"
100615 +
100616 +#if !(defined(LS1043))
100617 +#error "unable to proceed without chip-definition"
100618 +#endif
100619 +
100620 +
100621 +/**************************************************************************//*
100622 + @Description Part data structure - must be contained in any integration
100623 + data structure.
100624 +*//***************************************************************************/
100625 +typedef struct t_Part
100626 +{
100627 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
100628 + /**< Returns the address of the module's memory map base. */
100629 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
100630 + /**< Returns the module's ID according to its memory map base. */
100631 +} t_Part;
100632 +
100633 +
100634 +#endif /* __PART_EXT_H */
100635 --- /dev/null
100636 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/LS1043/part_integration_ext.h
100637 @@ -0,0 +1,185 @@
100638 +/*
100639 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100640 + *
100641 + * Redistribution and use in source and binary forms, with or without
100642 + * modification, are permitted provided that the following conditions are met:
100643 + * * Redistributions of source code must retain the above copyright
100644 + * notice, this list of conditions and the following disclaimer.
100645 + * * Redistributions in binary form must reproduce the above copyright
100646 + * notice, this list of conditions and the following disclaimer in the
100647 + * documentation and/or other materials provided with the distribution.
100648 + * * Neither the name of Freescale Semiconductor nor the
100649 + * names of its contributors may be used to endorse or promote products
100650 + * derived from this software without specific prior written permission.
100651 + *
100652 + *
100653 + * ALTERNATIVELY, this software may be distributed under the terms of the
100654 + * GNU General Public License ("GPL") as published by the Free Software
100655 + * Foundation, either version 2 of that License or (at your option) any
100656 + * later version.
100657 + *
100658 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100659 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100660 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100661 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100662 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100663 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100664 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100665 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100666 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100667 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100668 + */
100669 +
100670 +/**
100671 +
100672 + @File part_integration_ext.h
100673 +
100674 + @Description T4240 external definitions and structures.
100675 +*//***************************************************************************/
100676 +#ifndef __PART_INTEGRATION_EXT_H
100677 +#define __PART_INTEGRATION_EXT_H
100678 +
100679 +#include "std_ext.h"
100680 +#include "ddr_std_ext.h"
100681 +#include "enet_ext.h"
100682 +#include "dpaa_integration_ext.h"
100683 +
100684 +
100685 +/**************************************************************************//**
100686 + @Group T4240_chip_id T4240 Application Programming Interface
100687 +
100688 + @Description T4240 Chip functions,definitions and enums.
100689 +
100690 + @{
100691 +*//***************************************************************************/
100692 +
100693 +#define INTG_MAX_NUM_OF_CORES 4
100694 +
100695 +/**************************************************************************//**
100696 + @Description Module types.
100697 +*//***************************************************************************/
100698 +typedef enum e_ModuleId
100699 +{
100700 + e_MODULE_ID_DUART_1 = 0,
100701 + e_MODULE_ID_DUART_2,
100702 + e_MODULE_ID_DUART_3,
100703 + e_MODULE_ID_DUART_4,
100704 + e_MODULE_ID_LAW,
100705 + e_MODULE_ID_IFC,
100706 + e_MODULE_ID_PAMU,
100707 + e_MODULE_ID_QM, /**< Queue manager module */
100708 + e_MODULE_ID_BM, /**< Buffer manager module */
100709 + e_MODULE_ID_QM_CE_PORTAL_0,
100710 + e_MODULE_ID_QM_CI_PORTAL_0,
100711 + e_MODULE_ID_QM_CE_PORTAL_1,
100712 + e_MODULE_ID_QM_CI_PORTAL_1,
100713 + e_MODULE_ID_QM_CE_PORTAL_2,
100714 + e_MODULE_ID_QM_CI_PORTAL_2,
100715 + e_MODULE_ID_QM_CE_PORTAL_3,
100716 + e_MODULE_ID_QM_CI_PORTAL_3,
100717 + e_MODULE_ID_QM_CE_PORTAL_4,
100718 + e_MODULE_ID_QM_CI_PORTAL_4,
100719 + e_MODULE_ID_QM_CE_PORTAL_5,
100720 + e_MODULE_ID_QM_CI_PORTAL_5,
100721 + e_MODULE_ID_QM_CE_PORTAL_6,
100722 + e_MODULE_ID_QM_CI_PORTAL_6,
100723 + e_MODULE_ID_QM_CE_PORTAL_7,
100724 + e_MODULE_ID_QM_CI_PORTAL_7,
100725 + e_MODULE_ID_QM_CE_PORTAL_8,
100726 + e_MODULE_ID_QM_CI_PORTAL_8,
100727 + e_MODULE_ID_QM_CE_PORTAL_9,
100728 + e_MODULE_ID_QM_CI_PORTAL_9,
100729 + e_MODULE_ID_BM_CE_PORTAL_0,
100730 + e_MODULE_ID_BM_CI_PORTAL_0,
100731 + e_MODULE_ID_BM_CE_PORTAL_1,
100732 + e_MODULE_ID_BM_CI_PORTAL_1,
100733 + e_MODULE_ID_BM_CE_PORTAL_2,
100734 + e_MODULE_ID_BM_CI_PORTAL_2,
100735 + e_MODULE_ID_BM_CE_PORTAL_3,
100736 + e_MODULE_ID_BM_CI_PORTAL_3,
100737 + e_MODULE_ID_BM_CE_PORTAL_4,
100738 + e_MODULE_ID_BM_CI_PORTAL_4,
100739 + e_MODULE_ID_BM_CE_PORTAL_5,
100740 + e_MODULE_ID_BM_CI_PORTAL_5,
100741 + e_MODULE_ID_BM_CE_PORTAL_6,
100742 + e_MODULE_ID_BM_CI_PORTAL_6,
100743 + e_MODULE_ID_BM_CE_PORTAL_7,
100744 + e_MODULE_ID_BM_CI_PORTAL_7,
100745 + e_MODULE_ID_BM_CE_PORTAL_8,
100746 + e_MODULE_ID_BM_CI_PORTAL_8,
100747 + e_MODULE_ID_BM_CE_PORTAL_9,
100748 + e_MODULE_ID_BM_CI_PORTAL_9,
100749 + e_MODULE_ID_FM, /**< Frame manager module */
100750 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
100751 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
100752 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
100753 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
100754 + e_MODULE_ID_FM_PARSER, /**< FM parser block */
100755 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
100756 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
100757 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
100758 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
100759 + e_MODULE_ID_FM_PORT_HO5, /**< FM Host-command/offline-parsing port block */
100760 + e_MODULE_ID_FM_PORT_HO6, /**< FM Host-command/offline-parsing port block */
100761 + e_MODULE_ID_FM_PORT_HO7, /**< FM Host-command/offline-parsing port block */
100762 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
100763 + e_MODULE_ID_FM_PORT_1GRx2, /**< FM Rx 1G MAC port block */
100764 + e_MODULE_ID_FM_PORT_1GRx3, /**< FM Rx 1G MAC port block */
100765 + e_MODULE_ID_FM_PORT_1GRx4, /**< FM Rx 1G MAC port block */
100766 + e_MODULE_ID_FM_PORT_1GRx5, /**< FM Rx 1G MAC port block */
100767 + e_MODULE_ID_FM_PORT_1GRx6, /**< FM Rx 1G MAC port block */
100768 + e_MODULE_ID_FM_PORT_10GRx1, /**< FM Rx 10G MAC port block */
100769 + e_MODULE_ID_FM_PORT_10GRx2, /**< FM Rx 10G MAC port block */
100770 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
100771 + e_MODULE_ID_FM_PORT_1GTx2, /**< FM Tx 1G MAC port block */
100772 + e_MODULE_ID_FM_PORT_1GTx3, /**< FM Tx 1G MAC port block */
100773 + e_MODULE_ID_FM_PORT_1GTx4, /**< FM Tx 1G MAC port block */
100774 + e_MODULE_ID_FM_PORT_1GTx5, /**< FM Tx 1G MAC port block */
100775 + e_MODULE_ID_FM_PORT_1GTx6, /**< FM Tx 1G MAC port block */
100776 + e_MODULE_ID_FM_PORT_10GTx1, /**< FM Tx 10G MAC port block */
100777 + e_MODULE_ID_FM_PORT_10GTx2, /**< FM Tx 10G MAC port block */
100778 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
100779 + e_MODULE_ID_FM_KG, /**< FM Keygen */
100780 + e_MODULE_ID_FM_DMA, /**< FM DMA */
100781 + e_MODULE_ID_FM_FPM, /**< FM FPM */
100782 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
100783 + e_MODULE_ID_FM_1GMDIO, /**< FM 1G MDIO MAC */
100784 + e_MODULE_ID_FM_10GMDIO, /**< FM 10G MDIO */
100785 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
100786 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
100787 + e_MODULE_ID_FM_1GMAC2, /**< FM 1G MAC #2 */
100788 + e_MODULE_ID_FM_1GMAC3, /**< FM 1G MAC #3 */
100789 + e_MODULE_ID_FM_1GMAC4, /**< FM 1G MAC #4 */
100790 + e_MODULE_ID_FM_1GMAC5, /**< FM 1G MAC #5 */
100791 + e_MODULE_ID_FM_1GMAC6, /**< FM 1G MAC #6 */
100792 + e_MODULE_ID_FM_10GMAC1, /**< FM 10G MAC */
100793 + e_MODULE_ID_FM_10GMAC2, /**< FM 10G MAC */
100794 +
100795 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
100796 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
100797 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
100798 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
100799 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
100800 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
100801 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
100802 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
100803 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
100804 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
100805 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
100806 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
100807 +
100808 + e_MODULE_ID_PIC, /**< PIC */
100809 + e_MODULE_ID_GPIO, /**< GPIO */
100810 + e_MODULE_ID_SERDES, /**< SERDES */
100811 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
100812 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
100813 +
100814 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
100815 +
100816 + e_MODULE_ID_DUMMY_LAST
100817 +} e_ModuleId;
100818 +
100819 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
100820 +
100821 +
100822 +#endif /* __PART_INTEGRATION_EXT_H */
100823 --- /dev/null
100824 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/dpaa_integration_ext.h
100825 @@ -0,0 +1,213 @@
100826 +/*
100827 + * Copyright 2008-2012 Freescale Semiconductor Inc.
100828 + *
100829 + * Redistribution and use in source and binary forms, with or without
100830 + * modification, are permitted provided that the following conditions are met:
100831 + * * Redistributions of source code must retain the above copyright
100832 + * notice, this list of conditions and the following disclaimer.
100833 + * * Redistributions in binary form must reproduce the above copyright
100834 + * notice, this list of conditions and the following disclaimer in the
100835 + * documentation and/or other materials provided with the distribution.
100836 + * * Neither the name of Freescale Semiconductor nor the
100837 + * names of its contributors may be used to endorse or promote products
100838 + * derived from this software without specific prior written permission.
100839 + *
100840 + *
100841 + * ALTERNATIVELY, this software may be distributed under the terms of the
100842 + * GNU General Public License ("GPL") as published by the Free Software
100843 + * Foundation, either version 2 of that License or (at your option) any
100844 + * later version.
100845 + *
100846 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
100847 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
100848 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
100849 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
100850 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
100851 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
100852 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
100853 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100854 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
100855 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100856 + */
100857 +
100858 +
100859 +/**
100860 +
100861 + @File dpaa_integration_ext.h
100862 +
100863 + @Description P1023 FM external definitions and structures.
100864 +*//***************************************************************************/
100865 +#ifndef __DPAA_INTEGRATION_EXT_H
100866 +#define __DPAA_INTEGRATION_EXT_H
100867 +
100868 +#include "std_ext.h"
100869 +
100870 +
100871 +#define DPAA_VERSION 10
100872 +
100873 +typedef enum e_DpaaSwPortal {
100874 + e_DPAA_SWPORTAL0 = 0,
100875 + e_DPAA_SWPORTAL1,
100876 + e_DPAA_SWPORTAL2,
100877 + e_DPAA_SWPORTAL_DUMMY_LAST
100878 +} e_DpaaSwPortal;
100879 +
100880 +typedef enum {
100881 + e_DPAA_DCPORTAL0 = 0,
100882 + e_DPAA_DCPORTAL2,
100883 + e_DPAA_DCPORTAL_DUMMY_LAST
100884 +} e_DpaaDcPortal;
100885 +
100886 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
100887 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
100888 +
100889 +/*****************************************************************************
100890 + QMAN INTEGRATION-SPECIFIC DEFINITIONS
100891 +******************************************************************************/
100892 +#define QM_MAX_NUM_OF_POOL_CHANNELS 3
100893 +#define QM_MAX_NUM_OF_WQ 8
100894 +#define QM_MAX_NUM_OF_SWP_AS 2
100895 +#define QM_MAX_NUM_OF_CGS 64
100896 +#define QM_MAX_NUM_OF_FQIDS (16*MEGABYTE)
100897 +
100898 +typedef enum {
100899 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0,
100900 + e_QM_FQ_CHANNEL_SWPORTAL1,
100901 + e_QM_FQ_CHANNEL_SWPORTAL2,
100902 +
100903 + e_QM_FQ_CHANNEL_POOL1 = 0x21,
100904 + e_QM_FQ_CHANNEL_POOL2,
100905 + e_QM_FQ_CHANNEL_POOL3,
100906 +
100907 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40,
100908 + e_QM_FQ_CHANNEL_FMAN0_SP1,
100909 + e_QM_FQ_CHANNEL_FMAN0_SP2,
100910 + e_QM_FQ_CHANNEL_FMAN0_SP3,
100911 + e_QM_FQ_CHANNEL_FMAN0_SP4,
100912 + e_QM_FQ_CHANNEL_FMAN0_SP5,
100913 + e_QM_FQ_CHANNEL_FMAN0_SP6,
100914 +
100915 +
100916 + e_QM_FQ_CHANNEL_CAAM = 0x80
100917 +} e_QmFQChannel;
100918 +
100919 +/*****************************************************************************
100920 + BMAN INTEGRATION-SPECIFIC DEFINITIONS
100921 +******************************************************************************/
100922 +#define BM_MAX_NUM_OF_POOLS 8
100923 +
100924 +/*****************************************************************************
100925 + SEC INTEGRATION-SPECIFIC DEFINITIONS
100926 +******************************************************************************/
100927 +#define SEC_NUM_OF_DECOS 2
100928 +#define SEC_ALL_DECOS_MASK 0x00000003
100929 +#define SEC_RNGB
100930 +#define SEC_NO_ESP_TRAILER_REMOVAL
100931 +
100932 +/*****************************************************************************
100933 + FM INTEGRATION-SPECIFIC DEFINITIONS
100934 +******************************************************************************/
100935 +#define INTG_MAX_NUM_OF_FM 1
100936 +
100937 +/* Ports defines */
100938 +#define FM_MAX_NUM_OF_1G_MACS 2
100939 +#define FM_MAX_NUM_OF_10G_MACS 0
100940 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
100941 +#define FM_MAX_NUM_OF_OH_PORTS 5
100942 +
100943 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
100944 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
100945 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
100946 +
100947 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
100948 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
100949 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
100950 +
100951 +#define FM_MAX_NUM_OF_MACSECS 1
100952 +
100953 +#define FM_MACSEC_SUPPORT
100954 +
100955 +#define FM_LOW_END_RESTRICTION /* prevents the use of TX port 1 with OP port 0 */
100956 +
100957 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 4 /**< Number of external BM pools per Rx port */
100958 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 2 /**< Number of Offline parsing port external BM pools per Rx port */
100959 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 32 /**< Total number of congestion groups in QM */
100960 +#define FM_MAX_NUM_OF_SUB_PORTALS 7
100961 +
100962 +/* Rams defines */
100963 +#define FM_MURAM_SIZE (64*KILOBYTE)
100964 +#define FM_IRAM_SIZE(major, minor) (32 * KILOBYTE)
100965 +#define FM_NUM_OF_CTRL 2
100966 +
100967 +/* PCD defines */
100968 +#define FM_PCD_PLCR_NUM_ENTRIES 32 /**< Total number of policer profiles */
100969 +#define FM_PCD_KG_NUM_OF_SCHEMES 16 /**< Total number of KG schemes */
100970 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 128 /**< Number of classification plan entries. */
100971 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000240 /**< Number of bytes saved for patches */
100972 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
100973 +
100974 +/* RTC defines */
100975 +#define FM_RTC_NUM_OF_ALARMS 2
100976 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2
100977 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2
100978 +
100979 +/* QMI defines */
100980 +#define QMI_MAX_NUM_OF_TNUMS 15
100981 +
100982 +/* FPM defines */
100983 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
100984 +
100985 +/* DMA defines */
100986 +#define DMA_THRESH_MAX_COMMQ 15
100987 +#define DMA_THRESH_MAX_BUF 7
100988 +
100989 +/* BMI defines */
100990 +#define BMI_MAX_NUM_OF_TASKS 64
100991 +#define BMI_MAX_NUM_OF_DMAS 16
100992 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
100993 +#define PORT_MAX_WEIGHT 4
100994 +
100995 +/*****************************************************************************
100996 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
100997 +******************************************************************************/
100998 +#define NUM_OF_RX_SC 16
100999 +#define NUM_OF_TX_SC 16
101000 +
101001 +#define NUM_OF_SA_PER_RX_SC 2
101002 +#define NUM_OF_SA_PER_TX_SC 2
101003 +
101004 +/**************************************************************************//**
101005 + @Description Enum for inter-module interrupts registration
101006 +*//***************************************************************************/
101007 +
101008 +/* 1023 unique features */
101009 +#define FM_QMI_NO_ECC_EXCEPTIONS
101010 +#define FM_CSI_CFED_LIMIT
101011 +#define FM_PEDANTIC_DMA
101012 +#define FM_QMI_NO_DEQ_OPTIONS_SUPPORT
101013 +#define FM_FIFO_ALLOCATION_ALG
101014 +#define FM_DEQ_PIPELINE_PARAMS_FOR_OP
101015 +#define FM_HAS_TOTAL_DMAS
101016 +#define FM_KG_NO_IPPID_SUPPORT
101017 +#define FM_NO_GUARANTEED_RESET_VALUES
101018 +#define FM_MAC_RESET
101019 +
101020 +/* FM erratas */
101021 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
101022 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
101023 +
101024 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
101025 +#define FM_INT_BUF_LEAK_FMAN_A005 /* No implementation, Out of LLD scope. App must avoid S/G */
101026 +
101027 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
101028 +
101029 +/* #define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173 */
101030 +
101031 +/*
101032 +TKT056919 - axi12axi0 can hang if read request follows the single byte write on the very next cycle
101033 +TKT038900 - FM dma lockup occur due to AXI slave protocol violation
101034 +*/
101035 +#define FM_LOCKUP_ALIGNMENT_ERRATA_FMAN_SW004
101036 +
101037 +
101038 +#endif /* __DPAA_INTEGRATION_EXT_H */
101039 --- /dev/null
101040 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_ext.h
101041 @@ -0,0 +1,82 @@
101042 +/*
101043 + * Copyright 2008-2012 Freescale Semiconductor Inc.
101044 + *
101045 + * Redistribution and use in source and binary forms, with or without
101046 + * modification, are permitted provided that the following conditions are met:
101047 + * * Redistributions of source code must retain the above copyright
101048 + * notice, this list of conditions and the following disclaimer.
101049 + * * Redistributions in binary form must reproduce the above copyright
101050 + * notice, this list of conditions and the following disclaimer in the
101051 + * documentation and/or other materials provided with the distribution.
101052 + * * Neither the name of Freescale Semiconductor nor the
101053 + * names of its contributors may be used to endorse or promote products
101054 + * derived from this software without specific prior written permission.
101055 + *
101056 + *
101057 + * ALTERNATIVELY, this software may be distributed under the terms of the
101058 + * GNU General Public License ("GPL") as published by the Free Software
101059 + * Foundation, either version 2 of that License or (at your option) any
101060 + * later version.
101061 + *
101062 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101063 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101064 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101065 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101066 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101067 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101068 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101069 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101070 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101071 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101072 + */
101073 +
101074 +
101075 +/**************************************************************************//**
101076 +
101077 + @File part_ext.h
101078 +
101079 + @Description Definitions for the part (integration) module.
101080 +*//***************************************************************************/
101081 +
101082 +#ifndef __PART_EXT_H
101083 +#define __PART_EXT_H
101084 +
101085 +#include "std_ext.h"
101086 +#include "part_integration_ext.h"
101087 +
101088 +
101089 +#if !(defined(MPC8306) || \
101090 + defined(MPC8309) || \
101091 + defined(MPC834x) || \
101092 + defined(MPC836x) || \
101093 + defined(MPC832x) || \
101094 + defined(MPC837x) || \
101095 + defined(MPC8568) || \
101096 + defined(MPC8569) || \
101097 + defined(P1020) || \
101098 + defined(P1021) || \
101099 + defined(P1022) || \
101100 + defined(P1023) || \
101101 + defined(P2020) || \
101102 + defined(P3041) || \
101103 + defined(P4080) || \
101104 + defined(P5020) || \
101105 + defined(MSC814x))
101106 +#error "unable to proceed without chip-definition"
101107 +#endif
101108 +
101109 +
101110 +/**************************************************************************//*
101111 + @Description Part data structure - must be contained in any integration
101112 + data structure.
101113 +*//***************************************************************************/
101114 +typedef struct t_Part
101115 +{
101116 + uint64_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
101117 + /**< Returns the address of the module's memory map base. */
101118 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uint64_t baseAddress);
101119 + /**< Returns the module's ID according to its memory map base. */
101120 +} t_Part;
101121 +
101122 +
101123 +#endif /* __PART_EXT_H */
101124 --- /dev/null
101125 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P1023/part_integration_ext.h
101126 @@ -0,0 +1,635 @@
101127 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
101128 + * All rights reserved.
101129 + *
101130 + * Redistribution and use in source and binary forms, with or without
101131 + * modification, are permitted provided that the following conditions are met:
101132 + * * Redistributions of source code must retain the above copyright
101133 + * notice, this list of conditions and the following disclaimer.
101134 + * * Redistributions in binary form must reproduce the above copyright
101135 + * notice, this list of conditions and the following disclaimer in the
101136 + * documentation and/or other materials provided with the distribution.
101137 + * * Neither the name of Freescale Semiconductor nor the
101138 + * names of its contributors may be used to endorse or promote products
101139 + * derived from this software without specific prior written permission.
101140 + *
101141 + *
101142 + * ALTERNATIVELY, this software may be distributed under the terms of the
101143 + * GNU General Public License ("GPL") as published by the Free Software
101144 + * Foundation, either version 2 of that License or (at your option) any
101145 + * later version.
101146 + *
101147 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101148 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101149 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101150 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101151 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101152 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101153 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101154 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101155 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101156 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101157 + */
101158 +
101159 +/**************************************************************************//**
101160 + @File part_integration_ext.h
101161 +
101162 + @Description P1023 external definitions and structures.
101163 +*//***************************************************************************/
101164 +#ifndef __PART_INTEGRATION_EXT_H
101165 +#define __PART_INTEGRATION_EXT_H
101166 +
101167 +#include "std_ext.h"
101168 +#include "dpaa_integration_ext.h"
101169 +
101170 +
101171 +/**************************************************************************//**
101172 + @Group 1023_chip_id P1023 Application Programming Interface
101173 +
101174 + @Description P1023 Chip functions,definitions and enums.
101175 +
101176 + @{
101177 +*//***************************************************************************/
101178 +
101179 +#define INTG_MAX_NUM_OF_CORES 2
101180 +
101181 +
101182 +/**************************************************************************//**
101183 + @Description Module types.
101184 +*//***************************************************************************/
101185 +typedef enum e_ModuleId
101186 +{
101187 + e_MODULE_ID_LAW, /**< Local Access module */
101188 + e_MODULE_ID_ECM, /**< e500 Coherency Module */
101189 + e_MODULE_ID_DDR, /**< DDR memory controller */
101190 + e_MODULE_ID_I2C_1, /**< I2C 1 */
101191 + e_MODULE_ID_I2C_2, /**< I2C 1 */
101192 + e_MODULE_ID_DUART_1, /**< DUART module 1 */
101193 + e_MODULE_ID_DUART_2, /**< DUART module 2 */
101194 + e_MODULE_ID_LBC, /**< Local bus memory controller module */
101195 + e_MODULE_ID_PCIE_1, /**< PCI Express 1 controller module */
101196 + e_MODULE_ID_PCIE_ATMU_1, /**< PCI 1 ATMU Window */
101197 + e_MODULE_ID_PCIE_2, /**< PCI Express 2 controller module */
101198 + e_MODULE_ID_PCIE_ATMU_2, /**< PCI 2 ATMU Window */
101199 + e_MODULE_ID_PCIE_3, /**< PCI Express 3 controller module */
101200 + e_MODULE_ID_PCIE_ATMU_3, /**< PCI 3 ATMU Window */
101201 + e_MODULE_ID_MSI, /**< MSI registers */
101202 + e_MODULE_ID_L2_SRAM, /**< L2/SRAM Memory-Mapped controller module */
101203 + e_MODULE_ID_DMA_1, /**< DMA controller 1 */
101204 + e_MODULE_ID_DMA_2, /**< DMA controller 2 */
101205 + e_MODULE_ID_EPIC, /**< Programmable interrupt controller */
101206 + e_MODULE_ID_ESPI, /**< ESPI module */
101207 + e_MODULE_ID_GPIO, /**< General Purpose I/O */
101208 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
101209 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
101210 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
101211 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
101212 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
101213 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
101214 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
101215 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
101216 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
101217 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
101218 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
101219 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
101220 + e_MODULE_ID_USB_DR_1, /**< USB 2.0 module 1 */
101221 + e_MODULE_ID_USB_DR_2, /**< USB 2.0 module 2 */
101222 + e_MODULE_ID_ETSEC_MII_MNG, /**< MII MNG registers */
101223 + e_MODULE_ID_ETSEC_1, /**< ETSEC module 1 */
101224 + e_MODULE_ID_ETSEC_2, /**< ETSEC module 2 */
101225 + e_MODULE_ID_GUTS, /**< Serial DMA */
101226 + e_MODULE_ID_PM, /**< Performance Monitor module */
101227 + e_MODULE_ID_QM, /**< Queue manager module */
101228 + e_MODULE_ID_BM, /**< Buffer manager module */
101229 + e_MODULE_ID_QM_CE_PORTAL,
101230 + e_MODULE_ID_QM_CI_PORTAL,
101231 + e_MODULE_ID_BM_CE_PORTAL,
101232 + e_MODULE_ID_BM_CI_PORTAL,
101233 + e_MODULE_ID_FM, /**< Frame manager #1 module */
101234 + e_MODULE_ID_FM_RTC, /**< FM Real-Time-Clock */
101235 + e_MODULE_ID_FM_MURAM, /**< FM Multi-User-RAM */
101236 + e_MODULE_ID_FM_BMI, /**< FM BMI block */
101237 + e_MODULE_ID_FM_QMI, /**< FM QMI block */
101238 + e_MODULE_ID_FM_PRS, /**< FM parser block */
101239 + e_MODULE_ID_FM_PORT_HO0, /**< FM Host-command/offline-parsing port block */
101240 + e_MODULE_ID_FM_PORT_HO1, /**< FM Host-command/offline-parsing port block */
101241 + e_MODULE_ID_FM_PORT_HO2, /**< FM Host-command/offline-parsing port block */
101242 + e_MODULE_ID_FM_PORT_HO3, /**< FM Host-command/offline-parsing port block */
101243 + e_MODULE_ID_FM_PORT_HO4, /**< FM Host-command/offline-parsing port block */
101244 + e_MODULE_ID_FM_PORT_1GRx0, /**< FM Rx 1G MAC port block */
101245 + e_MODULE_ID_FM_PORT_1GRx1, /**< FM Rx 1G MAC port block */
101246 + e_MODULE_ID_FM_PORT_1GTx0, /**< FM Tx 1G MAC port block */
101247 + e_MODULE_ID_FM_PORT_1GTx1, /**< FM Tx 1G MAC port block */
101248 + e_MODULE_ID_FM_PLCR, /**< FM Policer */
101249 + e_MODULE_ID_FM_KG, /**< FM Keygen */
101250 + e_MODULE_ID_FM_DMA, /**< FM DMA */
101251 + e_MODULE_ID_FM_FPM, /**< FM FPM */
101252 + e_MODULE_ID_FM_IRAM, /**< FM Instruction-RAM */
101253 + e_MODULE_ID_FM_1GMDIO0, /**< FM 1G MDIO MAC 0*/
101254 + e_MODULE_ID_FM_1GMDIO1, /**< FM 1G MDIO MAC 1*/
101255 + e_MODULE_ID_FM_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
101256 + e_MODULE_ID_FM_RISC0, /**< FM risc #0 */
101257 + e_MODULE_ID_FM_RISC1, /**< FM risc #1 */
101258 + e_MODULE_ID_FM_1GMAC0, /**< FM 1G MAC #0 */
101259 + e_MODULE_ID_FM_1GMAC1, /**< FM 1G MAC #1 */
101260 + e_MODULE_ID_FM_MACSEC, /**< FM MACSEC */
101261 +
101262 + e_MODULE_ID_DUMMY_LAST
101263 +} e_ModuleId;
101264 +
101265 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
101266 +
101267 +
101268 +#define P1023_OFFSET_LAW 0x00000C08
101269 +#define P1023_OFFSET_ECM 0x00001000
101270 +#define P1023_OFFSET_DDR 0x00002000
101271 +#define P1023_OFFSET_I2C1 0x00003000
101272 +#define P1023_OFFSET_I2C2 0x00003100
101273 +#define P1023_OFFSET_DUART1 0x00004500
101274 +#define P1023_OFFSET_DUART2 0x00004600
101275 +#define P1023_OFFSET_LBC 0x00005000
101276 +#define P1023_OFFSET_ESPI 0x00007000
101277 +#define P1023_OFFSET_PCIE2 0x00009000
101278 +#define P1023_OFFSET_PCIE2_ATMU 0x00009C00
101279 +#define P1023_OFFSET_PCIE1 0x0000A000
101280 +#define P1023_OFFSET_PCIE1_ATMU 0x0000AC00
101281 +#define P1023_OFFSET_PCIE3 0x0000B000
101282 +#define P1023_OFFSET_PCIE3_ATMU 0x0000BC00
101283 +#define P1023_OFFSET_DMA2 0x0000C100
101284 +#define P1023_OFFSET_GPIO 0x0000F000
101285 +#define P1023_OFFSET_L2_SRAM 0x00020000
101286 +#define P1023_OFFSET_DMA1 0x00021100
101287 +#define P1023_OFFSET_USB1 0x00022000
101288 +#define P1023_OFFSET_SEC_GEN 0x00030000
101289 +#define P1023_OFFSET_SEC_JQ0 0x00031000
101290 +#define P1023_OFFSET_SEC_JQ1 0x00032000
101291 +#define P1023_OFFSET_SEC_JQ2 0x00033000
101292 +#define P1023_OFFSET_SEC_JQ3 0x00034000
101293 +#define P1023_OFFSET_SEC_RTIC 0x00036000
101294 +#define P1023_OFFSET_SEC_QI 0x00037000
101295 +#define P1023_OFFSET_SEC_DECO0_CCB0 0x00038000
101296 +#define P1023_OFFSET_SEC_DECO1_CCB1 0x00039000
101297 +#define P1023_OFFSET_SEC_DECO2_CCB2 0x0003a000
101298 +#define P1023_OFFSET_SEC_DECO3_CCB3 0x0003b000
101299 +#define P1023_OFFSET_SEC_DECO4_CCB4 0x0003c000
101300 +#define P1023_OFFSET_PIC 0x00040000
101301 +#define P1023_OFFSET_MSI 0x00041600
101302 +#define P1023_OFFSET_AXI 0x00081000
101303 +#define P1023_OFFSET_QM 0x00088000
101304 +#define P1023_OFFSET_BM 0x0008A000
101305 +#define P1022_OFFSET_PM 0x000E1000
101306 +
101307 +#define P1023_OFFSET_GUTIL 0x000E0000
101308 +#define P1023_OFFSET_PM 0x000E1000
101309 +#define P1023_OFFSET_DEBUG 0x000E2000
101310 +#define P1023_OFFSET_SERDES 0x000E3000
101311 +#define P1023_OFFSET_ROM 0x000F0000
101312 +#define P1023_OFFSET_FM 0x00100000
101313 +
101314 +#define P1023_OFFSET_FM_MURAM (P1023_OFFSET_FM + 0x00000000)
101315 +#define P1023_OFFSET_FM_BMI (P1023_OFFSET_FM + 0x00080000)
101316 +#define P1023_OFFSET_FM_QMI (P1023_OFFSET_FM + 0x00080400)
101317 +#define P1023_OFFSET_FM_PRS (P1023_OFFSET_FM + 0x00080800)
101318 +#define P1023_OFFSET_FM_PORT_HO0 (P1023_OFFSET_FM + 0x00081000)
101319 +#define P1023_OFFSET_FM_PORT_HO1 (P1023_OFFSET_FM + 0x00082000)
101320 +#define P1023_OFFSET_FM_PORT_HO2 (P1023_OFFSET_FM + 0x00083000)
101321 +#define P1023_OFFSET_FM_PORT_HO3 (P1023_OFFSET_FM + 0x00084000)
101322 +#define P1023_OFFSET_FM_PORT_HO4 (P1023_OFFSET_FM + 0x00085000)
101323 +#define P1023_OFFSET_FM_PORT_1GRX0 (P1023_OFFSET_FM + 0x00088000)
101324 +#define P1023_OFFSET_FM_PORT_1GRX1 (P1023_OFFSET_FM + 0x00089000)
101325 +#define P1023_OFFSET_FM_PORT_1GTX0 (P1023_OFFSET_FM + 0x000A8000)
101326 +#define P1023_OFFSET_FM_PORT_1GTX1 (P1023_OFFSET_FM + 0x000A9000)
101327 +#define P1023_OFFSET_FM_PLCR (P1023_OFFSET_FM + 0x000C0000)
101328 +#define P1023_OFFSET_FM_KG (P1023_OFFSET_FM + 0x000C1000)
101329 +#define P1023_OFFSET_FM_DMA (P1023_OFFSET_FM + 0x000C2000)
101330 +#define P1023_OFFSET_FM_FPM (P1023_OFFSET_FM + 0x000C3000)
101331 +#define P1023_OFFSET_FM_IRAM (P1023_OFFSET_FM + 0x000C4000)
101332 +#define P1023_OFFSET_FM_PRS_IRAM (P1023_OFFSET_FM + 0x000C7000)
101333 +#define P1023_OFFSET_FM_RISC0 (P1023_OFFSET_FM + 0x000D0000)
101334 +#define P1023_OFFSET_FM_RISC1 (P1023_OFFSET_FM + 0x000D0400)
101335 +#define P1023_OFFSET_FM_MACSEC (P1023_OFFSET_FM + 0x000D8000)
101336 +#define P1023_OFFSET_FM_1GMAC0 (P1023_OFFSET_FM + 0x000E0000)
101337 +#define P1023_OFFSET_FM_1GMDIO0 (P1023_OFFSET_FM + 0x000E1120)
101338 +#define P1023_OFFSET_FM_1GMAC1 (P1023_OFFSET_FM + 0x000E2000)
101339 +#define P1023_OFFSET_FM_1GMDIO1 (P1023_OFFSET_FM + 0x000E3000)
101340 +#define P1023_OFFSET_FM_RTC (P1023_OFFSET_FM + 0x000FE000)
101341 +
101342 +/* Offsets relative to QM or BM portals base */
101343 +#define P1023_OFFSET_PORTALS_CE_AREA 0x00000000 /* cache enabled area */
101344 +#define P1023_OFFSET_PORTALS_CI_AREA 0x00100000 /* cache inhibited area */
101345 +
101346 +#define P1023_OFFSET_PORTALS_CE(portal) (P1023_OFFSET_PORTALS_CE_AREA + 0x4000 * (portal))
101347 +#define P1023_OFFSET_PORTALS_CI(portal) (P1023_OFFSET_PORTALS_CI_AREA + 0x1000 * (portal))
101348 +
101349 +/**************************************************************************//**
101350 + @Description Transaction source ID (for memory controllers error reporting).
101351 +*//***************************************************************************/
101352 +typedef enum e_TransSrc
101353 +{
101354 + e_TRANS_SRC_PCIE_2 = 0x01, /**< PCIe port 2 */
101355 + e_TRANS_SRC_PCIE_1 = 0x02, /**< PCIe port 1 */
101356 + e_TRANS_SRC_PCIE_3 = 0x03, /**< PCIe port 3 */
101357 + e_TRANS_SRC_LBC = 0x04, /**< Enhanced local bus */
101358 + e_TRANS_SRC_DPAA_SW_PORTALS = 0x0E, /**< DPAA software portals or SRAM */
101359 + e_TRANS_SRC_DDR = 0x0F, /**< DDR controller */
101360 + e_TRANS_SRC_CORE_INS_FETCH = 0x10, /**< Processor (instruction) */
101361 + e_TRANS_SRC_CORE_DATA = 0x11, /**< Processor (data) */
101362 + e_TRANS_SRC_DMA = 0x15 /**< DMA */
101363 +} e_TransSrc;
101364 +
101365 +/**************************************************************************//**
101366 + @Description Local Access Window Target interface ID
101367 +*//***************************************************************************/
101368 +typedef enum e_P1023LawTargetId
101369 +{
101370 + e_P1023_LAW_TARGET_PCIE_2 = 0x01, /**< PCI Express 2 target interface */
101371 + e_P1023_LAW_TARGET_PCIE_1 = 0x02, /**< PCI Express 1 target interface */
101372 + e_P1023_LAW_TARGET_PCIE_3 = 0x03, /**< PCI Express 3 target interface */
101373 + e_P1023_LAW_TARGET_LBC = 0x04, /**< Local bus target interface */
101374 + e_P1023_LAW_TARGET_QM_PORTALS = 0x0E, /**< Queue Manager Portals */
101375 + e_P1023_LAW_TARGET_BM_PORTALS = 0x0E, /**< Buffer Manager Portals */
101376 + e_P1023_LAW_TARGET_SRAM = 0x0E, /**< SRAM scratchpad */
101377 + e_P1023_LAW_TARGET_DDR = 0x0F, /**< DDR target interface */
101378 + e_P1023_LAW_TARGET_NONE = 0xFF /**< Invalid target interface */
101379 +} e_P1023LawTargetId;
101380 +
101381 +
101382 +/**************************************************************************//**
101383 + @Group 1023_init_grp P1023 Initialization Unit
101384 +
101385 + @Description P1023 initialization unit API functions, definitions and enums
101386 +
101387 + @{
101388 +*//***************************************************************************/
101389 +
101390 +/**************************************************************************//**
101391 + @Description Part ID and revision number
101392 +*//***************************************************************************/
101393 +typedef enum e_P1023DeviceName
101394 +{
101395 + e_P1023_REV_INVALID = 0x00000000, /**< Invalid revision */
101396 + e_SC1023_REV_1_0 = (int)0x80FC0010, /**< SC1023 rev 1.0 */
101397 + e_SC1023_REV_1_1 = (int)0x80FC0011, /**< SC1023 rev 1.1 */
101398 + e_P1023_REV_1_0 = (int)0x80FE0010, /**< P1023 rev 1.0 with security */
101399 + e_P1023_REV_1_1 = (int)0x80FE0011, /**< P1023 rev 1.1 with security */
101400 + e_P1017_REV_1_1 = (int)0x80FF0011, /**< P1017 rev 1.1 with security */
101401 + e_P1023_REV_1_0_NO_SEC = (int)0x80F60010, /**< P1023 rev 1.0 without security */
101402 + e_P1023_REV_1_1_NO_SEC = (int)0x80F60011, /**< P1023 rev 1.1 without security */
101403 + e_P1017_REV_1_1_NO_SEC = (int)0x80F70011 /**< P1017 rev 1.1 without security */
101404 +} e_P1023DeviceName;
101405 +
101406 +/**************************************************************************//**
101407 + @Description structure representing P1023 initialization parameters
101408 +*//***************************************************************************/
101409 +typedef struct t_P1023Params
101410 +{
101411 + uintptr_t ccsrBaseAddress; /**< CCSR base address (virtual) */
101412 + uintptr_t bmPortalsBaseAddress; /**< Portals base address (virtual) */
101413 + uintptr_t qmPortalsBaseAddress; /**< Portals base address (virtual) */
101414 +} t_P1023Params;
101415 +
101416 +/**************************************************************************//**
101417 + @Function P1023_ConfigAndInit
101418 +
101419 + @Description General initiation of the chip registers.
101420 +
101421 + @Param[in] p_P1023Params - A pointer to data structure of parameters
101422 +
101423 + @Return A handle to the P1023 data structure.
101424 +*//***************************************************************************/
101425 +t_Handle P1023_ConfigAndInit(t_P1023Params *p_P1023Params);
101426 +
101427 +/**************************************************************************//**
101428 + @Function P1023_Free
101429 +
101430 + @Description Free all resources.
101431 +
101432 + @Param h_P1023 - (In) The handle of the initialized P1023 object.
101433 +
101434 + @Return E_OK on success; Other value otherwise.
101435 +*//***************************************************************************/
101436 +t_Error P1023_Free(t_Handle h_P1023);
101437 +
101438 +/**************************************************************************//**
101439 + @Function P1023_GetRevInfo
101440 +
101441 + @Description This routine enables access to chip and revision information.
101442 +
101443 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101444 +
101445 + @Return Part ID and revision.
101446 +*//***************************************************************************/
101447 +e_P1023DeviceName P1023_GetRevInfo(uintptr_t gutilBase);
101448 +
101449 +/**************************************************************************//**
101450 + @Function P1023_GetE500Factor
101451 +
101452 + @Description Returns E500 core clock multiplication factor.
101453 +
101454 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101455 + @Param[in] coreId - Id of the requested core.
101456 + @Param[out] p_E500MulFactor - Returns E500 to CCB multification factor.
101457 + @Param[out] p_E500DivFactor - Returns E500 to CCB division factor.
101458 +
101459 + @Return E_OK on success; Other value otherwise.
101460 +*
101461 +*//***************************************************************************/
101462 +t_Error P1023_GetE500Factor(uintptr_t gutilBase,
101463 + uint32_t coreId,
101464 + uint32_t *p_E500MulFactor,
101465 + uint32_t *p_E500DivFactor);
101466 +
101467 +/**************************************************************************//**
101468 + @Function P1023_GetFmFactor
101469 +
101470 + @Description returns FM multiplication factors. (This value is returned using
101471 + two parameters to avoid using float parameter).
101472 +
101473 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101474 + @Param[out] p_FmMulFactor - returns E500 to CCB multification factor.
101475 + @Param[out] p_FmDivFactor - returns E500 to CCB division factor.
101476 +
101477 + @Return E_OK on success; Other value otherwise.
101478 +*//***************************************************************************/
101479 +t_Error P1023_GetFmFactor(uintptr_t gutilBase, uint32_t *p_FmMulFactor, uint32_t *p_FmDivFactor);
101480 +
101481 +/**************************************************************************//**
101482 + @Function P1023_GetCcbFactor
101483 +
101484 + @Description returns system multiplication factor.
101485 +
101486 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101487 +
101488 + @Return System multiplication factor.
101489 +*//***************************************************************************/
101490 +uint32_t P1023_GetCcbFactor(uintptr_t gutilBase);
101491 +
101492 +#if 0
101493 +/**************************************************************************//**
101494 + @Function P1023_GetDdrFactor
101495 +
101496 + @Description returns the multiplication factor of the clock in for the DDR clock .
101497 + Note: assumes the ddr_in_clk is identical to the sys_in_clk
101498 +
101499 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101500 + @Param p_DdrMulFactor - returns DDR in clk multification factor.
101501 + @Param p_DdrDivFactor - returns DDR division factor.
101502 +
101503 + @Return E_OK on success; Other value otherwise..
101504 +*//***************************************************************************/
101505 +t_Error P1023_GetDdrFactor( uintptr_t gutilBase,
101506 + uint32_t *p_DdrMulFactor,
101507 + uint32_t *p_DdrDivFactor);
101508 +
101509 +/**************************************************************************//**
101510 + @Function P1023_GetDdrType
101511 +
101512 + @Description returns the multiplication factor of the clock in for the DDR clock .
101513 +
101514 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101515 + @Param p_DdrType - (Out) returns DDR type DDR1/DDR2/DDR3.
101516 +
101517 + @Return E_OK on success; Other value otherwise.
101518 +*//***************************************************************************/
101519 +t_Error P1023_GetDdrType(uintptr_t gutilBase, e_DdrType *p_DdrType );
101520 +#endif
101521 +
101522 +/** @} */ /* end of 1023_init_grp group */
101523 +/** @} */ /* end of 1023_grp group */
101524 +
101525 +#define CORE_E500V2
101526 +
101527 +#if 0 /* using unified values */
101528 +/*****************************************************************************
101529 + INTEGRATION-SPECIFIC MODULE CODES
101530 +******************************************************************************/
101531 +#define MODULE_UNKNOWN 0x00000000
101532 +#define MODULE_MEM 0x00010000
101533 +#define MODULE_MM 0x00020000
101534 +#define MODULE_CORE 0x00030000
101535 +#define MODULE_P1023 0x00040000
101536 +#define MODULE_MII 0x00050000
101537 +#define MODULE_PM 0x00060000
101538 +#define MODULE_MMU 0x00070000
101539 +#define MODULE_PIC 0x00080000
101540 +#define MODULE_L2_CACHE 0x00090000
101541 +#define MODULE_DUART 0x000a0000
101542 +#define MODULE_SERDES 0x000b0000
101543 +#define MODULE_PIO 0x000c0000
101544 +#define MODULE_QM 0x000d0000
101545 +#define MODULE_BM 0x000e0000
101546 +#define MODULE_SEC 0x000f0000
101547 +#define MODULE_FM 0x00100000
101548 +#define MODULE_FM_MURAM 0x00110000
101549 +#define MODULE_FM_PCD 0x00120000
101550 +#define MODULE_FM_RTC 0x00130000
101551 +#define MODULE_FM_MAC 0x00140000
101552 +#define MODULE_FM_PORT 0x00150000
101553 +#define MODULE_FM_MACSEC 0x00160000
101554 +#define MODULE_FM_MACSEC_SECY 0x00170000
101555 +#define MODULE_FM_SP 0x00280000
101556 +#define MODULE_ECM 0x00190000
101557 +#define MODULE_DMA 0x001a0000
101558 +#define MODULE_DDR 0x001b0000
101559 +#define MODULE_LAW 0x001c0000
101560 +#define MODULE_LBC 0x001d0000
101561 +#define MODULE_I2C 0x001e0000
101562 +#define MODULE_ESPI 0x001f0000
101563 +#define MODULE_PCI 0x00200000
101564 +#define MODULE_DPA_PORT 0x00210000
101565 +#define MODULE_USB 0x00220000
101566 +#endif /* using unified values */
101567 +
101568 +/*****************************************************************************
101569 + LBC INTEGRATION-SPECIFIC DEFINITIONS
101570 +******************************************************************************/
101571 +/**************************************************************************//**
101572 + @Group lbc_exception_grp LBC Exception Unit
101573 +
101574 + @Description LBC Exception unit API functions, definitions and enums
101575 +
101576 + @{
101577 +*//***************************************************************************/
101578 +
101579 +/**************************************************************************//**
101580 + @Anchor lbc_exbm
101581 +
101582 + @Collection LBC Errors Bit Mask
101583 +
101584 + These errors are reported through the exceptions callback..
101585 + The values can be or'ed in any combination in the errors mask
101586 + parameter of the errors report structure.
101587 +
101588 + These errors can also be passed as a bit-mask to
101589 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
101590 + for enabling or disabling error checking.
101591 + @{
101592 +*//***************************************************************************/
101593 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
101594 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
101595 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
101596 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
101597 +
101598 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
101599 + LBC_ERR_WRITE_PROTECT | LBC_ERR_CHIP_SELECT)
101600 + /**< All possible errors */
101601 +/* @} */
101602 +/** @} */ /* end of lbc_exception_grp group */
101603 +
101604 +#define LBC_NUM_OF_BANKS 2
101605 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
101606 +#define LBC_ATOMIC_OPERATION_SUPPORT
101607 +#define LBC_PARITY_SUPPORT
101608 +#define LBC_ADDRESS_SHIFT_SUPPORT
101609 +#define LBC_ADDRESS_HOLD_TIME_CTRL
101610 +#define LBC_HIGH_CLK_DIVIDERS
101611 +#define LBC_FCM_AVAILABLE
101612 +
101613 +
101614 +/*****************************************************************************
101615 + LAW INTEGRATION-SPECIFIC DEFINITIONS
101616 +******************************************************************************/
101617 +#define LAW_ARCH_CCB
101618 +#define LAW_NUM_OF_WINDOWS 12
101619 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
101620 +#define LAW_MAX_WINDOW_SIZE 0x0000001000000000LL /**< 32GB */
101621 +
101622 +
101623 +/*****************************************************************************
101624 + SPI INTEGRATION-SPECIFIC DEFINITIONS
101625 +******************************************************************************/
101626 +#define SPI_NUM_OF_CONTROLLERS 1
101627 +
101628 +/*****************************************************************************
101629 + PCI/PCIe INTEGRATION-SPECIFIC DEFINITIONS
101630 +******************************************************************************/
101631 +
101632 +#define PCI_MAX_INBOUND_WINDOWS_NUM 4
101633 +#define PCI_MAX_OUTBOUND_WINDOWS_NUM 5
101634 +
101635 +/**************************************************************************//**
101636 + @Description Target interface of an inbound window
101637 +*//***************************************************************************/
101638 +typedef enum e_PciTargetInterface
101639 +{
101640 + e_PCI_TARGET_PCIE_2 = 0x1, /**< PCI Express target interface 2 */
101641 + e_PCI_TARGET_PCIE_1 = 0x2, /**< PCI Express target interface 1 */
101642 + e_PCI_TARGET_PCIE_3 = 0x3, /**< PCI Express target interface 3 */
101643 + e_PCI_TARGET_LOCAL_MEMORY = 0xF /**< Local Memory (DDR SDRAM, Local Bus, SRAM) target interface */
101644 +
101645 +} e_PciTargetInterface;
101646 +
101647 +/*****************************************************************************
101648 + DDR INTEGRATION-SPECIFIC DEFINITIONS
101649 +******************************************************************************/
101650 +#define DDR_NUM_OF_VALID_CS 2
101651 +
101652 +/*****************************************************************************
101653 + SEC INTEGRATION-SPECIFIC DEFINITIONS
101654 +******************************************************************************/
101655 +#define SEC_ERRATA_STAT_REGS_UNUSABLE
101656 +
101657 +/*****************************************************************************
101658 + DMA INTEGRATION-SPECIFIC DEFINITIONS
101659 +******************************************************************************/
101660 +#define DMA_NUM_OF_CONTROLLERS 2
101661 +
101662 +
101663 +
101664 +
101665 +/*****************************************************************************
101666 + 1588 INTEGRATION-SPECIFIC DEFINITIONS
101667 +******************************************************************************/
101668 +#define PTP_V2
101669 +
101670 +/**************************************************************************//**
101671 + @Function P1023_GetMuxControlReg
101672 +
101673 + @Description Returns the value of PMUXCR (Alternate Function Signal Multiplex
101674 + Control Register)
101675 +
101676 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101677 +
101678 + @Return Value of PMUXCR
101679 +*//***************************************************************************/
101680 +uint32_t P1023_GetMuxControlReg(uintptr_t gutilBase);
101681 +
101682 +/**************************************************************************//**
101683 + @Function P1023_SetMuxControlReg
101684 +
101685 + @Description Sets the value of PMUXCR (Alternate Function Signal Multiplex
101686 + Control Register)
101687 +
101688 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101689 + @Param[in] val - the new value for PMUXCR.
101690 +
101691 + @Return None
101692 +*//***************************************************************************/
101693 +void P1023_SetMuxControlReg(uintptr_t gutilBase, uint32_t val);
101694 +
101695 +/**************************************************************************//**
101696 + @Function P1023_GetDeviceDisableStatusRegister
101697 +
101698 + @Description Returns the value of DEVDISR (Device Disable Register)
101699 +
101700 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101701 +
101702 + @Return Value of DEVDISR
101703 +*//***************************************************************************/
101704 +uint32_t P1023_GetDeviceDisableStatusRegister(uintptr_t gutilBase);
101705 +
101706 +/**************************************************************************//**
101707 + @Function P1023_GetPorDeviceStatusRegister
101708 +
101709 + @Description Returns the value of POR Device Status Register
101710 +
101711 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101712 +
101713 + @Return POR Device Status Register
101714 +*//***************************************************************************/
101715 +uint32_t P1023_GetPorDeviceStatusRegister(uintptr_t gutilBase);
101716 +
101717 +/**************************************************************************//**
101718 + @Function P1023_GetPorBootModeStatusRegister
101719 +
101720 + @Description Returns the value of POR Boot Mode Status Register
101721 +
101722 + @Param[in] gutilBase - Base address of P1023 GUTIL registers.
101723 +
101724 + @Return POR Boot Mode Status Register value
101725 +*//***************************************************************************/
101726 +uint32_t P1023_GetPorBootModeStatusRegister(uintptr_t gutilBase);
101727 +
101728 +
101729 +#define PORDEVSR_SGMII1_DIS 0x10000000
101730 +#define PORDEVSR_SGMII2_DIS 0x08000000
101731 +#define PORDEVSR_ECP1 0x02000000
101732 +#define PORDEVSR_IO_SEL 0x00780000
101733 +#define PORDEVSR_IO_SEL_SHIFT 19
101734 +#define PORBMSR_HA 0x00070000
101735 +#define PORBMSR_HA_SHIFT 16
101736 +
101737 +#define DEVDISR_QM_BM 0x80000000
101738 +#define DEVDISR_FM 0x40000000
101739 +#define DEVDISR_PCIE1 0x20000000
101740 +#define DEVDISR_MAC_SEC 0x10000000
101741 +#define DEVDISR_ELBC 0x08000000
101742 +#define DEVDISR_PCIE2 0x04000000
101743 +#define DEVDISR_PCIE3 0x02000000
101744 +#define DEVDISR_CAAM 0x01000000
101745 +#define DEVDISR_USB0 0x00800000
101746 +#define DEVDISR_1588 0x00020000
101747 +#define DEVDISR_CORE0 0x00008000
101748 +#define DEVDISR_TB0 0x00004000
101749 +#define DEVDISR_CORE1 0x00002000
101750 +#define DEVDISR_TB1 0x00001000
101751 +#define DEVDISR_DMA1 0x00000400
101752 +#define DEVDISR_DMA2 0x00000200
101753 +#define DEVDISR_DDR 0x00000010
101754 +#define DEVDISR_TSEC1 0x00000080
101755 +#define DEVDISR_TSEC2 0x00000040
101756 +#define DEVDISR_SPI 0x00000008
101757 +#define DEVDISR_I2C 0x00000004
101758 +#define DEVDISR_DUART 0x00000002
101759 +
101760 +
101761 +#endif /* __PART_INTEGRATION_EXT_H */
101762 --- /dev/null
101763 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/dpaa_integration_ext.h
101764 @@ -0,0 +1,276 @@
101765 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc
101766 + * All rights reserved.
101767 + *
101768 + * Redistribution and use in source and binary forms, with or without
101769 + * modification, are permitted provided that the following conditions are met:
101770 + * * Redistributions of source code must retain the above copyright
101771 + * notice, this list of conditions and the following disclaimer.
101772 + * * Redistributions in binary form must reproduce the above copyright
101773 + * notice, this list of conditions and the following disclaimer in the
101774 + * documentation and/or other materials provided with the distribution.
101775 + * * Neither the name of Freescale Semiconductor nor the
101776 + * names of its contributors may be used to endorse or promote products
101777 + * derived from this software without specific prior written permission.
101778 + *
101779 + *
101780 + * ALTERNATIVELY, this software may be distributed under the terms of the
101781 + * GNU General Public License ("GPL") as published by the Free Software
101782 + * Foundation, either version 2 of that License or (at your option) any
101783 + * later version.
101784 + *
101785 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
101786 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
101787 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
101788 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
101789 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
101790 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
101791 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
101792 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
101793 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
101794 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
101795 + */
101796 +
101797 +/**************************************************************************//**
101798 + @File dpaa_integration_ext.h
101799 +
101800 + @Description P3040/P4080/P5020 FM external definitions and structures.
101801 +*//***************************************************************************/
101802 +#ifndef __DPAA_INTEGRATION_EXT_H
101803 +#define __DPAA_INTEGRATION_EXT_H
101804 +
101805 +#include "std_ext.h"
101806 +
101807 +
101808 +#define DPAA_VERSION 10
101809 +
101810 +typedef enum {
101811 + e_DPAA_SWPORTAL0 = 0,
101812 + e_DPAA_SWPORTAL1,
101813 + e_DPAA_SWPORTAL2,
101814 + e_DPAA_SWPORTAL3,
101815 + e_DPAA_SWPORTAL4,
101816 + e_DPAA_SWPORTAL5,
101817 + e_DPAA_SWPORTAL6,
101818 + e_DPAA_SWPORTAL7,
101819 + e_DPAA_SWPORTAL8,
101820 + e_DPAA_SWPORTAL9,
101821 + e_DPAA_SWPORTAL_DUMMY_LAST
101822 +} e_DpaaSwPortal;
101823 +
101824 +typedef enum {
101825 + e_DPAA_DCPORTAL0 = 0,
101826 + e_DPAA_DCPORTAL1,
101827 + e_DPAA_DCPORTAL2,
101828 + e_DPAA_DCPORTAL3,
101829 + e_DPAA_DCPORTAL4,
101830 + e_DPAA_DCPORTAL_DUMMY_LAST
101831 +} e_DpaaDcPortal;
101832 +
101833 +#define DPAA_MAX_NUM_OF_SW_PORTALS e_DPAA_SWPORTAL_DUMMY_LAST
101834 +#define DPAA_MAX_NUM_OF_DC_PORTALS e_DPAA_DCPORTAL_DUMMY_LAST
101835 +
101836 +/*****************************************************************************
101837 + QMan INTEGRATION-SPECIFIC DEFINITIONS
101838 +******************************************************************************/
101839 +#define QM_MAX_NUM_OF_POOL_CHANNELS 15 /**< Total number of channels, dedicated and pool */
101840 +#define QM_MAX_NUM_OF_WQ 8 /**< Number of work queues per channel */
101841 +#define QM_MAX_NUM_OF_SWP_AS 4
101842 +#define QM_MAX_NUM_OF_CGS 256 /**< Number of congestion groups */
101843 +#define QM_MAX_NUM_OF_FQIDS (16 * MEGABYTE) /**< FQIDs range - 24 bits */
101844 +
101845 +/**************************************************************************//**
101846 + @Description Work Queue Channel assignments in QMan.
101847 +*//***************************************************************************/
101848 +typedef enum
101849 +{
101850 + e_QM_FQ_CHANNEL_SWPORTAL0 = 0, /**< Dedicated channels serviced by software portals 0 to 9 */
101851 + e_QM_FQ_CHANNEL_SWPORTAL1,
101852 + e_QM_FQ_CHANNEL_SWPORTAL2,
101853 + e_QM_FQ_CHANNEL_SWPORTAL3,
101854 + e_QM_FQ_CHANNEL_SWPORTAL4,
101855 + e_QM_FQ_CHANNEL_SWPORTAL5,
101856 + e_QM_FQ_CHANNEL_SWPORTAL6,
101857 + e_QM_FQ_CHANNEL_SWPORTAL7,
101858 + e_QM_FQ_CHANNEL_SWPORTAL8,
101859 + e_QM_FQ_CHANNEL_SWPORTAL9,
101860 +
101861 + e_QM_FQ_CHANNEL_POOL1 = 0x21, /**< Pool channels that can be serviced by any of the software portals */
101862 + e_QM_FQ_CHANNEL_POOL2,
101863 + e_QM_FQ_CHANNEL_POOL3,
101864 + e_QM_FQ_CHANNEL_POOL4,
101865 + e_QM_FQ_CHANNEL_POOL5,
101866 + e_QM_FQ_CHANNEL_POOL6,
101867 + e_QM_FQ_CHANNEL_POOL7,
101868 + e_QM_FQ_CHANNEL_POOL8,
101869 + e_QM_FQ_CHANNEL_POOL9,
101870 + e_QM_FQ_CHANNEL_POOL10,
101871 + e_QM_FQ_CHANNEL_POOL11,
101872 + e_QM_FQ_CHANNEL_POOL12,
101873 + e_QM_FQ_CHANNEL_POOL13,
101874 + e_QM_FQ_CHANNEL_POOL14,
101875 + e_QM_FQ_CHANNEL_POOL15,
101876 +
101877 + e_QM_FQ_CHANNEL_FMAN0_SP0 = 0x40, /**< Dedicated channels serviced by Direct Connect Portal 0:
101878 + connected to FMan 0; assigned in incrementing order to
101879 + each sub-portal (SP) in the portal */
101880 + e_QM_FQ_CHANNEL_FMAN0_SP1,
101881 + e_QM_FQ_CHANNEL_FMAN0_SP2,
101882 + e_QM_FQ_CHANNEL_FMAN0_SP3,
101883 + e_QM_FQ_CHANNEL_FMAN0_SP4,
101884 + e_QM_FQ_CHANNEL_FMAN0_SP5,
101885 + e_QM_FQ_CHANNEL_FMAN0_SP6,
101886 + e_QM_FQ_CHANNEL_FMAN0_SP7,
101887 + e_QM_FQ_CHANNEL_FMAN0_SP8,
101888 + e_QM_FQ_CHANNEL_FMAN0_SP9,
101889 + e_QM_FQ_CHANNEL_FMAN0_SP10,
101890 + e_QM_FQ_CHANNEL_FMAN0_SP11,
101891 +/* difference between 5020 and 4080 :) */
101892 + e_QM_FQ_CHANNEL_FMAN1_SP0 = 0x60,
101893 + e_QM_FQ_CHANNEL_FMAN1_SP1,
101894 + e_QM_FQ_CHANNEL_FMAN1_SP2,
101895 + e_QM_FQ_CHANNEL_FMAN1_SP3,
101896 + e_QM_FQ_CHANNEL_FMAN1_SP4,
101897 + e_QM_FQ_CHANNEL_FMAN1_SP5,
101898 + e_QM_FQ_CHANNEL_FMAN1_SP6,
101899 + e_QM_FQ_CHANNEL_FMAN1_SP7,
101900 + e_QM_FQ_CHANNEL_FMAN1_SP8,
101901 + e_QM_FQ_CHANNEL_FMAN1_SP9,
101902 + e_QM_FQ_CHANNEL_FMAN1_SP10,
101903 + e_QM_FQ_CHANNEL_FMAN1_SP11,
101904 +
101905 + e_QM_FQ_CHANNEL_CAAM = 0x80, /**< Dedicated channel serviced by Direct Connect Portal 2:
101906 + connected to SEC 4.x */
101907 +
101908 + e_QM_FQ_CHANNEL_PME = 0xA0, /**< Dedicated channel serviced by Direct Connect Portal 3:
101909 + connected to PME */
101910 + e_QM_FQ_CHANNEL_RAID = 0xC0 /**< Dedicated channel serviced by Direct Connect Portal 4:
101911 + connected to RAID */
101912 +} e_QmFQChannel;
101913 +
101914 +/*****************************************************************************
101915 + BMan INTEGRATION-SPECIFIC DEFINITIONS
101916 +******************************************************************************/
101917 +#define BM_MAX_NUM_OF_POOLS 64 /**< Number of buffers pools */
101918 +
101919 +
101920 +/*****************************************************************************
101921 + FM INTEGRATION-SPECIFIC DEFINITIONS
101922 +******************************************************************************/
101923 +#define INTG_MAX_NUM_OF_FM 2
101924 +
101925 +/* Ports defines */
101926 +#define FM_MAX_NUM_OF_1G_MACS 5
101927 +#define FM_MAX_NUM_OF_10G_MACS 1
101928 +#define FM_MAX_NUM_OF_MACS (FM_MAX_NUM_OF_1G_MACS + FM_MAX_NUM_OF_10G_MACS)
101929 +#define FM_MAX_NUM_OF_OH_PORTS 7
101930 +
101931 +#define FM_MAX_NUM_OF_1G_RX_PORTS FM_MAX_NUM_OF_1G_MACS
101932 +#define FM_MAX_NUM_OF_10G_RX_PORTS FM_MAX_NUM_OF_10G_MACS
101933 +#define FM_MAX_NUM_OF_RX_PORTS (FM_MAX_NUM_OF_10G_RX_PORTS + FM_MAX_NUM_OF_1G_RX_PORTS)
101934 +
101935 +#define FM_MAX_NUM_OF_1G_TX_PORTS FM_MAX_NUM_OF_1G_MACS
101936 +#define FM_MAX_NUM_OF_10G_TX_PORTS FM_MAX_NUM_OF_10G_MACS
101937 +#define FM_MAX_NUM_OF_TX_PORTS (FM_MAX_NUM_OF_10G_TX_PORTS + FM_MAX_NUM_OF_1G_TX_PORTS)
101938 +
101939 +#define FM_PORT_MAX_NUM_OF_EXT_POOLS 8 /**< Number of external BM pools per Rx port */
101940 +#define FM_PORT_NUM_OF_CONGESTION_GRPS 256 /**< Total number of congestion groups in QM */
101941 +#define FM_MAX_NUM_OF_SUB_PORTALS 12
101942 +#define FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS 0
101943 +
101944 +/* Rams defines */
101945 +#define FM_MURAM_SIZE (160*KILOBYTE)
101946 +#define FM_IRAM_SIZE(major, minor) (64 * KILOBYTE)
101947 +#define FM_NUM_OF_CTRL 2
101948 +
101949 +/* PCD defines */
101950 +#define FM_PCD_PLCR_NUM_ENTRIES 256 /**< Total number of policer profiles */
101951 +#define FM_PCD_KG_NUM_OF_SCHEMES 32 /**< Total number of KG schemes */
101952 +#define FM_PCD_MAX_NUM_OF_CLS_PLANS 256 /**< Number of classification plan entries. */
101953 +#define FM_PCD_PRS_SW_PATCHES_SIZE 0x00000200 /**< Number of bytes saved for patches */
101954 +#define FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
101955 +
101956 +/* RTC defines */
101957 +#define FM_RTC_NUM_OF_ALARMS 2 /**< RTC number of alarms */
101958 +#define FM_RTC_NUM_OF_PERIODIC_PULSES 2 /**< RTC number of periodic pulses */
101959 +#define FM_RTC_NUM_OF_EXT_TRIGGERS 2 /**< RTC number of external triggers */
101960 +
101961 +/* QMI defines */
101962 +#define QMI_MAX_NUM_OF_TNUMS 64
101963 +#define QMI_DEF_TNUMS_THRESH 48
101964 +
101965 +/* FPM defines */
101966 +#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS 4
101967 +
101968 +/* DMA defines */
101969 +#define DMA_THRESH_MAX_COMMQ 31
101970 +#define DMA_THRESH_MAX_BUF 127
101971 +
101972 +/* BMI defines */
101973 +#define BMI_MAX_NUM_OF_TASKS 128
101974 +#define BMI_MAX_NUM_OF_DMAS 32
101975 +#define BMI_MAX_FIFO_SIZE (FM_MURAM_SIZE)
101976 +#define PORT_MAX_WEIGHT 16
101977 +
101978 +
101979 +#define FM_CHECK_PORT_RESTRICTIONS(__validPorts, __newPortIndx) TRUE
101980 +
101981 +/* p4080-rev1 unique features */
101982 +#define QM_CGS_NO_FRAME_MODE
101983 +
101984 +/* p4080 unique features */
101985 +#define FM_NO_DISPATCH_RAM_ECC
101986 +#define FM_NO_WATCHDOG
101987 +#define FM_NO_TNUM_AGING
101988 +#define FM_KG_NO_BYPASS_FQID_GEN
101989 +#define FM_KG_NO_BYPASS_PLCR_PROFILE_GEN
101990 +#define FM_NO_BACKUP_POOLS
101991 +#define FM_NO_OP_OBSERVED_POOLS
101992 +#define FM_NO_ADVANCED_RATE_LIMITER
101993 +#define FM_NO_OP_OBSERVED_CGS
101994 +#define FM_HAS_TOTAL_DMAS
101995 +#define FM_KG_NO_IPPID_SUPPORT
101996 +#define FM_NO_GUARANTEED_RESET_VALUES
101997 +#define FM_MAC_RESET
101998 +
101999 +/* FM erratas */
102000 +#define FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
102001 +#define FM_TX_SHORT_FRAME_BAD_TS_ERRATA_10GMAC_A006 /* No implementation, Out of LLD scope */
102002 +#define FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
102003 +#define FM_ECC_HALT_NO_SYNC_ERRATA_10GMAC_A008
102004 +#define FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 /* Out of LLD scope, user may disable ECC exceptions using FM_DisableRamsEcc */
102005 +#define FM_BAD_VLAN_DETECT_ERRATA_10GMAC_A010
102006 +
102007 +#define FM_RX_PREAM_4_ERRATA_DTSEC_A001
102008 +#define FM_GRS_ERRATA_DTSEC_A002
102009 +#define FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
102010 +#define FM_GTS_ERRATA_DTSEC_A004
102011 +#define FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012
102012 +#define FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
102013 +#define FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
102014 +
102015 +#define FM_MAGIC_PACKET_UNRECOGNIZED_ERRATA_DTSEC2 /* No implementation, Out of LLD scope */
102016 +#define FM_TX_LOCKUP_ERRATA_DTSEC6
102017 +
102018 +#define FM_HC_DEF_FQID_ONLY_ERRATA_FMAN_A003 /* Implemented by ucode */
102019 +#define FM_DEBUG_TRACE_FMAN_A004 /* No implementation, Out of LLD scope */
102020 +
102021 +#define FM_UCODE_NOT_RESET_ERRATA_BUGZILLA6173
102022 +
102023 +#define FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005
102024 +
102025 +#define FM_LEN_CHECK_ERRATA_FMAN_SW002
102026 +
102027 +#define FM_NO_CTXA_COPY_ERRATA_FMAN_SW001
102028 +#define FM_KG_ERASE_FLOW_ID_ERRATA_FMAN_SW004
102029 +
102030 +/*****************************************************************************
102031 + FM MACSEC INTEGRATION-SPECIFIC DEFINITIONS
102032 +******************************************************************************/
102033 +#define NUM_OF_RX_SC 16
102034 +#define NUM_OF_TX_SC 16
102035 +
102036 +#define NUM_OF_SA_PER_RX_SC 2
102037 +#define NUM_OF_SA_PER_TX_SC 2
102038 +
102039 +
102040 +#endif /* __DPAA_INTEGRATION_EXT_H */
102041 --- /dev/null
102042 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_ext.h
102043 @@ -0,0 +1,83 @@
102044 +/*
102045 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102046 + *
102047 + * Redistribution and use in source and binary forms, with or without
102048 + * modification, are permitted provided that the following conditions are met:
102049 + * * Redistributions of source code must retain the above copyright
102050 + * notice, this list of conditions and the following disclaimer.
102051 + * * Redistributions in binary form must reproduce the above copyright
102052 + * notice, this list of conditions and the following disclaimer in the
102053 + * documentation and/or other materials provided with the distribution.
102054 + * * Neither the name of Freescale Semiconductor nor the
102055 + * names of its contributors may be used to endorse or promote products
102056 + * derived from this software without specific prior written permission.
102057 + *
102058 + *
102059 + * ALTERNATIVELY, this software may be distributed under the terms of the
102060 + * GNU General Public License ("GPL") as published by the Free Software
102061 + * Foundation, either version 2 of that License or (at your option) any
102062 + * later version.
102063 + *
102064 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102065 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102066 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102067 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102068 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102069 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102070 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102071 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102072 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102073 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102074 + */
102075 +
102076 +/**************************************************************************//**
102077 +
102078 + @File part_ext.h
102079 +
102080 + @Description Definitions for the part (integration) module.
102081 +*//***************************************************************************/
102082 +
102083 +#ifndef __PART_EXT_H
102084 +#define __PART_EXT_H
102085 +
102086 +#include "std_ext.h"
102087 +#include "part_integration_ext.h"
102088 +
102089 +
102090 +#if !(defined(MPC8306) || \
102091 + defined(MPC8309) || \
102092 + defined(MPC834x) || \
102093 + defined(MPC836x) || \
102094 + defined(MPC832x) || \
102095 + defined(MPC837x) || \
102096 + defined(MPC8568) || \
102097 + defined(MPC8569) || \
102098 + defined(P1020) || \
102099 + defined(P1021) || \
102100 + defined(P1022) || \
102101 + defined(P1023) || \
102102 + defined(P2020) || \
102103 + defined(P2040) || \
102104 + defined(P3041) || \
102105 + defined(P4080) || \
102106 + defined(SC4080) || \
102107 + defined(P5020) || \
102108 + defined(MSC814x))
102109 +#error "unable to proceed without chip-definition"
102110 +#endif /* !(defined(MPC834x) || ... */
102111 +
102112 +
102113 +/**************************************************************************//*
102114 + @Description Part data structure - must be contained in any integration
102115 + data structure.
102116 +*//***************************************************************************/
102117 +typedef struct t_Part
102118 +{
102119 + uintptr_t (* f_GetModuleBase)(t_Handle h_Part, e_ModuleId moduleId);
102120 + /**< Returns the address of the module's memory map base. */
102121 + e_ModuleId (* f_GetModuleIdByBase)(t_Handle h_Part, uintptr_t baseAddress);
102122 + /**< Returns the module's ID according to its memory map base. */
102123 +} t_Part;
102124 +
102125 +
102126 +#endif /* __PART_EXT_H */
102127 --- /dev/null
102128 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/integrations/P3040_P4080_P5020/part_integration_ext.h
102129 @@ -0,0 +1,336 @@
102130 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102131 + * All rights reserved.
102132 + *
102133 + * Redistribution and use in source and binary forms, with or without
102134 + * modification, are permitted provided that the following conditions are met:
102135 + * * Redistributions of source code must retain the above copyright
102136 + * notice, this list of conditions and the following disclaimer.
102137 + * * Redistributions in binary form must reproduce the above copyright
102138 + * notice, this list of conditions and the following disclaimer in the
102139 + * documentation and/or other materials provided with the distribution.
102140 + * * Neither the name of Freescale Semiconductor nor the
102141 + * names of its contributors may be used to endorse or promote products
102142 + * derived from this software without specific prior written permission.
102143 + *
102144 + *
102145 + * ALTERNATIVELY, this software may be distributed under the terms of the
102146 + * GNU General Public License ("GPL") as published by the Free Software
102147 + * Foundation, either version 2 of that License or (at your option) any
102148 + * later version.
102149 + *
102150 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102151 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102152 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102153 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102154 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102155 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102156 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102157 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102158 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102159 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102160 + */
102161 +
102162 +/**************************************************************************//**
102163 + @File part_integration_ext.h
102164 +
102165 + @Description P3040/P4080/P5020 external definitions and structures.
102166 +*//***************************************************************************/
102167 +#ifndef __PART_INTEGRATION_EXT_H
102168 +#define __PART_INTEGRATION_EXT_H
102169 +
102170 +#include "std_ext.h"
102171 +#include "dpaa_integration_ext.h"
102172 +
102173 +
102174 +/**************************************************************************//**
102175 + @Group P3040/P4080/P5020_chip_id P5020 Application Programming Interface
102176 +
102177 + @Description P3040/P4080/P5020 Chip functions,definitions and enums.
102178 +
102179 + @{
102180 +*//***************************************************************************/
102181 +
102182 +#define CORE_E500MC
102183 +
102184 +#define INTG_MAX_NUM_OF_CORES 1
102185 +
102186 +
102187 +/**************************************************************************//**
102188 + @Description Module types.
102189 +*//***************************************************************************/
102190 +typedef enum e_ModuleId
102191 +{
102192 + e_MODULE_ID_DUART_1 = 0,
102193 + e_MODULE_ID_DUART_2,
102194 + e_MODULE_ID_DUART_3,
102195 + e_MODULE_ID_DUART_4,
102196 + e_MODULE_ID_LAW,
102197 + e_MODULE_ID_LBC,
102198 + e_MODULE_ID_PAMU,
102199 + e_MODULE_ID_QM, /**< Queue manager module */
102200 + e_MODULE_ID_BM, /**< Buffer manager module */
102201 + e_MODULE_ID_QM_CE_PORTAL_0,
102202 + e_MODULE_ID_QM_CI_PORTAL_0,
102203 + e_MODULE_ID_QM_CE_PORTAL_1,
102204 + e_MODULE_ID_QM_CI_PORTAL_1,
102205 + e_MODULE_ID_QM_CE_PORTAL_2,
102206 + e_MODULE_ID_QM_CI_PORTAL_2,
102207 + e_MODULE_ID_QM_CE_PORTAL_3,
102208 + e_MODULE_ID_QM_CI_PORTAL_3,
102209 + e_MODULE_ID_QM_CE_PORTAL_4,
102210 + e_MODULE_ID_QM_CI_PORTAL_4,
102211 + e_MODULE_ID_QM_CE_PORTAL_5,
102212 + e_MODULE_ID_QM_CI_PORTAL_5,
102213 + e_MODULE_ID_QM_CE_PORTAL_6,
102214 + e_MODULE_ID_QM_CI_PORTAL_6,
102215 + e_MODULE_ID_QM_CE_PORTAL_7,
102216 + e_MODULE_ID_QM_CI_PORTAL_7,
102217 + e_MODULE_ID_QM_CE_PORTAL_8,
102218 + e_MODULE_ID_QM_CI_PORTAL_8,
102219 + e_MODULE_ID_QM_CE_PORTAL_9,
102220 + e_MODULE_ID_QM_CI_PORTAL_9,
102221 + e_MODULE_ID_BM_CE_PORTAL_0,
102222 + e_MODULE_ID_BM_CI_PORTAL_0,
102223 + e_MODULE_ID_BM_CE_PORTAL_1,
102224 + e_MODULE_ID_BM_CI_PORTAL_1,
102225 + e_MODULE_ID_BM_CE_PORTAL_2,
102226 + e_MODULE_ID_BM_CI_PORTAL_2,
102227 + e_MODULE_ID_BM_CE_PORTAL_3,
102228 + e_MODULE_ID_BM_CI_PORTAL_3,
102229 + e_MODULE_ID_BM_CE_PORTAL_4,
102230 + e_MODULE_ID_BM_CI_PORTAL_4,
102231 + e_MODULE_ID_BM_CE_PORTAL_5,
102232 + e_MODULE_ID_BM_CI_PORTAL_5,
102233 + e_MODULE_ID_BM_CE_PORTAL_6,
102234 + e_MODULE_ID_BM_CI_PORTAL_6,
102235 + e_MODULE_ID_BM_CE_PORTAL_7,
102236 + e_MODULE_ID_BM_CI_PORTAL_7,
102237 + e_MODULE_ID_BM_CE_PORTAL_8,
102238 + e_MODULE_ID_BM_CI_PORTAL_8,
102239 + e_MODULE_ID_BM_CE_PORTAL_9,
102240 + e_MODULE_ID_BM_CI_PORTAL_9,
102241 + e_MODULE_ID_FM1, /**< Frame manager #1 module */
102242 + e_MODULE_ID_FM1_RTC, /**< FM Real-Time-Clock */
102243 + e_MODULE_ID_FM1_MURAM, /**< FM Multi-User-RAM */
102244 + e_MODULE_ID_FM1_BMI, /**< FM BMI block */
102245 + e_MODULE_ID_FM1_QMI, /**< FM QMI block */
102246 + e_MODULE_ID_FM1_PRS, /**< FM parser block */
102247 + e_MODULE_ID_FM1_PORT_HO0, /**< FM Host-command/offline-parsing port block */
102248 + e_MODULE_ID_FM1_PORT_HO1, /**< FM Host-command/offline-parsing port block */
102249 + e_MODULE_ID_FM1_PORT_HO2, /**< FM Host-command/offline-parsing port block */
102250 + e_MODULE_ID_FM1_PORT_HO3, /**< FM Host-command/offline-parsing port block */
102251 + e_MODULE_ID_FM1_PORT_HO4, /**< FM Host-command/offline-parsing port block */
102252 + e_MODULE_ID_FM1_PORT_HO5, /**< FM Host-command/offline-parsing port block */
102253 + e_MODULE_ID_FM1_PORT_HO6, /**< FM Host-command/offline-parsing port block */
102254 + e_MODULE_ID_FM1_PORT_1GRx0, /**< FM Rx 1G MAC port block */
102255 + e_MODULE_ID_FM1_PORT_1GRx1, /**< FM Rx 1G MAC port block */
102256 + e_MODULE_ID_FM1_PORT_1GRx2, /**< FM Rx 1G MAC port block */
102257 + e_MODULE_ID_FM1_PORT_1GRx3, /**< FM Rx 1G MAC port block */
102258 + e_MODULE_ID_FM1_PORT_1GRx4, /**< FM Rx 1G MAC port block */
102259 + e_MODULE_ID_FM1_PORT_10GRx0, /**< FM Rx 10G MAC port block */
102260 + e_MODULE_ID_FM1_PORT_1GTx0, /**< FM Tx 1G MAC port block */
102261 + e_MODULE_ID_FM1_PORT_1GTx1, /**< FM Tx 1G MAC port block */
102262 + e_MODULE_ID_FM1_PORT_1GTx2, /**< FM Tx 1G MAC port block */
102263 + e_MODULE_ID_FM1_PORT_1GTx3, /**< FM Tx 1G MAC port block */
102264 + e_MODULE_ID_FM1_PORT_1GTx4, /**< FM Tx 1G MAC port block */
102265 + e_MODULE_ID_FM1_PORT_10GTx0, /**< FM Tx 10G MAC port block */
102266 + e_MODULE_ID_FM1_PLCR, /**< FM Policer */
102267 + e_MODULE_ID_FM1_KG, /**< FM Keygen */
102268 + e_MODULE_ID_FM1_DMA, /**< FM DMA */
102269 + e_MODULE_ID_FM1_FPM, /**< FM FPM */
102270 + e_MODULE_ID_FM1_IRAM, /**< FM Instruction-RAM */
102271 + e_MODULE_ID_FM1_1GMDIO0, /**< FM 1G MDIO MAC 0*/
102272 + e_MODULE_ID_FM1_1GMDIO1, /**< FM 1G MDIO MAC 1*/
102273 + e_MODULE_ID_FM1_1GMDIO2, /**< FM 1G MDIO MAC 2*/
102274 + e_MODULE_ID_FM1_1GMDIO3, /**< FM 1G MDIO MAC 3*/
102275 + e_MODULE_ID_FM1_10GMDIO, /**< FM 10G MDIO */
102276 + e_MODULE_ID_FM1_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
102277 + e_MODULE_ID_FM1_1GMAC0, /**< FM 1G MAC #0 */
102278 + e_MODULE_ID_FM1_1GMAC1, /**< FM 1G MAC #1 */
102279 + e_MODULE_ID_FM1_1GMAC2, /**< FM 1G MAC #2 */
102280 + e_MODULE_ID_FM1_1GMAC3, /**< FM 1G MAC #3 */
102281 + e_MODULE_ID_FM1_10GMAC0, /**< FM 10G MAC #0 */
102282 +
102283 + e_MODULE_ID_FM2, /**< Frame manager #2 module */
102284 + e_MODULE_ID_FM2_RTC, /**< FM Real-Time-Clock */
102285 + e_MODULE_ID_FM2_MURAM, /**< FM Multi-User-RAM */
102286 + e_MODULE_ID_FM2_BMI, /**< FM BMI block */
102287 + e_MODULE_ID_FM2_QMI, /**< FM QMI block */
102288 + e_MODULE_ID_FM2_PRS, /**< FM parser block */
102289 + e_MODULE_ID_FM2_PORT_HO0, /**< FM Host-command/offline-parsing port block */
102290 + e_MODULE_ID_FM2_PORT_HO1, /**< FM Host-command/offline-parsing port block */
102291 + e_MODULE_ID_FM2_PORT_HO2, /**< FM Host-command/offline-parsing port block */
102292 + e_MODULE_ID_FM2_PORT_HO3, /**< FM Host-command/offline-parsing port block */
102293 + e_MODULE_ID_FM2_PORT_HO4, /**< FM Host-command/offline-parsing port block */
102294 + e_MODULE_ID_FM2_PORT_HO5, /**< FM Host-command/offline-parsing port block */
102295 + e_MODULE_ID_FM2_PORT_HO6, /**< FM Host-command/offline-parsing port block */
102296 + e_MODULE_ID_FM2_PORT_1GRx0, /**< FM Rx 1G MAC port block */
102297 + e_MODULE_ID_FM2_PORT_1GRx1, /**< FM Rx 1G MAC port block */
102298 + e_MODULE_ID_FM2_PORT_1GRx2, /**< FM Rx 1G MAC port block */
102299 + e_MODULE_ID_FM2_PORT_1GRx3, /**< FM Rx 1G MAC port block */
102300 + e_MODULE_ID_FM2_PORT_10GRx0, /**< FM Rx 10G MAC port block */
102301 + e_MODULE_ID_FM2_PORT_1GTx0, /**< FM Tx 1G MAC port block */
102302 + e_MODULE_ID_FM2_PORT_1GTx1, /**< FM Tx 1G MAC port block */
102303 + e_MODULE_ID_FM2_PORT_1GTx2, /**< FM Tx 1G MAC port block */
102304 + e_MODULE_ID_FM2_PORT_1GTx3, /**< FM Tx 1G MAC port block */
102305 + e_MODULE_ID_FM2_PORT_10GTx0, /**< FM Tx 10G MAC port block */
102306 + e_MODULE_ID_FM2_PLCR, /**< FM Policer */
102307 + e_MODULE_ID_FM2_KG, /**< FM Keygen */
102308 + e_MODULE_ID_FM2_DMA, /**< FM DMA */
102309 + e_MODULE_ID_FM2_FPM, /**< FM FPM */
102310 + e_MODULE_ID_FM2_IRAM, /**< FM Instruction-RAM */
102311 + e_MODULE_ID_FM2_1GMDIO0, /**< FM 1G MDIO MAC 0*/
102312 + e_MODULE_ID_FM2_1GMDIO1, /**< FM 1G MDIO MAC 1*/
102313 + e_MODULE_ID_FM2_1GMDIO2, /**< FM 1G MDIO MAC 2*/
102314 + e_MODULE_ID_FM2_1GMDIO3, /**< FM 1G MDIO MAC 3*/
102315 + e_MODULE_ID_FM2_10GMDIO, /**< FM 10G MDIO */
102316 + e_MODULE_ID_FM2_PRS_IRAM, /**< FM SW-parser Instruction-RAM */
102317 + e_MODULE_ID_FM2_1GMAC0, /**< FM 1G MAC #0 */
102318 + e_MODULE_ID_FM2_1GMAC1, /**< FM 1G MAC #1 */
102319 + e_MODULE_ID_FM2_1GMAC2, /**< FM 1G MAC #2 */
102320 + e_MODULE_ID_FM2_1GMAC3, /**< FM 1G MAC #3 */
102321 + e_MODULE_ID_FM2_10GMAC0, /**< FM 10G MAC #0 */
102322 +
102323 + e_MODULE_ID_SEC_GEN, /**< SEC 4.0 General registers */
102324 + e_MODULE_ID_SEC_QI, /**< SEC 4.0 QI registers */
102325 + e_MODULE_ID_SEC_JQ0, /**< SEC 4.0 JQ-0 registers */
102326 + e_MODULE_ID_SEC_JQ1, /**< SEC 4.0 JQ-1 registers */
102327 + e_MODULE_ID_SEC_JQ2, /**< SEC 4.0 JQ-2 registers */
102328 + e_MODULE_ID_SEC_JQ3, /**< SEC 4.0 JQ-3 registers */
102329 + e_MODULE_ID_SEC_RTIC, /**< SEC 4.0 RTIC registers */
102330 + e_MODULE_ID_SEC_DECO0_CCB0, /**< SEC 4.0 DECO-0/CCB-0 registers */
102331 + e_MODULE_ID_SEC_DECO1_CCB1, /**< SEC 4.0 DECO-1/CCB-1 registers */
102332 + e_MODULE_ID_SEC_DECO2_CCB2, /**< SEC 4.0 DECO-2/CCB-2 registers */
102333 + e_MODULE_ID_SEC_DECO3_CCB3, /**< SEC 4.0 DECO-3/CCB-3 registers */
102334 + e_MODULE_ID_SEC_DECO4_CCB4, /**< SEC 4.0 DECO-4/CCB-4 registers */
102335 +
102336 + e_MODULE_ID_MPIC, /**< MPIC */
102337 + e_MODULE_ID_GPIO, /**< GPIO */
102338 + e_MODULE_ID_SERDES, /**< SERDES */
102339 + e_MODULE_ID_CPC_1, /**< CoreNet-Platform-Cache 1 */
102340 + e_MODULE_ID_CPC_2, /**< CoreNet-Platform-Cache 2 */
102341 +
102342 + e_MODULE_ID_SRIO_PORTS, /**< RapidIO controller */
102343 + e_MODULE_ID_SRIO_MU, /**< RapidIO messaging unit module */
102344 +
102345 + e_MODULE_ID_DUMMY_LAST
102346 +} e_ModuleId;
102347 +
102348 +#define NUM_OF_MODULES e_MODULE_ID_DUMMY_LAST
102349 +
102350 +#if 0 /* using unified values */
102351 +/*****************************************************************************
102352 + INTEGRATION-SPECIFIC MODULE CODES
102353 +******************************************************************************/
102354 +#define MODULE_UNKNOWN 0x00000000
102355 +#define MODULE_MEM 0x00010000
102356 +#define MODULE_MM 0x00020000
102357 +#define MODULE_CORE 0x00030000
102358 +#define MODULE_CHIP 0x00040000
102359 +#define MODULE_PLTFRM 0x00050000
102360 +#define MODULE_PM 0x00060000
102361 +#define MODULE_MMU 0x00070000
102362 +#define MODULE_PIC 0x00080000
102363 +#define MODULE_CPC 0x00090000
102364 +#define MODULE_DUART 0x000a0000
102365 +#define MODULE_SERDES 0x000b0000
102366 +#define MODULE_PIO 0x000c0000
102367 +#define MODULE_QM 0x000d0000
102368 +#define MODULE_BM 0x000e0000
102369 +#define MODULE_SEC 0x000f0000
102370 +#define MODULE_LAW 0x00100000
102371 +#define MODULE_LBC 0x00110000
102372 +#define MODULE_PAMU 0x00120000
102373 +#define MODULE_FM 0x00130000
102374 +#define MODULE_FM_MURAM 0x00140000
102375 +#define MODULE_FM_PCD 0x00150000
102376 +#define MODULE_FM_RTC 0x00160000
102377 +#define MODULE_FM_MAC 0x00170000
102378 +#define MODULE_FM_PORT 0x00180000
102379 +#define MODULE_FM_SP 0x00190000
102380 +#define MODULE_DPA_PORT 0x001a0000
102381 +#define MODULE_MII 0x001b0000
102382 +#define MODULE_I2C 0x001c0000
102383 +#define MODULE_DMA 0x001d0000
102384 +#define MODULE_DDR 0x001e0000
102385 +#define MODULE_ESPI 0x001f0000
102386 +#define MODULE_DPAA_IPSEC 0x00200000
102387 +#endif /* using unified values */
102388 +
102389 +/*****************************************************************************
102390 + PAMU INTEGRATION-SPECIFIC DEFINITIONS
102391 +******************************************************************************/
102392 +#define PAMU_NUM_OF_PARTITIONS 5
102393 +
102394 +#define PAMU_PICS_AVICS_ERRATA_PAMU3
102395 +
102396 +/*****************************************************************************
102397 + LAW INTEGRATION-SPECIFIC DEFINITIONS
102398 +******************************************************************************/
102399 +#define LAW_NUM_OF_WINDOWS 32
102400 +#define LAW_MIN_WINDOW_SIZE 0x0000000000001000LL /**< 4KB */
102401 +#define LAW_MAX_WINDOW_SIZE 0x0000002000000000LL /**< 64GB */
102402 +
102403 +
102404 +/*****************************************************************************
102405 + LBC INTEGRATION-SPECIFIC DEFINITIONS
102406 +******************************************************************************/
102407 +/**************************************************************************//**
102408 + @Group lbc_exception_grp LBC Exception Unit
102409 +
102410 + @Description LBC Exception unit API functions, definitions and enums
102411 +
102412 + @{
102413 +*//***************************************************************************/
102414 +
102415 +/**************************************************************************//**
102416 + @Anchor lbc_exbm
102417 +
102418 + @Collection LBC Errors Bit Mask
102419 +
102420 + These errors are reported through the exceptions callback..
102421 + The values can be or'ed in any combination in the errors mask
102422 + parameter of the errors report structure.
102423 +
102424 + These errors can also be passed as a bit-mask to
102425 + LBC_EnableErrorChecking() or LBC_DisableErrorChecking(),
102426 + for enabling or disabling error checking.
102427 + @{
102428 +*//***************************************************************************/
102429 +#define LBC_ERR_BUS_MONITOR 0x80000000 /**< Bus monitor error */
102430 +#define LBC_ERR_PARITY_ECC 0x20000000 /**< Parity error for GPCM/UPM */
102431 +#define LBC_ERR_WRITE_PROTECT 0x04000000 /**< Write protection error */
102432 +#define LBC_ERR_ATOMIC_WRITE 0x00800000 /**< Atomic write error */
102433 +#define LBC_ERR_ATOMIC_READ 0x00400000 /**< Atomic read error */
102434 +#define LBC_ERR_CHIP_SELECT 0x00080000 /**< Unrecognized chip select */
102435 +
102436 +#define LBC_ERR_ALL (LBC_ERR_BUS_MONITOR | LBC_ERR_PARITY_ECC | \
102437 + LBC_ERR_WRITE_PROTECT | LBC_ERR_ATOMIC_WRITE | \
102438 + LBC_ERR_ATOMIC_READ | LBC_ERR_CHIP_SELECT)
102439 + /**< All possible errors */
102440 +/* @} */
102441 +/** @} */ /* end of lbc_exception_grp group */
102442 +
102443 +#define LBC_INCORRECT_ERROR_REPORT_ERRATA
102444 +
102445 +#define LBC_NUM_OF_BANKS 8
102446 +#define LBC_MAX_CS_SIZE 0x0000000100000000LL
102447 +#define LBC_ATOMIC_OPERATION_SUPPORT
102448 +#define LBC_PARITY_SUPPORT
102449 +#define LBC_ADDRESS_HOLD_TIME_CTRL
102450 +#define LBC_HIGH_CLK_DIVIDERS
102451 +#define LBC_FCM_AVAILABLE
102452 +
102453 +/*****************************************************************************
102454 + GPIO INTEGRATION-SPECIFIC DEFINITIONS
102455 +******************************************************************************/
102456 +#define GPIO_NUM_OF_PORTS 1 /**< Number of ports in GPIO module;
102457 + Each port contains up to 32 i/O pins. */
102458 +
102459 +#define GPIO_VALID_PIN_MASKS \
102460 + { /* Port A */ 0xFFFFFFFF }
102461 +
102462 +#define GPIO_VALID_INTR_MASKS \
102463 + { /* Port A */ 0xFFFFFFFF }
102464 +
102465 +#endif /* __PART_INTEGRATION_EXT_H */
102466 --- /dev/null
102467 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/math_ext.h
102468 @@ -0,0 +1,100 @@
102469 +/*
102470 + * Copyright 2008-2012 Freescale Semiconductor Inc.
102471 + *
102472 + * Redistribution and use in source and binary forms, with or without
102473 + * modification, are permitted provided that the following conditions are met:
102474 + * * Redistributions of source code must retain the above copyright
102475 + * notice, this list of conditions and the following disclaimer.
102476 + * * Redistributions in binary form must reproduce the above copyright
102477 + * notice, this list of conditions and the following disclaimer in the
102478 + * documentation and/or other materials provided with the distribution.
102479 + * * Neither the name of Freescale Semiconductor nor the
102480 + * names of its contributors may be used to endorse or promote products
102481 + * derived from this software without specific prior written permission.
102482 + *
102483 + *
102484 + * ALTERNATIVELY, this software may be distributed under the terms of the
102485 + * GNU General Public License ("GPL") as published by the Free Software
102486 + * Foundation, either version 2 of that License or (at your option) any
102487 + * later version.
102488 + *
102489 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102490 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102491 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102492 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102493 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102494 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102495 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102496 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102497 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102498 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102499 + */
102500 +
102501 +
102502 +#ifndef __MATH_EXT_H
102503 +#define __MATH_EXT_H
102504 +
102505 +
102506 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
102507 +#include <linux/math.h>
102508 +#include <linux/math64.h>
102509 +
102510 +#elif defined(__MWERKS__)
102511 +#define LOW(x) ( sizeof(x)==8 ? *(1+(int32_t*)&x) : (*(int32_t*)&x))
102512 +#define HIGH(x) (*(int32_t*)&x)
102513 +#define ULOW(x) ( sizeof(x)==8 ? *(1+(uint32_t*)&x) : (*(uint32_t*)&x))
102514 +#define UHIGH(x) (*(uint32_t*)&x)
102515 +
102516 +static const double big = 1.0e300;
102517 +
102518 +/* Macro for checking if a number is a power of 2 */
102519 +static __inline__ double ceil(double x)
102520 +{
102521 + int32_t i0,i1,j0; /*- cc 020130 -*/
102522 + uint32_t i,j; /*- cc 020130 -*/
102523 + i0 = HIGH(x);
102524 + i1 = LOW(x);
102525 + j0 = ((i0>>20)&0x7ff)-0x3ff;
102526 + if(j0<20) {
102527 + if(j0<0) { /* raise inexact if x != 0 */
102528 + if(big+x>0.0) {/* return 0*sign(x) if |x|<1 */
102529 + if(i0<0) {i0=0x80000000;i1=0;}
102530 + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
102531 + }
102532 + } else {
102533 + i = (uint32_t)(0x000fffff)>>j0;
102534 + if(((i0&i)|i1)==0) return x; /* x is integral */
102535 + if(big+x>0.0) { /* raise inexact flag */
102536 + if(i0>0) i0 += (0x00100000)>>j0;
102537 + i0 &= (~i); i1=0;
102538 + }
102539 + }
102540 + } else if (j0>51) {
102541 + if(j0==0x400) return x+x; /* inf or NaN */
102542 + else return x; /* x is integral */
102543 + } else {
102544 + i = ((uint32_t)(0xffffffff))>>(j0-20); /*- cc 020130 -*/
102545 + if((i1&i)==0) return x; /* x is integral */
102546 + if(big+x>0.0) { /* raise inexact flag */
102547 + if(i0>0) {
102548 + if(j0==20) i0+=1;
102549 + else {
102550 + j = (uint32_t)(i1 + (1<<(52-j0)));
102551 + if(j<i1) i0+=1; /* got a carry */
102552 + i1 = (int32_t)j;
102553 + }
102554 + }
102555 + i1 &= (~i);
102556 + }
102557 + }
102558 + HIGH(x) = i0;
102559 + LOW(x) = i1;
102560 + return x;
102561 +}
102562 +
102563 +#else
102564 +#include <math.h>
102565 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
102566 +
102567 +
102568 +#endif /* __MATH_EXT_H */
102569 --- /dev/null
102570 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/ncsw_ext.h
102571 @@ -0,0 +1,435 @@
102572 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
102573 + * All rights reserved.
102574 + *
102575 + * Redistribution and use in source and binary forms, with or without
102576 + * modification, are permitted provided that the following conditions are met:
102577 + * * Redistributions of source code must retain the above copyright
102578 + * notice, this list of conditions and the following disclaimer.
102579 + * * Redistributions in binary form must reproduce the above copyright
102580 + * notice, this list of conditions and the following disclaimer in the
102581 + * documentation and/or other materials provided with the distribution.
102582 + * * Neither the name of Freescale Semiconductor nor the
102583 + * names of its contributors may be used to endorse or promote products
102584 + * derived from this software without specific prior written permission.
102585 + *
102586 + *
102587 + * ALTERNATIVELY, this software may be distributed under the terms of the
102588 + * GNU General Public License ("GPL") as published by the Free Software
102589 + * Foundation, either version 2 of that License or (at your option) any
102590 + * later version.
102591 + *
102592 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
102593 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
102594 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
102595 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
102596 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
102597 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
102598 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
102599 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
102600 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
102601 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102602 + */
102603 +
102604 +
102605 +/**************************************************************************//**
102606 + @File ncsw_ext.h
102607 +
102608 + @Description General NetCommSw Standard Definitions
102609 +*//***************************************************************************/
102610 +
102611 +#ifndef __NCSW_EXT_H
102612 +#define __NCSW_EXT_H
102613 +
102614 +
102615 +#include "memcpy_ext.h"
102616 +
102617 +#define WRITE_BLOCK IOMemSet32 /* include memcpy_ext.h */
102618 +#define COPY_BLOCK Mem2IOCpy32 /* include memcpy_ext.h */
102619 +
102620 +#define PTR_TO_UINT(_ptr) ((uintptr_t)(_ptr))
102621 +#define UINT_TO_PTR(_val) ((void*)(uintptr_t)(_val))
102622 +
102623 +#define PTR_MOVE(_ptr, _offset) (void*)((uint8_t*)(_ptr) + (_offset))
102624 +
102625 +
102626 +#define WRITE_UINT8_UINT24(arg, data08, data24) \
102627 + WRITE_UINT32(arg,((uint32_t)(data08)<<24)|((uint32_t)(data24)&0x00FFFFFF))
102628 +#define WRITE_UINT24_UINT8(arg, data24, data08) \
102629 + WRITE_UINT32(arg,((uint32_t)(data24)<< 8)|((uint32_t)(data08)&0x000000FF))
102630 +
102631 +/* Little-Endian access macros */
102632 +
102633 +#define WRITE_UINT16_LE(arg, data) \
102634 + WRITE_UINT16((arg), SwapUint16(data))
102635 +
102636 +#define WRITE_UINT32_LE(arg, data) \
102637 + WRITE_UINT32((arg), SwapUint32(data))
102638 +
102639 +#define WRITE_UINT64_LE(arg, data) \
102640 + WRITE_UINT64((arg), SwapUint64(data))
102641 +
102642 +#define GET_UINT16_LE(arg) \
102643 + SwapUint16(GET_UINT16(arg))
102644 +
102645 +#define GET_UINT32_LE(arg) \
102646 + SwapUint32(GET_UINT32(arg))
102647 +
102648 +#define GET_UINT64_LE(arg) \
102649 + SwapUint64(GET_UINT64(arg))
102650 +
102651 +/* Write and Read again macros */
102652 +#define WRITE_UINT_SYNC(size, arg, data) \
102653 + do { \
102654 + WRITE_UINT##size((arg), (data)); \
102655 + CORE_MemoryBarrier(); \
102656 + } while (0)
102657 +
102658 +#define WRITE_UINT8_SYNC(arg, data) WRITE_UINT_SYNC(8, (arg), (data))
102659 +
102660 +#define WRITE_UINT16_SYNC(arg, data) WRITE_UINT_SYNC(16, (arg), (data))
102661 +#define WRITE_UINT32_SYNC(arg, data) WRITE_UINT_SYNC(32, (arg), (data))
102662 +
102663 +#define MAKE_UINT64(high32, low32) (((uint64_t)high32 << 32) | (low32))
102664 +
102665 +
102666 +/*----------------------*/
102667 +/* Miscellaneous macros */
102668 +/*----------------------*/
102669 +
102670 +#define UNUSED(_x) ((void)(_x))
102671 +
102672 +#define KILOBYTE 0x400UL /* 1024 */
102673 +#define MEGABYTE (KILOBYTE * KILOBYTE) /* 1024*1024 */
102674 +#define GIGABYTE ((uint64_t)(KILOBYTE * MEGABYTE)) /* 1024*1024*1024 */
102675 +#define TERABYTE ((uint64_t)(KILOBYTE * GIGABYTE)) /* 1024*1024*1024*1024 */
102676 +
102677 +#ifndef NO_IRQ
102678 +#define NO_IRQ (0)
102679 +#endif
102680 +#define NCSW_MASTER_ID (0)
102681 +
102682 +/* Macro for checking if a number is a power of 2 */
102683 +#define POWER_OF_2(n) (!((n) & ((n)-1)))
102684 +
102685 +/* Macro for calculating log of base 2 */
102686 +#define LOG2(num, log2Num) \
102687 + do \
102688 + { \
102689 + uint64_t tmp = (num); \
102690 + log2Num = 0; \
102691 + while (tmp > 1) \
102692 + { \
102693 + log2Num++; \
102694 + tmp >>= 1; \
102695 + } \
102696 + } while (0)
102697 +
102698 +#define NEXT_POWER_OF_2(_num, _nextPow) \
102699 +do \
102700 +{ \
102701 + if (POWER_OF_2(_num)) \
102702 + _nextPow = (_num); \
102703 + else \
102704 + { \
102705 + uint64_t tmp = (_num); \
102706 + _nextPow = 1; \
102707 + while (tmp) \
102708 + { \
102709 + _nextPow <<= 1; \
102710 + tmp >>= 1; \
102711 + } \
102712 + } \
102713 +} while (0)
102714 +
102715 +/* Ceiling division - not the fastest way, but safer in terms of overflow */
102716 +#define DIV_CEIL(x,y) (div64_u64((x),(y)) + (((div64_u64((x),(y))*(y)) == (x)) ? 0 : 1))
102717 +
102718 +/* Round up a number to be a multiple of a second number */
102719 +#define ROUND_UP(x,y) ((((x) + (y) - 1) / (y)) * (y))
102720 +
102721 +/* Timing macro for converting usec units to number of ticks. */
102722 +/* (number of usec * clock_Hz) / 1,000,000) - since */
102723 +/* clk is in MHz units, no division needed. */
102724 +#define USEC_TO_CLK(usec,clk) ((usec) * (clk))
102725 +#define CYCLES_TO_USEC(cycles,clk) ((cycles) / (clk))
102726 +
102727 +/* Timing macros for converting between nsec units and number of clocks. */
102728 +#define NSEC_TO_CLK(nsec,clk) DIV_CEIL(((nsec) * (clk)), 1000)
102729 +#define CYCLES_TO_NSEC(cycles,clk) (((cycles) * 1000) / (clk))
102730 +
102731 +/* Timing macros for converting between psec units and number of clocks. */
102732 +#define PSEC_TO_CLK(psec,clk) DIV_CEIL(((psec) * (clk)), 1000000)
102733 +#define CYCLES_TO_PSEC(cycles,clk) (((cycles) * 1000000) / (clk))
102734 +
102735 +/* Min, Max macros */
102736 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
102737 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
102738 +#define IN_RANGE(min,val,max) ((min)<=(val) && (val)<=(max))
102739 +
102740 +#define ABS(a) ((a<0)?(a*-1):a)
102741 +
102742 +#if !(defined(ARRAY_SIZE))
102743 +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
102744 +#endif /* !defined(ARRAY_SIZE) */
102745 +
102746 +
102747 +/* possible alignments */
102748 +#define HALF_WORD_ALIGNMENT 2
102749 +#define WORD_ALIGNMENT 4
102750 +#define DOUBLE_WORD_ALIGNMENT 8
102751 +#define BURST_ALIGNMENT 32
102752 +
102753 +#define HALF_WORD_ALIGNED 0x00000001
102754 +#define WORD_ALIGNED 0x00000003
102755 +#define DOUBLE_WORD_ALIGNED 0x00000007
102756 +#define BURST_ALIGNED 0x0000001f
102757 +#ifndef IS_ALIGNED
102758 +#define IS_ALIGNED(n,align) (!((uint32_t)(n) & (align - 1)))
102759 +#endif /* IS_ALIGNED */
102760 +
102761 +
102762 +#define LAST_BUF 1
102763 +#define FIRST_BUF 2
102764 +#define SINGLE_BUF (LAST_BUF | FIRST_BUF)
102765 +#define MIDDLE_BUF 4
102766 +
102767 +#define ARRAY_END -1
102768 +
102769 +#define ILLEGAL_BASE (~0)
102770 +
102771 +#define BUF_POSITION(first, last) state[(!!(last))<<1 | !!(first)]
102772 +#define DECLARE_POSITION static uint8_t state[4] = { (uint8_t)MIDDLE_BUF, (uint8_t)FIRST_BUF, (uint8_t)LAST_BUF, (uint8_t)SINGLE_BUF };
102773 +
102774 +
102775 +/**************************************************************************//**
102776 + @Description Timers operation mode
102777 +*//***************************************************************************/
102778 +typedef enum e_TimerMode
102779 +{
102780 + e_TIMER_MODE_INVALID = 0,
102781 + e_TIMER_MODE_FREE_RUN, /**< Free run - counter continues to increase
102782 + after reaching the reference value. */
102783 + e_TIMER_MODE_PERIODIC, /**< Periodic - counter restarts counting from 0
102784 + after reaching the reference value. */
102785 + e_TIMER_MODE_SINGLE /**< Single (one-shot) - counter stops counting
102786 + after reaching the reference value. */
102787 +} e_TimerMode;
102788 +
102789 +
102790 +/**************************************************************************//**
102791 + @Description Enumeration (bit flags) of communication modes (Transmit,
102792 + receive or both).
102793 +*//***************************************************************************/
102794 +typedef enum e_CommMode
102795 +{
102796 + e_COMM_MODE_NONE = 0, /**< No transmit/receive communication */
102797 + e_COMM_MODE_RX = 1, /**< Only receive communication */
102798 + e_COMM_MODE_TX = 2, /**< Only transmit communication */
102799 + e_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
102800 +} e_CommMode;
102801 +
102802 +/**************************************************************************//**
102803 + @Description General Diagnostic Mode
102804 +*//***************************************************************************/
102805 +typedef enum e_DiagMode
102806 +{
102807 + e_DIAG_MODE_NONE = 0, /**< Normal operation; no diagnostic mode */
102808 + e_DIAG_MODE_CTRL_LOOPBACK, /**< Loopback in the controller */
102809 + e_DIAG_MODE_CHIP_LOOPBACK, /**< Loopback in the chip but not in the
102810 + controller; e.g. IO-pins, SerDes, etc. */
102811 + e_DIAG_MODE_PHY_LOOPBACK, /**< Loopback in the external PHY */
102812 + e_DIAG_MODE_EXT_LOOPBACK, /**< Loopback in the external line (beyond the PHY) */
102813 + e_DIAG_MODE_CTRL_ECHO, /**< Echo incoming data by the controller */
102814 + e_DIAG_MODE_PHY_ECHO /**< Echo incoming data by the PHY */
102815 +} e_DiagMode;
102816 +
102817 +/**************************************************************************//**
102818 + @Description Possible RxStore callback responses.
102819 +*//***************************************************************************/
102820 +typedef enum e_RxStoreResponse
102821 +{
102822 + e_RX_STORE_RESPONSE_PAUSE /**< Pause invoking callback with received data;
102823 + in polling mode, start again invoking callback
102824 + only next time user invokes the receive routine;
102825 + in interrupt mode, start again invoking callback
102826 + only next time a receive event triggers an interrupt;
102827 + in all cases, received data that are pending are not
102828 + lost, rather, their processing is temporarily deferred;
102829 + in all cases, received data are processed in the order
102830 + in which they were received. */
102831 + , e_RX_STORE_RESPONSE_CONTINUE /**< Continue invoking callback with received data. */
102832 +} e_RxStoreResponse;
102833 +
102834 +
102835 +/**************************************************************************//**
102836 + @Description General Handle
102837 +*//***************************************************************************/
102838 +typedef void * t_Handle; /**< handle, used as object's descriptor */
102839 +
102840 +/**************************************************************************//**
102841 + @Description MUTEX type
102842 +*//***************************************************************************/
102843 +typedef uint32_t t_Mutex;
102844 +
102845 +/**************************************************************************//**
102846 + @Description Error Code.
102847 +
102848 + The high word of the error code is the code of the software
102849 + module (driver). The low word is the error type (e_ErrorType).
102850 + To get the values from the error code, use GET_ERROR_TYPE()
102851 + and GET_ERROR_MODULE().
102852 +*//***************************************************************************/
102853 +typedef uint32_t t_Error;
102854 +
102855 +/**************************************************************************//**
102856 + @Description General prototype of interrupt service routine (ISR).
102857 +
102858 + @Param[in] handle - Optional handle of the module handling the interrupt.
102859 +
102860 + @Return None
102861 + *//***************************************************************************/
102862 +typedef void (t_Isr)(t_Handle handle);
102863 +
102864 +/**************************************************************************//**
102865 + @Anchor mem_attr
102866 +
102867 + @Collection Memory Attributes
102868 +
102869 + Various attributes of memory partitions. These values may be
102870 + or'ed together to create a mask of all memory attributes.
102871 + @{
102872 +*//***************************************************************************/
102873 +#define MEMORY_ATTR_CACHEABLE 0x00000001
102874 + /**< Memory is cacheable */
102875 +#define MEMORY_ATTR_QE_2ND_BUS_ACCESS 0x00000002
102876 + /**< Memory can be accessed by QUICC Engine
102877 + through its secondary bus interface */
102878 +
102879 +/* @} */
102880 +
102881 +
102882 +/**************************************************************************//**
102883 + @Function t_GetBufFunction
102884 +
102885 + @Description User callback function called by driver to get data buffer.
102886 +
102887 + User provides this function. Driver invokes it.
102888 +
102889 + @Param[in] h_BufferPool - A handle to buffer pool manager
102890 + @Param[out] p_BufContextHandle - Returns the user's private context that
102891 + should be associated with the buffer
102892 +
102893 + @Return Pointer to data buffer, NULL if error
102894 + *//***************************************************************************/
102895 +typedef uint8_t * (t_GetBufFunction)(t_Handle h_BufferPool,
102896 + t_Handle *p_BufContextHandle);
102897 +
102898 +/**************************************************************************//**
102899 + @Function t_PutBufFunction
102900 +
102901 + @Description User callback function called by driver to return data buffer.
102902 +
102903 + User provides this function. Driver invokes it.
102904 +
102905 + @Param[in] h_BufferPool - A handle to buffer pool manager
102906 + @Param[in] p_Buffer - A pointer to buffer to return
102907 + @Param[in] h_BufContext - The user's private context associated with
102908 + the returned buffer
102909 +
102910 + @Return E_OK on success; Error code otherwise
102911 + *//***************************************************************************/
102912 +typedef t_Error (t_PutBufFunction)(t_Handle h_BufferPool,
102913 + uint8_t *p_Buffer,
102914 + t_Handle h_BufContext);
102915 +
102916 +/**************************************************************************//**
102917 + @Function t_PhysToVirt
102918 +
102919 + @Description Translates a physical address to the matching virtual address.
102920 +
102921 + @Param[in] addr - The physical address to translate.
102922 +
102923 + @Return Virtual address.
102924 +*//***************************************************************************/
102925 +typedef void * t_PhysToVirt(physAddress_t addr);
102926 +
102927 +/**************************************************************************//**
102928 + @Function t_VirtToPhys
102929 +
102930 + @Description Translates a virtual address to the matching physical address.
102931 +
102932 + @Param[in] addr - The virtual address to translate.
102933 +
102934 + @Return Physical address.
102935 +*//***************************************************************************/
102936 +typedef physAddress_t t_VirtToPhys(void *addr);
102937 +
102938 +/**************************************************************************//**
102939 + @Description Buffer Pool Information Structure.
102940 +*//***************************************************************************/
102941 +typedef struct t_BufferPoolInfo
102942 +{
102943 + t_Handle h_BufferPool; /**< A handle to the buffer pool manager */
102944 + t_GetBufFunction *f_GetBuf; /**< User callback to get a free buffer */
102945 + t_PutBufFunction *f_PutBuf; /**< User callback to return a buffer */
102946 + uint16_t bufferSize; /**< Buffer size (in bytes) */
102947 +
102948 + t_PhysToVirt *f_PhysToVirt; /**< User callback to translate pool buffers
102949 + physical addresses to virtual addresses */
102950 + t_VirtToPhys *f_VirtToPhys; /**< User callback to translate pool buffers
102951 + virtual addresses to physical addresses */
102952 +} t_BufferPoolInfo;
102953 +
102954 +
102955 +/**************************************************************************//**
102956 + @Description User callback function called by driver when transmit completed.
102957 +
102958 + User provides this function. Driver invokes it.
102959 +
102960 + @Param[in] h_App - Application's handle, as was provided to the
102961 + driver by the user
102962 + @Param[in] queueId - Transmit queue ID
102963 + @Param[in] p_Data - Pointer to the data buffer
102964 + @Param[in] h_BufContext - The user's private context associated with
102965 + the given data buffer
102966 + @Param[in] status - Transmit status and errors
102967 + @Param[in] flags - Driver-dependent information
102968 + *//***************************************************************************/
102969 +typedef void (t_TxConfFunction)(t_Handle h_App,
102970 + uint32_t queueId,
102971 + uint8_t *p_Data,
102972 + t_Handle h_BufContext,
102973 + uint16_t status,
102974 + uint32_t flags);
102975 +
102976 +/**************************************************************************//**
102977 + @Description User callback function called by driver with receive data.
102978 +
102979 + User provides this function. Driver invokes it.
102980 +
102981 + @Param[in] h_App - Application's handle, as was provided to the
102982 + driver by the user
102983 + @Param[in] queueId - Receive queue ID
102984 + @Param[in] p_Data - Pointer to the buffer with received data
102985 + @Param[in] h_BufContext - The user's private context associated with
102986 + the given data buffer
102987 + @Param[in] length - Length of received data
102988 + @Param[in] status - Receive status and errors
102989 + @Param[in] position - Position of buffer in frame
102990 + @Param[in] flags - Driver-dependent information
102991 +
102992 + @Retval e_RX_STORE_RESPONSE_CONTINUE - order the driver to continue Rx
102993 + operation for all ready data.
102994 + @Retval e_RX_STORE_RESPONSE_PAUSE - order the driver to stop Rx operation.
102995 + *//***************************************************************************/
102996 +typedef e_RxStoreResponse (t_RxStoreFunction)(t_Handle h_App,
102997 + uint32_t queueId,
102998 + uint8_t *p_Data,
102999 + t_Handle h_BufContext,
103000 + uint32_t length,
103001 + uint16_t status,
103002 + uint8_t position,
103003 + uint32_t flags);
103004 +
103005 +
103006 +#endif /* __NCSW_EXT_H */
103007 --- /dev/null
103008 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/net_ext.h
103009 @@ -0,0 +1,430 @@
103010 +/*
103011 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103012 + *
103013 + * Redistribution and use in source and binary forms, with or without
103014 + * modification, are permitted provided that the following conditions are met:
103015 + * * Redistributions of source code must retain the above copyright
103016 + * notice, this list of conditions and the following disclaimer.
103017 + * * Redistributions in binary form must reproduce the above copyright
103018 + * notice, this list of conditions and the following disclaimer in the
103019 + * documentation and/or other materials provided with the distribution.
103020 + * * Neither the name of Freescale Semiconductor nor the
103021 + * names of its contributors may be used to endorse or promote products
103022 + * derived from this software without specific prior written permission.
103023 + *
103024 + *
103025 + * ALTERNATIVELY, this software may be distributed under the terms of the
103026 + * GNU General Public License ("GPL") as published by the Free Software
103027 + * Foundation, either version 2 of that License or (at your option) any
103028 + * later version.
103029 + *
103030 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103031 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103032 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103033 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103034 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103035 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103036 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103037 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103038 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103039 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103040 + */
103041 +
103042 +
103043 +/**************************************************************************//**
103044 + @File net_ext.h
103045 +
103046 + @Description This file contains common and general netcomm headers definitions.
103047 +*//***************************************************************************/
103048 +#ifndef __NET_EXT_H
103049 +#define __NET_EXT_H
103050 +
103051 +#include "std_ext.h"
103052 +
103053 +
103054 +typedef uint8_t headerFieldPpp_t;
103055 +
103056 +#define NET_HEADER_FIELD_PPP_PID (1)
103057 +#define NET_HEADER_FIELD_PPP_COMPRESSED (NET_HEADER_FIELD_PPP_PID << 1)
103058 +#define NET_HEADER_FIELD_PPP_ALL_FIELDS ((NET_HEADER_FIELD_PPP_PID << 2) - 1)
103059 +
103060 +
103061 +typedef uint8_t headerFieldPppoe_t;
103062 +
103063 +#define NET_HEADER_FIELD_PPPoE_VER (1)
103064 +#define NET_HEADER_FIELD_PPPoE_TYPE (NET_HEADER_FIELD_PPPoE_VER << 1)
103065 +#define NET_HEADER_FIELD_PPPoE_CODE (NET_HEADER_FIELD_PPPoE_VER << 2)
103066 +#define NET_HEADER_FIELD_PPPoE_SID (NET_HEADER_FIELD_PPPoE_VER << 3)
103067 +#define NET_HEADER_FIELD_PPPoE_LEN (NET_HEADER_FIELD_PPPoE_VER << 4)
103068 +#define NET_HEADER_FIELD_PPPoE_SESSION (NET_HEADER_FIELD_PPPoE_VER << 5)
103069 +#define NET_HEADER_FIELD_PPPoE_PID (NET_HEADER_FIELD_PPPoE_VER << 6)
103070 +#define NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
103071 +
103072 +#define NET_HEADER_FIELD_PPPMUX_PID (1)
103073 +#define NET_HEADER_FIELD_PPPMUX_CKSUM (NET_HEADER_FIELD_PPPMUX_PID << 1)
103074 +#define NET_HEADER_FIELD_PPPMUX_COMPRESSED (NET_HEADER_FIELD_PPPMUX_PID << 2)
103075 +#define NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
103076 +
103077 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
103078 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
103079 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
103080 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
103081 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
103082 +#define NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
103083 +
103084 +
103085 +typedef uint8_t headerFieldEth_t;
103086 +
103087 +#define NET_HEADER_FIELD_ETH_DA (1)
103088 +#define NET_HEADER_FIELD_ETH_SA (NET_HEADER_FIELD_ETH_DA << 1)
103089 +#define NET_HEADER_FIELD_ETH_LENGTH (NET_HEADER_FIELD_ETH_DA << 2)
103090 +#define NET_HEADER_FIELD_ETH_TYPE (NET_HEADER_FIELD_ETH_DA << 3)
103091 +#define NET_HEADER_FIELD_ETH_FINAL_CKSUM (NET_HEADER_FIELD_ETH_DA << 4)
103092 +#define NET_HEADER_FIELD_ETH_PADDING (NET_HEADER_FIELD_ETH_DA << 5)
103093 +#define NET_HEADER_FIELD_ETH_ALL_FIELDS ((NET_HEADER_FIELD_ETH_DA << 6) - 1)
103094 +
103095 +#define NET_HEADER_FIELD_ETH_ADDR_SIZE 6
103096 +
103097 +typedef uint16_t headerFieldIp_t;
103098 +
103099 +#define NET_HEADER_FIELD_IP_VER (1)
103100 +#define NET_HEADER_FIELD_IP_DSCP (NET_HEADER_FIELD_IP_VER << 2)
103101 +#define NET_HEADER_FIELD_IP_ECN (NET_HEADER_FIELD_IP_VER << 3)
103102 +#define NET_HEADER_FIELD_IP_PROTO (NET_HEADER_FIELD_IP_VER << 4)
103103 +
103104 +#define NET_HEADER_FIELD_IP_PROTO_SIZE 1
103105 +
103106 +typedef uint16_t headerFieldIpv4_t;
103107 +
103108 +#define NET_HEADER_FIELD_IPv4_VER (1)
103109 +#define NET_HEADER_FIELD_IPv4_HDR_LEN (NET_HEADER_FIELD_IPv4_VER << 1)
103110 +#define NET_HEADER_FIELD_IPv4_TOS (NET_HEADER_FIELD_IPv4_VER << 2)
103111 +#define NET_HEADER_FIELD_IPv4_TOTAL_LEN (NET_HEADER_FIELD_IPv4_VER << 3)
103112 +#define NET_HEADER_FIELD_IPv4_ID (NET_HEADER_FIELD_IPv4_VER << 4)
103113 +#define NET_HEADER_FIELD_IPv4_FLAG_D (NET_HEADER_FIELD_IPv4_VER << 5)
103114 +#define NET_HEADER_FIELD_IPv4_FLAG_M (NET_HEADER_FIELD_IPv4_VER << 6)
103115 +#define NET_HEADER_FIELD_IPv4_OFFSET (NET_HEADER_FIELD_IPv4_VER << 7)
103116 +#define NET_HEADER_FIELD_IPv4_TTL (NET_HEADER_FIELD_IPv4_VER << 8)
103117 +#define NET_HEADER_FIELD_IPv4_PROTO (NET_HEADER_FIELD_IPv4_VER << 9)
103118 +#define NET_HEADER_FIELD_IPv4_CKSUM (NET_HEADER_FIELD_IPv4_VER << 10)
103119 +#define NET_HEADER_FIELD_IPv4_SRC_IP (NET_HEADER_FIELD_IPv4_VER << 11)
103120 +#define NET_HEADER_FIELD_IPv4_DST_IP (NET_HEADER_FIELD_IPv4_VER << 12)
103121 +#define NET_HEADER_FIELD_IPv4_OPTS (NET_HEADER_FIELD_IPv4_VER << 13)
103122 +#define NET_HEADER_FIELD_IPv4_OPTS_COUNT (NET_HEADER_FIELD_IPv4_VER << 14)
103123 +#define NET_HEADER_FIELD_IPv4_ALL_FIELDS ((NET_HEADER_FIELD_IPv4_VER << 15) - 1)
103124 +
103125 +#define NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
103126 +#define NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
103127 +
103128 +
103129 +typedef uint8_t headerFieldIpv6_t;
103130 +
103131 +#define NET_HEADER_FIELD_IPv6_VER (1)
103132 +#define NET_HEADER_FIELD_IPv6_TC (NET_HEADER_FIELD_IPv6_VER << 1)
103133 +#define NET_HEADER_FIELD_IPv6_SRC_IP (NET_HEADER_FIELD_IPv6_VER << 2)
103134 +#define NET_HEADER_FIELD_IPv6_DST_IP (NET_HEADER_FIELD_IPv6_VER << 3)
103135 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR (NET_HEADER_FIELD_IPv6_VER << 4)
103136 +#define NET_HEADER_FIELD_IPv6_FL (NET_HEADER_FIELD_IPv6_VER << 5)
103137 +#define NET_HEADER_FIELD_IPv6_HOP_LIMIT (NET_HEADER_FIELD_IPv6_VER << 6)
103138 +#define NET_HEADER_FIELD_IPv6_ALL_FIELDS ((NET_HEADER_FIELD_IPv6_VER << 7) - 1)
103139 +
103140 +#define NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
103141 +#define NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
103142 +
103143 +#define NET_HEADER_FIELD_ICMP_TYPE (1)
103144 +#define NET_HEADER_FIELD_ICMP_CODE (NET_HEADER_FIELD_ICMP_TYPE << 1)
103145 +#define NET_HEADER_FIELD_ICMP_CKSUM (NET_HEADER_FIELD_ICMP_TYPE << 2)
103146 +#define NET_HEADER_FIELD_ICMP_ID (NET_HEADER_FIELD_ICMP_TYPE << 3)
103147 +#define NET_HEADER_FIELD_ICMP_SQ_NUM (NET_HEADER_FIELD_ICMP_TYPE << 4)
103148 +#define NET_HEADER_FIELD_ICMP_ALL_FIELDS ((NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
103149 +
103150 +#define NET_HEADER_FIELD_ICMP_CODE_SIZE 1
103151 +#define NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
103152 +
103153 +#define NET_HEADER_FIELD_IGMP_VERSION (1)
103154 +#define NET_HEADER_FIELD_IGMP_TYPE (NET_HEADER_FIELD_IGMP_VERSION << 1)
103155 +#define NET_HEADER_FIELD_IGMP_CKSUM (NET_HEADER_FIELD_IGMP_VERSION << 2)
103156 +#define NET_HEADER_FIELD_IGMP_DATA (NET_HEADER_FIELD_IGMP_VERSION << 3)
103157 +#define NET_HEADER_FIELD_IGMP_ALL_FIELDS ((NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
103158 +
103159 +
103160 +typedef uint16_t headerFieldTcp_t;
103161 +
103162 +#define NET_HEADER_FIELD_TCP_PORT_SRC (1)
103163 +#define NET_HEADER_FIELD_TCP_PORT_DST (NET_HEADER_FIELD_TCP_PORT_SRC << 1)
103164 +#define NET_HEADER_FIELD_TCP_SEQ (NET_HEADER_FIELD_TCP_PORT_SRC << 2)
103165 +#define NET_HEADER_FIELD_TCP_ACK (NET_HEADER_FIELD_TCP_PORT_SRC << 3)
103166 +#define NET_HEADER_FIELD_TCP_OFFSET (NET_HEADER_FIELD_TCP_PORT_SRC << 4)
103167 +#define NET_HEADER_FIELD_TCP_FLAGS (NET_HEADER_FIELD_TCP_PORT_SRC << 5)
103168 +#define NET_HEADER_FIELD_TCP_WINDOW (NET_HEADER_FIELD_TCP_PORT_SRC << 6)
103169 +#define NET_HEADER_FIELD_TCP_CKSUM (NET_HEADER_FIELD_TCP_PORT_SRC << 7)
103170 +#define NET_HEADER_FIELD_TCP_URGPTR (NET_HEADER_FIELD_TCP_PORT_SRC << 8)
103171 +#define NET_HEADER_FIELD_TCP_OPTS (NET_HEADER_FIELD_TCP_PORT_SRC << 9)
103172 +#define NET_HEADER_FIELD_TCP_OPTS_COUNT (NET_HEADER_FIELD_TCP_PORT_SRC << 10)
103173 +#define NET_HEADER_FIELD_TCP_ALL_FIELDS ((NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
103174 +
103175 +#define NET_HEADER_FIELD_TCP_PORT_SIZE 2
103176 +
103177 +
103178 +typedef uint8_t headerFieldSctp_t;
103179 +
103180 +#define NET_HEADER_FIELD_SCTP_PORT_SRC (1)
103181 +#define NET_HEADER_FIELD_SCTP_PORT_DST (NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
103182 +#define NET_HEADER_FIELD_SCTP_VER_TAG (NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
103183 +#define NET_HEADER_FIELD_SCTP_CKSUM (NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
103184 +#define NET_HEADER_FIELD_SCTP_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
103185 +
103186 +#define NET_HEADER_FIELD_SCTP_PORT_SIZE 2
103187 +
103188 +typedef uint8_t headerFieldDccp_t;
103189 +
103190 +#define NET_HEADER_FIELD_DCCP_PORT_SRC (1)
103191 +#define NET_HEADER_FIELD_DCCP_PORT_DST (NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
103192 +#define NET_HEADER_FIELD_DCCP_ALL_FIELDS ((NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
103193 +
103194 +#define NET_HEADER_FIELD_DCCP_PORT_SIZE 2
103195 +
103196 +
103197 +typedef uint8_t headerFieldUdp_t;
103198 +
103199 +#define NET_HEADER_FIELD_UDP_PORT_SRC (1)
103200 +#define NET_HEADER_FIELD_UDP_PORT_DST (NET_HEADER_FIELD_UDP_PORT_SRC << 1)
103201 +#define NET_HEADER_FIELD_UDP_LEN (NET_HEADER_FIELD_UDP_PORT_SRC << 2)
103202 +#define NET_HEADER_FIELD_UDP_CKSUM (NET_HEADER_FIELD_UDP_PORT_SRC << 3)
103203 +#define NET_HEADER_FIELD_UDP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
103204 +
103205 +#define NET_HEADER_FIELD_UDP_PORT_SIZE 2
103206 +
103207 +typedef uint8_t headerFieldUdpLite_t;
103208 +
103209 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
103210 +#define NET_HEADER_FIELD_UDP_LITE_PORT_DST (NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
103211 +#define NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
103212 +
103213 +#define NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
103214 +
103215 +typedef uint8_t headerFieldUdpEncapEsp_t;
103216 +
103217 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
103218 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
103219 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
103220 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
103221 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
103222 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
103223 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
103224 +
103225 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
103226 +#define NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
103227 +
103228 +#define NET_HEADER_FIELD_IPHC_CID (1)
103229 +#define NET_HEADER_FIELD_IPHC_CID_TYPE (NET_HEADER_FIELD_IPHC_CID << 1)
103230 +#define NET_HEADER_FIELD_IPHC_HCINDEX (NET_HEADER_FIELD_IPHC_CID << 2)
103231 +#define NET_HEADER_FIELD_IPHC_GEN (NET_HEADER_FIELD_IPHC_CID << 3)
103232 +#define NET_HEADER_FIELD_IPHC_D_BIT (NET_HEADER_FIELD_IPHC_CID << 4)
103233 +#define NET_HEADER_FIELD_IPHC_ALL_FIELDS ((NET_HEADER_FIELD_IPHC_CID << 5) - 1)
103234 +
103235 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
103236 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
103237 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
103238 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
103239 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
103240 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
103241 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
103242 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
103243 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
103244 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
103245 +#define NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
103246 +
103247 +#define NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
103248 +#define NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
103249 +#define NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
103250 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
103251 +#define NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
103252 +#define NET_HEADER_FIELD_L2TPv2_VERSION (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
103253 +#define NET_HEADER_FIELD_L2TPv2_LEN (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
103254 +#define NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
103255 +#define NET_HEADER_FIELD_L2TPv2_SESSION_ID (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
103256 +#define NET_HEADER_FIELD_L2TPv2_NS (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
103257 +#define NET_HEADER_FIELD_L2TPv2_NR (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
103258 +#define NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
103259 +#define NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
103260 +#define NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
103261 +
103262 +#define NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
103263 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
103264 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
103265 +#define NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
103266 +#define NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
103267 +#define NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
103268 +#define NET_HEADER_FIELD_L2TPv3_CTRL_SENT (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
103269 +#define NET_HEADER_FIELD_L2TPv3_CTRL_RECV (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
103270 +#define NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
103271 +#define NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
103272 +
103273 +#define NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
103274 +#define NET_HEADER_FIELD_L2TPv3_SESS_VERSION (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
103275 +#define NET_HEADER_FIELD_L2TPv3_SESS_ID (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
103276 +#define NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
103277 +#define NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
103278 +
103279 +
103280 +typedef uint8_t headerFieldVlan_t;
103281 +
103282 +#define NET_HEADER_FIELD_VLAN_VPRI (1)
103283 +#define NET_HEADER_FIELD_VLAN_CFI (NET_HEADER_FIELD_VLAN_VPRI << 1)
103284 +#define NET_HEADER_FIELD_VLAN_VID (NET_HEADER_FIELD_VLAN_VPRI << 2)
103285 +#define NET_HEADER_FIELD_VLAN_LENGTH (NET_HEADER_FIELD_VLAN_VPRI << 3)
103286 +#define NET_HEADER_FIELD_VLAN_TYPE (NET_HEADER_FIELD_VLAN_VPRI << 4)
103287 +#define NET_HEADER_FIELD_VLAN_ALL_FIELDS ((NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
103288 +
103289 +#define NET_HEADER_FIELD_VLAN_TCI (NET_HEADER_FIELD_VLAN_VPRI | \
103290 + NET_HEADER_FIELD_VLAN_CFI | \
103291 + NET_HEADER_FIELD_VLAN_VID)
103292 +
103293 +
103294 +typedef uint8_t headerFieldLlc_t;
103295 +
103296 +#define NET_HEADER_FIELD_LLC_DSAP (1)
103297 +#define NET_HEADER_FIELD_LLC_SSAP (NET_HEADER_FIELD_LLC_DSAP << 1)
103298 +#define NET_HEADER_FIELD_LLC_CTRL (NET_HEADER_FIELD_LLC_DSAP << 2)
103299 +#define NET_HEADER_FIELD_LLC_ALL_FIELDS ((NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
103300 +
103301 +#define NET_HEADER_FIELD_NLPID_NLPID (1)
103302 +#define NET_HEADER_FIELD_NLPID_ALL_FIELDS ((NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
103303 +
103304 +
103305 +typedef uint8_t headerFieldSnap_t;
103306 +
103307 +#define NET_HEADER_FIELD_SNAP_OUI (1)
103308 +#define NET_HEADER_FIELD_SNAP_PID (NET_HEADER_FIELD_SNAP_OUI << 1)
103309 +#define NET_HEADER_FIELD_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
103310 +
103311 +
103312 +typedef uint8_t headerFieldLlcSnap_t;
103313 +
103314 +#define NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
103315 +#define NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
103316 +
103317 +#define NET_HEADER_FIELD_ARP_HTYPE (1)
103318 +#define NET_HEADER_FIELD_ARP_PTYPE (NET_HEADER_FIELD_ARP_HTYPE << 1)
103319 +#define NET_HEADER_FIELD_ARP_HLEN (NET_HEADER_FIELD_ARP_HTYPE << 2)
103320 +#define NET_HEADER_FIELD_ARP_PLEN (NET_HEADER_FIELD_ARP_HTYPE << 3)
103321 +#define NET_HEADER_FIELD_ARP_OPER (NET_HEADER_FIELD_ARP_HTYPE << 4)
103322 +#define NET_HEADER_FIELD_ARP_SHA (NET_HEADER_FIELD_ARP_HTYPE << 5)
103323 +#define NET_HEADER_FIELD_ARP_SPA (NET_HEADER_FIELD_ARP_HTYPE << 6)
103324 +#define NET_HEADER_FIELD_ARP_THA (NET_HEADER_FIELD_ARP_HTYPE << 7)
103325 +#define NET_HEADER_FIELD_ARP_TPA (NET_HEADER_FIELD_ARP_HTYPE << 8)
103326 +#define NET_HEADER_FIELD_ARP_ALL_FIELDS ((NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
103327 +
103328 +#define NET_HEADER_FIELD_RFC2684_LLC (1)
103329 +#define NET_HEADER_FIELD_RFC2684_NLPID (NET_HEADER_FIELD_RFC2684_LLC << 1)
103330 +#define NET_HEADER_FIELD_RFC2684_OUI (NET_HEADER_FIELD_RFC2684_LLC << 2)
103331 +#define NET_HEADER_FIELD_RFC2684_PID (NET_HEADER_FIELD_RFC2684_LLC << 3)
103332 +#define NET_HEADER_FIELD_RFC2684_VPN_OUI (NET_HEADER_FIELD_RFC2684_LLC << 4)
103333 +#define NET_HEADER_FIELD_RFC2684_VPN_IDX (NET_HEADER_FIELD_RFC2684_LLC << 5)
103334 +#define NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
103335 +
103336 +#define NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
103337 +#define NET_HEADER_FIELD_USER_DEFINED_PCDID (NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
103338 +#define NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
103339 +
103340 +#define NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
103341 +#define NET_HEADER_FIELD_PAYLOAD_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
103342 +#define NET_HEADER_FIELD_MAX_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
103343 +#define NET_HEADER_FIELD_MIN_FRM_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
103344 +#define NET_HEADER_FIELD_PAYLOAD_TYPE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
103345 +#define NET_HEADER_FIELD_FRAME_SIZE (NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
103346 +#define NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
103347 +
103348 +
103349 +typedef uint8_t headerFieldGre_t;
103350 +
103351 +#define NET_HEADER_FIELD_GRE_TYPE (1)
103352 +#define NET_HEADER_FIELD_GRE_ALL_FIELDS ((NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
103353 +
103354 +
103355 +typedef uint8_t headerFieldMinencap_t;
103356 +
103357 +#define NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
103358 +#define NET_HEADER_FIELD_MINENCAP_DST_IP (NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
103359 +#define NET_HEADER_FIELD_MINENCAP_TYPE (NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
103360 +#define NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
103361 +
103362 +
103363 +typedef uint8_t headerFieldIpsecAh_t;
103364 +
103365 +#define NET_HEADER_FIELD_IPSEC_AH_SPI (1)
103366 +#define NET_HEADER_FIELD_IPSEC_AH_NH (NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
103367 +#define NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
103368 +
103369 +
103370 +typedef uint8_t headerFieldIpsecEsp_t;
103371 +
103372 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
103373 +#define NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
103374 +#define NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
103375 +
103376 +#define NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
103377 +
103378 +
103379 +typedef uint8_t headerFieldMpls_t;
103380 +
103381 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
103382 +#define NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
103383 +
103384 +
103385 +typedef uint8_t headerFieldMacsec_t;
103386 +
103387 +#define NET_HEADER_FIELD_MACSEC_SECTAG (1)
103388 +#define NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
103389 +
103390 +
103391 +typedef enum {
103392 + HEADER_TYPE_NONE = 0,
103393 + HEADER_TYPE_PAYLOAD,
103394 + HEADER_TYPE_ETH,
103395 + HEADER_TYPE_VLAN,
103396 + HEADER_TYPE_IPv4,
103397 + HEADER_TYPE_IPv6,
103398 + HEADER_TYPE_IP,
103399 + HEADER_TYPE_TCP,
103400 + HEADER_TYPE_UDP,
103401 + HEADER_TYPE_UDP_LITE,
103402 + HEADER_TYPE_IPHC,
103403 + HEADER_TYPE_SCTP,
103404 + HEADER_TYPE_SCTP_CHUNK_DATA,
103405 + HEADER_TYPE_PPPoE,
103406 + HEADER_TYPE_PPP,
103407 + HEADER_TYPE_PPPMUX,
103408 + HEADER_TYPE_PPPMUX_SUBFRAME,
103409 + HEADER_TYPE_L2TPv2,
103410 + HEADER_TYPE_L2TPv3_CTRL,
103411 + HEADER_TYPE_L2TPv3_SESS,
103412 + HEADER_TYPE_LLC,
103413 + HEADER_TYPE_LLC_SNAP,
103414 + HEADER_TYPE_NLPID,
103415 + HEADER_TYPE_SNAP,
103416 + HEADER_TYPE_MPLS,
103417 + HEADER_TYPE_IPSEC_AH,
103418 + HEADER_TYPE_IPSEC_ESP,
103419 + HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
103420 + HEADER_TYPE_MACSEC,
103421 + HEADER_TYPE_GRE,
103422 + HEADER_TYPE_MINENCAP,
103423 + HEADER_TYPE_DCCP,
103424 + HEADER_TYPE_ICMP,
103425 + HEADER_TYPE_IGMP,
103426 + HEADER_TYPE_ARP,
103427 + HEADER_TYPE_CAPWAP,
103428 + HEADER_TYPE_CAPWAP_DTLS,
103429 + HEADER_TYPE_RFC2684,
103430 + HEADER_TYPE_USER_DEFINED_L2,
103431 + HEADER_TYPE_USER_DEFINED_L3,
103432 + HEADER_TYPE_USER_DEFINED_L4,
103433 + HEADER_TYPE_USER_DEFINED_SHIM1,
103434 + HEADER_TYPE_USER_DEFINED_SHIM2,
103435 + MAX_HEADER_TYPE_COUNT
103436 +} e_NetHeaderType;
103437 +
103438 +
103439 +#endif /* __NET_EXT_H */
103440 --- /dev/null
103441 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/std_ext.h
103442 @@ -0,0 +1,48 @@
103443 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
103444 + * All rights reserved.
103445 + *
103446 + * Redistribution and use in source and binary forms, with or without
103447 + * modification, are permitted provided that the following conditions are met:
103448 + * * Redistributions of source code must retain the above copyright
103449 + * notice, this list of conditions and the following disclaimer.
103450 + * * Redistributions in binary form must reproduce the above copyright
103451 + * notice, this list of conditions and the following disclaimer in the
103452 + * documentation and/or other materials provided with the distribution.
103453 + * * Neither the name of Freescale Semiconductor nor the
103454 + * names of its contributors may be used to endorse or promote products
103455 + * derived from this software without specific prior written permission.
103456 + *
103457 + *
103458 + * ALTERNATIVELY, this software may be distributed under the terms of the
103459 + * GNU General Public License ("GPL") as published by the Free Software
103460 + * Foundation, either version 2 of that License or (at your option) any
103461 + * later version.
103462 + *
103463 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103464 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103465 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103466 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103467 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103468 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103469 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103470 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103471 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103472 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103473 + */
103474 +
103475 +
103476 +/**************************************************************************//**
103477 + @File std_ext.h
103478 +
103479 + @Description General Standard Definitions
103480 +*//***************************************************************************/
103481 +
103482 +#ifndef __STD_EXT_H
103483 +#define __STD_EXT_H
103484 +
103485 +
103486 +#include "types_ext.h"
103487 +#include "ncsw_ext.h"
103488 +
103489 +
103490 +#endif /* __STD_EXT_H */
103491 --- /dev/null
103492 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdarg_ext.h
103493 @@ -0,0 +1,49 @@
103494 +/*
103495 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103496 + *
103497 + * Redistribution and use in source and binary forms, with or without
103498 + * modification, are permitted provided that the following conditions are met:
103499 + * * Redistributions of source code must retain the above copyright
103500 + * notice, this list of conditions and the following disclaimer.
103501 + * * Redistributions in binary form must reproduce the above copyright
103502 + * notice, this list of conditions and the following disclaimer in the
103503 + * documentation and/or other materials provided with the distribution.
103504 + * * Neither the name of Freescale Semiconductor nor the
103505 + * names of its contributors may be used to endorse or promote products
103506 + * derived from this software without specific prior written permission.
103507 + *
103508 + *
103509 + * ALTERNATIVELY, this software may be distributed under the terms of the
103510 + * GNU General Public License ("GPL") as published by the Free Software
103511 + * Foundation, either version 2 of that License or (at your option) any
103512 + * later version.
103513 + *
103514 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103515 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103516 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103517 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103518 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103519 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103520 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103521 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103522 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103523 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103524 + */
103525 +
103526 +
103527 +#ifndef __STDARG_EXT_H
103528 +#define __STDARG_EXT_H
103529 +
103530 +
103531 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
103532 +#include <stdarg.h>
103533 +
103534 +#else
103535 +#include <stdarg.h>
103536 +
103537 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
103538 +
103539 +#include "std_ext.h"
103540 +
103541 +
103542 +#endif /* __STDARG_EXT_H */
103543 --- /dev/null
103544 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/stdlib_ext.h
103545 @@ -0,0 +1,162 @@
103546 +/*
103547 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103548 + *
103549 + * Redistribution and use in source and binary forms, with or without
103550 + * modification, are permitted provided that the following conditions are met:
103551 + * * Redistributions of source code must retain the above copyright
103552 + * notice, this list of conditions and the following disclaimer.
103553 + * * Redistributions in binary form must reproduce the above copyright
103554 + * notice, this list of conditions and the following disclaimer in the
103555 + * documentation and/or other materials provided with the distribution.
103556 + * * Neither the name of Freescale Semiconductor nor the
103557 + * names of its contributors may be used to endorse or promote products
103558 + * derived from this software without specific prior written permission.
103559 + *
103560 + *
103561 + * ALTERNATIVELY, this software may be distributed under the terms of the
103562 + * GNU General Public License ("GPL") as published by the Free Software
103563 + * Foundation, either version 2 of that License or (at your option) any
103564 + * later version.
103565 + *
103566 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103567 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103568 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103569 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103570 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103571 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103572 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103573 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103574 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103575 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103576 + */
103577 +
103578 +
103579 +
103580 +#ifndef __STDLIB_EXT_H
103581 +#define __STDLIB_EXT_H
103582 +
103583 +
103584 +#if (defined(NCSW_LINUX)) && defined(__KERNEL__)
103585 +#include "stdarg_ext.h"
103586 +#include "std_ext.h"
103587 +
103588 +
103589 +/**
103590 + * strtoul - convert a string to an uint32_t
103591 + * @cp: The start of the string
103592 + * @endp: A pointer to the end of the parsed string will be placed here
103593 + * @base: The number base to use
103594 + */
103595 +uint32_t strtoul(const char *cp,char **endp,uint32_t base);
103596 +
103597 +/**
103598 + * strtol - convert a string to a int32_t
103599 + * @cp: The start of the string
103600 + * @endp: A pointer to the end of the parsed string will be placed here
103601 + * @base: The number base to use
103602 + */
103603 +long strtol(const char *cp,char **endp,uint32_t base);
103604 +
103605 +/**
103606 + * strtoull - convert a string to an uint64_t
103607 + * @cp: The start of the string
103608 + * @endp: A pointer to the end of the parsed string will be placed here
103609 + * @base: The number base to use
103610 + */
103611 +uint64_t strtoull(const char *cp,char **endp,uint32_t base);
103612 +
103613 +/**
103614 + * strtoll - convert a string to a int64 long
103615 + * @cp: The start of the string
103616 + * @endp: A pointer to the end of the parsed string will be placed here
103617 + * @base: The number base to use
103618 + */
103619 +long long strtoll(const char *cp,char **endp,uint32_t base);
103620 +
103621 +/**
103622 + * atoi - convert a character to a int
103623 + * @s: The start of the string
103624 + */
103625 +int atoi(const char *s);
103626 +
103627 +/**
103628 + * strnlen - Find the length of a length-limited string
103629 + * @s: The string to be sized
103630 + * @count: The maximum number of bytes to search
103631 + */
103632 +size_t strnlen(const char * s, size_t count);
103633 +
103634 +/**
103635 + * strlen - Find the length of a string
103636 + * @s: The string to be sized
103637 + */
103638 +size_t strlen(const char * s);
103639 +
103640 +/**
103641 + * strtok - Split a string into tokens
103642 + * @s: The string to be searched
103643 + * @ct: The characters to search for
103644 + *
103645 + * WARNING: strtok is deprecated, use strsep instead.
103646 + */
103647 +char * strtok(char * s,const char * ct);
103648 +
103649 +/**
103650 + * strncpy - Copy a length-limited, %NUL-terminated string
103651 + * @dest: Where to copy the string to
103652 + * @src: Where to copy the string from
103653 + * @count: The maximum number of bytes to copy
103654 + *
103655 + * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
103656 + * However, the result is not %NUL-terminated if the source exceeds
103657 + * @count bytes.
103658 + */
103659 +char * strncpy(char * dest,const char *src,size_t count);
103660 +
103661 +/**
103662 + * strcpy - Copy a %NUL terminated string
103663 + * @dest: Where to copy the string to
103664 + * @src: Where to copy the string from
103665 + */
103666 +char * strcpy(char * dest,const char *src);
103667 +
103668 +/**
103669 + * vsscanf - Unformat a buffer into a list of arguments
103670 + * @buf: input buffer
103671 + * @fmt: format of buffer
103672 + * @args: arguments
103673 + */
103674 +int vsscanf(const char * buf, const char * fmt, va_list args);
103675 +
103676 +/**
103677 + * vsnprintf - Format a string and place it in a buffer
103678 + * @buf: The buffer to place the result into
103679 + * @size: The size of the buffer, including the trailing null space
103680 + * @fmt: The format string to use
103681 + * @args: Arguments for the format string
103682 + *
103683 + * Call this function if you are already dealing with a va_list.
103684 + * You probably want snprintf instead.
103685 + */
103686 +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
103687 +
103688 +/**
103689 + * vsprintf - Format a string and place it in a buffer
103690 + * @buf: The buffer to place the result into
103691 + * @fmt: The format string to use
103692 + * @args: Arguments for the format string
103693 + *
103694 + * Call this function if you are already dealing with a va_list.
103695 + * You probably want sprintf instead.
103696 + */
103697 +int vsprintf(char *buf, const char *fmt, va_list args);
103698 +
103699 +#else
103700 +#include <stdlib.h>
103701 +#include <stdio.h>
103702 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
103703 +
103704 +#include "std_ext.h"
103705 +
103706 +
103707 +#endif /* __STDLIB_EXT_H */
103708 --- /dev/null
103709 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/string_ext.h
103710 @@ -0,0 +1,56 @@
103711 +/*
103712 + * Copyright 2008-2012 Freescale Semiconductor Inc.
103713 + *
103714 + * Redistribution and use in source and binary forms, with or without
103715 + * modification, are permitted provided that the following conditions are met:
103716 + * * Redistributions of source code must retain the above copyright
103717 + * notice, this list of conditions and the following disclaimer.
103718 + * * Redistributions in binary form must reproduce the above copyright
103719 + * notice, this list of conditions and the following disclaimer in the
103720 + * documentation and/or other materials provided with the distribution.
103721 + * * Neither the name of Freescale Semiconductor nor the
103722 + * names of its contributors may be used to endorse or promote products
103723 + * derived from this software without specific prior written permission.
103724 + *
103725 + *
103726 + * ALTERNATIVELY, this software may be distributed under the terms of the
103727 + * GNU General Public License ("GPL") as published by the Free Software
103728 + * Foundation, either version 2 of that License or (at your option) any
103729 + * later version.
103730 + *
103731 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103732 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103733 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103734 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103735 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103736 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103737 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103738 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103739 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103740 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103741 + */
103742 +
103743 +
103744 +#ifndef __STRING_EXT_H
103745 +#define __STRING_EXT_H
103746 +
103747 +
103748 +#if defined(NCSW_LINUX) && defined(__KERNEL__)
103749 +#include <linux/kernel.h>
103750 +#include <linux/string.h>
103751 +extern char * strtok ( char * str, const char * delimiters );
103752 +
103753 +#elif defined(__KERNEL__)
103754 +#include "linux/types.h"
103755 +#include "linux/posix_types.h"
103756 +#include "linux/string.h"
103757 +
103758 +#else
103759 +#include <string.h>
103760 +
103761 +#endif /* defined(NCSW_LINUX) && defined(__KERNEL__) */
103762 +
103763 +#include "std_ext.h"
103764 +
103765 +
103766 +#endif /* __STRING_EXT_H */
103767 --- /dev/null
103768 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/types_ext.h
103769 @@ -0,0 +1,62 @@
103770 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
103771 + * All rights reserved.
103772 + *
103773 + * Redistribution and use in source and binary forms, with or without
103774 + * modification, are permitted provided that the following conditions are met:
103775 + * * Redistributions of source code must retain the above copyright
103776 + * notice, this list of conditions and the following disclaimer.
103777 + * * Redistributions in binary form must reproduce the above copyright
103778 + * notice, this list of conditions and the following disclaimer in the
103779 + * documentation and/or other materials provided with the distribution.
103780 + * * Neither the name of Freescale Semiconductor nor the
103781 + * names of its contributors may be used to endorse or promote products
103782 + * derived from this software without specific prior written permission.
103783 + *
103784 + *
103785 + * ALTERNATIVELY, this software may be distributed under the terms of the
103786 + * GNU General Public License ("GPL") as published by the Free Software
103787 + * Foundation, either version 2 of that License or (at your option) any
103788 + * later version.
103789 + *
103790 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103791 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103792 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103793 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103794 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103795 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103796 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103797 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103798 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103799 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103800 + */
103801 +
103802 +
103803 +/**************************************************************************//**
103804 + @File types_ext.h
103805 +
103806 + @Description General types Standard Definitions
103807 +*//***************************************************************************/
103808 +
103809 +#ifndef __TYPES_EXT_H
103810 +#define __TYPES_EXT_H
103811 +
103812 +#if defined(NCSW_LINUX)
103813 +#include "types_linux.h"
103814 +
103815 +#elif defined(NCSW_VXWORKS)
103816 +#include "types_vxworks.h"
103817 +
103818 +#elif defined(__GNUC__) && defined(__cplusplus)
103819 +#include "types_bb_gpp.h"
103820 +
103821 +#elif defined(__GNUC__)
103822 +#include "types_bb_gcc.h"
103823 +
103824 +#elif defined(__ghs__)
103825 +#include "types_ghs.h"
103826 +
103827 +#else
103828 +#include "types_dflt.h"
103829 +#endif /* defined (__ROCOO__) */
103830 +
103831 +#endif /* __TYPES_EXT_H */
103832 --- /dev/null
103833 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_common.h
103834 @@ -0,0 +1,56 @@
103835 +/*
103836 + * Copyright 2012 Freescale Semiconductor Inc.
103837 + *
103838 + * Redistribution and use in source and binary forms, with or without
103839 + * modification, are permitted provided that the following conditions are met:
103840 + * * Redistributions of source code must retain the above copyright
103841 + * notice, this list of conditions and the following disclaimer.
103842 + * * Redistributions in binary form must reproduce the above copyright
103843 + * notice, this list of conditions and the following disclaimer in the
103844 + * documentation and/or other materials provided with the distribution.
103845 + * * Neither the name of Freescale Semiconductor nor the
103846 + * names of its contributors may be used to endorse or promote products
103847 + * derived from this software without specific prior written permission.
103848 + *
103849 + *
103850 + * ALTERNATIVELY, this software may be distributed under the terms of the
103851 + * GNU General Public License ("GPL") as published by the Free Software
103852 + * Foundation, either version 2 of that License or (at your option) any
103853 + * later version.
103854 + *
103855 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103856 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103857 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103858 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103859 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103860 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103861 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103862 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103863 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103864 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103865 + */
103866 +
103867 +
103868 +/**************************************************************************//**
103869 + @File debug_ext.h
103870 +
103871 + @Description Debug mode definitions.
103872 +*//***************************************************************************/
103873 +
103874 +#ifndef __XX_COMMON_H
103875 +#define __XX_COMMON_H
103876 +
103877 +/*****************************************************************************
103878 + * UNIFIED MODULE CODES
103879 + *****************************************************************************/
103880 +#define MODULE_UNKNOWN 0x00000000
103881 +#define MODULE_FM 0x00010000
103882 +#define MODULE_FM_MURAM 0x00020000
103883 +#define MODULE_FM_PCD 0x00030000
103884 +#define MODULE_FM_RTC 0x00040000
103885 +#define MODULE_FM_MAC 0x00050000
103886 +#define MODULE_FM_PORT 0x00060000
103887 +#define MODULE_MM 0x00070000
103888 +#define MODULE_FM_SP 0x00080000
103889 +#define MODULE_FM_MACSEC 0x00090000
103890 +#endif /* __XX_COMMON_H */
103891 --- /dev/null
103892 +++ b/drivers/net/ethernet/freescale/sdk_fman/inc/xx_ext.h
103893 @@ -0,0 +1,791 @@
103894 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc
103895 + * All rights reserved.
103896 + *
103897 + * Redistribution and use in source and binary forms, with or without
103898 + * modification, are permitted provided that the following conditions are met:
103899 + * * Redistributions of source code must retain the above copyright
103900 + * notice, this list of conditions and the following disclaimer.
103901 + * * Redistributions in binary form must reproduce the above copyright
103902 + * notice, this list of conditions and the following disclaimer in the
103903 + * documentation and/or other materials provided with the distribution.
103904 + * * Neither the name of Freescale Semiconductor nor the
103905 + * names of its contributors may be used to endorse or promote products
103906 + * derived from this software without specific prior written permission.
103907 + *
103908 + *
103909 + * ALTERNATIVELY, this software may be distributed under the terms of the
103910 + * GNU General Public License ("GPL") as published by the Free Software
103911 + * Foundation, either version 2 of that License or (at your option) any
103912 + * later version.
103913 + *
103914 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
103915 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
103916 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
103917 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
103918 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
103919 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
103920 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
103921 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
103922 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
103923 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
103924 + */
103925 +
103926 +
103927 +/**************************************************************************//**
103928 + @File xx_ext.h
103929 +
103930 + @Description Prototypes, externals and typedefs for system-supplied
103931 + (external) routines
103932 +*//***************************************************************************/
103933 +
103934 +#ifndef __XX_EXT_H
103935 +#define __XX_EXT_H
103936 +
103937 +#include "std_ext.h"
103938 +#include "xx_common.h"
103939 +#include "part_ext.h"
103940 +
103941 +
103942 +
103943 +/**************************************************************************//**
103944 + @Group xx_id XX Interface (System call hooks)
103945 +
103946 + @Description Prototypes, externals and typedefs for system-supplied
103947 + (external) routines
103948 +
103949 + @{
103950 +*//***************************************************************************/
103951 +
103952 +#ifdef DEBUG_XX_MALLOC
103953 +void * XX_MallocDebug(uint32_t size, char *fname, int line);
103954 +
103955 +void * XX_MallocSmartDebug(uint32_t size,
103956 + int memPartitionId,
103957 + uint32_t alignment,
103958 + char *fname,
103959 + int line);
103960 +
103961 +#define XX_Malloc(sz) \
103962 + XX_MallocDebug((sz), __FILE__, __LINE__)
103963 +
103964 +#define XX_MallocSmart(sz, memt, al) \
103965 + XX_MallocSmartDebug((sz), (memt), (al), __FILE__, __LINE__)
103966 +
103967 +#else /* not DEBUG_XX_MALLOC */
103968 +/**************************************************************************//**
103969 + @Function XX_Malloc
103970 +
103971 + @Description allocates contiguous block of memory.
103972 +
103973 + @Param[in] size - Number of bytes to allocate.
103974 +
103975 + @Return The address of the newly allocated block on success, NULL on failure.
103976 +*//***************************************************************************/
103977 +void * XX_Malloc(uint32_t size);
103978 +
103979 +/**************************************************************************//**
103980 + @Function XX_MallocSmart
103981 +
103982 + @Description Allocates contiguous block of memory in a specified
103983 + alignment and from the specified segment.
103984 +
103985 + @Param[in] size - Number of bytes to allocate.
103986 + @Param[in] memPartitionId - Memory partition ID; The value zero must
103987 + be mapped to the default heap partition.
103988 + @Param[in] alignment - Required memory alignment (in bytes).
103989 +
103990 + @Return The address of the newly allocated block on success, NULL on failure.
103991 +*//***************************************************************************/
103992 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment);
103993 +#endif /* not DEBUG_XX_MALLOC */
103994 +
103995 +/**************************************************************************//**
103996 + @Function XX_FreeSmart
103997 +
103998 + @Description Frees the memory block pointed to by "p".
103999 + Only for memory allocated by XX_MallocSmart
104000 +
104001 + @Param[in] p_Memory - pointer to the memory block.
104002 +
104003 + @Return None.
104004 +*//***************************************************************************/
104005 +void XX_FreeSmart(void *p_Memory);
104006 +
104007 +/**************************************************************************//**
104008 + @Function XX_Free
104009 +
104010 + @Description frees the memory block pointed to by "p".
104011 +
104012 + @Param[in] p_Memory - pointer to the memory block.
104013 +
104014 + @Return None.
104015 +*//***************************************************************************/
104016 +void XX_Free(void *p_Memory);
104017 +
104018 +/**************************************************************************//**
104019 + @Function XX_Print
104020 +
104021 + @Description print a string.
104022 +
104023 + @Param[in] str - string to print.
104024 +
104025 + @Return None.
104026 +*//***************************************************************************/
104027 +void XX_Print(char *str, ...);
104028 +
104029 +/**************************************************************************//**
104030 + @Function XX_SetIntr
104031 +
104032 + @Description Set an interrupt service routine for a specific interrupt source.
104033 +
104034 + @Param[in] irq - Interrupt ID (system-specific number).
104035 + @Param[in] f_Isr - Callback routine that will be called when the interrupt occurs.
104036 + @Param[in] handle - The argument for the user callback routine.
104037 +
104038 + @Return E_OK on success; error code otherwise..
104039 +*//***************************************************************************/
104040 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle);
104041 +
104042 +/**************************************************************************//**
104043 + @Function XX_FreeIntr
104044 +
104045 + @Description Free a specific interrupt and a specific callback routine.
104046 +
104047 + @Param[in] irq - Interrupt ID (system-specific number).
104048 +
104049 + @Return E_OK on success; error code otherwise..
104050 +*//***************************************************************************/
104051 +t_Error XX_FreeIntr(int irq);
104052 +
104053 +/**************************************************************************//**
104054 + @Function XX_EnableIntr
104055 +
104056 + @Description Enable a specific interrupt.
104057 +
104058 + @Param[in] irq - Interrupt ID (system-specific number).
104059 +
104060 + @Return E_OK on success; error code otherwise..
104061 +*//***************************************************************************/
104062 +t_Error XX_EnableIntr(int irq);
104063 +
104064 +/**************************************************************************//**
104065 + @Function XX_DisableIntr
104066 +
104067 + @Description Disable a specific interrupt.
104068 +
104069 + @Param[in] irq - Interrupt ID (system-specific number).
104070 +
104071 + @Return E_OK on success; error code otherwise..
104072 +*//***************************************************************************/
104073 +t_Error XX_DisableIntr(int irq);
104074 +
104075 +/**************************************************************************//**
104076 + @Function XX_DisableAllIntr
104077 +
104078 + @Description Disable all interrupts by masking them at the CPU.
104079 +
104080 + @Return A value that represents the interrupts state before the
104081 + operation, and should be passed to the matching
104082 + XX_RestoreAllIntr() call.
104083 +*//***************************************************************************/
104084 +uint32_t XX_DisableAllIntr(void);
104085 +
104086 +/**************************************************************************//**
104087 + @Function XX_RestoreAllIntr
104088 +
104089 + @Description Restore previous state of interrupts level at the CPU.
104090 +
104091 + @Param[in] flags - A value that represents the interrupts state to restore,
104092 + as returned by the matching call for XX_DisableAllIntr().
104093 +
104094 + @Return None.
104095 +*//***************************************************************************/
104096 +void XX_RestoreAllIntr(uint32_t flags);
104097 +
104098 +
104099 +/**************************************************************************//**
104100 + @Function XX_Exit
104101 +
104102 + @Description Stop execution and report status (where it is applicable)
104103 +
104104 + @Param[in] status - exit status
104105 +*//***************************************************************************/
104106 +void XX_Exit(int status);
104107 +
104108 +
104109 +/*****************************************************************************/
104110 +/* Tasklet Service Routines */
104111 +/*****************************************************************************/
104112 +typedef t_Handle t_TaskletHandle;
104113 +
104114 +/**************************************************************************//**
104115 + @Function XX_InitTasklet
104116 +
104117 + @Description Create and initialize a tasklet object.
104118 +
104119 + @Param[in] routine - A routine to be ran as a tasklet.
104120 + @Param[in] data - An argument to pass to the tasklet.
104121 +
104122 + @Return Tasklet handle is returned on success. NULL is returned otherwise.
104123 +*//***************************************************************************/
104124 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data);
104125 +
104126 +/**************************************************************************//**
104127 + @Function XX_FreeTasklet
104128 +
104129 + @Description Free a tasklet object.
104130 +
104131 + @Param[in] h_Tasklet - A handle to a tasklet to be free.
104132 +
104133 + @Return None.
104134 +*//***************************************************************************/
104135 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet);
104136 +
104137 +/**************************************************************************//**
104138 + @Function XX_ScheduleTask
104139 +
104140 + @Description Schedule a tasklet object.
104141 +
104142 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
104143 + @Param[in] immediate - Indicate whether to schedule this tasklet on
104144 + the immediate queue or on the delayed one.
104145 +
104146 + @Return 0 - on success. Error code - otherwise.
104147 +*//***************************************************************************/
104148 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate);
104149 +
104150 +/**************************************************************************//**
104151 + @Function XX_FlushScheduledTasks
104152 +
104153 + @Description Flush all tasks there are in the scheduled tasks queue.
104154 +
104155 + @Return None.
104156 +*//***************************************************************************/
104157 +void XX_FlushScheduledTasks(void);
104158 +
104159 +/**************************************************************************//**
104160 + @Function XX_TaskletIsQueued
104161 +
104162 + @Description Check if task is queued.
104163 +
104164 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
104165 +
104166 + @Return 1 - task is queued. 0 - otherwise.
104167 +*//***************************************************************************/
104168 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet);
104169 +
104170 +/**************************************************************************//**
104171 + @Function XX_SetTaskletData
104172 +
104173 + @Description Set data to a scheduled task. Used to change data of already
104174 + scheduled task.
104175 +
104176 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
104177 + @Param[in] data - Data to be set.
104178 +*//***************************************************************************/
104179 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data);
104180 +
104181 +/**************************************************************************//**
104182 + @Function XX_GetTaskletData
104183 +
104184 + @Description Get the data of scheduled task.
104185 +
104186 + @Param[in] h_Tasklet - A handle to a tasklet to be scheduled.
104187 +
104188 + @Return handle to the data of the task.
104189 +*//***************************************************************************/
104190 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet);
104191 +
104192 +/**************************************************************************//**
104193 + @Function XX_BottomHalf
104194 +
104195 + @Description Bottom half implementation, invoked by the interrupt handler.
104196 +
104197 + This routine handles all bottom-half tasklets with interrupts
104198 + enabled.
104199 +
104200 + @Return None.
104201 +*//***************************************************************************/
104202 +void XX_BottomHalf(void);
104203 +
104204 +
104205 +/*****************************************************************************/
104206 +/* Spinlock Service Routines */
104207 +/*****************************************************************************/
104208 +
104209 +/**************************************************************************//**
104210 + @Function XX_InitSpinlock
104211 +
104212 + @Description Creates a spinlock.
104213 +
104214 + @Return Spinlock handle is returned on success; NULL otherwise.
104215 +*//***************************************************************************/
104216 +t_Handle XX_InitSpinlock(void);
104217 +
104218 +/**************************************************************************//**
104219 + @Function XX_FreeSpinlock
104220 +
104221 + @Description Frees the memory allocated for the spinlock creation.
104222 +
104223 + @Param[in] h_Spinlock - A handle to a spinlock.
104224 +
104225 + @Return None.
104226 +*//***************************************************************************/
104227 +void XX_FreeSpinlock(t_Handle h_Spinlock);
104228 +
104229 +/**************************************************************************//**
104230 + @Function XX_LockSpinlock
104231 +
104232 + @Description Locks a spinlock.
104233 +
104234 + @Param[in] h_Spinlock - A handle to a spinlock.
104235 +
104236 + @Return None.
104237 +*//***************************************************************************/
104238 +void XX_LockSpinlock(t_Handle h_Spinlock);
104239 +
104240 +/**************************************************************************//**
104241 + @Function XX_UnlockSpinlock
104242 +
104243 + @Description Unlocks a spinlock.
104244 +
104245 + @Param[in] h_Spinlock - A handle to a spinlock.
104246 +
104247 + @Return None.
104248 +*//***************************************************************************/
104249 +void XX_UnlockSpinlock(t_Handle h_Spinlock);
104250 +
104251 +/**************************************************************************//**
104252 + @Function XX_LockIntrSpinlock
104253 +
104254 + @Description Locks a spinlock (interrupt safe).
104255 +
104256 + @Param[in] h_Spinlock - A handle to a spinlock.
104257 +
104258 + @Return A value that represents the interrupts state before the
104259 + operation, and should be passed to the matching
104260 + XX_UnlockIntrSpinlock() call.
104261 +*//***************************************************************************/
104262 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock);
104263 +
104264 +/**************************************************************************//**
104265 + @Function XX_UnlockIntrSpinlock
104266 +
104267 + @Description Unlocks a spinlock (interrupt safe).
104268 +
104269 + @Param[in] h_Spinlock - A handle to a spinlock.
104270 + @Param[in] intrFlags - A value that represents the interrupts state to
104271 + restore, as returned by the matching call for
104272 + XX_LockIntrSpinlock().
104273 +
104274 + @Return None.
104275 +*//***************************************************************************/
104276 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags);
104277 +
104278 +
104279 +/*****************************************************************************/
104280 +/* Timers Service Routines */
104281 +/*****************************************************************************/
104282 +
104283 +/**************************************************************************//**
104284 + @Function XX_CurrentTime
104285 +
104286 + @Description Returns current system time.
104287 +
104288 + @Return Current system time (in milliseconds).
104289 +*//***************************************************************************/
104290 +uint32_t XX_CurrentTime(void);
104291 +
104292 +/**************************************************************************//**
104293 + @Function XX_CreateTimer
104294 +
104295 + @Description Creates a timer.
104296 +
104297 + @Return Timer handle is returned on success; NULL otherwise.
104298 +*//***************************************************************************/
104299 +t_Handle XX_CreateTimer(void);
104300 +
104301 +/**************************************************************************//**
104302 + @Function XX_FreeTimer
104303 +
104304 + @Description Frees the memory allocated for the timer creation.
104305 +
104306 + @Param[in] h_Timer - A handle to a timer.
104307 +
104308 + @Return None.
104309 +*//***************************************************************************/
104310 +void XX_FreeTimer(t_Handle h_Timer);
104311 +
104312 +/**************************************************************************//**
104313 + @Function XX_StartTimer
104314 +
104315 + @Description Starts a timer.
104316 +
104317 + The user can select to start the timer as periodic timer or as
104318 + one-shot timer. The user should provide a callback routine that
104319 + will be called when the timer expires.
104320 +
104321 + @Param[in] h_Timer - A handle to a timer.
104322 + @Param[in] msecs - Timer expiration period (in milliseconds).
104323 + @Param[in] periodic - TRUE for a periodic timer;
104324 + FALSE for a one-shot timer..
104325 + @Param[in] f_TimerExpired - A callback routine to be called when the
104326 + timer expires.
104327 + @Param[in] h_Arg - The argument to pass in the timer-expired
104328 + callback routine.
104329 +
104330 + @Return None.
104331 +*//***************************************************************************/
104332 +void XX_StartTimer(t_Handle h_Timer,
104333 + uint32_t msecs,
104334 + bool periodic,
104335 + void (*f_TimerExpired)(t_Handle h_Arg),
104336 + t_Handle h_Arg);
104337 +
104338 +/**************************************************************************//**
104339 + @Function XX_StopTimer
104340 +
104341 + @Description Frees the memory allocated for the timer creation.
104342 +
104343 + @Param[in] h_Timer - A handle to a timer.
104344 +
104345 + @Return None.
104346 +*//***************************************************************************/
104347 +void XX_StopTimer(t_Handle h_Timer);
104348 +
104349 +/**************************************************************************//**
104350 + @Function XX_ModTimer
104351 +
104352 + @Description Updates the expiration time of a timer.
104353 +
104354 + This routine adds the given time to the current system time,
104355 + and sets this value as the new expiration time of the timer.
104356 +
104357 + @Param[in] h_Timer - A handle to a timer.
104358 + @Param[in] msecs - The new interval until timer expiration
104359 + (in milliseconds).
104360 +
104361 + @Return None.
104362 +*//***************************************************************************/
104363 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs);
104364 +
104365 +/**************************************************************************//**
104366 + @Function XX_Sleep
104367 +
104368 + @Description Non-busy wait until the desired time (in milliseconds) has passed.
104369 +
104370 + @Param[in] msecs - The requested sleep time (in milliseconds).
104371 +
104372 + @Return Zero if the requested time has elapsed; Otherwise, the value
104373 + returned will be the unslept amount) in milliseconds.
104374 +
104375 + @Cautions This routine enables interrupts during its wait time.
104376 +*//***************************************************************************/
104377 +uint32_t XX_Sleep(uint32_t msecs);
104378 +
104379 +/**************************************************************************//**
104380 + @Function XX_UDelay
104381 +
104382 + @Description Busy-wait until the desired time (in microseconds) has passed.
104383 +
104384 + @Param[in] usecs - The requested delay time (in microseconds).
104385 +
104386 + @Return None.
104387 +
104388 + @Cautions It is highly unrecommended to call this routine during interrupt
104389 + time, because the system time may not be updated properly during
104390 + the delay loop. The behavior of this routine during interrupt
104391 + time is unexpected.
104392 +*//***************************************************************************/
104393 +void XX_UDelay(uint32_t usecs);
104394 +
104395 +
104396 +/*****************************************************************************/
104397 +/* Other Service Routines */
104398 +/*****************************************************************************/
104399 +
104400 +/**************************************************************************//**
104401 + @Function XX_PhysToVirt
104402 +
104403 + @Description Translates a physical address to the matching virtual address.
104404 +
104405 + @Param[in] addr - The physical address to translate.
104406 +
104407 + @Return Virtual address.
104408 +*//***************************************************************************/
104409 +void * XX_PhysToVirt(physAddress_t addr);
104410 +
104411 +/**************************************************************************//**
104412 + @Function XX_VirtToPhys
104413 +
104414 + @Description Translates a virtual address to the matching physical address.
104415 +
104416 + @Param[in] addr - The virtual address to translate.
104417 +
104418 + @Return Physical address.
104419 +*//***************************************************************************/
104420 +physAddress_t XX_VirtToPhys(void *addr);
104421 +
104422 +
104423 +/**************************************************************************//**
104424 + @Group xx_ipc XX Inter-Partition-Communication API
104425 +
104426 + @Description The following API is to be used when working with multiple
104427 + partitions configuration.
104428 +
104429 + @{
104430 +*//***************************************************************************/
104431 +
104432 +#define XX_IPC_MAX_ADDR_NAME_LENGTH 16 /**< Maximum length of an endpoint name string;
104433 + The IPC service can use this constant to limit
104434 + the storage space for IPC endpoint names. */
104435 +
104436 +
104437 +/**************************************************************************//**
104438 + @Function t_IpcMsgCompletion
104439 +
104440 + @Description Callback function used upon IPC non-blocking transaction completion
104441 + to return message buffer to the caller and to forward reply if available.
104442 +
104443 + This callback function may be attached by the source endpoint to any outgoing
104444 + IPC message to indicate a non-blocking send (see also XX_IpcSendMessage() routine).
104445 + Upon completion of an IPC transaction (consisting of a message and an optional reply),
104446 + the IPC service invokes this callback routine to return the message buffer to the sender
104447 + and to provide the received reply, if requested.
104448 +
104449 + User provides this function. Driver invokes it.
104450 +
104451 + @Param[in] h_Module - Abstract handle to the sending module - the same handle as was passed
104452 + in the XX_IpcSendMessage() function; This handle is typically used to point
104453 + to the internal data structure of the source endpoint.
104454 + @Param[in] p_Msg - Pointer to original (sent) message buffer;
104455 + The source endpoint can free (or reuse) this buffer when message
104456 + completion callback is called.
104457 + @Param[in] p_Reply - Pointer to (received) reply buffer;
104458 + This pointer is the same as was provided by the source endpoint in
104459 + XX_IpcSendMessage().
104460 + @Param[in] replyLength - Length (in bytes) of actual data in the reply buffer.
104461 + @Param[in] status - Completion status - E_OK or failure indication, e.g. IPC transaction completion
104462 + timeout.
104463 +
104464 + @Return None
104465 + *//***************************************************************************/
104466 +typedef void (t_IpcMsgCompletion)(t_Handle h_Module,
104467 + uint8_t *p_Msg,
104468 + uint8_t *p_Reply,
104469 + uint32_t replyLength,
104470 + t_Error status);
104471 +
104472 +/**************************************************************************//**
104473 + @Function t_IpcMsgHandler
104474 +
104475 + @Description Callback function used as IPC message handler.
104476 +
104477 + The IPC service invokes message handlers for each IPC message received.
104478 + The actual function pointer should be registered by each destination endpoint
104479 + via the XX_IpcRegisterMsgHandler() routine.
104480 +
104481 + User provides this function. Driver invokes it.
104482 +
104483 + @Param[in] h_Module - Abstract handle to the message handling module - the same handle as
104484 + was passed in the XX_IpcRegisterMsgHandler() function; this handle is
104485 + typically used to point to the internal data structure of the destination
104486 + endpoint.
104487 + @Param[in] p_Msg - Pointer to message buffer with data received from peer.
104488 + @Param[in] msgLength - Length (in bytes) of message data.
104489 + @Param[in] p_Reply - Pointer to reply buffer, to be filled by the message handler and then sent
104490 + by the IPC service;
104491 + The reply buffer is allocated by the IPC service with size equals to the
104492 + replyLength parameter provided in message handler registration (see
104493 + XX_IpcRegisterMsgHandler() function);
104494 + If replyLength was initially specified as zero during message handler registration,
104495 + the IPC service may set this pointer to NULL and assume that a reply is not needed;
104496 + The IPC service is also responsible for freeing the reply buffer after the
104497 + reply has been sent or dismissed.
104498 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
104499 + [In] equals the replyLength parameter provided in message handler
104500 + registration (see XX_IpcRegisterMsgHandler() function), and
104501 + [Out] should be updated by message handler to the actual reply length; if
104502 + this value is set to zero, the IPC service must assume that a reply should
104503 + not be sent;
104504 + Note: If p_Reply is not NULL, p_ReplyLength must not be NULL as well.
104505 +
104506 + @Return E_OK on success; Error code otherwise.
104507 + *//***************************************************************************/
104508 +typedef t_Error (t_IpcMsgHandler)(t_Handle h_Module,
104509 + uint8_t *p_Msg,
104510 + uint32_t msgLength,
104511 + uint8_t *p_Reply,
104512 + uint32_t *p_ReplyLength);
104513 +
104514 +/**************************************************************************//**
104515 + @Function XX_IpcRegisterMsgHandler
104516 +
104517 + @Description IPC mailbox registration.
104518 +
104519 + This function is used for registering an IPC message handler in the IPC service.
104520 + This function is called by each destination endpoint to indicate that it is ready
104521 + to handle incoming messages. The IPC service invokes the message handler upon receiving
104522 + a message addressed to the specified destination endpoint.
104523 +
104524 + @Param[in] addr - The address name string associated with the destination endpoint;
104525 + This address must be unique across the IPC service domain to ensure
104526 + correct message routing.
104527 + @Param[in] f_MsgHandler - Pointer to the message handler callback for processing incoming
104528 + message; invoked by the IPC service upon receiving a message
104529 + addressed to the destination endpoint specified by the addr
104530 + parameter.
104531 + @Param[in] h_Module - Abstract handle to the message handling module, passed unchanged
104532 + to f_MsgHandler callback function.
104533 + @Param[in] replyLength - The maximal data length (in bytes) of any reply that the specified message handler
104534 + may generate; the IPC service provides the message handler with buffer
104535 + for reply according to the length specified here (refer also to the description
104536 + of #t_IpcMsgHandler callback function type);
104537 + This size shall be zero if the message handler never generates replies.
104538 +
104539 + @Return E_OK on success; Error code otherwise.
104540 +*//***************************************************************************/
104541 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
104542 + t_IpcMsgHandler *f_MsgHandler,
104543 + t_Handle h_Module,
104544 + uint32_t replyLength);
104545 +
104546 +/**************************************************************************//**
104547 + @Function XX_IpcUnregisterMsgHandler
104548 +
104549 + @Description Release IPC mailbox routine.
104550 +
104551 + This function is used for unregistering an IPC message handler from the IPC service.
104552 + This function is called by each destination endpoint to indicate that it is no longer
104553 + capable of handling incoming messages.
104554 +
104555 + @Param[in] addr - The address name string associated with the destination endpoint;
104556 + This address is the same as was used when the message handler was
104557 + registered via XX_IpcRegisterMsgHandler().
104558 +
104559 + @Return E_OK on success; Error code otherwise.
104560 +*//***************************************************************************/
104561 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
104562 +
104563 +/**************************************************************************//**
104564 + @Function XX_IpcInitSession
104565 +
104566 + @Description This function is used for creating an IPC session between the source endpoint
104567 + and the destination endpoint.
104568 +
104569 + The actual implementation and representation of a session is left for the IPC service.
104570 + The function returns an abstract handle to the created session. This handle shall be used
104571 + by the source endpoint in subsequent calls to XX_IpcSendMessage().
104572 + The IPC service assumes that before this function is called, no messages are sent from
104573 + the specified source endpoint to the specified destination endpoint.
104574 +
104575 + The IPC service may use a connection-oriented approach or a connectionless approach (or both)
104576 + as described below.
104577 +
104578 + @par Connection-Oriented Approach
104579 +
104580 + The IPC service may implement a session in a connection-oriented approach - when this function is called,
104581 + the IPC service should take the necessary steps to bring up a source-to-destination channel for messages
104582 + and a destination-to-source channel for replies. The returned handle should represent the internal
104583 + representation of these channels.
104584 +
104585 + @par Connectionless Approach
104586 +
104587 + The IPC service may implement a session in a connectionless approach - when this function is called, the
104588 + IPC service should not perform any particular steps, but it must store the pair of source and destination
104589 + addresses in some session representation and return it as a handle. When XX_IpcSendMessage() shall be
104590 + called, the IPC service may use this handle to provide the necessary identifiers for routing the messages
104591 + through the connectionless medium.
104592 +
104593 + @Param[in] destAddr - The address name string associated with the destination endpoint.
104594 + @Param[in] srcAddr - The address name string associated with the source endpoint.
104595 +
104596 + @Return Abstract handle to the initialized session, or NULL on error.
104597 +*//***************************************************************************/
104598 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
104599 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH]);
104600 +
104601 +/**************************************************************************//**
104602 + @Function XX_IpcFreeSession
104603 +
104604 + @Description This function is used for terminating an existing IPC session between a source endpoint
104605 + and a destination endpoint.
104606 +
104607 + The IPC service assumes that after this function is called, no messages shall be sent from
104608 + the associated source endpoint to the associated destination endpoint.
104609 +
104610 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
104611 + returned by the XX_IpcInitSession() function.
104612 +
104613 + @Return E_OK on success; Error code otherwise.
104614 +*//***************************************************************************/
104615 +t_Error XX_IpcFreeSession(t_Handle h_Session);
104616 +
104617 +/**************************************************************************//**
104618 + @Function XX_IpcSendMessage
104619 +
104620 + @Description IPC message send routine.
104621 +
104622 + This function may be used by a source endpoint to send an IPC message to a destination
104623 + endpoint. The source endpoint cannot send a message to the destination endpoint without
104624 + first initiating a session with that destination endpoint via XX_IpcInitSession() routine.
104625 +
104626 + The source endpoint must provide the buffer pointer and length of the outgoing message.
104627 + Optionally, it may also provide a buffer for an expected reply. In the latter case, the
104628 + transaction is not considered complete by the IPC service until the reply has been received.
104629 + If the source endpoint does not provide a reply buffer, the transaction is considered
104630 + complete after the message has been sent. The source endpoint must keep the message (and
104631 + optional reply) buffers valid until the transaction is complete.
104632 +
104633 + @par Non-blocking mode
104634 +
104635 + The source endpoint may request a non-blocking send by providing a non-NULL pointer to a message
104636 + completion callback function (f_Completion). Upon completion of the IPC transaction (consisting of a
104637 + message and an optional reply), the IPC service invokes this callback routine to return the message
104638 + buffer to the sender and to provide the received reply, if requested.
104639 +
104640 + @par Blocking mode
104641 +
104642 + The source endpoint may request a blocking send by setting f_Completion to NULL. The function is
104643 + expected to block until the IPC transaction is complete - either the reply has been received or (if no reply
104644 + was requested) the message has been sent.
104645 +
104646 + @Param[in] h_Session - Abstract handle to the IPC session - the same handle as was originally
104647 + returned by the XX_IpcInitSession() function.
104648 + @Param[in] p_Msg - Pointer to message buffer to send.
104649 + @Param[in] msgLength - Length (in bytes) of actual data in the message buffer.
104650 + @Param[in] p_Reply - Pointer to reply buffer - if this buffer is not NULL, the IPC service
104651 + fills this buffer with the received reply data;
104652 + In blocking mode, the reply data must be valid when the function returns;
104653 + In non-blocking mode, the reply data is valid when f_Completion is called;
104654 + If this pointer is NULL, no reply is expected.
104655 + @Param[in,out] p_ReplyLength - Pointer to reply length, which has a dual role in this function:
104656 + [In] specifies the maximal length (in bytes) of the reply buffer pointed by
104657 + p_Reply, and
104658 + [Out] in non-blocking mode this value is updated by the IPC service to the
104659 + actual reply length (in bytes).
104660 + @Param[in] f_Completion - Pointer to a completion callback to be used in non-blocking send mode;
104661 + The completion callback is invoked by the IPC service upon
104662 + completion of the IPC transaction (consisting of a message and an optional
104663 + reply);
104664 + If this pointer is NULL, the function is expected to block until the IPC
104665 + transaction is complete.
104666 + @Param[in] h_Arg - Abstract handle to the sending module; passed unchanged to the f_Completion
104667 + callback function as the first argument.
104668 +
104669 + @Return E_OK on success; Error code otherwise.
104670 +*//***************************************************************************/
104671 +t_Error XX_IpcSendMessage(t_Handle h_Session,
104672 + uint8_t *p_Msg,
104673 + uint32_t msgLength,
104674 + uint8_t *p_Reply,
104675 + uint32_t *p_ReplyLength,
104676 + t_IpcMsgCompletion *f_Completion,
104677 + t_Handle h_Arg);
104678 +
104679 +
104680 +/** @} */ /* end of xx_ipc group */
104681 +/** @} */ /* end of xx_id group */
104682 +
104683 +
104684 +#endif /* __XX_EXT_H */
104685 --- /dev/null
104686 +++ b/drivers/net/ethernet/freescale/sdk_fman/ls1043_dflags.h
104687 @@ -0,0 +1,56 @@
104688 +/*
104689 + * Copyright 2012 Freescale Semiconductor Inc.
104690 + *
104691 + * Redistribution and use in source and binary forms, with or without
104692 + * modification, are permitted provided that the following conditions are met:
104693 + * * Redistributions of source code must retain the above copyright
104694 + * notice, this list of conditions and the following disclaimer.
104695 + * * Redistributions in binary form must reproduce the above copyright
104696 + * notice, this list of conditions and the following disclaimer in the
104697 + * documentation and/or other materials provided with the distribution.
104698 + * * Neither the name of Freescale Semiconductor nor the
104699 + * names of its contributors may be used to endorse or promote products
104700 + * derived from this software without specific prior written permission.
104701 + *
104702 + *
104703 + * ALTERNATIVELY, this software may be distributed under the terms of the
104704 + * GNU General Public License ("GPL") as published by the Free Software
104705 + * Foundation, either version 2 of that License or (at your option) any
104706 + * later version.
104707 + *
104708 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104709 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104710 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104711 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104712 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104713 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104714 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104715 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104716 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104717 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104718 + */
104719 +
104720 +#ifndef __dflags_h
104721 +#define __dflags_h
104722 +
104723 +
104724 +#define NCSW_LINUX
104725 +
104726 +#define LS1043
104727 +
104728 +#define DEBUG_ERRORS 1
104729 +
104730 +#if defined(DEBUG)
104731 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
104732 +
104733 +#define DEBUG_XX_MALLOC
104734 +#define DEBUG_MEM_LEAKS
104735 +
104736 +#else
104737 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
104738 +#endif /* (DEBUG) */
104739 +
104740 +#define REPORT_EVENTS 1
104741 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
104742 +
104743 +#endif /* __dflags_h */
104744 --- /dev/null
104745 +++ b/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104746 @@ -0,0 +1,53 @@
104747 +#
104748 +# Makefile config for the Freescale NetcommSW
104749 +#
104750 +NET_DPA = $(srctree)/drivers/net
104751 +DRV_DPA = $(srctree)/drivers/net/ethernet/freescale/sdk_dpaa
104752 +FMAN = $(srctree)/drivers/net/ethernet/freescale/sdk_fman
104753 +
104754 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
104755 +ccflags-y +=-include $(FMAN)/p3040_4080_5020_dflags.h
104756 +endif
104757 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
104758 +ccflags-y +=-include $(FMAN)/p1023_dflags.h
104759 +endif
104760 +ifdef CONFIG_FMAN_V3H
104761 +ccflags-y +=-include $(FMAN)/fmanv3h_dflags.h
104762 +endif
104763 +ifdef CONFIG_FMAN_V3L
104764 +ccflags-y +=-include $(FMAN)/fmanv3l_dflags.h
104765 +endif
104766 +ifdef CONFIG_FMAN_ARM
104767 +ccflags-y +=-include $(FMAN)/ls1043_dflags.h
104768 +endif
104769 +
104770 +ccflags-y += -I$(DRV_DPA)/
104771 +ccflags-y += -I$(FMAN)/inc
104772 +ccflags-y += -I$(FMAN)/inc/cores
104773 +ccflags-y += -I$(FMAN)/inc/etc
104774 +ccflags-y += -I$(FMAN)/inc/Peripherals
104775 +ccflags-y += -I$(FMAN)/inc/flib
104776 +
104777 +ifeq ("$(CONFIG_FMAN_P3040_P4080_P5020)", "y")
104778 +ccflags-y += -I$(FMAN)/inc/integrations/P3040_P4080_P5020
104779 +endif
104780 +ifeq ("$(CONFIG_FMAN_P1023)", "y")
104781 +ccflags-y += -I$(FMAN)/inc/integrations/P1023
104782 +endif
104783 +ifdef CONFIG_FMAN_V3H
104784 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3H
104785 +endif
104786 +ifdef CONFIG_FMAN_V3L
104787 +ccflags-y += -I$(FMAN)/inc/integrations/FMANV3L
104788 +endif
104789 +ifdef CONFIG_FMAN_ARM
104790 +ccflags-y += -I$(FMAN)/inc/integrations/LS1043
104791 +endif
104792 +
104793 +ccflags-y += -I$(FMAN)/src/inc
104794 +ccflags-y += -I$(FMAN)/src/inc/system
104795 +ccflags-y += -I$(FMAN)/src/inc/wrapper
104796 +ccflags-y += -I$(FMAN)/src/inc/xx
104797 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd
104798 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/Peripherals
104799 +ccflags-y += -I$(srctree)/include/uapi/linux/fmd/integrations
104800 --- /dev/null
104801 +++ b/drivers/net/ethernet/freescale/sdk_fman/p1023_dflags.h
104802 @@ -0,0 +1,65 @@
104803 +/*
104804 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104805 + *
104806 + * Redistribution and use in source and binary forms, with or without
104807 + * modification, are permitted provided that the following conditions are met:
104808 + * * Redistributions of source code must retain the above copyright
104809 + * notice, this list of conditions and the following disclaimer.
104810 + * * Redistributions in binary form must reproduce the above copyright
104811 + * notice, this list of conditions and the following disclaimer in the
104812 + * documentation and/or other materials provided with the distribution.
104813 + * * Neither the name of Freescale Semiconductor nor the
104814 + * names of its contributors may be used to endorse or promote products
104815 + * derived from this software without specific prior written permission.
104816 + *
104817 + *
104818 + * ALTERNATIVELY, this software may be distributed under the terms of the
104819 + * GNU General Public License ("GPL") as published by the Free Software
104820 + * Foundation, either version 2 of that License or (at your option) any
104821 + * later version.
104822 + *
104823 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104824 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104825 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104826 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104827 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104828 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104829 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104830 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104831 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104832 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104833 + */
104834 +
104835 +#ifndef __dflags_h
104836 +#define __dflags_h
104837 +
104838 +
104839 +#define NCSW_LINUX
104840 +#if 0
104841 +#define DEBUG
104842 +#endif
104843 +
104844 +#define P1023
104845 +#define NCSW_PPC_CORE
104846 +
104847 +#define DEBUG_ERRORS 1
104848 +
104849 +#if defined(DEBUG)
104850 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
104851 +
104852 +#define DEBUG_XX_MALLOC
104853 +#define DEBUG_MEM_LEAKS
104854 +
104855 +#else
104856 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
104857 +#endif /* (DEBUG) */
104858 +
104859 +#define REPORT_EVENTS 1
104860 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
104861 +
104862 +#ifdef CONFIG_P4080_SIM
104863 +#error "Do not define CONFIG_P4080_SIM..."
104864 +#endif
104865 +
104866 +
104867 +#endif /* __dflags_h */
104868 --- /dev/null
104869 +++ b/drivers/net/ethernet/freescale/sdk_fman/p3040_4080_5020_dflags.h
104870 @@ -0,0 +1,62 @@
104871 +/*
104872 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104873 + *
104874 + * Redistribution and use in source and binary forms, with or without
104875 + * modification, are permitted provided that the following conditions are met:
104876 + * * Redistributions of source code must retain the above copyright
104877 + * notice, this list of conditions and the following disclaimer.
104878 + * * Redistributions in binary form must reproduce the above copyright
104879 + * notice, this list of conditions and the following disclaimer in the
104880 + * documentation and/or other materials provided with the distribution.
104881 + * * Neither the name of Freescale Semiconductor nor the
104882 + * names of its contributors may be used to endorse or promote products
104883 + * derived from this software without specific prior written permission.
104884 + *
104885 + *
104886 + * ALTERNATIVELY, this software may be distributed under the terms of the
104887 + * GNU General Public License ("GPL") as published by the Free Software
104888 + * Foundation, either version 2 of that License or (at your option) any
104889 + * later version.
104890 + *
104891 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104892 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104893 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104894 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104895 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104896 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104897 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104898 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104899 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104900 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104901 + */
104902 +
104903 +#ifndef __dflags_h
104904 +#define __dflags_h
104905 +
104906 +
104907 +#define NCSW_LINUX
104908 +
104909 +#define P4080
104910 +#define NCSW_PPC_CORE
104911 +
104912 +#define DEBUG_ERRORS 1
104913 +
104914 +#if defined(DEBUG)
104915 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_INFO
104916 +
104917 +#define DEBUG_XX_MALLOC
104918 +#define DEBUG_MEM_LEAKS
104919 +
104920 +#else
104921 +#define DEBUG_GLOBAL_LEVEL REPORT_LEVEL_WARNING
104922 +#endif /* (DEBUG) */
104923 +
104924 +#define REPORT_EVENTS 1
104925 +#define EVENT_GLOBAL_LEVEL REPORT_LEVEL_MINOR
104926 +
104927 +#ifdef CONFIG_P4080_SIM
104928 +#define SIMULATOR
104929 +#endif /* CONFIG_P4080_SIM */
104930 +
104931 +
104932 +#endif /* __dflags_h */
104933 --- /dev/null
104934 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/Makefile
104935 @@ -0,0 +1,11 @@
104936 +#
104937 +# Makefile for the Freescale Ethernet controllers
104938 +#
104939 +ccflags-y += -DVERSION=\"\"
104940 +#
104941 +#Include netcomm SW specific definitions
104942 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
104943 +#
104944 +obj-y += system/
104945 +obj-y += wrapper/
104946 +obj-y += xx/
104947 --- /dev/null
104948 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_ext.h
104949 @@ -0,0 +1,118 @@
104950 +/*
104951 + * Copyright 2008-2012 Freescale Semiconductor Inc.
104952 + *
104953 + * Redistribution and use in source and binary forms, with or without
104954 + * modification, are permitted provided that the following conditions are met:
104955 + * * Redistributions of source code must retain the above copyright
104956 + * notice, this list of conditions and the following disclaimer.
104957 + * * Redistributions in binary form must reproduce the above copyright
104958 + * notice, this list of conditions and the following disclaimer in the
104959 + * documentation and/or other materials provided with the distribution.
104960 + * * Neither the name of Freescale Semiconductor nor the
104961 + * names of its contributors may be used to endorse or promote products
104962 + * derived from this software without specific prior written permission.
104963 + *
104964 + *
104965 + * ALTERNATIVELY, this software may be distributed under the terms of the
104966 + * GNU General Public License ("GPL") as published by the Free Software
104967 + * Foundation, either version 2 of that License or (at your option) any
104968 + * later version.
104969 + *
104970 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
104971 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
104972 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
104973 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
104974 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
104975 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
104976 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
104977 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
104978 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
104979 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
104980 + */
104981 +
104982 +#ifndef __SYS_EXT_H
104983 +#define __SYS_EXT_H
104984 +
104985 +#include "std_ext.h"
104986 +
104987 +
104988 +/**************************************************************************//**
104989 + @Group sys_grp System Interfaces
104990 +
104991 + @Description Linux system programming interfaces.
104992 +
104993 + @{
104994 +*//***************************************************************************/
104995 +
104996 +/**************************************************************************//**
104997 + @Group sys_gen_grp System General Interface
104998 +
104999 + @Description General definitions, structures and routines of the linux
105000 + system programming interface.
105001 +
105002 + @{
105003 +*//***************************************************************************/
105004 +
105005 +/**************************************************************************//**
105006 + @Collection Macros for Advanced Configuration Requests
105007 + @{
105008 +*//***************************************************************************/
105009 +#define SYS_MAX_ADV_CONFIG_ARGS 4
105010 + /**< Maximum number of arguments in
105011 + an advanced configuration entry */
105012 +/* @} */
105013 +
105014 +/**************************************************************************//**
105015 + @Description System Object Advanced Configuration Entry
105016 +
105017 + This structure represents a single request for an advanced
105018 + configuration call on the initialized object. An array of such
105019 + requests may be contained in the settings structure of the
105020 + corresponding object.
105021 +
105022 + The maximum number of arguments is limited to #SYS_MAX_ADV_CONFIG_ARGS.
105023 +*//***************************************************************************/
105024 +typedef struct t_SysObjectAdvConfigEntry
105025 +{
105026 + void *p_Function; /**< Pointer to advanced configuration routine */
105027 +
105028 + uintptr_t args[SYS_MAX_ADV_CONFIG_ARGS];
105029 + /**< Array of arguments for the specified routine;
105030 + All arguments should be casted to uint32_t. */
105031 +} t_SysObjectAdvConfigEntry;
105032 +
105033 +
105034 +/** @} */ /* end of sys_gen_grp */
105035 +/** @} */ /* end of sys_grp */
105036 +
105037 +#define NCSW_PARAMS(_num, _params) ADV_CONFIG_PARAMS_##_num _params
105038 +
105039 +#define ADV_CONFIG_PARAMS_1(_type) \
105040 + , (_type)p_Entry->args[0]
105041 +
105042 +#define SET_ADV_CONFIG_ARGS_1(_arg0) \
105043 + p_Entry->args[0] = (uintptr_t )(_arg0); \
105044 +
105045 +#define ARGS(_num, _params) SET_ADV_CONFIG_ARGS_##_num _params
105046 +
105047 +#define ADD_ADV_CONFIG_START(_p_Entries, _maxEntries) \
105048 + { \
105049 + t_SysObjectAdvConfigEntry *p_Entry; \
105050 + t_SysObjectAdvConfigEntry *p_Entrys = (_p_Entries); \
105051 + int i=0, max = (_maxEntries); \
105052 +
105053 +#define ADD_ADV_CONFIG_END \
105054 + }
105055 +
105056 +#define ADV_CONFIG_CHECK_START(_p_Entry) \
105057 + { \
105058 + t_SysObjectAdvConfigEntry *p_Entry = _p_Entry; \
105059 + t_Error errCode; \
105060 +
105061 +#define ADV_CONFIG_CHECK(_handle, _func, _params) \
105062 + if (p_Entry->p_Function == _func) \
105063 + { \
105064 + errCode = _func(_handle _params); \
105065 + } else
105066 +
105067 +#endif /* __SYS_EXT_H */
105068 --- /dev/null
105069 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/system/sys_io_ext.h
105070 @@ -0,0 +1,46 @@
105071 +/*
105072 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105073 + *
105074 + * Redistribution and use in source and binary forms, with or without
105075 + * modification, are permitted provided that the following conditions are met:
105076 + * * Redistributions of source code must retain the above copyright
105077 + * notice, this list of conditions and the following disclaimer.
105078 + * * Redistributions in binary form must reproduce the above copyright
105079 + * notice, this list of conditions and the following disclaimer in the
105080 + * documentation and/or other materials provided with the distribution.
105081 + * * Neither the name of Freescale Semiconductor nor the
105082 + * names of its contributors may be used to endorse or promote products
105083 + * derived from this software without specific prior written permission.
105084 + *
105085 + *
105086 + * ALTERNATIVELY, this software may be distributed under the terms of the
105087 + * GNU General Public License ("GPL") as published by the Free Software
105088 + * Foundation, either version 2 of that License or (at your option) any
105089 + * later version.
105090 + *
105091 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105092 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105093 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105094 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105095 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105096 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105097 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105098 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105099 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105100 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105101 + */
105102 +
105103 +#ifndef __SYS_IO_EXT_H
105104 +#define __SYS_IO_EXT_H
105105 +
105106 +#include "std_ext.h"
105107 +#include "error_ext.h"
105108 +
105109 +
105110 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size);
105111 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr);
105112 +uint64_t SYS_PhysToVirt (uint64_t addr);
105113 +uint64_t SYS_VirtToPhys (uint64_t addr);
105114 +
105115 +
105116 +#endif /* __SYS_IO_EXT_H */
105117 --- /dev/null
105118 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/types_linux.h
105119 @@ -0,0 +1,208 @@
105120 +/*
105121 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105122 + *
105123 + * Redistribution and use in source and binary forms, with or without
105124 + * modification, are permitted provided that the following conditions are met:
105125 + * * Redistributions of source code must retain the above copyright
105126 + * notice, this list of conditions and the following disclaimer.
105127 + * * Redistributions in binary form must reproduce the above copyright
105128 + * notice, this list of conditions and the following disclaimer in the
105129 + * documentation and/or other materials provided with the distribution.
105130 + * * Neither the name of Freescale Semiconductor nor the
105131 + * names of its contributors may be used to endorse or promote products
105132 + * derived from this software without specific prior written permission.
105133 + *
105134 + *
105135 + * ALTERNATIVELY, this software may be distributed under the terms of the
105136 + * GNU General Public License ("GPL") as published by the Free Software
105137 + * Foundation, either version 2 of that License or (at your option) any
105138 + * later version.
105139 + *
105140 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105141 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105142 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105143 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105144 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105145 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105146 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105147 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105148 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105149 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105150 + */
105151 +
105152 +#ifndef __TYPES_LINUX_H__
105153 +#define __TYPES_LINUX_H__
105154 +
105155 +#include <linux/version.h>
105156 +
105157 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
105158 +#define MODVERSIONS
105159 +#endif
105160 +#ifdef MODVERSIONS
105161 +#include <config/modversions.h>
105162 +#endif /* MODVERSIONS */
105163 +
105164 +#include <linux/kernel.h>
105165 +#include <linux/types.h>
105166 +#include <asm/io.h>
105167 +#include <linux/delay.h>
105168 +
105169 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
105170 + #error "This kernel is probably not supported!!!"
105171 +#elif (!((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) || \
105172 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)) || \
105173 + (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,30))))
105174 + #warning "This kernel is probably not supported!!! You may need to add some fixes."
105175 +#endif /* LINUX_VERSION_CODE */
105176 +
105177 +
105178 +typedef float float_t; /* Single precision floating point */
105179 +typedef double double_t; /* Double precision floating point */
105180 +
105181 +
105182 +#define _Packed
105183 +#define _PackedType __attribute__ ((packed))
105184 +
105185 +typedef phys_addr_t physAddress_t;
105186 +
105187 +#define UINT8_MAX 0xFF
105188 +#define UINT8_MIN 0
105189 +#define UINT16_MAX 0xFFFF
105190 +#define UINT16_MIN 0
105191 +#define UINT32_MAX 0xFFFFFFFF
105192 +#define UINT32_MIN 0
105193 +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFLL
105194 +#define UINT64_MIN 0
105195 +#define INT8_MAX 0x7F
105196 +#define INT8_MIN 0x80
105197 +#define INT16_MAX 0x7FFF
105198 +#define INT16_MIN 0x8000
105199 +#define INT32_MAX 0x7FFFFFFF
105200 +#define INT32_MIN 0x80000000
105201 +#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
105202 +#define INT64_MIN 0x8000000000000000LL
105203 +
105204 +#define ON 1
105205 +#define OFF 0
105206 +
105207 +#define FALSE false
105208 +#define TRUE true
105209 +
105210 +
105211 +/************************/
105212 +/* memory access macros */
105213 +/************************/
105214 +#ifdef CONFIG_FMAN_ARM
105215 +#define in_be16(a) __be16_to_cpu(__raw_readw(a))
105216 +#define in_be32(a) __be32_to_cpu(__raw_readl(a))
105217 +#define out_be16(a, v) __raw_writew(__cpu_to_be16(v), a)
105218 +#define out_be32(a, v) __raw_writel(__cpu_to_be32(v), a)
105219 +#endif
105220 +
105221 +#define GET_UINT8(arg) *(volatile uint8_t *)(&(arg))
105222 +#define GET_UINT16(arg) in_be16(&(arg))//*(volatile uint16_t*)(&(arg))
105223 +#define GET_UINT32(arg) in_be32(&(arg))//*(volatile uint32_t*)(&(arg))
105224 +#define GET_UINT64(arg) *(volatile uint64_t*)(&(arg))
105225 +
105226 +#ifdef VERBOSE_WRITE
105227 +void XX_Print(char *str, ...);
105228 +#define WRITE_UINT8(arg, data) \
105229 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%02x\r\n", (uint32_t)&(arg), (data)); *(volatile uint8_t *)(&(arg)) = (data); } while (0)
105230 +#define WRITE_UINT16(arg, data) \
105231 + 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)
105232 +#define WRITE_UINT32(arg, data) \
105233 + 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)
105234 +#define WRITE_UINT64(arg, data) \
105235 + do { XX_Print("ADDR: 0x%08x, VAL: 0x%016llx\r\n", (uint32_t)&(arg), (data)); *(volatile uint64_t*)(&(arg)) = (data); } while (0)
105236 +
105237 +#else /* not VERBOSE_WRITE */
105238 +#define WRITE_UINT8(arg, data) *(volatile uint8_t *)(&(arg)) = (data)
105239 +#define WRITE_UINT16(arg, data) out_be16(&(arg), data)//*(volatile uint16_t*)(&(arg)) = (data)
105240 +#define WRITE_UINT32(arg, data) out_be32(&(arg), data)//*(volatile unsigned int *)(&(arg)) = (data)
105241 +#define WRITE_UINT64(arg, data) *(volatile uint64_t*)(&(arg)) = (data)
105242 +#endif /* not VERBOSE_WRITE */
105243 +
105244 +
105245 +/*****************************************************************************/
105246 +/* General stuff */
105247 +/*****************************************************************************/
105248 +#ifdef ARRAY_SIZE
105249 +#undef ARRAY_SIZE
105250 +#endif /* ARRAY_SIZE */
105251 +
105252 +#ifdef MAJOR
105253 +#undef MAJOR
105254 +#endif /* MAJOR */
105255 +
105256 +#ifdef MINOR
105257 +#undef MINOR
105258 +#endif /* MINOR */
105259 +
105260 +#ifdef QE_SIZEOF_BD
105261 +#undef QE_SIZEOF_BD
105262 +#endif /* QE_SIZEOF_BD */
105263 +
105264 +#ifdef BD_BUFFER_CLEAR
105265 +#undef BD_BUFFER_CLEAR
105266 +#endif /* BD_BUFFER_CLEAR */
105267 +
105268 +#ifdef BD_BUFFER
105269 +#undef BD_BUFFER
105270 +#endif /* BD_BUFFER */
105271 +
105272 +#ifdef BD_STATUS_AND_LENGTH_SET
105273 +#undef BD_STATUS_AND_LENGTH_SET
105274 +#endif /* BD_STATUS_AND_LENGTH_SET */
105275 +
105276 +#ifdef BD_STATUS_AND_LENGTH
105277 +#undef BD_STATUS_AND_LENGTH
105278 +#endif /* BD_STATUS_AND_LENGTH */
105279 +
105280 +#ifdef BD_BUFFER_ARG
105281 +#undef BD_BUFFER_ARG
105282 +#endif /* BD_BUFFER_ARG */
105283 +
105284 +#ifdef BD_GET_NEXT
105285 +#undef BD_GET_NEXT
105286 +#endif /* BD_GET_NEXT */
105287 +
105288 +#ifdef QE_SDEBCR_BA_MASK
105289 +#undef QE_SDEBCR_BA_MASK
105290 +#endif /* QE_SDEBCR_BA_MASK */
105291 +
105292 +#ifdef BD_BUFFER_SET
105293 +#undef BD_BUFFER_SET
105294 +#endif /* BD_BUFFER_SET */
105295 +
105296 +#ifdef UPGCR_PROTOCOL
105297 +#undef UPGCR_PROTOCOL
105298 +#endif /* UPGCR_PROTOCOL */
105299 +
105300 +#ifdef UPGCR_TMS
105301 +#undef UPGCR_TMS
105302 +#endif /* UPGCR_TMS */
105303 +
105304 +#ifdef UPGCR_RMS
105305 +#undef UPGCR_RMS
105306 +#endif /* UPGCR_RMS */
105307 +
105308 +#ifdef UPGCR_ADDR
105309 +#undef UPGCR_ADDR
105310 +#endif /* UPGCR_ADDR */
105311 +
105312 +#ifdef UPGCR_DIAG
105313 +#undef UPGCR_DIAG
105314 +#endif /* UPGCR_DIAG */
105315 +
105316 +#ifdef NCSW_PARAMS
105317 +#undef NCSW_PARAMS
105318 +#endif /* NCSW_PARAMS */
105319 +
105320 +#ifdef NO_IRQ
105321 +#undef NO_IRQ
105322 +#endif /* NO_IRQ */
105323 +
105324 +#define PRINT_LINE XX_Print("%s:\n %s [%d]\n",__FILE__,__FUNCTION__,__LINE__);
105325 +
105326 +
105327 +#endif /* __TYPES_LINUX_H__ */
105328 --- /dev/null
105329 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/fsl_fman_test.h
105330 @@ -0,0 +1,84 @@
105331 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
105332 + * All rights reserved.
105333 + *
105334 + * Redistribution and use in source and binary forms, with or without
105335 + * modification, are permitted provided that the following conditions are met:
105336 + * * Redistributions of source code must retain the above copyright
105337 + * notice, this list of conditions and the following disclaimer.
105338 + * * Redistributions in binary form must reproduce the above copyright
105339 + * notice, this list of conditions and the following disclaimer in the
105340 + * documentation and/or other materials provided with the distribution.
105341 + * * Neither the name of Freescale Semiconductor nor the
105342 + * names of its contributors may be used to endorse or promote products
105343 + * derived from this software without specific prior written permission.
105344 + *
105345 + *
105346 + * ALTERNATIVELY, this software may be distributed under the terms of the
105347 + * GNU General Public License ("GPL") as published by the Free Software
105348 + * Foundation, either version 2 of that License or (at your option) any
105349 + * later version.
105350 + *
105351 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105352 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105353 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105354 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105355 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105356 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105357 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105358 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105359 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105360 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105361 + */
105362 +
105363 +/******************************************************************************
105364 + @File fsl_fman_test.h
105365 +
105366 + @Description
105367 +*//***************************************************************************/
105368 +
105369 +#ifndef __FSL_FMAN_TEST_H
105370 +#define __FSL_FMAN_TEST_H
105371 +
105372 +#include <linux/types.h>
105373 +#include <linux/smp.h> /* raw_smp_processor_id() */
105374 +
105375 +//#define FMT_K_DBG
105376 +//#define FMT_K_DBG_RUNTIME
105377 +
105378 +#define _fmt_prk(stage, format, arg...) \
105379 + printk(stage "fmt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
105380 +
105381 +#define _fmt_inf(format, arg...) _fmt_prk(KERN_INFO, format, ##arg)
105382 +#define _fmt_wrn(format, arg...) _fmt_prk(KERN_WARNING, format, ##arg)
105383 +#define _fmt_err(format, arg...) _fmt_prk(KERN_ERR, format, ##arg)
105384 +
105385 +/* there are two macros for debugging: for runtime and generic.
105386 + * Helps when the runtime functions are not targeted for debugging,
105387 + * thus all the unnecessary information will be skipped.
105388 + */
105389 +/* used for generic debugging */
105390 +#if defined(FMT_K_DBG)
105391 + #define _fmt_dbg(format, arg...) \
105392 + printk("fmt [%s:%u](cpu:%u) - " format, \
105393 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
105394 +#else
105395 +# define _fmt_dbg(arg...)
105396 +#endif
105397 +
105398 +/* used for debugging runtime functions */
105399 +#if defined(FMT_K_DBG_RUNTIME)
105400 + #define _fmt_dbgr(format, arg...) \
105401 + printk("fmt [%s:%u](cpu:%u) - " format, \
105402 + __func__, __LINE__, raw_smp_processor_id(), ##arg)
105403 +#else
105404 +# define _fmt_dbgr(arg...)
105405 +#endif
105406 +
105407 +#define FMT_RX_ERR_Q 0xffffffff
105408 +#define FMT_RX_DFLT_Q 0xfffffffe
105409 +#define FMT_TX_ERR_Q 0xfffffffd
105410 +#define FMT_TX_CONF_Q 0xfffffffc
105411 +
105412 +#define FMAN_TEST_MAX_TX_FQS 8
105413 +
105414 +#endif /* __FSL_FMAN_TEST_H */
105415 --- /dev/null
105416 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_exp_sym.h
105417 @@ -0,0 +1,130 @@
105418 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
105419 + * All rights reserved.
105420 + *
105421 + * Redistribution and use in source and binary forms, with or without
105422 + * modification, are permitted provided that the following conditions are met:
105423 + * * Redistributions of source code must retain the above copyright
105424 + * notice, this list of conditions and the following disclaimer.
105425 + * * Redistributions in binary form must reproduce the above copyright
105426 + * notice, this list of conditions and the following disclaimer in the
105427 + * documentation and/or other materials provided with the distribution.
105428 + * * Neither the name of Freescale Semiconductor nor the
105429 + * names of its contributors may be used to endorse or promote products
105430 + * derived from this software without specific prior written permission.
105431 + *
105432 + *
105433 + * ALTERNATIVELY, this software may be distributed under the terms of the
105434 + * GNU General Public License ("GPL") as published by the Free Software
105435 + * Foundation, either version 2 of that License or (at your option) any
105436 + * later version.
105437 + *
105438 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105439 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105440 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105441 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105442 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105443 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105444 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105445 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105446 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105447 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105448 + */
105449 +
105450 +/*
105451 + @File lnxwrp_exp_sym.h
105452 + @Description FMan exported routines
105453 +*/
105454 +
105455 +#ifndef __LNXWRP_EXP_SYM_H
105456 +#define __LNXWRP_EXP_SYM_H
105457 +
105458 +#include "fm_port_ext.h"
105459 +#include "fm_pcd_ext.h"
105460 +#include "fm_mac_ext.h"
105461 +
105462 +
105463 +/* FMAN Port exported routines */
105464 +EXPORT_SYMBOL(FM_PORT_Disable);
105465 +EXPORT_SYMBOL(FM_PORT_Enable);
105466 +EXPORT_SYMBOL(FM_PORT_SetPCD);
105467 +EXPORT_SYMBOL(FM_PORT_DeletePCD);
105468 +
105469 +/* Runtime PCD exported routines */
105470 +EXPORT_SYMBOL(FM_PCD_Enable);
105471 +EXPORT_SYMBOL(FM_PCD_Disable);
105472 +EXPORT_SYMBOL(FM_PCD_GetCounter);
105473 +EXPORT_SYMBOL(FM_PCD_PrsLoadSw);
105474 +EXPORT_SYMBOL(FM_PCD_KgSetDfltValue);
105475 +EXPORT_SYMBOL(FM_PCD_KgSetAdditionalDataAfterParsing);
105476 +EXPORT_SYMBOL(FM_PCD_SetException);
105477 +EXPORT_SYMBOL(FM_PCD_ModifyCounter);
105478 +EXPORT_SYMBOL(FM_PCD_SetPlcrStatistics);
105479 +EXPORT_SYMBOL(FM_PCD_SetPrsStatistics);
105480 +EXPORT_SYMBOL(FM_PCD_ForceIntr);
105481 +EXPORT_SYMBOL(FM_PCD_HcTxConf);
105482 +
105483 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsSet);
105484 +EXPORT_SYMBOL(FM_PCD_NetEnvCharacteristicsDelete);
105485 +EXPORT_SYMBOL(FM_PCD_KgSchemeSet);
105486 +EXPORT_SYMBOL(FM_PCD_KgSchemeDelete);
105487 +EXPORT_SYMBOL(FM_PCD_KgSchemeGetCounter);
105488 +EXPORT_SYMBOL(FM_PCD_KgSchemeSetCounter);
105489 +EXPORT_SYMBOL(FM_PCD_CcRootBuild);
105490 +EXPORT_SYMBOL(FM_PCD_CcRootDelete);
105491 +EXPORT_SYMBOL(FM_PCD_MatchTableSet);
105492 +EXPORT_SYMBOL(FM_PCD_MatchTableDelete);
105493 +EXPORT_SYMBOL(FM_PCD_CcRootModifyNextEngine);
105494 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyNextEngine);
105495 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyNextEngine);
105496 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyMissNextEngine);
105497 +EXPORT_SYMBOL(FM_PCD_MatchTableRemoveKey);
105498 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNRemoveKey);
105499 +EXPORT_SYMBOL(FM_PCD_MatchTableAddKey);
105500 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKeyAndNextEngine);
105501 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKeyAndNextEngine);
105502 +EXPORT_SYMBOL(FM_PCD_MatchTableModifyKey);
105503 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNModifyKey);
105504 +EXPORT_SYMBOL(FM_PCD_MatchTableGetIndexedHashBucket);
105505 +EXPORT_SYMBOL(FM_PCD_MatchTableGetNextEngine);
105506 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyCounter);
105507 +EXPORT_SYMBOL(FM_PCD_MatchTableGetKeyStatistics);
105508 +EXPORT_SYMBOL(FM_PCD_MatchTableFindNGetKeyStatistics);
105509 +EXPORT_SYMBOL(FM_PCD_MatchTableGetMissStatistics);
105510 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissStatistics);
105511 +EXPORT_SYMBOL(FM_PCD_HashTableSet);
105512 +EXPORT_SYMBOL(FM_PCD_HashTableDelete);
105513 +EXPORT_SYMBOL(FM_PCD_HashTableAddKey);
105514 +EXPORT_SYMBOL(FM_PCD_HashTableRemoveKey);
105515 +EXPORT_SYMBOL(FM_PCD_HashTableModifyNextEngine);
105516 +EXPORT_SYMBOL(FM_PCD_HashTableModifyMissNextEngine);
105517 +EXPORT_SYMBOL(FM_PCD_HashTableGetMissNextEngine);
105518 +EXPORT_SYMBOL(FM_PCD_HashTableFindNGetKeyStatistics);
105519 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSet);
105520 +EXPORT_SYMBOL(FM_PCD_PlcrProfileDelete);
105521 +EXPORT_SYMBOL(FM_PCD_PlcrProfileGetCounter);
105522 +EXPORT_SYMBOL(FM_PCD_PlcrProfileSetCounter);
105523 +EXPORT_SYMBOL(FM_PCD_ManipNodeSet);
105524 +EXPORT_SYMBOL(FM_PCD_ManipNodeDelete);
105525 +EXPORT_SYMBOL(FM_PCD_ManipGetStatistics);
105526 +EXPORT_SYMBOL(FM_PCD_ManipNodeReplace);
105527 +#if (DPAA_VERSION >= 11)
105528 +EXPORT_SYMBOL(FM_PCD_FrmReplicSetGroup);
105529 +EXPORT_SYMBOL(FM_PCD_FrmReplicDeleteGroup);
105530 +EXPORT_SYMBOL(FM_PCD_FrmReplicAddMember);
105531 +EXPORT_SYMBOL(FM_PCD_FrmReplicRemoveMember);
105532 +#endif /* DPAA_VERSION >= 11 */
105533 +
105534 +#ifdef FM_CAPWAP_SUPPORT
105535 +EXPORT_SYMBOL(FM_PCD_StatisticsSetNode);
105536 +#endif /* FM_CAPWAP_SUPPORT */
105537 +
105538 +EXPORT_SYMBOL(FM_PCD_SetAdvancedOffloadSupport);
105539 +
105540 +/* FMAN MAC exported routines */
105541 +EXPORT_SYMBOL(FM_MAC_GetStatistics);
105542 +
105543 +EXPORT_SYMBOL(FM_MAC_GetFrameSizeCounters);
105544 +
105545 +EXPORT_SYMBOL(FM_GetSpecialOperationCoding);
105546 +
105547 +#endif /* __LNXWRP_EXP_SYM_H */
105548 --- /dev/null
105549 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fm_ext.h
105550 @@ -0,0 +1,163 @@
105551 +/*
105552 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105553 + *
105554 + * Redistribution and use in source and binary forms, with or without
105555 + * modification, are permitted provided that the following conditions are met:
105556 + * * Redistributions of source code must retain the above copyright
105557 + * notice, this list of conditions and the following disclaimer.
105558 + * * Redistributions in binary form must reproduce the above copyright
105559 + * notice, this list of conditions and the following disclaimer in the
105560 + * documentation and/or other materials provided with the distribution.
105561 + * * Neither the name of Freescale Semiconductor nor the
105562 + * names of its contributors may be used to endorse or promote products
105563 + * derived from this software without specific prior written permission.
105564 + *
105565 + *
105566 + * ALTERNATIVELY, this software may be distributed under the terms of the
105567 + * GNU General Public License ("GPL") as published by the Free Software
105568 + * Foundation, either version 2 of that License or (at your option) any
105569 + * later version.
105570 + *
105571 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105572 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105573 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105574 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105575 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105576 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105577 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105578 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105579 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105580 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105581 + */
105582 +
105583 +/******************************************************************************
105584 + @File lnxwrp_fm_ext.h
105585 +
105586 + @Description TODO
105587 +*//***************************************************************************/
105588 +
105589 +#ifndef __LNXWRP_FM_EXT_H
105590 +#define __LNXWRP_FM_EXT_H
105591 +
105592 +#include "std_ext.h"
105593 +#include "sys_ext.h"
105594 +#include "fm_ext.h"
105595 +#include "fm_muram_ext.h"
105596 +#include "fm_pcd_ext.h"
105597 +#include "fm_port_ext.h"
105598 +#include "fm_mac_ext.h"
105599 +#include "fm_rtc_ext.h"
105600 +
105601 +
105602 +/**************************************************************************//**
105603 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
105604 +
105605 + @Description FM API functions, definitions and enums.
105606 +
105607 + @{
105608 +*//***************************************************************************/
105609 +
105610 +/**************************************************************************//**
105611 + @Group FM_LnxKern_init_grp Initialization Unit
105612 +
105613 + @Description Initialization Unit
105614 +
105615 + Initialization Flow:
105616 + Initialization of the FM Module will be carried out by the Linux
105617 + kernel according to the following sequence:
105618 + a. Calling the initialization routine with no parameters.
105619 + b. The driver will register to the Device-Tree.
105620 + c. The Linux Device-Tree will initiate a call to the driver for
105621 + initialization.
105622 + d. The driver will read the appropriate information from the Device-Tree
105623 + e. [Optional] Calling the advance initialization routines to change
105624 + driver's defaults.
105625 + f. Initialization of the device will be automatically upon using it.
105626 +
105627 + @{
105628 +*//***************************************************************************/
105629 +
105630 +typedef struct t_WrpFmDevSettings
105631 +{
105632 + t_FmParams param;
105633 + t_SysObjectAdvConfigEntry *advConfig;
105634 +} t_WrpFmDevSettings;
105635 +
105636 +typedef struct t_WrpFmPcdDevSettings
105637 +{
105638 + t_FmPcdParams param;
105639 + t_SysObjectAdvConfigEntry *advConfig;
105640 +} t_WrpFmPcdDevSettings;
105641 +
105642 +typedef struct t_WrpFmPortDevSettings
105643 +{
105644 + bool frag_enabled;
105645 + t_FmPortParams param;
105646 + t_SysObjectAdvConfigEntry *advConfig;
105647 +} t_WrpFmPortDevSettings;
105648 +
105649 +typedef struct t_WrpFmMacDevSettings
105650 +{
105651 + t_FmMacParams param;
105652 + t_SysObjectAdvConfigEntry *advConfig;
105653 +} t_WrpFmMacDevSettings;
105654 +
105655 +
105656 +/**************************************************************************//**
105657 + @Function LNXWRP_FM_Init
105658 +
105659 + @Description Initialize the FM linux wrapper.
105660 +
105661 + @Return A handle (descriptor) of the newly created FM Linux wrapper
105662 + structure.
105663 +*//***************************************************************************/
105664 +t_Handle LNXWRP_FM_Init(void);
105665 +
105666 +/**************************************************************************//**
105667 + @Function LNXWRP_FM_Free
105668 +
105669 + @Description Free the FM linux wrapper.
105670 +
105671 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
105672 +
105673 + @Return E_OK on success; Error code otherwise.
105674 +*//***************************************************************************/
105675 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm);
105676 +
105677 +/**************************************************************************//**
105678 + @Function LNXWRP_FM_GetMacHandle
105679 +
105680 + @Description Get the FM-MAC LLD handle from the FM linux wrapper.
105681 +
105682 + @Param[in] h_LnxWrpFm - A handle to the FM linux wrapper.
105683 + @Param[in] fmId - Index of the FM device to get the MAC handle from.
105684 + @Param[in] macId - Index of the mac handle.
105685 +
105686 + @Return A handle of the LLD compressor.
105687 +*//***************************************************************************/
105688 +t_Handle LNXWRP_FM_GetMacHandle(t_Handle h_LnxWrpFm, uint8_t fmId, uint8_t macId);
105689 +
105690 +#ifdef CONFIG_FSL_SDK_FMAN_TEST
105691 +t_Handle LNXWRP_FM_TEST_Init(void);
105692 +t_Error LNXWRP_FM_TEST_Free(t_Handle h_FmTestLnxWrp);
105693 +#endif /* CONFIG_FSL_SDK_FMAN_TEST */
105694 +
105695 +/** @} */ /* end of FM_LnxKern_init_grp group */
105696 +
105697 +
105698 +/**************************************************************************//**
105699 + @Group FM_LnxKern_ctrl_grp Control Unit
105700 +
105701 + @Description Control Unit
105702 +
105703 + TODO
105704 + @{
105705 +*//***************************************************************************/
105706 +
105707 +#include "lnxwrp_fsl_fman.h"
105708 +
105709 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
105710 +/** @} */ /* end of FM_LnxKern_grp group */
105711 +
105712 +
105713 +#endif /* __LNXWRP_FM_EXT_H */
105714 --- /dev/null
105715 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/wrapper/lnxwrp_fsl_fman.h
105716 @@ -0,0 +1,921 @@
105717 +/*
105718 + * Copyright 2008-2012 Freescale Semiconductor Inc.
105719 + *
105720 + * Redistribution and use in source and binary forms, with or without
105721 + * modification, are permitted provided that the following conditions are met:
105722 + * * Redistributions of source code must retain the above copyright
105723 + * notice, this list of conditions and the following disclaimer.
105724 + * * Redistributions in binary form must reproduce the above copyright
105725 + * notice, this list of conditions and the following disclaimer in the
105726 + * documentation and/or other materials provided with the distribution.
105727 + * * Neither the name of Freescale Semiconductor nor the
105728 + * names of its contributors may be used to endorse or promote products
105729 + * derived from this software without specific prior written permission.
105730 + *
105731 + *
105732 + * ALTERNATIVELY, this software may be distributed under the terms of the
105733 + * GNU General Public License ("GPL") as published by the Free Software
105734 + * Foundation, either version 2 of that License or (at your option) any
105735 + * later version.
105736 + *
105737 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
105738 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
105739 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
105740 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
105741 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
105742 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
105743 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
105744 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
105745 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
105746 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105747 + */
105748 +
105749 +/******************************************************************************
105750 + @File lnxwrp_fsl_fman.h
105751 +
105752 + @Description Linux internal kernel API
105753 +*//***************************************************************************/
105754 +
105755 +#ifndef __LNXWRP_FSL_FMAN_H
105756 +#define __LNXWRP_FSL_FMAN_H
105757 +
105758 +#include <linux/types.h>
105759 +#include <linux/device.h> /* struct device */
105760 +#include <linux/fsl_qman.h> /* struct qman_fq */
105761 +#include "dpaa_integration_ext.h"
105762 +#include "fm_port_ext.h"
105763 +#include "fm_mac_ext.h"
105764 +#include "fm_macsec_ext.h"
105765 +#include "fm_rtc_ext.h"
105766 +
105767 +/**************************************************************************//**
105768 + @Group FM_LnxKern_grp Frame Manager Linux wrapper API
105769 +
105770 + @Description FM API functions, definitions and enums.
105771 +
105772 + @{
105773 +*//***************************************************************************/
105774 +
105775 +/**************************************************************************//**
105776 + @Group FM_LnxKern_ctrl_grp Control Unit
105777 +
105778 + @Description Control Unit
105779 +
105780 + Internal Kernel Control Unit API
105781 + @{
105782 +*//***************************************************************************/
105783 +
105784 +/*****************************************************************************/
105785 +/* Internal Linux kernel routines */
105786 +/*****************************************************************************/
105787 +
105788 +/**************************************************************************//**
105789 + @Description MACSEC Exceptions wrapper
105790 +*//***************************************************************************/
105791 +typedef enum fm_macsec_exception {
105792 + SINGLE_BIT_ECC = e_FM_MACSEC_EX_SINGLE_BIT_ECC,
105793 + MULTI_BIT_ECC = e_FM_MACSEC_EX_MULTI_BIT_ECC
105794 +} fm_macsec_exception;
105795 +
105796 +/**************************************************************************//**
105797 + @Description Unknown sci frame treatment wrapper
105798 +*//***************************************************************************/
105799 +typedef enum fm_macsec_unknown_sci_frame_treatment {
105800 + SCI_DISCARD_BOTH = e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_BOTH,
105801 + SCI_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
105802 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED,
105803 + SCI_DELIVER_UNCTRL_DISCARD_CTRL = \
105804 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
105805 + SCI_DELIVER_DISCARD_UNCTRL_DELIVER_DISCARD_CTRL = \
105806 + e_FM_MACSEC_UNKNOWN_SCI_FRAME_TREATMENT_DELIVER_OR_DISCARD_UNCONTROLLED_DELIVER_OR_DISCARD_CONTROLLED
105807 +} fm_macsec_unknown_sci_frame_treatment;
105808 +
105809 +/**************************************************************************//**
105810 + @Description Untag frame treatment wrapper
105811 +*//***************************************************************************/
105812 +typedef enum fm_macsec_untag_frame_treatment {
105813 + UNTAG_DELIVER_UNCTRL_DISCARD_CTRL = \
105814 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DELIVER_UNCONTROLLED_DISCARD_CONTROLLED,
105815 + UNTAG_DISCARD_BOTH = e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_BOTH,
105816 + UNTAG_DISCARD_UNCTRL_DELIVER_CTRL_UNMODIFIED = \
105817 + e_FM_MACSEC_UNTAG_FRAME_TREATMENT_DISCARD_UNCONTROLLED_DELIVER_CONTROLLED_UNMODIFIED
105818 +} fm_macsec_untag_frame_treatment;
105819 +
105820 +/**************************************************************************//**
105821 +@Description MACSEC SECY Cipher Suite wrapper
105822 +*//***************************************************************************/
105823 +typedef enum fm_macsec_secy_cipher_suite {
105824 + SECY_GCM_AES_128 = e_FM_MACSEC_SECY_GCM_AES_128, /**< GCM-AES-128 */
105825 +#if (DPAA_VERSION >= 11)
105826 + SECY_GCM_AES_256 = e_FM_MACSEC_SECY_GCM_AES_256 /**< GCM-AES-256 */
105827 +#endif /* (DPAA_VERSION >= 11) */
105828 +} fm_macsec_secy_cipher_suite;
105829 +
105830 +/**************************************************************************//**
105831 + @Description MACSEC SECY Exceptions wrapper
105832 +*//***************************************************************************/
105833 +typedef enum fm_macsec_secy_exception {
105834 + SECY_EX_FRAME_DISCARDED = e_FM_MACSEC_SECY_EX_FRAME_DISCARDED
105835 +} fm_macsec_secy_exception;
105836 +
105837 +/**************************************************************************//**
105838 + @Description MACSEC SECY Events wrapper
105839 +*//***************************************************************************/
105840 +typedef enum fm_macsec_secy_event {
105841 + SECY_EV_NEXT_PN = e_FM_MACSEC_SECY_EV_NEXT_PN
105842 +} fm_macsec_secy_event;
105843 +
105844 +/**************************************************************************//**
105845 + @Description Valid frame behaviors wrapper
105846 +*//***************************************************************************/
105847 +typedef enum fm_macsec_valid_frame_behavior {
105848 + VALID_FRAME_BEHAVIOR_DISABLE = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_DISABLE,
105849 + VALID_FRAME_BEHAVIOR_CHECK = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_CHECK,
105850 + VALID_FRAME_BEHAVIOR_STRICT = e_FM_MACSEC_VALID_FRAME_BEHAVIOR_STRICT
105851 +} fm_macsec_valid_frame_behavior;
105852 +
105853 +/**************************************************************************//**
105854 + @Description SCI insertion modes wrapper
105855 +*//***************************************************************************/
105856 +typedef enum fm_macsec_sci_insertion_mode {
105857 + SCI_INSERTION_MODE_EXPLICIT_SECTAG = \
105858 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_SECTAG,
105859 + SCI_INSERTION_MODE_EXPLICIT_MAC_SA = \
105860 + e_FM_MACSEC_SCI_INSERTION_MODE_EXPLICIT_MAC_SA,
105861 + SCI_INSERTION_MODE_IMPLICT_PTP = e_FM_MACSEC_SCI_INSERTION_MODE_IMPLICT_PTP
105862 +} fm_macsec_sci_insertion_mode;
105863 +
105864 +typedef macsecSAKey_t macsec_sa_key_t;
105865 +typedef macsecSCI_t macsec_sci_t;
105866 +typedef macsecAN_t macsec_an_t;
105867 +typedef t_Handle handle_t;
105868 +
105869 +/**************************************************************************//**
105870 + @Function fm_macsec_secy_exception_callback wrapper
105871 + @Description Exceptions user callback routine, will be called upon an
105872 + exception passing the exception identification.
105873 + @Param[in] app_h A handle to an application layer object; This handle
105874 + will be passed by the driver upon calling this callback.
105875 + @Param[in] exception The exception.
105876 +*//***************************************************************************/
105877 +typedef void (fm_macsec_secy_exception_callback) (handle_t app_h,
105878 + fm_macsec_secy_exception exception);
105879 +
105880 +/**************************************************************************//**
105881 + @Function fm_macsec_secy_event_callback wrapper
105882 + @Description Events user callback routine, will be called upon an
105883 + event passing the event identification.
105884 + @Param[in] app_h A handle to an application layer object; This handle
105885 + will be passed by the driver upon calling this callback.
105886 + @Param[in] event The event.
105887 +*//***************************************************************************/
105888 +typedef void (fm_macsec_secy_event_callback) (handle_t app_h,
105889 + fm_macsec_secy_event event);
105890 +
105891 +/**************************************************************************//**
105892 + @Function fm_macsec_exception_callback wrapper
105893 + @Description Exceptions user callback routine, will be called upon an
105894 + exception passing the exception identification.
105895 + @Param[in] app_h A handle to an application layer object; This handle
105896 + will be passed by the driver upon calling this callback.
105897 + @Param[in] exception The exception.
105898 +*//***************************************************************************/
105899 +typedef void (fm_macsec_exception_callback) (handle_t app_h,
105900 + fm_macsec_exception exception);
105901 +
105902 +/**************************************************************************//**
105903 + @Description MACSEC SecY SC Params wrapper
105904 +*//***************************************************************************/
105905 +struct fm_macsec_secy_sc_params {
105906 + macsec_sci_t sci;
105907 + fm_macsec_secy_cipher_suite cipher_suite;
105908 +};
105909 +
105910 +/**************************************************************************//**
105911 + @Description FM MACSEC SecY config input wrapper
105912 +*//***************************************************************************/
105913 +struct fm_macsec_secy_params {
105914 + handle_t fm_macsec_h;
105915 + struct fm_macsec_secy_sc_params tx_sc_params;
105916 + uint32_t num_receive_channels;
105917 + fm_macsec_secy_exception_callback *exception_f;
105918 + fm_macsec_secy_event_callback *event_f;
105919 + handle_t app_h;
105920 +};
105921 +
105922 +/**************************************************************************//**
105923 + @Description FM MACSEC config input wrapper
105924 +*//***************************************************************************/
105925 +struct fm_macsec_params {
105926 + handle_t fm_h;
105927 + bool guest_mode;
105928 +
105929 + union {
105930 + struct {
105931 + uint8_t fm_mac_id;
105932 + } guest_params;
105933 +
105934 + struct {
105935 + uintptr_t base_addr;
105936 + handle_t fm_mac_h;
105937 + fm_macsec_exception_callback *exception_f;
105938 + handle_t app_h;
105939 + } non_guest_params;
105940 + };
105941 +
105942 +};
105943 +
105944 +/**************************************************************************//**
105945 + @Description FM device opaque structure used for type checking
105946 +*//***************************************************************************/
105947 +struct fm;
105948 +
105949 +/**************************************************************************//**
105950 + @Description FM MAC device opaque structure used for type checking
105951 +*//***************************************************************************/
105952 +struct fm_mac_dev;
105953 +
105954 +/**************************************************************************//**
105955 + @Description FM MACSEC device opaque structure used for type checking
105956 +*//***************************************************************************/
105957 +struct fm_macsec_dev;
105958 +struct fm_macsec_secy_dev;
105959 +
105960 +/**************************************************************************//**
105961 + @Description A structure ..,
105962 +*//***************************************************************************/
105963 +struct fm_port;
105964 +
105965 +typedef int (*alloc_pcd_fqids)(struct device *dev, uint32_t num,
105966 + uint8_t alignment, uint32_t *base_fqid);
105967 +
105968 +typedef int (*free_pcd_fqids)(struct device *dev, uint32_t base_fqid);
105969 +
105970 +struct fm_port_pcd_param {
105971 + alloc_pcd_fqids cba;
105972 + free_pcd_fqids cbf;
105973 + struct device *dev;
105974 +};
105975 +
105976 +/**************************************************************************//**
105977 + @Description A structure of information about each of the external
105978 + buffer pools used by the port,
105979 +*//***************************************************************************/
105980 +struct fm_port_pool_param {
105981 + uint8_t id; /**< External buffer pool id */
105982 + uint16_t size; /**< External buffer pool buffer size */
105983 +};
105984 +
105985 +/**************************************************************************//**
105986 + @Description structure for additional port parameters
105987 +*//***************************************************************************/
105988 +struct fm_port_params {
105989 + uint32_t errq; /**< Error Queue Id. */
105990 + uint32_t defq; /**< For Tx and HC - Default Confirmation queue,
105991 + 0 means no Tx conf for processed frames.
105992 + For Rx and OP - default Rx queue. */
105993 + uint8_t num_pools; /**< Number of pools use by this port */
105994 + struct fm_port_pool_param pool_param[FM_PORT_MAX_NUM_OF_EXT_POOLS];
105995 + /**< Parameters for each pool */
105996 + uint16_t priv_data_size; /**< Area that user may save for his own
105997 + need (E.g. save the SKB) */
105998 + bool parse_results; /**< Put the parser-results in the Rx/Tx buffer */
105999 + bool hash_results; /**< Put the hash-results in the Rx/Tx buffer */
106000 + bool time_stamp; /**< Put the time-stamp in the Rx/Tx buffer */
106001 + bool frag_enable; /**< Fragmentation support, for OP only */
106002 + uint16_t data_align; /**< value for selecting a data alignment (must be a power of 2);
106003 + if write optimization is used, must be >= 16. */
106004 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
106005 + Note that this field impacts the size of the buffer-prefix
106006 + (i.e. it pushes the data offset); */
106007 +};
106008 +
106009 +/**************************************************************************//**
106010 + @Function fm_bind
106011 +
106012 + @Description Bind to a specific FM device.
106013 +
106014 + @Param[in] fm_dev - the OF handle of the FM device.
106015 +
106016 + @Return A handle of the FM device.
106017 +
106018 + @Cautions Allowed only after the port was created.
106019 +*//***************************************************************************/
106020 +struct fm *fm_bind(struct device *fm_dev);
106021 +
106022 +/**************************************************************************//**
106023 + @Function fm_unbind
106024 +
106025 + @Description Un-bind from a specific FM device.
106026 +
106027 + @Param[in] fm - A handle of the FM device.
106028 +
106029 + @Cautions Allowed only after the port was created.
106030 +*//***************************************************************************/
106031 +void fm_unbind(struct fm *fm);
106032 +
106033 +void *fm_get_handle(struct fm *fm);
106034 +void *fm_get_rtc_handle(struct fm *fm);
106035 +struct resource *fm_get_mem_region(struct fm *fm);
106036 +
106037 +/**************************************************************************//**
106038 + @Function fm_port_bind
106039 +
106040 + @Description Bind to a specific FM-port device (may be Rx or Tx port).
106041 +
106042 + @Param[in] fm_port_dev - the OF handle of the FM port device.
106043 +
106044 + @Return A handle of the FM port device.
106045 +
106046 + @Cautions Allowed only after the port was created.
106047 +*//***************************************************************************/
106048 +struct fm_port *fm_port_bind(struct device *fm_port_dev);
106049 +
106050 +/**************************************************************************//**
106051 + @Function fm_port_unbind
106052 +
106053 + @Description Un-bind from a specific FM-port device (may be Rx or Tx port).
106054 +
106055 + @Param[in] port - A handle of the FM port device.
106056 +
106057 + @Cautions Allowed only after the port was created.
106058 +*//***************************************************************************/
106059 +void fm_port_unbind(struct fm_port *port);
106060 +
106061 +/**************************************************************************//**
106062 + @Function fm_set_rx_port_params
106063 +
106064 + @Description Configure parameters for a specific Rx FM-port device.
106065 +
106066 + @Param[in] port - A handle of the FM port device.
106067 + @Param[in] params - Rx port parameters
106068 +
106069 + @Cautions Allowed only after the port is binded.
106070 +*//***************************************************************************/
106071 +void fm_set_rx_port_params(struct fm_port *port,
106072 + struct fm_port_params *params);
106073 +
106074 +/**************************************************************************//**
106075 + @Function fm_port_pcd_bind
106076 +
106077 + @Description Bind as a listener on a port PCD.
106078 +
106079 + @Param[in] port - A handle of the FM port device.
106080 + @Param[in] params - PCD port parameters
106081 +
106082 + @Cautions Allowed only after the port is binded.
106083 +*//***************************************************************************/
106084 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params);
106085 +
106086 +/**************************************************************************//**
106087 + @Function fm_port_get_buff_layout_ext_params
106088 +
106089 + @Description Get data_align and manip_extra_space from the device tree
106090 + chosen node if applied.
106091 + This function will only update these two parameters.
106092 + When this port has no such parameters in the device tree
106093 + values will be set to 0.
106094 +
106095 + @Param[in] port - A handle of the FM port device.
106096 + @Param[in] params - PCD port parameters
106097 +
106098 + @Cautions Allowed only after the port is binded.
106099 +*//***************************************************************************/
106100 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params);
106101 +
106102 +/**************************************************************************//**
106103 + @Function fm_get_tx_port_channel
106104 +
106105 + @Description Get qman-channel number for this Tx port.
106106 +
106107 + @Param[in] port - A handle of the FM port device.
106108 +
106109 + @Return qman-channel number for this Tx port.
106110 +
106111 + @Cautions Allowed only after the port is binded.
106112 +*//***************************************************************************/
106113 +uint16_t fm_get_tx_port_channel(struct fm_port *port);
106114 +
106115 +/**************************************************************************//**
106116 + @Function fm_set_tx_port_params
106117 +
106118 + @Description Configure parameters for a specific Tx FM-port device
106119 +
106120 + @Param[in] port - A handle of the FM port device.
106121 + @Param[in] params - Tx port parameters
106122 +
106123 + @Cautions Allowed only after the port is binded.
106124 +*//***************************************************************************/
106125 +void fm_set_tx_port_params(struct fm_port *port, struct fm_port_params *params);
106126 +
106127 +
106128 +/**************************************************************************//**
106129 + @Function fm_mac_set_handle
106130 +
106131 + @Description Set mac handle
106132 +
106133 + @Param[in] h_lnx_wrp_fm_dev - A handle of the LnxWrp FM device.
106134 + @Param[in] h_fm_mac - A handle of the LnxWrp FM MAC device.
106135 + @Param[in] mac_id - MAC id.
106136 +*//***************************************************************************/
106137 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev, t_Handle h_fm_mac,
106138 + int mac_id);
106139 +
106140 +/**************************************************************************//**
106141 + @Function fm_port_enable
106142 +
106143 + @Description Enable specific FM-port device (may be Rx or Tx port).
106144 +
106145 + @Param[in] port - A handle of the FM port device.
106146 +
106147 + @Cautions Allowed only after the port is initialized.
106148 +*//***************************************************************************/
106149 +int fm_port_enable(struct fm_port *port);
106150 +
106151 +/**************************************************************************//**
106152 + @Function fm_port_disable
106153 +
106154 + @Description Disable specific FM-port device (may be Rx or Tx port).
106155 +
106156 + @Param[in] port - A handle of the FM port device.
106157 +
106158 + @Cautions Allowed only after the port is initialized.
106159 +*//***************************************************************************/
106160 +int fm_port_disable(struct fm_port *port);
106161 +
106162 +void *fm_port_get_handle(const struct fm_port *port);
106163 +
106164 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
106165 + const void *data);
106166 +
106167 +/**************************************************************************//**
106168 + @Function fm_port_get_base_address
106169 +
106170 + @Description Get base address of this port. Useful for accessing
106171 + port-specific registers (i.e., not common ones).
106172 +
106173 + @Param[in] port - A handle of the FM port device.
106174 +
106175 + @Param[out] base_addr - The port's base addr (virtual address).
106176 +*//***************************************************************************/
106177 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr);
106178 +
106179 +/**************************************************************************//**
106180 + @Function fm_mutex_lock
106181 +
106182 + @Description Lock function required before any FMD/LLD call.
106183 +*//***************************************************************************/
106184 +void fm_mutex_lock(void);
106185 +
106186 +/**************************************************************************//**
106187 + @Function fm_mutex_unlock
106188 +
106189 + @Description Unlock function required after any FMD/LLD call.
106190 +*//***************************************************************************/
106191 +void fm_mutex_unlock(void);
106192 +
106193 +/**************************************************************************//**
106194 + @Function fm_get_max_frm
106195 +
106196 + @Description Get the maximum frame size
106197 +*//***************************************************************************/
106198 +int fm_get_max_frm(void);
106199 +
106200 +/**************************************************************************//**
106201 + @Function fm_get_rx_extra_headroom
106202 +
106203 + @Description Get the extra headroom size
106204 +*//***************************************************************************/
106205 +int fm_get_rx_extra_headroom(void);
106206 +
106207 +/**************************************************************************//**
106208 +@Function fm_port_set_rate_limit
106209 +
106210 +@Description Configure Shaper parameter on FM-port device (Tx port).
106211 +
106212 +@Param[in] port - A handle of the FM port device.
106213 +@Param[in] max_burst_size - Value of maximum burst size allowed.
106214 +@Param[in] rate_limit - The required rate value.
106215 +
106216 +@Cautions Allowed only after the port is initialized.
106217 +*//***************************************************************************/
106218 +int fm_port_set_rate_limit(struct fm_port *port,
106219 + uint16_t max_burst_size,
106220 + uint32_t rate_limit);
106221 +/**************************************************************************//**
106222 +@Function fm_port_set_rate_limit
106223 +
106224 +@Description Delete Shaper configuration on FM-port device (Tx port).
106225 +
106226 +@Param[in] port - A handle of the FM port device.
106227 +
106228 +@Cautions Allowed only after the port is initialized.
106229 +*//***************************************************************************/
106230 +int fm_port_del_rate_limit(struct fm_port *port);
106231 +
106232 +struct auto_res_tables_sizes
106233 +{
106234 + uint16_t max_num_of_arp_entries;
106235 + uint16_t max_num_of_echo_ipv4_entries;
106236 + uint16_t max_num_of_ndp_entries;
106237 + uint16_t max_num_of_echo_ipv6_entries;
106238 + uint16_t max_num_of_snmp_ipv4_entries;
106239 + uint16_t max_num_of_snmp_ipv6_entries;
106240 + uint16_t max_num_of_snmp_oid_entries;
106241 + uint16_t max_num_of_snmp_char; /* total amount of character needed
106242 + for the snmp table */
106243 + uint16_t max_num_of_ip_prot_filtering;
106244 + uint16_t max_num_of_tcp_port_filtering;
106245 + uint16_t max_num_of_udp_port_filtering;
106246 +};
106247 +/* ARP */
106248 +struct auto_res_arp_entry
106249 +{
106250 + uint32_t ip_address;
106251 + uint8_t mac[6];
106252 + bool is_vlan;
106253 + uint16_t vid;
106254 +};
106255 +struct auto_res_arp_info
106256 +{
106257 + uint8_t table_size;
106258 + struct auto_res_arp_entry *auto_res_table;
106259 + bool enable_conflict_detection; /* when TRUE
106260 + Conflict Detection will be checked and wake the host if
106261 + needed */
106262 +};
106263 +
106264 +/* NDP */
106265 +struct auto_res_ndp_entry
106266 +{
106267 + uint32_t ip_address[4];
106268 + uint8_t mac[6];
106269 + bool is_vlan;
106270 + uint16_t vid;
106271 +};
106272 +struct auto_res_ndp_info
106273 +{
106274 + uint32_t multicast_group;
106275 + uint8_t table_size_assigned;
106276 + struct auto_res_ndp_entry *auto_res_table_assigned; /* This list
106277 + refer to solicitation IP addresses. Note that all IP adresses
106278 + must be from the same multicast group. This will be checked and
106279 + if not operation will fail. */
106280 + uint8_t table_size_tmp;
106281 + struct auto_res_ndp_entry *auto_res_table_tmp; /* This list
106282 + refer to temp IP addresses. Note that all temp IP adresses must
106283 + be from the same multicast group. This will be checked and if
106284 + not operation will fail. */
106285 +
106286 + bool enable_conflict_detection; /* when TRUE
106287 + Conflict Detection will be checked and wake the host if
106288 + needed */
106289 +};
106290 +
106291 +/* ICMP ECHO */
106292 +struct auto_res_echo_ipv4_info
106293 +{
106294 + uint8_t table_size;
106295 + struct auto_res_arp_entry *auto_res_table;
106296 +};
106297 +
106298 +struct auto_res_echo_ipv6_info
106299 +{
106300 + uint8_t table_size;
106301 + struct auto_res_ndp_entry *auto_res_table;
106302 +};
106303 +
106304 +/* SNMP */
106305 +struct auto_res_snmp_entry
106306 +{
106307 + uint16_t oidSize;
106308 + uint8_t *oidVal; /* only the oid string */
106309 + uint16_t resSize;
106310 + uint8_t *resVal; /* resVal will be the entire reply,
106311 + i.e. "Type|Length|Value" */
106312 +};
106313 +
106314 +/**************************************************************************//**
106315 + @Description Deep Sleep Auto Response SNMP IPv4 Addresses Table Entry
106316 + Refer to the FMan Controller spec for more details.
106317 +*//***************************************************************************/
106318 +struct auto_res_snmp_ipv4addr_tbl_entry
106319 +{
106320 + uint32_t ipv4addr; /*!< 32 bit IPv4 Address. */
106321 + bool is_vlan;
106322 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
106323 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
106324 +};
106325 +
106326 +/**************************************************************************//**
106327 + @Description Deep Sleep Auto Response SNMP IPv6 Addresses Table Entry
106328 + Refer to the FMan Controller spec for more details.
106329 +*//***************************************************************************/
106330 +struct auto_res_snmp_ipv6addr_tbl_entry
106331 +{
106332 + uint32_t ipv6Addr[4]; /*!< 4 * 32 bit IPv6 Address. */
106333 + bool isVlan;
106334 + uint16_t vid; /*!< 12 bits VLAN ID. The 4 left-most bits should be cleared */
106335 + /*!< This field should be 0x0000 for an entry with no VLAN tag or a null VLAN ID. */
106336 +};
106337 +
106338 +struct auto_res_snmp_info
106339 +{
106340 + uint16_t control; /**< Control bits [0-15]. */
106341 + uint16_t max_snmp_msg_length; /**< Maximal allowed SNMP message length. */
106342 + uint16_t num_ipv4_addresses; /**< Number of entries in IPv4 addresses table. */
106343 + uint16_t num_ipv6_addresses; /**< Number of entries in IPv6 addresses table. */
106344 + struct auto_res_snmp_ipv4addr_tbl_entry *ipv4addr_tbl; /**< Pointer to IPv4 addresses table. */
106345 + struct auto_res_snmp_ipv6addr_tbl_entry *ipv6addr_tbl; /**< Pointer to IPv6 addresses table. */
106346 + char *community_read_write_string;
106347 + char *community_read_only_string;
106348 + struct auto_res_snmp_entry *oid_table;
106349 + uint32_t oid_table_size;
106350 + uint32_t *statistics;
106351 +};
106352 +
106353 +/* Filtering */
106354 +struct auto_res_port_filtering_entry
106355 +{
106356 + uint16_t src_port;
106357 + uint16_t dst_port;
106358 + uint16_t src_port_mask;
106359 + uint16_t dst_port_mask;
106360 +};
106361 +struct auto_res_filtering_info
106362 +{
106363 + /* IP protocol filtering parameters */
106364 + uint8_t ip_prot_table_size;
106365 + uint8_t *ip_prot_table_ptr;
106366 + bool ip_prot_pass_on_hit; /* when TRUE, miss in the table will
106367 + cause the packet to be droped, hit will pass the packet to
106368 + UDP/TCP filters if needed and if not to the classification
106369 + tree. If the classification tree will pass the packet to a
106370 + queue it will cause a wake interupt. When FALSE it the other
106371 + way around. */
106372 + /* UDP port filtering parameters */
106373 + uint8_t udp_ports_table_size;
106374 + struct auto_res_port_filtering_entry *udp_ports_table_ptr;
106375 + bool udp_port_pass_on_hit; /* when TRUE, miss in the table will
106376 + cause the packet to be droped, hit will pass the packet to
106377 + classification tree. If the classification tree will pass the
106378 + packet to a queue it will cause a wake interupt. When FALSE it
106379 + the other way around. */
106380 + /* TCP port filtering parameters */
106381 + uint16_t tcp_flags_mask;
106382 + uint8_t tcp_ports_table_size;
106383 + struct auto_res_port_filtering_entry *tcp_ports_table_ptr;
106384 + bool tcp_port_pass_on_hit; /* when TRUE, miss in the table will
106385 + cause the packet to be droped, hit will pass the packet to
106386 + classification tree. If the classification tree will pass the
106387 + packet to a queue it will cause a wake interupt. When FALSE it
106388 + the other way around. */
106389 +};
106390 +
106391 +struct auto_res_port_params
106392 +{
106393 + t_Handle h_FmPortTx;
106394 + struct auto_res_arp_info *p_auto_res_arp_info;
106395 + struct auto_res_echo_ipv4_info *p_auto_res_echo_ipv4_info;
106396 + struct auto_res_ndp_info *p_auto_res_ndp_info;
106397 + struct auto_res_echo_ipv6_info *p_auto_res_echo_ipv6_info;
106398 + struct auto_res_snmp_info *p_auto_res_snmp_info;
106399 + struct auto_res_filtering_info *p_auto_res_filtering_info;
106400 +};
106401 +
106402 +struct auto_res_port_stats
106403 +{
106404 + uint32_t arp_ar_cnt;
106405 + uint32_t echo_icmpv4_ar_cnt;
106406 + uint32_t ndp_ar_cnt;
106407 + uint32_t echo_icmpv6_ar_cnt;
106408 +};
106409 +
106410 +int fm_port_config_autores_for_deepsleep_support(struct fm_port *port,
106411 + struct auto_res_tables_sizes *params);
106412 +
106413 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
106414 + struct auto_res_port_params *params);
106415 +
106416 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
106417 + struct fm_port *port_tx);
106418 +
106419 +bool fm_port_is_in_auto_res_mode(struct fm_port *port);
106420 +
106421 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
106422 + struct fm_port *port);
106423 +
106424 +int fm_port_get_autores_stats(struct fm_port *port, struct auto_res_port_stats
106425 + *stats);
106426 +
106427 +int fm_port_resume(struct fm_port *port);
106428 +
106429 +int fm_port_suspend(struct fm_port *port);
106430 +
106431 +#ifdef CONFIG_FMAN_PFC
106432 +/**************************************************************************//**
106433 +@Function fm_port_set_pfc_priorities_mapping_to_qman_wq
106434 +
106435 +@Description Associate a QMan Work Queue with a PFC priority on this
106436 + FM-port device (Tx port).
106437 +
106438 +@Param[in] port - A handle of the FM port device.
106439 +
106440 +@Param[in] prio - The PFC priority.
106441 +
106442 +@Param[in] wq - The Work Queue associated with the PFC priority.
106443 +
106444 +@Cautions Allowed only after the port is initialized.
106445 +*//***************************************************************************/
106446 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
106447 + uint8_t prio, uint8_t wq);
106448 +#endif
106449 +
106450 +/**************************************************************************//**
106451 +@Function fm_mac_set_exception
106452 +
106453 +@Description Set MAC exception state.
106454 +
106455 +@Param[in] fm_mac_dev - A handle of the FM MAC device.
106456 +@Param[in] exception - FM MAC exception type.
106457 +@Param[in] enable - new state.
106458 +
106459 +*//***************************************************************************/
106460 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
106461 + e_FmMacExceptions exception, bool enable);
106462 +
106463 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev);
106464 +
106465 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params);
106466 +
106467 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
106468 + int len);
106469 +
106470 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable);
106471 +
106472 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable);
106473 +
106474 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable);
106475 +
106476 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev);
106477 +
106478 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version);
106479 +
106480 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev);
106481 +
106482 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev);
106483 +
106484 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev);
106485 +
106486 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
106487 + bool enable);
106488 +
106489 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
106490 + t_EnetAddr *mac_addr);
106491 +
106492 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
106493 + t_EnetAddr *mac_addr);
106494 +
106495 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
106496 + uint8_t *addr);
106497 +
106498 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
106499 + bool link, int speed, bool duplex);
106500 +
106501 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
106502 +
106503 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev);
106504 +
106505 +int fm_mac_set_rx_pause_frames(
106506 + struct fm_mac_dev *fm_mac_dev, bool en);
106507 +
106508 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
106509 + bool en);
106510 +
106511 +int fm_rtc_enable(struct fm *fm_dev);
106512 +
106513 +int fm_rtc_disable(struct fm *fm_dev);
106514 +
106515 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts);
106516 +
106517 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts);
106518 +
106519 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift);
106520 +
106521 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift);
106522 +
106523 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
106524 + uint64_t time);
106525 +
106526 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
106527 + uint64_t fiper);
106528 +
106529 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev,
106530 + bool en);
106531 +
106532 +/**************************************************************************//**
106533 +@Function fm_macsec_set_exception
106534 +
106535 +@Description Set MACSEC exception state.
106536 +
106537 +@Param[in] fm_macsec_dev - A handle of the FM MACSEC device.
106538 +@Param[in] exception - FM MACSEC exception type.
106539 +@Param[in] enable - new state.
106540 +
106541 +*//***************************************************************************/
106542 +
106543 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
106544 + fm_macsec_exception exception, bool enable);
106545 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev);
106546 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params);
106547 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev);
106548 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
106549 + *fm_macsec_dev,
106550 + fm_macsec_unknown_sci_frame_treatment treat_mode);
106551 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
106552 + bool deliver_uncontrolled);
106553 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
106554 + bool discard_uncontrolled);
106555 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
106556 + fm_macsec_untag_frame_treatment treat_mode);
106557 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
106558 + uint32_t pnExhThr);
106559 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev);
106560 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev);
106561 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
106562 + fm_macsec_exception exception, bool enable);
106563 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
106564 + int *macsec_revision);
106565 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev);
106566 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev);
106567 +
106568 +
106569 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106570 + fm_macsec_secy_exception exception,
106571 + bool enable);
106572 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
106573 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params);
106574 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
106575 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106576 + fm_macsec_sci_insertion_mode sci_insertion_mode);
106577 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106578 + bool protect_frames);
106579 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106580 + bool replay_protect, uint32_t replay_window);
106581 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106582 + fm_macsec_valid_frame_behavior validate_frames);
106583 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106584 + bool confidentiality_enable,
106585 + uint32_t confidentiality_offset);
106586 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev);
106587 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106588 + fm_macsec_secy_event event,
106589 + bool enable);
106590 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106591 + struct fm_macsec_secy_sc_params *params);
106592 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106593 + struct rx_sc_dev *sc);
106594 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106595 + struct rx_sc_dev *sc, macsec_an_t an,
106596 + uint32_t lowest_pn, macsec_sa_key_t key);
106597 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106598 + struct rx_sc_dev *sc, macsec_an_t an);
106599 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106600 + struct rx_sc_dev *sc,
106601 + macsec_an_t an);
106602 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106603 + struct rx_sc_dev *sc,
106604 + macsec_an_t an);
106605 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106606 + struct rx_sc_dev *sc,
106607 + macsec_an_t an, uint32_t updt_next_pn);
106608 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106609 + struct rx_sc_dev *sc,
106610 + macsec_an_t an, uint32_t updt_lowest_pn);
106611 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106612 + struct rx_sc_dev *sc,
106613 + macsec_an_t an, macsec_sa_key_t key);
106614 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106615 + macsec_an_t an, macsec_sa_key_t key);
106616 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106617 + macsec_an_t an);
106618 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106619 + macsec_an_t next_active_an,
106620 + macsec_sa_key_t key);
106621 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106622 + macsec_an_t an);
106623 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106624 + macsec_an_t *p_an);
106625 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106626 + struct rx_sc_dev *sc, uint32_t *sc_phys_id);
106627 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
106628 + uint32_t *sc_phys_id);
106629 +
106630 +/** @} */ /* end of FM_LnxKern_ctrl_grp group */
106631 +/** @} */ /* end of FM_LnxKern_grp group */
106632 +
106633 +/* default values for initializing PTP 1588 timer clock */
106634 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT 2 /* power of 2 for better performance */
106635 +#define DPA_PTP_NOMINAL_FREQ_PERIOD_NS (1 << DPA_PTP_NOMINAL_FREQ_PERIOD_SHIFT) /* 4ns,250MHz */
106636 +
106637 +#endif /* __LNXWRP_FSL_FMAN_H */
106638 --- /dev/null
106639 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/inc/xx/xx.h
106640 @@ -0,0 +1,50 @@
106641 +/*
106642 + * Copyright 2008-2012 Freescale Semiconductor Inc.
106643 + *
106644 + * Redistribution and use in source and binary forms, with or without
106645 + * modification, are permitted provided that the following conditions are met:
106646 + * * Redistributions of source code must retain the above copyright
106647 + * notice, this list of conditions and the following disclaimer.
106648 + * * Redistributions in binary form must reproduce the above copyright
106649 + * notice, this list of conditions and the following disclaimer in the
106650 + * documentation and/or other materials provided with the distribution.
106651 + * * Neither the name of Freescale Semiconductor nor the
106652 + * names of its contributors may be used to endorse or promote products
106653 + * derived from this software without specific prior written permission.
106654 + *
106655 + *
106656 + * ALTERNATIVELY, this software may be distributed under the terms of the
106657 + * GNU General Public License ("GPL") as published by the Free Software
106658 + * Foundation, either version 2 of that License or (at your option) any
106659 + * later version.
106660 + *
106661 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106662 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106663 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106664 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106665 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106666 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106667 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106668 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106669 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106670 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106671 + */
106672 +
106673 +#ifndef __XX_H
106674 +#define __XX_H
106675 +
106676 +#include "xx_ext.h"
106677 +
106678 +void * xx_Malloc(uint32_t n);
106679 +void xx_Free(void *p);
106680 +
106681 +void *xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t align);
106682 +void xx_FreeSmart(void *p);
106683 +
106684 +/* never used: */
106685 +#define GetDeviceName(irq) ((char *)NULL)
106686 +
106687 +int GetDeviceIrqNum(int irq);
106688 +
106689 +
106690 +#endif /* __XX_H */
106691 --- /dev/null
106692 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/Makefile
106693 @@ -0,0 +1,10 @@
106694 +#
106695 +# Makefile for the Freescale Ethernet controllers
106696 +#
106697 +ccflags-y += -DVERSION=\"\"
106698 +#
106699 +#Include netcomm SW specific definitions
106700 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
106701 +#
106702 +
106703 +obj-y += sys_io.o
106704 --- /dev/null
106705 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/system/sys_io.c
106706 @@ -0,0 +1,171 @@
106707 +/*
106708 + * Copyright 2008-2012 Freescale Semiconductor Inc.
106709 + *
106710 + * Redistribution and use in source and binary forms, with or without
106711 + * modification, are permitted provided that the following conditions are met:
106712 + * * Redistributions of source code must retain the above copyright
106713 + * notice, this list of conditions and the following disclaimer.
106714 + * * Redistributions in binary form must reproduce the above copyright
106715 + * notice, this list of conditions and the following disclaimer in the
106716 + * documentation and/or other materials provided with the distribution.
106717 + * * Neither the name of Freescale Semiconductor nor the
106718 + * names of its contributors may be used to endorse or promote products
106719 + * derived from this software without specific prior written permission.
106720 + *
106721 + *
106722 + * ALTERNATIVELY, this software may be distributed under the terms of the
106723 + * GNU General Public License ("GPL") as published by the Free Software
106724 + * Foundation, either version 2 of that License or (at your option) any
106725 + * later version.
106726 + *
106727 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106728 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106729 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106730 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106731 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106732 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106733 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106734 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106735 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106736 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106737 + */
106738 +
106739 +#include <linux/version.h>
106740 +
106741 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
106742 +#define MODVERSIONS
106743 +#endif
106744 +#ifdef MODVERSIONS
106745 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
106746 +#include <linux/modversions.h>
106747 +#else
106748 +#include <config/modversions.h>
106749 +#endif /* LINUX_VERSION_CODE */
106750 +#endif /* MODVERSIONS */
106751 +
106752 +#include <linux/module.h>
106753 +#include <linux/kernel.h>
106754 +
106755 +#include <asm/io.h>
106756 +
106757 +#include "std_ext.h"
106758 +#include "error_ext.h"
106759 +#include "string_ext.h"
106760 +#include "list_ext.h"
106761 +#include "sys_io_ext.h"
106762 +
106763 +
106764 +#define __ERR_MODULE__ MODULE_UNKNOWN
106765 +
106766 +
106767 +typedef struct {
106768 + uint64_t virtAddr;
106769 + uint64_t physAddr;
106770 + uint32_t size;
106771 + t_List node;
106772 +} t_IoMap;
106773 +#define IOMAP_OBJECT(ptr) LIST_OBJECT(ptr, t_IoMap, node)
106774 +
106775 +LIST(mapsList);
106776 +
106777 +
106778 +static void EnqueueIoMap(t_IoMap *p_IoMap)
106779 +{
106780 + uint32_t intFlags;
106781 +
106782 + intFlags = XX_DisableAllIntr();
106783 + LIST_AddToTail(&p_IoMap->node, &mapsList);
106784 + XX_RestoreAllIntr(intFlags);
106785 +}
106786 +
106787 +static t_IoMap * FindIoMapByVirtAddr(uint64_t addr)
106788 +{
106789 + t_IoMap *p_IoMap;
106790 + t_List *p_Pos;
106791 +
106792 + LIST_FOR_EACH(p_Pos, &mapsList)
106793 + {
106794 + p_IoMap = IOMAP_OBJECT(p_Pos);
106795 + if ((addr >= p_IoMap->virtAddr) && (addr < p_IoMap->virtAddr+p_IoMap->size))
106796 + return p_IoMap;
106797 + }
106798 +
106799 + return NULL;
106800 +}
106801 +
106802 +static t_IoMap * FindIoMapByPhysAddr(uint64_t addr)
106803 +{
106804 + t_IoMap *p_IoMap;
106805 + t_List *p_Pos;
106806 +
106807 + LIST_FOR_EACH(p_Pos, &mapsList)
106808 + {
106809 + p_IoMap = IOMAP_OBJECT(p_Pos);
106810 + if ((addr >= p_IoMap->physAddr) && (addr < p_IoMap->physAddr+p_IoMap->size))
106811 + return p_IoMap;
106812 + }
106813 +
106814 + return NULL;
106815 +}
106816 +
106817 +t_Error SYS_RegisterIoMap (uint64_t virtAddr, uint64_t physAddr, uint32_t size)
106818 +{
106819 + t_IoMap *p_IoMap;
106820 +
106821 + p_IoMap = (t_IoMap*)XX_Malloc(sizeof(t_IoMap));
106822 + if (!p_IoMap)
106823 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
106824 + memset(p_IoMap, 0, sizeof(t_IoMap));
106825 +
106826 + p_IoMap->virtAddr = virtAddr;
106827 + p_IoMap->physAddr = physAddr;
106828 + p_IoMap->size = size;
106829 +
106830 + INIT_LIST(&p_IoMap->node);
106831 + EnqueueIoMap(p_IoMap);
106832 +
106833 + return E_OK;
106834 +}
106835 +
106836 +t_Error SYS_UnregisterIoMap (uint64_t virtAddr)
106837 +{
106838 + t_IoMap *p_IoMap = FindIoMapByVirtAddr(virtAddr);
106839 + if (!p_IoMap)
106840 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
106841 +
106842 + LIST_Del(&p_IoMap->node);
106843 + XX_Free(p_IoMap);
106844 +
106845 + return E_OK;
106846 +}
106847 +
106848 +uint64_t SYS_PhysToVirt(uint64_t addr)
106849 +{
106850 + t_IoMap *p_IoMap = FindIoMapByPhysAddr(addr);
106851 + if (p_IoMap)
106852 + {
106853 + /* This is optimization - put the latest in the list-head - like a cache */
106854 + if (mapsList.p_Next != &p_IoMap->node)
106855 + {
106856 + uint32_t intFlags = XX_DisableAllIntr();
106857 + LIST_DelAndInit(&p_IoMap->node);
106858 + LIST_Add(&p_IoMap->node, &mapsList);
106859 + XX_RestoreAllIntr(intFlags);
106860 + }
106861 + return (uint64_t)(addr - p_IoMap->physAddr + p_IoMap->virtAddr);
106862 + }
106863 + return PTR_TO_UINT(phys_to_virt((unsigned long)addr));
106864 +}
106865 +
106866 +uint64_t SYS_VirtToPhys(uint64_t addr)
106867 +{
106868 + t_IoMap *p_IoMap;
106869 +
106870 + if (addr == 0)
106871 + return 0;
106872 +
106873 + p_IoMap = FindIoMapByVirtAddr(addr);
106874 + if (p_IoMap)
106875 + return (uint64_t)(addr - p_IoMap->virtAddr + p_IoMap->physAddr);
106876 + return (uint64_t)virt_to_phys(UINT_TO_PTR(addr));
106877 +}
106878 --- /dev/null
106879 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/Makefile
106880 @@ -0,0 +1,19 @@
106881 +#
106882 +# Makefile for the Freescale Ethernet controllers
106883 +#
106884 +ccflags-y += -DVERSION=\"\"
106885 +#
106886 +#Include netcomm SW specific definitions
106887 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
106888 +
106889 +NCSW_FM_INC = $(srctree)/drivers/net/ethernet/freescale/sdk_fman/Peripherals/FM/inc
106890 +
106891 +ccflags-y += -I$(NCSW_FM_INC)
106892 +ccflags-y += -I$(NET_DPA)
106893 +
106894 +obj-y += fsl-ncsw-PFM.o
106895 +obj-$(CONFIG_FSL_SDK_FMAN_TEST) += fman_test.o
106896 +
106897 +fsl-ncsw-PFM-objs := lnxwrp_fm.o lnxwrp_fm_port.o lnxwrp_ioctls_fm.o \
106898 + lnxwrp_sysfs.o lnxwrp_sysfs_fm.o lnxwrp_sysfs_fm_port.o
106899 +obj-$(CONFIG_COMPAT) += lnxwrp_ioctls_fm_compat.o
106900 --- /dev/null
106901 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/fman_test.c
106902 @@ -0,0 +1,1665 @@
106903 +/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
106904 + * All rights reserved.
106905 + *
106906 + * Redistribution and use in source and binary forms, with or without
106907 + * modification, are permitted provided that the following conditions are met:
106908 + * * Redistributions of source code must retain the above copyright
106909 + * notice, this list of conditions and the following disclaimer.
106910 + * * Redistributions in binary form must reproduce the above copyright
106911 + * notice, this list of conditions and the following disclaimer in the
106912 + * documentation and/or other materials provided with the distribution.
106913 + * * Neither the name of Freescale Semiconductor nor the
106914 + * names of its contributors may be used to endorse or promote products
106915 + * derived from this software without specific prior written permission.
106916 + *
106917 + *
106918 + * ALTERNATIVELY, this software may be distributed under the terms of the
106919 + * GNU General Public License ("GPL") as published by the Free Software
106920 + * Foundation, either version 2 of that License or (at your option) any
106921 + * later version.
106922 + *
106923 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
106924 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
106925 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
106926 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
106927 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
106928 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
106929 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
106930 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
106931 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
106932 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
106933 + */
106934 +
106935 +/*
106936 + @File fman_test.c
106937 + @Authors Pistirica Sorin Andrei
106938 + @Description FM Linux test environment
106939 +*/
106940 +
106941 +#include <linux/kernel.h>
106942 +#include <linux/module.h>
106943 +#include <linux/fs.h>
106944 +#include <linux/cdev.h>
106945 +#include <linux/device.h>
106946 +#include <linux/io.h>
106947 +#include <linux/ioport.h>
106948 +#include <linux/of_platform.h>
106949 +#include <linux/ip.h>
106950 +#include <linux/compat.h>
106951 +#include <linux/uaccess.h>
106952 +#include <linux/errno.h>
106953 +#include <linux/netdevice.h>
106954 +#include <linux/spinlock.h>
106955 +#include <linux/types.h>
106956 +#include <linux/fsl_qman.h>
106957 +#include <linux/fsl_bman.h>
106958 +
106959 +/* private headers */
106960 +#include "fm_ext.h"
106961 +#include "lnxwrp_fsl_fman.h"
106962 +#include "fm_port_ext.h"
106963 +#if (DPAA_VERSION == 11)
106964 +#include "../../Peripherals/FM/MAC/memac.h"
106965 +#endif
106966 +#include "fm_test_ioctls.h"
106967 +#include "fsl_fman_test.h"
106968 +
106969 +#include "dpaa_eth.h"
106970 +#include "dpaa_eth_common.h"
106971 +
106972 +#define FMT_FRM_WATERMARK 0xdeadbeefdeadbeeaLL
106973 +
106974 +struct fmt_frame_s {
106975 + ioc_fmt_buff_desc_t buff;
106976 + struct list_head list;
106977 +};
106978 +
106979 +struct fmt_fqs_s {
106980 + struct qman_fq fq_base;
106981 + bool init;
106982 + struct fmt_port_s *fmt_port_priv;
106983 +};
106984 +
106985 +struct fmt_port_pcd_s {
106986 + int num_queues;
106987 + struct fmt_fqs_s *fmt_pcd_fqs;
106988 + uint32_t fqid_base;
106989 +};
106990 +
106991 +/* char dev structure: fm test port */
106992 +struct fmt_port_s {
106993 + bool valid;
106994 + uint8_t id;
106995 + ioc_fmt_port_type port_type;
106996 + ioc_diag_mode diag;
106997 + bool compat_test_type;
106998 +
106999 + /* fm ports */
107000 + /* ! for oh ports p_tx_fm_port_dev == p_rx_fm_port_dev &&
107001 + * p_tx_port == p_rx_port */
107002 + /* t_LnxWrpFmPortDev */
107003 + struct fm_port *p_tx_port;
107004 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
107005 + void *p_tx_fm_port_dev;
107006 + /* t_LnxWrpFmPortDev */
107007 + struct fm_port *p_rx_port;
107008 + /* t_LnxWrpFmPortDev->h_Dev: t_FmPort */
107009 + void *p_rx_fm_port_dev;
107010 +
107011 + void *p_mac_dev;
107012 + uint64_t fm_phys_base_addr;
107013 +
107014 + /* read/write queue manipulation */
107015 + spinlock_t rx_q_lock;
107016 + struct list_head rx_q;
107017 +
107018 + /* tx queuee for injecting traffic */
107019 + int num_of_tx_fqs;
107020 + struct fmt_fqs_s p_tx_fqs[FMAN_TEST_MAX_TX_FQS];
107021 +
107022 + /* pcd private queues manipulation */
107023 + struct fmt_port_pcd_s fmt_port_pcd;
107024 +
107025 + /* debugging stuff */
107026 +
107027 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107028 + atomic_t enqueue_to_qman_frm;
107029 + atomic_t enqueue_to_rxq;
107030 + atomic_t dequeue_from_rxq;
107031 + atomic_t not_enqueue_to_rxq_wrong_frm;
107032 +#endif
107033 +
107034 +};
107035 +
107036 +/* The devices. */
107037 +struct fmt_s {
107038 + int major;
107039 + struct fmt_port_s ports[IOC_FMT_MAX_NUM_OF_PORTS];
107040 + struct class *fmt_class;
107041 +};
107042 +
107043 +/* fm test structure */
107044 +static struct fmt_s fm_test;
107045 +
107046 +#if (DPAA_VERSION == 11)
107047 +struct mac_priv_s {
107048 + t_Handle mac;
107049 +};
107050 +#endif
107051 +
107052 +#define DTSEC_BASE_ADDR 0x000e0000
107053 +#define DTSEC_MEM_RANGE 0x00002000
107054 +#define MAC_1G_MACCFG1 0x00000100
107055 +#define MAC_1G_LOOP_MASK 0x00000100
107056 +static int set_1gmac_loopback(
107057 + struct fmt_port_s *fmt_port,
107058 + bool en)
107059 +{
107060 +#if (DPAA_VERSION <= 10)
107061 + uint32_t dtsec_idx = fmt_port->id; /* dtsec for which port */
107062 + uint32_t dtsec_idx_off = dtsec_idx * DTSEC_MEM_RANGE;
107063 + phys_addr_t maccfg1_hw;
107064 + void *maccfg1_map;
107065 + uint32_t maccfg1_val;
107066 +
107067 + /* compute the maccfg1 register address */
107068 + maccfg1_hw = fmt_port->fm_phys_base_addr +
107069 + (phys_addr_t)(DTSEC_BASE_ADDR +
107070 + dtsec_idx_off +
107071 + MAC_1G_MACCFG1);
107072 +
107073 + /* map register */
107074 + maccfg1_map = ioremap(maccfg1_hw, sizeof(u32));
107075 +
107076 + /* set register */
107077 + maccfg1_val = in_be32(maccfg1_map);
107078 + if (en)
107079 + maccfg1_val |= MAC_1G_LOOP_MASK;
107080 + else
107081 + maccfg1_val &= ~MAC_1G_LOOP_MASK;
107082 + out_be32(maccfg1_map, maccfg1_val);
107083 +
107084 + /* unmap register */
107085 + iounmap(maccfg1_map);
107086 +#else
107087 + struct mac_device *mac_dev;
107088 + struct mac_priv_s *priv;
107089 + t_Memac *p_memac;
107090 +
107091 + if (!fmt_port)
107092 + return -EINVAL;
107093 +
107094 + mac_dev = (struct mac_device *)fmt_port->p_mac_dev;
107095 +
107096 + if (!mac_dev)
107097 + return -EINVAL;
107098 +
107099 + priv = macdev_priv(mac_dev);
107100 +
107101 + if (!priv)
107102 + return -EINVAL;
107103 +
107104 + p_memac = priv->mac;
107105 +
107106 + if (!p_memac)
107107 + return -EINVAL;
107108 +
107109 + memac_set_loopback(p_memac->p_MemMap, en);
107110 +#endif
107111 + return 0;
107112 +}
107113 +
107114 +/* TODO: re-write this function */
107115 +static int set_10gmac_int_loopback(
107116 + struct fmt_port_s *fmt_port,
107117 + bool en)
107118 +{
107119 +#ifndef FM_10G_MAC_NO_CTRL_LOOPBACK
107120 +#define FM_10GMAC0_OFFSET 0x000f0000
107121 +#define FM_10GMAC_CMD_CONF_CTRL_OFFSET 0x8
107122 +#define CMD_CFG_LOOPBACK_EN 0x00000400
107123 +
107124 + uint64_t base_addr, reg_addr;
107125 + uint32_t tmp_val;
107126 +
107127 + base_addr = fmt_port->fm_phys_base_addr + (FM_10GMAC0_OFFSET +
107128 + ((fmt_port->id-FM_MAX_NUM_OF_1G_RX_PORTS)*0x2000));
107129 +
107130 + base_addr = PTR_TO_UINT(ioremap(base_addr, 0x1000));
107131 +
107132 + reg_addr = base_addr + FM_10GMAC_CMD_CONF_CTRL_OFFSET;
107133 + tmp_val = GET_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)));
107134 + if (en)
107135 + tmp_val |= CMD_CFG_LOOPBACK_EN;
107136 + else
107137 + tmp_val &= ~CMD_CFG_LOOPBACK_EN;
107138 + WRITE_UINT32(*((uint32_t *)UINT_TO_PTR(reg_addr)), tmp_val);
107139 +
107140 + iounmap(UINT_TO_PTR(base_addr));
107141 +
107142 + return 0;
107143 +#else
107144 + _fmt_err("TGEC don't have internal-loopback.\n");
107145 + return -EPERM;
107146 +#endif
107147 +}
107148 +
107149 +static int set_mac_int_loopback(struct fmt_port_s *fmt_port, bool en)
107150 +{
107151 + int _err = 0;
107152 +
107153 + switch (fmt_port->port_type) {
107154 +
107155 + case e_IOC_FMT_PORT_T_RXTX:
107156 + /* 1G port */
107157 + if (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS)
107158 + _err = set_1gmac_loopback(fmt_port, en);
107159 + /* 10g port */
107160 + else if ((fmt_port->id >= FM_MAX_NUM_OF_1G_RX_PORTS) &&
107161 + (fmt_port->id < FM_MAX_NUM_OF_1G_RX_PORTS +
107162 + FM_MAX_NUM_OF_10G_RX_PORTS)) {
107163 +
107164 + _err = set_10gmac_int_loopback(fmt_port, en);
107165 + } else
107166 + _err = -EINVAL;
107167 + break;
107168 + /* op port does not have MAC (loopback mode) */
107169 + case e_IOC_FMT_PORT_T_OP:
107170 +
107171 + _err = 0;
107172 + break;
107173 + default:
107174 +
107175 + _err = -EPERM;
107176 + break;
107177 + }
107178 +
107179 + return _err;
107180 +}
107181 +
107182 +static void enqueue_fmt_frame(
107183 + struct fmt_port_s *fmt_port,
107184 + struct fmt_frame_s *p_fmt_frame)
107185 +{
107186 + spinlock_t *rx_q_lock = NULL;
107187 +
107188 + rx_q_lock = &fmt_port->rx_q_lock;
107189 +
107190 + spin_lock(rx_q_lock);
107191 + list_add_tail(&p_fmt_frame->list, &fmt_port->rx_q);
107192 + spin_unlock(rx_q_lock);
107193 +
107194 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107195 + atomic_inc(&fmt_port->enqueue_to_rxq);
107196 +#endif
107197 +}
107198 +
107199 +static struct fmt_frame_s *dequeue_fmt_frame(
107200 + struct fmt_port_s *fmt_port)
107201 +{
107202 + struct fmt_frame_s *p_fmt_frame = NULL;
107203 + spinlock_t *rx_q_lock = NULL;
107204 +
107205 + rx_q_lock = &fmt_port->rx_q_lock;
107206 +
107207 + spin_lock(rx_q_lock);
107208 +
107209 +#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
107210 +
107211 + if (!list_empty(&fmt_port->rx_q)) {
107212 + p_fmt_frame = list_last_entry(&fmt_port->rx_q,
107213 + struct fmt_frame_s,
107214 + list);
107215 + list_del(&p_fmt_frame->list);
107216 +
107217 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107218 + atomic_inc(&fmt_port->dequeue_from_rxq);
107219 +#endif
107220 + }
107221 +
107222 + spin_unlock(rx_q_lock);
107223 +
107224 + return p_fmt_frame;
107225 +}
107226 +
107227 +/* eth-dev -to- fmt port association */
107228 +struct fmt_port_s *match_dpa_to_fmt_port(
107229 + struct dpa_priv_s *dpa_priv) {
107230 + struct mac_device *mac_dev = dpa_priv->mac_dev;
107231 + struct fm_port *fm_port = (struct fm_port *) mac_dev;
107232 + struct fmt_port_s *fmt_port = NULL;
107233 + int i;
107234 +
107235 + _fmt_dbgr("calling...\n");
107236 +
107237 + /* find the FM-test-port object */
107238 + for (i = 0; i < IOC_FMT_MAX_NUM_OF_PORTS; i++)
107239 + if ((fm_test.ports[i].p_mac_dev &&
107240 + mac_dev == fm_test.ports[i].p_mac_dev) ||
107241 + fm_port == fm_test.ports[i].p_tx_port) {
107242 +
107243 + fmt_port = &fm_test.ports[i];
107244 + break;
107245 + }
107246 +
107247 + _fmt_dbgr("called\n");
107248 + return fmt_port;
107249 +}
107250 +
107251 +void dump_frame(
107252 + uint8_t *buffer,
107253 + uint32_t size)
107254 +{
107255 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107256 + unsigned int i;
107257 +
107258 + for (i = 0; i < size; i++) {
107259 + if (i%16 == 0)
107260 + printk(KERN_DEBUG "\n");
107261 + printk(KERN_DEBUG "%2x ", *(buffer+i));
107262 + }
107263 +#endif
107264 + return;
107265 +}
107266 +
107267 +bool test_and_steal_frame(struct fmt_port_s *fmt_port,
107268 + uint32_t fqid,
107269 + uint8_t *buffer,
107270 + uint32_t size)
107271 +{
107272 + struct fmt_frame_s *p_fmt_frame = NULL;
107273 + bool test_and_steal_frame_frame;
107274 + uint32_t data_offset;
107275 + uint32_t i;
107276 +
107277 + _fmt_dbgr("calling...\n");
107278 +
107279 + if (!fmt_port || !fmt_port->p_rx_fm_port_dev)
107280 + return false;
107281 +
107282 + /* check watermark */
107283 + test_and_steal_frame_frame = false;
107284 + for (i = 0; i < size; i++) {
107285 + uint64_t temp = *((uint64_t *)(buffer + i));
107286 +
107287 + if (temp == (uint64_t) FMT_FRM_WATERMARK) {
107288 + _fmt_dbgr("watermark found!\n");
107289 + test_and_steal_frame_frame = true;
107290 + break;
107291 + }
107292 + }
107293 +
107294 + if (!test_and_steal_frame_frame) {
107295 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107296 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
107297 +#endif
107298 + _fmt_dbgr("NOT watermark found!\n");
107299 + return false;
107300 + }
107301 +
107302 + /* do not enqueue the tx conf/err frames */
107303 + if ((fqid == FMT_TX_CONF_Q) || (fqid == FMT_TX_ERR_Q))
107304 + goto _test_and_steal_frame_return_true;
107305 +
107306 + _fmt_dbgr("on port %d got FMUC frame\n", fmt_port->id);
107307 + data_offset = FM_PORT_GetBufferDataOffset(
107308 + fmt_port->p_rx_fm_port_dev);
107309 +
107310 + p_fmt_frame = kmalloc(sizeof(struct fmt_frame_s), GFP_KERNEL);
107311 +
107312 + /* dump frame... no more space left on device */
107313 + if (p_fmt_frame == NULL) {
107314 + _fmt_err("no space left on device!\n");
107315 + goto _test_and_steal_frame_return_true;
107316 + }
107317 +
107318 + memset(p_fmt_frame, 0, sizeof(struct fmt_frame_s));
107319 + p_fmt_frame->buff.p_data = kmalloc(size * sizeof(uint8_t), GFP_KERNEL);
107320 +
107321 + /* No more space left on device*/
107322 + if (p_fmt_frame->buff.p_data == NULL) {
107323 + _fmt_err("no space left on device!\n");
107324 + kfree(p_fmt_frame);
107325 + goto _test_and_steal_frame_return_true;
107326 + }
107327 +
107328 + p_fmt_frame->buff.size = size-data_offset;
107329 + p_fmt_frame->buff.qid = fqid;
107330 +
107331 + memcpy(p_fmt_frame->buff.p_data,
107332 + (uint8_t *)PTR_MOVE(buffer, data_offset),
107333 + p_fmt_frame->buff.size);
107334 +
107335 + memcpy(p_fmt_frame->buff.buff_context.fm_prs_res,
107336 + FM_PORT_GetBufferPrsResult(fmt_port->p_rx_fm_port_dev,
107337 + (char *)buffer),
107338 + 32);
107339 +
107340 + /* enqueue frame - this frame will go to us */
107341 + enqueue_fmt_frame(fmt_port, p_fmt_frame);
107342 +
107343 +_test_and_steal_frame_return_true:
107344 + return true;
107345 +}
107346 +
107347 +static int fmt_fq_release(const struct qm_fd *fd)
107348 +{
107349 + struct dpa_bp *_dpa_bp;
107350 + struct bm_buffer _bmb;
107351 +
107352 + if (fd->format == qm_fd_contig) {
107353 + _dpa_bp = dpa_bpid2pool(fd->bpid);
107354 + BUG_ON(IS_ERR(_dpa_bp));
107355 +
107356 + _bmb.hi = fd->addr_hi;
107357 + _bmb.lo = fd->addr_lo;
107358 +
107359 + while (bman_release(_dpa_bp->pool, &_bmb, 1, 0))
107360 + cpu_relax();
107361 +
107362 + } else {
107363 + _fmt_err("frame not supported !\n");
107364 + return -1;
107365 + }
107366 +
107367 + return 0;
107368 +}
107369 +
107370 +/* sync it w/ dpaa_eth.c: DPA_BP_HEAD */
107371 +#define DPA_BP_HEADROOM (DPA_TX_PRIV_DATA_SIZE + \
107372 + fm_get_rx_extra_headroom() + \
107373 + DPA_PARSE_RESULTS_SIZE + \
107374 + DPA_HASH_RESULTS_SIZE)
107375 +#define MAC_HEADER_LENGTH 14
107376 +#define L2_AND_HEADROOM_OFF ((DPA_BP_HEADROOM) + (MAC_HEADER_LENGTH))
107377 +
107378 +/* dpa ingress hooks definition */
107379 +enum dpaa_eth_hook_result fmt_rx_default_hook(
107380 + struct sk_buff *skb,
107381 + struct net_device *net_dev,
107382 + u32 fqid)
107383 +{
107384 + struct dpa_priv_s *dpa_priv = NULL;
107385 + struct fmt_port_s *fmt_port = NULL;
107386 + uint8_t *buffer;
107387 + uint32_t buffer_len;
107388 +
107389 + _fmt_dbgr("calling...\n");
107390 +
107391 + dpa_priv = netdev_priv(net_dev);
107392 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107393 +
107394 + /* conversion from skb to fd:
107395 + * skb cames processed for L3, so we need to go back for
107396 + * layer 2 offset */
107397 + buffer = (uint8_t *)(skb->data - ((int)L2_AND_HEADROOM_OFF));
107398 + buffer_len = skb->len + ((int)L2_AND_HEADROOM_OFF);
107399 +
107400 + /* if is not out frame let dpa to handle it */
107401 + if (test_and_steal_frame(fmt_port,
107402 + FMT_RX_DFLT_Q,
107403 + buffer,
107404 + buffer_len))
107405 + goto _fmt_rx_default_hook_stolen;
107406 +
107407 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
107408 + return DPAA_ETH_CONTINUE;
107409 +
107410 +_fmt_rx_default_hook_stolen:
107411 + dev_kfree_skb(skb);
107412 +
107413 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
107414 + return DPAA_ETH_STOLEN;
107415 +}
107416 +
107417 +enum dpaa_eth_hook_result fmt_rx_error_hook(
107418 + struct net_device *net_dev,
107419 + const struct qm_fd *fd,
107420 + u32 fqid)
107421 +{
107422 + struct dpa_priv_s *dpa_priv = NULL;
107423 + struct dpa_bp *dpa_bp = NULL;
107424 + struct fmt_port_s *fmt_port = NULL;
107425 + void *fd_virt_addr = NULL;
107426 + dma_addr_t addr = qm_fd_addr(fd);
107427 +
107428 + _fmt_dbgr("calling...\n");
107429 +
107430 + dpa_priv = netdev_priv(net_dev);
107431 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107432 +
107433 + /* dpaa doesn't do this... we have to do it here */
107434 + dpa_bp = dpa_bpid2pool(fd->bpid);
107435 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
107436 +
107437 + fd_virt_addr = phys_to_virt(addr);
107438 + /* if is not out frame let dpa to handle it */
107439 + if (test_and_steal_frame(fmt_port,
107440 + FMT_RX_ERR_Q,
107441 + fd_virt_addr,
107442 + fd->length20 + fd->offset)) {
107443 + goto _fmt_rx_error_hook_stolen;
107444 + }
107445 +
107446 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
107447 + return DPAA_ETH_CONTINUE;
107448 +
107449 +_fmt_rx_error_hook_stolen:
107450 + /* the frame data doesn't matter,
107451 + * so, no mapping is needed */
107452 + fmt_fq_release(fd);
107453 +
107454 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
107455 + return DPAA_ETH_STOLEN;
107456 +}
107457 +
107458 +enum dpaa_eth_hook_result fmt_tx_confirm_hook(
107459 + struct net_device *net_dev,
107460 + const struct qm_fd *fd,
107461 + u32 fqid)
107462 +{
107463 + struct dpa_priv_s *dpa_priv = NULL;
107464 + struct fmt_port_s *fmt_port = NULL;
107465 + dma_addr_t addr = qm_fd_addr(fd);
107466 + void *fd_virt_addr = NULL;
107467 + uint32_t fd_len = 0;
107468 +
107469 + _fmt_dbgr("calling...\n");
107470 +
107471 + dpa_priv = netdev_priv(net_dev);
107472 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107473 +
107474 + fd_virt_addr = phys_to_virt(addr);
107475 + fd_len = fd->length20 + fd->offset;
107476 +
107477 + if (fd_len > fm_get_max_frm()) {
107478 + _fmt_err("tx confirm bad frame size: %u!\n", fd_len);
107479 + goto _fmt_tx_confirm_hook_continue;
107480 + }
107481 +
107482 + if (test_and_steal_frame(fmt_port,
107483 + FMT_TX_CONF_Q,
107484 + fd_virt_addr,
107485 + fd_len))
107486 + goto _fmt_tx_confirm_hook_stolen;
107487 +
107488 +_fmt_tx_confirm_hook_continue:
107489 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
107490 + return DPAA_ETH_CONTINUE;
107491 +
107492 +_fmt_tx_confirm_hook_stolen:
107493 + kfree(fd_virt_addr);
107494 +
107495 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
107496 + return DPAA_ETH_STOLEN;
107497 +}
107498 +
107499 +enum dpaa_eth_hook_result fmt_tx_confirm_error_hook(
107500 + struct net_device *net_dev,
107501 + const struct qm_fd *fd,
107502 + u32 fqid)
107503 +{
107504 + struct dpa_priv_s *dpa_priv = NULL;
107505 + struct fmt_port_s *fmt_port = NULL;
107506 + dma_addr_t addr = qm_fd_addr(fd);
107507 + void *fd_virt_addr = NULL;
107508 + uint32_t fd_len = 0;
107509 +
107510 + _fmt_dbgr("calling...\n");
107511 +
107512 + dpa_priv = netdev_priv(net_dev);
107513 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107514 +
107515 + fd_virt_addr = phys_to_virt(addr);
107516 + fd_len = fd->length20 + fd->offset;
107517 +
107518 + if (fd_len > fm_get_max_frm()) {
107519 + _fmt_err("tx confirm err bad frame size: %u !\n", fd_len);
107520 + goto _priv_ingress_tx_err_continue;
107521 + }
107522 +
107523 + if (test_and_steal_frame(fmt_port, FMT_TX_ERR_Q, fd_virt_addr, fd_len))
107524 + goto _priv_ingress_tx_err_stolen;
107525 +
107526 +_priv_ingress_tx_err_continue:
107527 + _fmt_dbgr("called:DPAA_ETH_CONTINUE.\n");
107528 + return DPAA_ETH_CONTINUE;
107529 +
107530 +_priv_ingress_tx_err_stolen:
107531 + kfree(fd_virt_addr);
107532 +
107533 + _fmt_dbgr("called:DPAA_ETH_STOLEN.\n");
107534 + return DPAA_ETH_STOLEN;
107535 +}
107536 +
107537 +/* egress callbacks definition */
107538 +enum qman_cb_dqrr_result fmt_egress_dqrr(
107539 + struct qman_portal *portal,
107540 + struct qman_fq *fq,
107541 + const struct qm_dqrr_entry *dqrr)
107542 +{
107543 + /* this callback should never be called */
107544 + BUG();
107545 + return qman_cb_dqrr_consume;
107546 +}
107547 +
107548 +static void fmt_egress_error_dqrr(
107549 + struct qman_portal *p,
107550 + struct qman_fq *fq,
107551 + const struct qm_mr_entry *msg)
107552 +{
107553 + uint8_t *fd_virt_addr = NULL;
107554 +
107555 + /* tx failure, on the ern callback - release buffer */
107556 + fd_virt_addr = (uint8_t *)phys_to_virt(qm_fd_addr(&msg->ern.fd));
107557 + kfree(fd_virt_addr);
107558 +
107559 + return;
107560 +}
107561 +
107562 +static const struct qman_fq fmt_egress_fq = {
107563 + .cb = { .dqrr = fmt_egress_dqrr,
107564 + .ern = fmt_egress_error_dqrr,
107565 + .fqs = NULL}
107566 +};
107567 +
107568 +int fmt_fq_alloc(
107569 + struct fmt_fqs_s *fmt_fqs,
107570 + const struct qman_fq *qman_fq,
107571 + uint32_t fqid, uint32_t flags,
107572 + uint16_t channel, uint8_t wq)
107573 +{
107574 + int _errno = 0;
107575 +
107576 + _fmt_dbg("calling...\n");
107577 +
107578 + fmt_fqs->fq_base = *qman_fq;
107579 +
107580 + if (fqid == 0) {
107581 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
107582 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
107583 + } else
107584 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
107585 +
107586 + fmt_fqs->init = !(flags & QMAN_FQ_FLAG_NO_MODIFY);
107587 +
107588 + _errno = qman_create_fq(fqid, flags, &fmt_fqs->fq_base);
107589 + if (_errno < 0) {
107590 + _fmt_err("frame queues create failed.\n");
107591 + return -EINVAL;
107592 + }
107593 +
107594 + if (fmt_fqs->init) {
107595 + struct qm_mcc_initfq initfq;
107596 +
107597 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
107598 + initfq.fqd.dest.channel = channel;
107599 + initfq.fqd.dest.wq = wq;
107600 +
107601 + _errno = qman_init_fq(&fmt_fqs->fq_base,
107602 + QMAN_INITFQ_FLAG_SCHED,
107603 + &initfq);
107604 + if (_errno < 0) {
107605 + _fmt_err("frame queues init erorr.\n");
107606 + qman_destroy_fq(&fmt_fqs->fq_base, 0);
107607 + return -EINVAL;
107608 + }
107609 + }
107610 +
107611 + _fmt_dbg("called.\n");
107612 + return 0;
107613 +}
107614 +
107615 +static int fmt_fq_free(struct fmt_fqs_s *fmt_fq)
107616 +{
107617 + int _err = 0;
107618 +
107619 + _fmt_dbg("calling...\n");
107620 +
107621 + if (fmt_fq->init) {
107622 + _err = qman_retire_fq(&fmt_fq->fq_base, NULL);
107623 + if (unlikely(_err < 0))
107624 + _fmt_err("qman_retire_fq(%u) = %d\n",
107625 + qman_fq_fqid(&fmt_fq->fq_base), _err);
107626 +
107627 + _err = qman_oos_fq(&fmt_fq->fq_base);
107628 + if (unlikely(_err < 0))
107629 + _fmt_err("qman_oos_fq(%u) = %d\n",
107630 + qman_fq_fqid(&fmt_fq->fq_base), _err);
107631 + }
107632 +
107633 + qman_destroy_fq(&fmt_fq->fq_base, 0);
107634 +
107635 + _fmt_dbg("called.\n");
107636 + return _err;
107637 +}
107638 +
107639 +/* private pcd dqrr calbacks */
107640 +static enum qman_cb_dqrr_result fmt_pcd_dqrr(
107641 + struct qman_portal *portal,
107642 + struct qman_fq *fq,
107643 + const struct qm_dqrr_entry *dq)
107644 +{
107645 + struct dpa_bp *dpa_bp = NULL;
107646 + dma_addr_t addr = qm_fd_addr(&dq->fd);
107647 + uint8_t *fd_virt_addr = NULL;
107648 + struct fmt_port_s *fmt_port;
107649 + struct fmt_port_pcd_s *fmt_port_pcd;
107650 + uint32_t relative_fqid = 0;
107651 + uint32_t fd_len = 0;
107652 +
107653 + _fmt_dbgr("calling...\n");
107654 +
107655 + /* upcast - from pcd_alloc_fq */
107656 + fmt_port = ((struct fmt_fqs_s *)fq)->fmt_port_priv;
107657 + if (!fmt_port) {
107658 + _fmt_err(" wrong fmt port -to- fq match.\n");
107659 + goto _fmt_pcd_dqrr_return;
107660 + }
107661 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
107662 +
107663 + relative_fqid = dq->fqid - fmt_port_pcd->fqid_base;
107664 + _fmt_dbgr("pcd dqrr got frame on relative fq:%u@base:%u\n",
107665 + relative_fqid, fmt_port_pcd->fqid_base);
107666 +
107667 + fd_len = dq->fd.length20 + dq->fd.offset;
107668 +
107669 + if (fd_len > fm_get_max_frm()) {
107670 + _fmt_err("pcd dqrr wrong frame size: %u (%u:%u)!\n",
107671 + fd_len, dq->fd.length20, dq->fd.offset);
107672 + goto _fmt_pcd_dqrr_return;
107673 + }
107674 +
107675 + dpa_bp = dpa_bpid2pool(dq->fd.bpid);
107676 + dma_unmap_single(dpa_bp->dev, addr, dpa_bp->size, DMA_BIDIRECTIONAL);
107677 +
107678 + fd_virt_addr = phys_to_virt(addr);
107679 + if (!test_and_steal_frame(fmt_port, relative_fqid, fd_virt_addr,
107680 + fd_len)) {
107681 +
107682 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107683 + atomic_inc(&fmt_port->not_enqueue_to_rxq_wrong_frm);
107684 +#endif
107685 + _fmt_wrn("pcd dqrr unrecognized frame@fqid: %u,"
107686 + " frame len: %u (dropped).\n",
107687 + dq->fqid, dq->fd.length20);
107688 + dump_frame(fd_virt_addr, fd_len);
107689 + }
107690 +
107691 +_fmt_pcd_dqrr_return:
107692 + /* no need to map again here */
107693 + fmt_fq_release(&dq->fd);
107694 +
107695 + _fmt_dbgr("calle.\n");
107696 + return qman_cb_dqrr_consume;
107697 +}
107698 +
107699 +static void fmt_pcd_err_dqrr(
107700 + struct qman_portal *qm,
107701 + struct qman_fq *fq,
107702 + const struct qm_mr_entry *msg)
107703 +{
107704 + _fmt_err("this callback should never be called.\n");
107705 + BUG();
107706 + return;
107707 +}
107708 +
107709 +static void fmt_pcd_fqs_dqrr(
107710 + struct qman_portal *qm,
107711 + struct qman_fq *fq,
107712 + const struct qm_mr_entry *msg)
107713 +{
107714 + _fmt_dbg(" fq state(0x%x)@fqid(%u.\n", msg->fq.fqs, msg->fq.fqid);
107715 + return;
107716 +}
107717 +
107718 +/* private pcd queue template */
107719 +static const struct qman_fq pcd_fq = {
107720 + .cb = { .dqrr = fmt_pcd_dqrr,
107721 + .ern = fmt_pcd_err_dqrr,
107722 + .fqs = fmt_pcd_fqs_dqrr}
107723 +};
107724 +
107725 +/* defined as weak in dpaa driver. */
107726 +/* ! parameters come from IOCTL call - US */
107727 +int dpa_alloc_pcd_fqids(
107728 + struct device *dev,
107729 + uint32_t num, uint8_t alignment,
107730 + uint32_t *base_fqid)
107731 +{
107732 + int _err = 0, i;
107733 + struct net_device *net_dev = NULL;
107734 + struct dpa_priv_s *dpa_priv = NULL;
107735 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
107736 + struct fmt_fqs_s *fmt_fqs = NULL;
107737 + struct fmt_port_s *fmt_port = NULL;
107738 + int num_allocated = 0;
107739 +
107740 + _fmt_dbg("calling...\n");
107741 +
107742 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
107743 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
107744 +
107745 + if (!netif_msg_probe(dpa_priv)) {
107746 + _fmt_err("dpa not probe.\n");
107747 + _err = -ENODEV;
107748 + goto _pcd_alloc_fqs_err;
107749 + }
107750 +
107751 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107752 + if (!fmt_port) {
107753 + _fmt_err("fmt port not found.");
107754 + _err = -EINVAL;
107755 + goto _pcd_alloc_fqs_err;
107756 + }
107757 +
107758 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
107759 +
107760 + num_allocated = qman_alloc_fqid_range(base_fqid, num, alignment, 0);
107761 +
107762 + if ((num_allocated <= 0) ||
107763 + (num_allocated < num) ||
107764 + (alignment && (*base_fqid) % alignment)) {
107765 + *base_fqid = 0;
107766 + _fmt_err("Failed to alloc pcd fqs rang.\n");
107767 + _err = -EINVAL;
107768 + goto _pcd_alloc_fqs_err;
107769 + }
107770 +
107771 + _fmt_dbg("wanted %d fqs(align %d), got %d fqids@%u.\n",
107772 + num, alignment, num_allocated, *base_fqid);
107773 +
107774 + /* alloc pcd queues */
107775 + fmt_port_pcd->fmt_pcd_fqs = kmalloc(num_allocated *
107776 + sizeof(struct fmt_fqs_s),
107777 + GFP_KERNEL);
107778 + fmt_port_pcd->num_queues = num_allocated;
107779 + fmt_port_pcd->fqid_base = *base_fqid;
107780 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
107781 +
107782 + /* alloc the pcd queues */
107783 + for (i = 0; i < num_allocated; i++, fmt_fqs++) {
107784 + _err = fmt_fq_alloc(
107785 + fmt_fqs,
107786 + &pcd_fq,
107787 + (*base_fqid) + i, QMAN_FQ_FLAG_NO_ENQUEUE,
107788 + dpa_priv->channel, 7);
107789 +
107790 + if (_err < 0)
107791 + goto _pcd_alloc_fqs_err;
107792 +
107793 + /* upcast to identify from where the frames came from */
107794 + fmt_fqs->fmt_port_priv = fmt_port;
107795 + }
107796 +
107797 + _fmt_dbg("called.\n");
107798 + return _err;
107799 +_pcd_alloc_fqs_err:
107800 + if (num_allocated > 0)
107801 + qman_release_fqid_range(*base_fqid, num_allocated);
107802 + /*TODO: free fmt_pcd_fqs if are any */
107803 +
107804 + _fmt_dbg("called(_err:%d).\n", _err);
107805 + return _err;
107806 +}
107807 +
107808 +/* defined as weak in dpaa driver. */
107809 +int dpa_free_pcd_fqids(
107810 + struct device *dev,
107811 + uint32_t base_fqid)
107812 +{
107813 +
107814 + int _err = 0, i;
107815 + struct net_device *net_dev = NULL;
107816 + struct dpa_priv_s *dpa_priv = NULL;
107817 + struct fmt_port_pcd_s *fmt_port_pcd = NULL;
107818 + struct fmt_fqs_s *fmt_fqs = NULL;
107819 + struct fmt_port_s *fmt_port = NULL;
107820 + int num_allocated = 0;
107821 +
107822 + _fmt_dbg("calling...\n");
107823 +
107824 + net_dev = (typeof(net_dev))dev_get_drvdata(dev);
107825 + dpa_priv = (typeof(dpa_priv))netdev_priv(net_dev);
107826 +
107827 + if (!netif_msg_probe(dpa_priv)) {
107828 + _fmt_err("dpa not probe.\n");
107829 + _err = -ENODEV;
107830 + goto _pcd_free_fqs_err;
107831 + }
107832 +
107833 + fmt_port = match_dpa_to_fmt_port(dpa_priv);
107834 + if (!fmt_port) {
107835 + _fmt_err("fmt port not found.");
107836 + _err = -EINVAL;
107837 + goto _pcd_free_fqs_err;
107838 + }
107839 +
107840 + fmt_port_pcd = &fmt_port->fmt_port_pcd;
107841 + num_allocated = fmt_port_pcd->num_queues;
107842 + fmt_fqs = fmt_port_pcd->fmt_pcd_fqs;
107843 +
107844 + for (i = 0; i < num_allocated; i++, fmt_fqs++)
107845 + fmt_fq_free(fmt_fqs);
107846 +
107847 + qman_release_fqid_range(base_fqid,num_allocated);
107848 +
107849 + kfree(fmt_port_pcd->fmt_pcd_fqs);
107850 + memset(fmt_port_pcd, 0, sizeof(*fmt_port_pcd));
107851 +
107852 + /* debugging stuff */
107853 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107854 + _fmt_dbg(" portid: %u.\n", fmt_port->id);
107855 + _fmt_dbg(" frames enqueue to qman: %u.\n",
107856 + atomic_read(&fmt_port->enqueue_to_qman_frm));
107857 + _fmt_dbg(" frames enqueue to rxq: %u.\n",
107858 + atomic_read(&fmt_port->enqueue_to_rxq));
107859 + _fmt_dbg(" frames dequeue from rxq: %u.\n",
107860 + atomic_read(&fmt_port->dequeue_from_rxq));
107861 + _fmt_dbg(" frames not enqueue to rxq - wrong frm: %u.\n",
107862 + atomic_read(&fmt_port->not_enqueue_to_rxq_wrong_frm));
107863 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
107864 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
107865 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
107866 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
107867 +#endif
107868 + return 0;
107869 +
107870 +_pcd_free_fqs_err:
107871 + return _err;
107872 +}
107873 +
107874 +static int fmt_port_init(
107875 + struct fmt_port_s *fmt_port,
107876 + ioc_fmt_port_param_t *p_Params)
107877 +{
107878 + struct device_node *fm_node, *fm_port_node;
107879 + const uint32_t *uint32_prop;
107880 + int _errno = 0, lenp = 0, i;
107881 + static struct of_device_id fm_node_of_match[] = {
107882 + { .compatible = "fsl,fman", },
107883 + { /* end of list */ },
107884 + };
107885 +
107886 + _fmt_dbg("calling...\n");
107887 +
107888 + /* init send/receive tu US list */
107889 + INIT_LIST_HEAD(&fmt_port->rx_q);
107890 +
107891 + /* check parameters */
107892 + if (p_Params->num_tx_queues > FMAN_TEST_MAX_TX_FQS ||
107893 + p_Params->fm_port_id > IOC_FMT_MAX_NUM_OF_PORTS) {
107894 + _fmt_dbg("wrong test parameters.\n");
107895 + return -EINVAL;
107896 + }
107897 +
107898 + /* set port parameters */
107899 + fmt_port->num_of_tx_fqs = p_Params->num_tx_queues;
107900 + fmt_port->id = p_Params->fm_port_id;
107901 + fmt_port->port_type = p_Params->fm_port_type;
107902 + fmt_port->diag = e_IOC_DIAG_MODE_NONE;
107903 +
107904 + /* init debugging stuff */
107905 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
107906 + atomic_set(&fmt_port->enqueue_to_qman_frm, 0);
107907 + atomic_set(&fmt_port->enqueue_to_rxq, 0);
107908 + atomic_set(&fmt_port->dequeue_from_rxq, 0);
107909 + atomic_set(&fmt_port->not_enqueue_to_rxq_wrong_frm, 0);
107910 +#endif
107911 +
107912 + /* TODO: This should be done at probe time not at runtime
107913 + * very ugly function */
107914 + /* fill fmt port properties from dts */
107915 + for_each_matching_node(fm_node, fm_node_of_match) {
107916 +
107917 + uint32_prop = (uint32_t *)of_get_property(fm_node,
107918 + "cell-index", &lenp);
107919 + if (unlikely(uint32_prop == NULL)) {
107920 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
107921 + fm_node->full_name);
107922 + return -EINVAL;
107923 + }
107924 + if (WARN_ON(lenp != sizeof(uint32_t))) {
107925 + _fmt_wrn("of_get_property(%s, cell-index) invalid",
107926 + fm_node->full_name);
107927 + return -EINVAL;
107928 + }
107929 +
107930 + if (*uint32_prop == p_Params->fm_id) {
107931 + struct resource res;
107932 +
107933 + /* Get the FM address */
107934 + _errno = of_address_to_resource(fm_node, 0, &res);
107935 + if (unlikely(_errno < 0)) {
107936 + _fmt_wrn("of_address_to_resource() = %u.\n", _errno);
107937 + return -EINVAL;
107938 + }
107939 +
107940 + fmt_port->fm_phys_base_addr = res.start;
107941 +
107942 + for_each_child_of_node(fm_node, fm_port_node) {
107943 + struct platform_device *of_dev;
107944 +
107945 + if (!of_device_is_available(fm_port_node))
107946 + continue;
107947 +
107948 + uint32_prop = (uint32_t *)of_get_property(
107949 + fm_port_node,
107950 + "cell-index",
107951 + &lenp);
107952 + if (uint32_prop == NULL)
107953 + continue;
107954 +
107955 + if (of_device_is_compatible(fm_port_node,
107956 + "fsl,fman-port-oh") &&
107957 + (fmt_port->port_type == e_IOC_FMT_PORT_T_OP)) {
107958 +
107959 + if (*uint32_prop == fmt_port->id) {
107960 + of_dev = of_find_device_by_node(fm_port_node);
107961 + if (unlikely(of_dev == NULL)) {
107962 + _fmt_wrn("fm id invalid\n");
107963 + return -EINVAL;
107964 + }
107965 +
107966 + fmt_port->p_tx_port =
107967 + fm_port_bind(&of_dev->dev);
107968 + fmt_port->p_tx_fm_port_dev =
107969 + (void *)fm_port_get_handle(
107970 + fmt_port->p_tx_port);
107971 + fmt_port->p_rx_port =
107972 + fmt_port->p_tx_port;
107973 + fmt_port->p_rx_fm_port_dev =
107974 + fmt_port->p_tx_fm_port_dev;
107975 + fmt_port->p_mac_dev = NULL;
107976 + break;
107977 + }
107978 + } else if ((*uint32_prop == fmt_port->id) &&
107979 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
107980 +
107981 + of_dev = of_find_device_by_node(fm_port_node);
107982 + if (unlikely(of_dev == NULL)) {
107983 + _fmt_wrn("dtb fm id invalid value");
107984 + return -EINVAL;
107985 + }
107986 +
107987 + if (of_device_is_compatible(fm_port_node,
107988 + "fsl,fman-port-1g-tx")) {
107989 + fmt_port->p_tx_port =
107990 + fm_port_bind(&of_dev->dev);
107991 + fmt_port->p_tx_fm_port_dev = (void *)
107992 + fm_port_get_handle(
107993 + fmt_port->p_tx_port);
107994 + } else if (of_device_is_compatible(fm_port_node,
107995 + "fsl,fman-port-1g-rx")) {
107996 + fmt_port->p_rx_port =
107997 + fm_port_bind(&of_dev->dev);
107998 + fmt_port->p_rx_fm_port_dev = (void *)
107999 + fm_port_get_handle(
108000 + fmt_port->p_rx_port);
108001 + } else if (of_device_is_compatible(fm_port_node,
108002 + "fsl,fman-1g-mac") ||
108003 + of_device_is_compatible(fm_port_node,
108004 + "fsl,fman-memac"))
108005 + fmt_port->p_mac_dev =
108006 + (typeof(fmt_port->p_mac_dev))
108007 + dev_get_drvdata(&of_dev->dev);
108008 + else
108009 + continue;
108010 +
108011 + if (fmt_port->p_tx_fm_port_dev &&
108012 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
108013 + break;
108014 + } else if (((*uint32_prop + FM_MAX_NUM_OF_1G_RX_PORTS) ==
108015 + fmt_port->id) &&
108016 + fmt_port->port_type == e_IOC_FMT_PORT_T_RXTX) {
108017 +
108018 + of_dev = of_find_device_by_node(fm_port_node);
108019 + if (unlikely(of_dev == NULL)) {
108020 + _fmt_wrn("dtb fm id invalid value\n");
108021 + return -EINVAL;
108022 + }
108023 +
108024 + if (of_device_is_compatible(fm_port_node,
108025 + "fsl,fman-port-10g-tx")) {
108026 + fmt_port->p_tx_port =
108027 + fm_port_bind(&of_dev->dev);
108028 + fmt_port->p_tx_fm_port_dev = (void *)
108029 + fm_port_get_handle(
108030 + fmt_port->p_tx_port);
108031 + } else if (of_device_is_compatible(fm_port_node,
108032 + "fsl,fman-port-10g-rx")) {
108033 + fmt_port->p_rx_port =
108034 + fm_port_bind(&of_dev->dev);
108035 + fmt_port->p_rx_fm_port_dev = (void *)
108036 + fm_port_get_handle(
108037 + fmt_port->p_rx_port);
108038 + } else if (of_device_is_compatible(fm_port_node,
108039 + "fsl,fman-10g-mac") ||
108040 + of_device_is_compatible(fm_port_node,
108041 + "fsl,fman-memac"))
108042 + fmt_port->p_mac_dev =
108043 + (typeof(fmt_port->p_mac_dev))
108044 + dev_get_drvdata(&of_dev->dev);
108045 + else
108046 + continue;
108047 +
108048 + if (fmt_port->p_tx_fm_port_dev &&
108049 + fmt_port->p_rx_fm_port_dev && fmt_port->p_mac_dev)
108050 + break;
108051 + }
108052 + } /* for_each_child */
108053 + }
108054 + } /* for each matching node */
108055 +
108056 + if (fmt_port->p_tx_fm_port_dev == 0 ||
108057 + fmt_port->p_rx_fm_port_dev == 0) {
108058 +
108059 + _fmt_err("bad fm port pointers.\n");
108060 + return -EINVAL;
108061 + }
108062 +
108063 + _fmt_dbg("alloc %u tx queues.\n", fmt_port->num_of_tx_fqs);
108064 +
108065 + /* init fman test egress dynamic frame queues */
108066 + for (i = 0; i < fmt_port->num_of_tx_fqs; i++) {
108067 + int _errno;
108068 + _errno = fmt_fq_alloc(
108069 + &fmt_port->p_tx_fqs[i],
108070 + &fmt_egress_fq,
108071 + 0,
108072 + QMAN_FQ_FLAG_TO_DCPORTAL,
108073 + fm_get_tx_port_channel(fmt_port->p_tx_port),
108074 + i);
108075 +
108076 + if (_errno < 0) {
108077 + _fmt_err("tx queues allocation failed.\n");
108078 + /* TODO: memory leak here if 1 queue is allocated and
108079 + * next queues are failing ... */
108080 + return -EINVAL;
108081 + }
108082 + }
108083 +
108084 + /* port is valid and ready to use. */
108085 + fmt_port->valid = TRUE;
108086 +
108087 + _fmt_dbg("called.\n");
108088 + return 0;
108089 +}
108090 +
108091 +/* fm test chardev functions */
108092 +static int fmt_open(struct inode *inode, struct file *file)
108093 +{
108094 + unsigned int minor = iminor(inode);
108095 +
108096 + _fmt_dbg("calling...\n");
108097 +
108098 + if (file->private_data != NULL)
108099 + return 0;
108100 +
108101 + /* The minor represent the port number.
108102 + * Set the port structure accordingly, thus all the operations
108103 + * will be done on this port. */
108104 + if ((minor >= DEV_FM_TEST_PORTS_MINOR_BASE) &&
108105 + (minor < DEV_FM_TEST_MAX_MINORS))
108106 + file->private_data = &fm_test.ports[minor];
108107 + else
108108 + return -ENXIO;
108109 +
108110 + _fmt_dbg("called.\n");
108111 + return 0;
108112 +}
108113 +
108114 +static int fmt_close(struct inode *inode, struct file *file)
108115 +{
108116 + struct fmt_port_s *fmt_port = NULL;
108117 + struct fmt_frame_s *fmt_frame = NULL;
108118 +
108119 + int err = 0;
108120 +
108121 + _fmt_dbg("calling...\n");
108122 +
108123 + fmt_port = file->private_data;
108124 + if (!fmt_port)
108125 + return -ENODEV;
108126 +
108127 + /* Close the current test port by invalidating it. */
108128 + fmt_port->valid = FALSE;
108129 +
108130 + /* clean the fmt port queue */
108131 + while ((fmt_frame = dequeue_fmt_frame(fmt_port)) != NULL) {
108132 + if (fmt_frame && fmt_frame->buff.p_data){
108133 + kfree(fmt_frame->buff.p_data);
108134 + kfree(fmt_frame);
108135 + }
108136 + }
108137 +
108138 + /* !!! the qman queues are cleaning from fm_ioctl...
108139 + * - very ugly */
108140 +
108141 + _fmt_dbg("called.\n");
108142 + return err;
108143 +}
108144 +
108145 +static int fmt_ioctls(unsigned int minor,
108146 + struct file *file,
108147 + unsigned int cmd,
108148 + unsigned long arg,
108149 + bool compat)
108150 +{
108151 + struct fmt_port_s *fmt_port = NULL;
108152 +
108153 + _fmt_dbg("IOCTL minor:%u "
108154 + " arg:0x%08lx ioctl cmd (0x%08x):(0x%02x:0x%02x.\n",
108155 + minor, arg, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
108156 +
108157 + fmt_port = file->private_data;
108158 + if (!fmt_port) {
108159 + _fmt_err("invalid fmt port.\n");
108160 + return -ENODEV;
108161 + }
108162 +
108163 + /* set test type properly */
108164 + if (compat)
108165 + fmt_port->compat_test_type = true;
108166 + else
108167 + fmt_port->compat_test_type = false;
108168 +
108169 + switch (cmd) {
108170 + case FMT_PORT_IOC_INIT:
108171 + {
108172 + ioc_fmt_port_param_t param;
108173 +
108174 + if (fmt_port->valid) {
108175 + _fmt_wrn("port is already initialized.\n");
108176 + return -EFAULT;
108177 + }
108178 +#if defined(CONFIG_COMPAT)
108179 + if (compat) {
108180 + if (copy_from_user(&param,
108181 + (ioc_fmt_port_param_t *)compat_ptr(arg),
108182 + sizeof(ioc_fmt_port_param_t)))
108183 +
108184 + return -EFAULT;
108185 + } else
108186 +#endif
108187 + {
108188 + if (copy_from_user(&param,
108189 + (ioc_fmt_port_param_t *) arg,
108190 + sizeof(ioc_fmt_port_param_t)))
108191 +
108192 + return -EFAULT;
108193 + }
108194 +
108195 + return fmt_port_init(fmt_port, &param);
108196 + }
108197 +
108198 + case FMT_PORT_IOC_SET_DIAG_MODE:
108199 + if (get_user(fmt_port->diag, (ioc_diag_mode *)arg))
108200 + return -EFAULT;
108201 +
108202 + if (fmt_port->diag == e_IOC_DIAG_MODE_CTRL_LOOPBACK)
108203 + return set_mac_int_loopback(fmt_port, TRUE);
108204 + else
108205 + return set_mac_int_loopback(fmt_port, FALSE);
108206 + break;
108207 +
108208 + case FMT_PORT_IOC_SET_DPAECHO_MODE:
108209 + case FMT_PORT_IOC_SET_IP_HEADER_MANIP:
108210 + default:
108211 + _fmt_wrn("ioctl unimplemented minor:%u@ioctl"
108212 + " cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
108213 + minor, cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
108214 + return -EFAULT;
108215 + }
108216 +
108217 + return 0;
108218 +}
108219 +
108220 +#ifdef CONFIG_COMPAT
108221 +static long fmt_compat_ioctl(
108222 + struct file *file,
108223 + unsigned int cmd,
108224 + unsigned long arg)
108225 +{
108226 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
108227 +
108228 + _fmt_dbg("calling...\n");
108229 + return fmt_ioctls(minor, file, cmd, arg, true);
108230 +}
108231 +#endif
108232 +
108233 +static long fmt_ioctl(
108234 + struct file *file,
108235 + unsigned int cmd,
108236 + unsigned long arg)
108237 +{
108238 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
108239 + unsigned int res;
108240 +
108241 + _fmt_dbg("calling...\n");
108242 +
108243 + fm_mutex_lock();
108244 + res = fmt_ioctls(minor, file, cmd, arg, false);
108245 + fm_mutex_unlock();
108246 +
108247 + _fmt_dbg("called.\n");
108248 +
108249 + return res;
108250 +}
108251 +
108252 +#ifdef CONFIG_COMPAT
108253 +void copy_compat_test_frame_buffer(
108254 + ioc_fmt_buff_desc_t *buff,
108255 + ioc_fmt_compat_buff_desc_t *compat_buff)
108256 +{
108257 + compat_buff->qid = buff->qid;
108258 + compat_buff->p_data = ptr_to_compat(buff->p_data);
108259 + compat_buff->size = buff->size;
108260 + compat_buff->status = buff->status;
108261 +
108262 + compat_buff->buff_context.p_user_priv =
108263 + ptr_to_compat(buff->buff_context.p_user_priv);
108264 + memcpy(compat_buff->buff_context.fm_prs_res,
108265 + buff->buff_context.fm_prs_res,
108266 + FM_PRS_MAX * sizeof(uint8_t));
108267 + memcpy(compat_buff->buff_context.fm_time_stamp,
108268 + buff->buff_context.fm_time_stamp,
108269 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
108270 +}
108271 +#endif
108272 +
108273 +ssize_t fmt_read(
108274 + struct file *file,
108275 + char __user *buf,
108276 + size_t size,
108277 + loff_t *ppos)
108278 +{
108279 + struct fmt_port_s *fmt_port = NULL;
108280 + struct fmt_frame_s *p_fmt_frame = NULL;
108281 + ssize_t cnt = 0;
108282 +
108283 + fmt_port = file->private_data;
108284 + if (!fmt_port || !fmt_port->valid) {
108285 + _fmt_err("fmt port not valid!\n");
108286 + return -ENODEV;
108287 + }
108288 +
108289 + p_fmt_frame = dequeue_fmt_frame(fmt_port);
108290 + if (p_fmt_frame == NULL)
108291 + return 0;
108292 +
108293 + _fmt_dbgr("calling...\n");
108294 +
108295 +#ifdef CONFIG_COMPAT
108296 + if (fmt_port->compat_test_type){
108297 + cnt = sizeof(ioc_fmt_compat_buff_desc_t);
108298 + }
108299 + else
108300 +#endif
108301 + {
108302 + cnt = sizeof(ioc_fmt_buff_desc_t);
108303 + }
108304 +
108305 + if (size < cnt) {
108306 + _fmt_err("illegal buffer-size!\n");
108307 + cnt = 0;
108308 + goto _fmt_read_return;
108309 + }
108310 +
108311 + /* Copy structure */
108312 +#ifdef CONFIG_COMPAT
108313 + if (fmt_port->compat_test_type) {
108314 + {
108315 + ioc_fmt_compat_buff_desc_t compat_buff;
108316 + copy_compat_test_frame_buffer(&p_fmt_frame->buff,
108317 + &compat_buff);
108318 +
108319 + if (copy_to_user(buf, &compat_buff, cnt)) {
108320 + _fmt_err("copy_to_user failed!\n");
108321 + goto _fmt_read_return;
108322 + }
108323 + }
108324 +
108325 + ((ioc_fmt_compat_buff_desc_t *)buf)->p_data =
108326 + ptr_to_compat(buf+sizeof(ioc_fmt_compat_buff_desc_t));
108327 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
108328 + } else
108329 +#endif
108330 + {
108331 + if (copy_to_user(buf, &p_fmt_frame->buff, cnt)) {
108332 + _fmt_err("copy_to_user failed!\n");
108333 + goto _fmt_read_return;
108334 + }
108335 +
108336 + ((ioc_fmt_buff_desc_t *)buf)->p_data =
108337 + buf + sizeof(ioc_fmt_buff_desc_t);
108338 + cnt += MIN(p_fmt_frame->buff.size, size-cnt);
108339 + }
108340 +
108341 + if (size < cnt) {
108342 + _fmt_err("illegal buffer-size!\n");
108343 + goto _fmt_read_return;
108344 + }
108345 +
108346 + /* copy frame */
108347 +#ifdef CONFIG_COMPAT
108348 + if (fmt_port->compat_test_type) {
108349 + if (copy_to_user(buf+sizeof(ioc_fmt_compat_buff_desc_t),
108350 + p_fmt_frame->buff.p_data, cnt)) {
108351 + _fmt_err("copy_to_user failed!\n");
108352 + goto _fmt_read_return;
108353 + }
108354 + } else
108355 +#endif
108356 + {
108357 + if (copy_to_user(buf+sizeof(ioc_fmt_buff_desc_t),
108358 + p_fmt_frame->buff.p_data, cnt)) {
108359 + _fmt_err("copy_to_user failed!\n");
108360 + goto _fmt_read_return;
108361 + }
108362 + }
108363 +
108364 +_fmt_read_return:
108365 + kfree(p_fmt_frame->buff.p_data);
108366 + kfree(p_fmt_frame);
108367 +
108368 + _fmt_dbgr("called.\n");
108369 + return cnt;
108370 +}
108371 +
108372 +ssize_t fmt_write(
108373 + struct file *file,
108374 + const char __user *buf,
108375 + size_t size,
108376 + loff_t *ppos)
108377 +{
108378 + struct fmt_port_s *fmt_port = NULL;
108379 + ioc_fmt_buff_desc_t buff_desc;
108380 +#ifdef CONFIG_COMPAT
108381 + ioc_fmt_compat_buff_desc_t buff_desc_compat;
108382 +#endif
108383 + uint8_t *p_data = NULL;
108384 + uint32_t data_offset;
108385 + int _errno;
108386 + t_DpaaFD fd;
108387 +
108388 + _fmt_dbgr("calling...\n");
108389 +
108390 + fmt_port = file->private_data;
108391 + if (!fmt_port || !fmt_port->valid) {
108392 + _fmt_err("fmt port not valid.\n");
108393 + return -EINVAL;
108394 + }
108395 +
108396 + /* If Compat (32B UserSpace - 64B KernelSpace) */
108397 +#ifdef CONFIG_COMPAT
108398 + if (fmt_port->compat_test_type) {
108399 + if (size < sizeof(ioc_fmt_compat_buff_desc_t)) {
108400 + _fmt_err("invalid buff_desc size.\n");
108401 + return -EFAULT;
108402 + }
108403 +
108404 + if (copy_from_user(&buff_desc_compat, buf,
108405 + sizeof(ioc_fmt_compat_buff_desc_t)))
108406 + return -EFAULT;
108407 +
108408 + buff_desc.qid = buff_desc_compat.qid;
108409 + buff_desc.p_data = compat_ptr(buff_desc_compat.p_data);
108410 + buff_desc.size = buff_desc_compat.size;
108411 + buff_desc.status = buff_desc_compat.status;
108412 +
108413 + buff_desc.buff_context.p_user_priv =
108414 + compat_ptr(buff_desc_compat.buff_context.p_user_priv);
108415 + memcpy(buff_desc.buff_context.fm_prs_res,
108416 + buff_desc_compat.buff_context.fm_prs_res,
108417 + FM_PRS_MAX * sizeof(uint8_t));
108418 + memcpy(buff_desc.buff_context.fm_time_stamp,
108419 + buff_desc_compat.buff_context.fm_time_stamp,
108420 + FM_TIME_STAMP_MAX * sizeof(uint8_t));
108421 + } else
108422 +#endif
108423 + {
108424 + if (size < sizeof(ioc_fmt_buff_desc_t)) {
108425 + _fmt_err("invalid buff_desc size.\n");
108426 + return -EFAULT;
108427 + }
108428 +
108429 + if (copy_from_user(&buff_desc, (ioc_fmt_buff_desc_t *)buf,
108430 + sizeof(ioc_fmt_buff_desc_t)))
108431 + return -EFAULT;
108432 + }
108433 +
108434 + data_offset = FM_PORT_GetBufferDataOffset(fmt_port->p_tx_fm_port_dev);
108435 + p_data = kmalloc(buff_desc.size+data_offset, GFP_KERNEL);
108436 + if (!p_data)
108437 + return -ENOMEM;
108438 +
108439 + /* If Compat (32UserSpace - 64KernelSpace) the buff_desc.p_data is ok */
108440 + if (copy_from_user((uint8_t *)PTR_MOVE(p_data, data_offset),
108441 + buff_desc.p_data,
108442 + buff_desc.size)) {
108443 + kfree(p_data);
108444 + return -EFAULT;
108445 + }
108446 +
108447 + /* TODO: dma_map_single here (cannot access the bpool struct) */
108448 +
108449 + /* prepare fd */
108450 + memset(&fd, 0, sizeof(fd));
108451 + DPAA_FD_SET_ADDR(&fd, p_data);
108452 + DPAA_FD_SET_OFFSET(&fd, data_offset);
108453 + DPAA_FD_SET_LENGTH(&fd, buff_desc.size);
108454 +
108455 + _errno = qman_enqueue(&fmt_port->p_tx_fqs[buff_desc.qid].fq_base,
108456 + (struct qm_fd *)&fd, 0);
108457 + if (_errno) {
108458 + buff_desc.status = (uint32_t)_errno;
108459 + if (copy_to_user((ioc_fmt_buff_desc_t *)buf, &buff_desc,
108460 + sizeof(ioc_fmt_buff_desc_t))) {
108461 + kfree(p_data);
108462 + return -EFAULT;
108463 + }
108464 + }
108465 +
108466 + /* for debugging */
108467 +#if defined(FMT_K_DBG) || defined(FMT_K_DBG_RUNTIME)
108468 + atomic_inc(&fmt_port->enqueue_to_qman_frm);
108469 +#endif
108470 + _fmt_dbgr("called.\n");
108471 + return buff_desc.size;
108472 +}
108473 +
108474 +/* fm test character device definition */
108475 +static const struct file_operations fmt_fops =
108476 +{
108477 + .owner = THIS_MODULE,
108478 +#ifdef CONFIG_COMPAT
108479 + .compat_ioctl = fmt_compat_ioctl,
108480 +#endif
108481 + .unlocked_ioctl = fmt_ioctl,
108482 + .open = fmt_open,
108483 + .release = fmt_close,
108484 + .read = fmt_read,
108485 + .write = fmt_write,
108486 +};
108487 +
108488 +static int fmt_init(void)
108489 +{
108490 + int id;
108491 +
108492 + _fmt_dbg("calling...\n");
108493 +
108494 + /* Register to the /dev for IOCTL API */
108495 + /* Register dynamically a new major number for the character device: */
108496 + fm_test.major = register_chrdev(0, DEV_FM_TEST_NAME, &fmt_fops);
108497 + if (fm_test.major <= 0) {
108498 + _fmt_wrn("Failed to allocate major number for device %s.\n",
108499 + DEV_FM_TEST_NAME);
108500 + return -ENODEV;
108501 + }
108502 +
108503 + /* Creating class for FMan_test */
108504 + fm_test.fmt_class = class_create(THIS_MODULE, DEV_FM_TEST_NAME);
108505 + if (IS_ERR(fm_test.fmt_class)) {
108506 + unregister_chrdev(fm_test.major, DEV_FM_TEST_NAME);
108507 + _fmt_wrn("Error creating %s class.\n", DEV_FM_TEST_NAME);
108508 + return -ENODEV;
108509 + }
108510 +
108511 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
108512 + if (NULL == device_create(fm_test.fmt_class, NULL,
108513 + MKDEV(fm_test.major,
108514 + DEV_FM_TEST_PORTS_MINOR_BASE + id), NULL,
108515 + DEV_FM_TEST_NAME "%d", id)) {
108516 +
108517 + _fmt_err("Error creating %s device.\n",
108518 + DEV_FM_TEST_NAME);
108519 + return -ENODEV;
108520 + }
108521 +
108522 + return 0;
108523 +}
108524 +
108525 +static void fmt_free(void)
108526 +{
108527 + int id;
108528 +
108529 + for (id = 0; id < IOC_FMT_MAX_NUM_OF_PORTS; id++)
108530 + device_destroy(fm_test.fmt_class, MKDEV(fm_test.major,
108531 + DEV_FM_TEST_PORTS_MINOR_BASE + id));
108532 + class_destroy(fm_test.fmt_class);
108533 +}
108534 +
108535 +static int __init __cold fmt_load(void)
108536 +{
108537 + struct dpaa_eth_hooks_s priv_dpaa_eth_hooks;
108538 +
108539 + /* set dpaa hooks for default queues */
108540 + memset(&priv_dpaa_eth_hooks, 0, sizeof(priv_dpaa_eth_hooks));
108541 + priv_dpaa_eth_hooks.rx_default = fmt_rx_default_hook;
108542 + priv_dpaa_eth_hooks.rx_error = fmt_rx_error_hook;
108543 + priv_dpaa_eth_hooks.tx_confirm = fmt_tx_confirm_hook;
108544 + priv_dpaa_eth_hooks.tx_error = fmt_tx_confirm_error_hook;
108545 +
108546 + fsl_dpaa_eth_set_hooks(&priv_dpaa_eth_hooks);
108547 +
108548 + /* initialize the fman test environment */
108549 + if (fmt_init() < 0) {
108550 + _fmt_err("Failed to init FM-test modul.\n");
108551 + fmt_free();
108552 + return -ENODEV;
108553 + }
108554 +
108555 + _fmt_inf("FSL FM test module loaded.\n");
108556 +
108557 + return 0;
108558 +}
108559 +
108560 +static void __exit __cold fmt_unload(void)
108561 +{
108562 + fmt_free();
108563 + _fmt_inf("FSL FM test module unloaded.\n");
108564 +}
108565 +
108566 +module_init(fmt_load);
108567 +module_exit(fmt_unload);
108568 --- /dev/null
108569 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.c
108570 @@ -0,0 +1,2910 @@
108571 +/*
108572 + * Copyright 2008-2012 Freescale Semiconductor Inc.
108573 + *
108574 + * Redistribution and use in source and binary forms, with or without
108575 + * modification, are permitted provided that the following conditions are met:
108576 + * * Redistributions of source code must retain the above copyright
108577 + * notice, this list of conditions and the following disclaimer.
108578 + * * Redistributions in binary form must reproduce the above copyright
108579 + * notice, this list of conditions and the following disclaimer in the
108580 + * documentation and/or other materials provided with the distribution.
108581 + * * Neither the name of Freescale Semiconductor nor the
108582 + * names of its contributors may be used to endorse or promote products
108583 + * derived from this software without specific prior written permission.
108584 + *
108585 + *
108586 + * ALTERNATIVELY, this software may be distributed under the terms of the
108587 + * GNU General Public License ("GPL") as published by the Free Software
108588 + * Foundation, either version 2 of that License or (at your option) any
108589 + * later version.
108590 + *
108591 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
108592 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
108593 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
108594 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
108595 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
108596 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
108597 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
108598 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
108599 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
108600 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
108601 + */
108602 +
108603 +/*
108604 + @File lnxwrp_fm.c
108605 + @Author Shlomi Gridish
108606 + @Description FM Linux wrapper functions.
108607 +*/
108608 +
108609 +#include <linux/version.h>
108610 +#include <linux/slab.h>
108611 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
108612 +#define MODVERSIONS
108613 +#endif
108614 +#ifdef MODVERSIONS
108615 +#include <config/modversions.h>
108616 +#endif /* MODVERSIONS */
108617 +#include <linux/kernel.h>
108618 +#include <linux/module.h>
108619 +#include <linux/fs.h>
108620 +#include <linux/cdev.h>
108621 +#include <linux/device.h>
108622 +#include <linux/irq.h>
108623 +#include <linux/interrupt.h>
108624 +#include <linux/io.h>
108625 +#include <linux/ioport.h>
108626 +#include <linux/of_platform.h>
108627 +#include <linux/of_address.h>
108628 +#include <linux/of_irq.h>
108629 +#include <linux/clk.h>
108630 +#include <asm/uaccess.h>
108631 +#include <asm/errno.h>
108632 +#ifndef CONFIG_FMAN_ARM
108633 +#include <sysdev/fsl_soc.h>
108634 +#include <linux/fsl/guts.h>
108635 +#include <linux/fsl/svr.h>
108636 +#endif
108637 +#include <linux/stat.h> /* For file access mask */
108638 +#include <linux/skbuff.h>
108639 +#include <linux/proc_fs.h>
108640 +
108641 +/* NetCommSw Headers --------------- */
108642 +#include "std_ext.h"
108643 +#include "error_ext.h"
108644 +#include "sprint_ext.h"
108645 +#include "debug_ext.h"
108646 +#include "sys_io_ext.h"
108647 +
108648 +#include "fm_ioctls.h"
108649 +
108650 +#include "lnxwrp_fm.h"
108651 +#include "lnxwrp_resources.h"
108652 +#include "lnxwrp_sysfs_fm.h"
108653 +#include "lnxwrp_sysfs_fm_port.h"
108654 +#include "lnxwrp_exp_sym.h"
108655 +#include "fm_common.h"
108656 +#include "../../sdk_fman/Peripherals/FM/fm.h"
108657 +#define __ERR_MODULE__ MODULE_FM
108658 +
108659 +extern struct device_node *GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
108660 + e_FmPortType portType,
108661 + uint8_t portId);
108662 +
108663 +#define PROC_PRINT(args...) offset += sprintf(buf+offset,args)
108664 +
108665 +#define ADD_ADV_CONFIG_NO_RET(_func, _param) \
108666 + do { \
108667 + if (i<max){ \
108668 + p_Entry = &p_Entrys[i]; \
108669 + p_Entry->p_Function = _func; \
108670 + _param \
108671 + i++; \
108672 + } \
108673 + else \
108674 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
108675 + ("Number of advanced-configuration entries exceeded"));\
108676 + } while (0)
108677 +
108678 +/* Bootarg used to override the Kconfig FSL_FM_MAX_FRAME_SIZE value */
108679 +#define FSL_FM_MAX_FRM_BOOTARG "fsl_fm_max_frm"
108680 +
108681 +/* Bootarg used to override FSL_FM_RX_EXTRA_HEADROOM Kconfig value */
108682 +#define FSL_FM_RX_EXTRA_HEADROOM_BOOTARG "fsl_fm_rx_extra_headroom"
108683 +
108684 +/* Minimum and maximum value for the fsl_fm_rx_extra_headroom bootarg */
108685 +#define FSL_FM_RX_EXTRA_HEADROOM_MIN 16
108686 +#define FSL_FM_RX_EXTRA_HEADROOM_MAX 384
108687 +
108688 +#define FSL_FM_PAUSE_TIME_ENABLE 0xf000
108689 +#define FSL_FM_PAUSE_TIME_DISABLE 0
108690 +#define FSL_FM_PAUSE_THRESH_DEFAULT 0
108691 +
108692 +/*
108693 + * Max frame size, across all interfaces.
108694 + * Configurable from Kconfig or bootargs, to avoid allocating
108695 + * oversized (socket) buffers when not using jumbo frames.
108696 + * Must be large enough to accommodate the network MTU, but small enough
108697 + * to avoid wasting skb memory.
108698 + *
108699 + * Could be overridden once, at boot-time, via the
108700 + * fm_set_max_frm() callback.
108701 + */
108702 +int fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
108703 +
108704 +/*
108705 + * Extra headroom for Rx buffers.
108706 + * FMan is instructed to allocate, on the Rx path, this amount of
108707 + * space at the beginning of a data buffer, beside the DPA private
108708 + * data area and the IC fields.
108709 + * Does not impact Tx buffer layout.
108710 + *
108711 + * Configurable from Kconfig or bootargs. Zero by default, it's needed
108712 + * on particular forwarding scenarios that add extra headers to the
108713 + * forwarded frame.
108714 + */
108715 +int fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
108716 +
108717 +#ifdef CONFIG_FMAN_PFC
108718 +static int fsl_fm_pfc_quanta[] = {
108719 + CONFIG_FMAN_PFC_QUANTA_0,
108720 + CONFIG_FMAN_PFC_QUANTA_1,
108721 + CONFIG_FMAN_PFC_QUANTA_2,
108722 + CONFIG_FMAN_PFC_QUANTA_3
108723 +};
108724 +#endif
108725 +
108726 +static t_LnxWrpFm lnxWrpFm;
108727 +
108728 +int fm_get_max_frm()
108729 +{
108730 + return fsl_fm_max_frm;
108731 +}
108732 +EXPORT_SYMBOL(fm_get_max_frm);
108733 +
108734 +int fm_get_rx_extra_headroom()
108735 +{
108736 + return ALIGN(fsl_fm_rx_extra_headroom, 16);
108737 +}
108738 +EXPORT_SYMBOL(fm_get_rx_extra_headroom);
108739 +
108740 +static int __init fm_set_max_frm(char *str)
108741 +{
108742 + int ret = 0;
108743 +
108744 + ret = get_option(&str, &fsl_fm_max_frm);
108745 + if (ret != 1) {
108746 + /*
108747 + * This will only work if CONFIG_EARLY_PRINTK is compiled in,
108748 + * and something like "earlyprintk=serial,uart0,115200" is
108749 + * specified in the bootargs
108750 + */
108751 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
108752 + "will use the default FSL_FM_MAX_FRAME_SIZE (%d) "
108753 + "from Kconfig.\n", FSL_FM_MAX_FRM_BOOTARG,
108754 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
108755 +
108756 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
108757 + return 1;
108758 + }
108759 +
108760 + /* Don't allow invalid bootargs; fallback to the Kconfig value */
108761 + if (fsl_fm_max_frm < 64 || fsl_fm_max_frm > 9600) {
108762 + printk(KERN_WARNING "Invalid %s=%d in bootargs, valid range is "
108763 + "64-9600. Falling back to the FSL_FM_MAX_FRAME_SIZE (%d) "
108764 + "from Kconfig.\n",
108765 + FSL_FM_MAX_FRM_BOOTARG, fsl_fm_max_frm,
108766 + CONFIG_FSL_FM_MAX_FRAME_SIZE);
108767 +
108768 + fsl_fm_max_frm = CONFIG_FSL_FM_MAX_FRAME_SIZE;
108769 + return 1;
108770 + }
108771 +
108772 + printk(KERN_INFO "Using fsl_fm_max_frm=%d from bootargs\n",
108773 + fsl_fm_max_frm);
108774 + return 0;
108775 +}
108776 +early_param(FSL_FM_MAX_FRM_BOOTARG, fm_set_max_frm);
108777 +
108778 +static int __init fm_set_rx_extra_headroom(char *str)
108779 +{
108780 + int ret;
108781 +
108782 + ret = get_option(&str, &fsl_fm_rx_extra_headroom);
108783 +
108784 + if (ret != 1) {
108785 + printk(KERN_WARNING "No suitable %s=<int> prop in bootargs; "
108786 + "will use the default FSL_FM_RX_EXTRA_HEADROOM (%d) "
108787 + "from Kconfig.\n", FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
108788 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
108789 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
108790 +
108791 + return 1;
108792 + }
108793 +
108794 + if (fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN ||
108795 + fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX) {
108796 + printk(KERN_WARNING "Invalid value for %s=%d prop in "
108797 + "bootargs; will use the default "
108798 + "FSL_FM_RX_EXTRA_HEADROOM (%d) from Kconfig.\n",
108799 + FSL_FM_RX_EXTRA_HEADROOM_BOOTARG,
108800 + fsl_fm_rx_extra_headroom,
108801 + CONFIG_FSL_FM_RX_EXTRA_HEADROOM);
108802 + fsl_fm_rx_extra_headroom = CONFIG_FSL_FM_RX_EXTRA_HEADROOM;
108803 + }
108804 +
108805 + printk(KERN_INFO "Using fsl_fm_rx_extra_headroom=%d from bootargs\n",
108806 + fsl_fm_rx_extra_headroom);
108807 +
108808 + return 0;
108809 +}
108810 +early_param(FSL_FM_RX_EXTRA_HEADROOM_BOOTARG, fm_set_rx_extra_headroom);
108811 +
108812 +static irqreturn_t fm_irq(int irq, void *_dev)
108813 +{
108814 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
108815 +#ifdef CONFIG_PM_SLEEP
108816 + t_Fm *p_Fm = (t_Fm*)p_LnxWrpFmDev->h_Dev;
108817 +#endif
108818 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
108819 + return IRQ_NONE;
108820 +
108821 +#ifdef CONFIG_PM_SLEEP
108822 + if (fman_get_normal_pending(p_Fm->p_FmFpmRegs) & INTR_EN_WAKEUP)
108823 + {
108824 + pm_wakeup_event(p_LnxWrpFmDev->dev, 200);
108825 + }
108826 +#endif
108827 + FM_EventIsr(p_LnxWrpFmDev->h_Dev);
108828 + return IRQ_HANDLED;
108829 +}
108830 +
108831 +static irqreturn_t fm_err_irq(int irq, void *_dev)
108832 +{
108833 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)_dev;
108834 +
108835 + if (!p_LnxWrpFmDev || !p_LnxWrpFmDev->h_Dev)
108836 + return IRQ_NONE;
108837 +
108838 + if (FM_ErrorIsr(p_LnxWrpFmDev->h_Dev) == E_OK)
108839 + return IRQ_HANDLED;
108840 +
108841 + return IRQ_NONE;
108842 +}
108843 +
108844 +/* used to protect FMD/LLD from concurrent calls in functions fm_mutex_lock / fm_mutex_unlock */
108845 +static struct mutex lnxwrp_mutex;
108846 +
108847 +static t_LnxWrpFmDev * CreateFmDev(uint8_t id)
108848 +{
108849 + t_LnxWrpFmDev *p_LnxWrpFmDev;
108850 + int j;
108851 +
108852 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)XX_Malloc(sizeof(t_LnxWrpFmDev));
108853 + if (!p_LnxWrpFmDev)
108854 + {
108855 + REPORT_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
108856 + return NULL;
108857 + }
108858 +
108859 + memset(p_LnxWrpFmDev, 0, sizeof(t_LnxWrpFmDev));
108860 + p_LnxWrpFmDev->fmDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108861 + memset(p_LnxWrpFmDev->fmDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108862 + p_LnxWrpFmDev->fmPcdDevSettings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108863 + memset(p_LnxWrpFmDev->fmPcdDevSettings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108864 + p_LnxWrpFmDev->hcPort.settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108865 + memset(p_LnxWrpFmDev->hcPort.settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108866 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
108867 + {
108868 + p_LnxWrpFmDev->rxPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108869 + memset(p_LnxWrpFmDev->rxPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108870 + }
108871 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
108872 + {
108873 + p_LnxWrpFmDev->txPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108874 + memset(p_LnxWrpFmDev->txPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108875 + }
108876 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
108877 + {
108878 + p_LnxWrpFmDev->opPorts[j].settings.advConfig = (t_SysObjectAdvConfigEntry*)XX_Malloc(FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry));
108879 + memset(p_LnxWrpFmDev->opPorts[j].settings.advConfig, 0, (FM_MAX_NUM_OF_ADV_SETTINGS*sizeof(t_SysObjectAdvConfigEntry)));
108880 + }
108881 +
108882 + return p_LnxWrpFmDev;
108883 +}
108884 +
108885 +static void DestroyFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
108886 +{
108887 + int j;
108888 +
108889 + for (j=0; j<FM_MAX_NUM_OF_OH_PORTS-1; j++)
108890 + if (p_LnxWrpFmDev->opPorts[j].settings.advConfig)
108891 + XX_Free(p_LnxWrpFmDev->opPorts[j].settings.advConfig);
108892 + for (j=0; j<FM_MAX_NUM_OF_TX_PORTS; j++)
108893 + if (p_LnxWrpFmDev->txPorts[j].settings.advConfig)
108894 + XX_Free(p_LnxWrpFmDev->txPorts[j].settings.advConfig);
108895 + for (j=0; j<FM_MAX_NUM_OF_RX_PORTS; j++)
108896 + if (p_LnxWrpFmDev->rxPorts[j].settings.advConfig)
108897 + XX_Free(p_LnxWrpFmDev->rxPorts[j].settings.advConfig);
108898 + if (p_LnxWrpFmDev->hcPort.settings.advConfig)
108899 + XX_Free(p_LnxWrpFmDev->hcPort.settings.advConfig);
108900 + if (p_LnxWrpFmDev->fmPcdDevSettings.advConfig)
108901 + XX_Free(p_LnxWrpFmDev->fmPcdDevSettings.advConfig);
108902 + if (p_LnxWrpFmDev->fmDevSettings.advConfig)
108903 + XX_Free(p_LnxWrpFmDev->fmDevSettings.advConfig);
108904 +
108905 + XX_Free(p_LnxWrpFmDev);
108906 +}
108907 +
108908 +static t_Error FillRestFmInfo(t_LnxWrpFmDev *p_LnxWrpFmDev)
108909 +{
108910 +#define FM_BMI_PPIDS_OFFSET 0x00080304
108911 +#define FM_DMA_PLR_OFFSET 0x000c2060
108912 +#define FM_FPM_IP_REV_1_OFFSET 0x000c30c4
108913 +#define DMA_HIGH_LIODN_MASK 0x0FFF0000
108914 +#define DMA_LOW_LIODN_MASK 0x00000FFF
108915 +#define DMA_LIODN_SHIFT 16
108916 +
108917 +typedef _Packed struct {
108918 + uint32_t plr[32];
108919 +} _PackedType t_Plr;
108920 +
108921 +typedef _Packed struct {
108922 + volatile uint32_t fmbm_ppid[63];
108923 +} _PackedType t_Ppids;
108924 +
108925 + t_Plr *p_Plr;
108926 + t_Ppids *p_Ppids;
108927 + int i,j;
108928 + uint32_t fmRev;
108929 +
108930 + static const uint8_t phys1GRxPortId[] = {0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf};
108931 + static const uint8_t phys10GRxPortId[] = {0x10,0x11};
108932 +#if (DPAA_VERSION >= 11)
108933 + static const uint8_t physOhPortId[] = {/* 0x1, */0x2,0x3,0x4,0x5,0x6,0x7};
108934 +#else
108935 + static const uint8_t physOhPortId[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7};
108936 +#endif
108937 + static const uint8_t phys1GTxPortId[] = {0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
108938 + static const uint8_t phys10GTxPortId[] = {0x30,0x31};
108939 +
108940 + fmRev = (uint32_t)(*((volatile uint32_t *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_FPM_IP_REV_1_OFFSET)));
108941 + fmRev &= 0xffff;
108942 +
108943 + p_Plr = (t_Plr *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_DMA_PLR_OFFSET);
108944 +#ifdef MODULE
108945 + for (i=0;i<FM_MAX_NUM_OF_PARTITIONS/2;i++)
108946 + p_Plr->plr[i] = 0;
108947 +#endif /* MODULE */
108948 +
108949 + for (i=0; i<FM_MAX_NUM_OF_PARTITIONS; i++)
108950 + {
108951 + uint16_t liodnBase = (uint16_t)((i%2) ?
108952 + (p_Plr->plr[i/2] & DMA_LOW_LIODN_MASK) :
108953 + ((p_Plr->plr[i/2] & DMA_HIGH_LIODN_MASK) >> DMA_LIODN_SHIFT));
108954 +#ifdef FM_PARTITION_ARRAY
108955 + /* TODO: this was .liodnPerPartition[i] = liodnBase; is the index meaning the same? */
108956 + p_LnxWrpFmDev->fmDevSettings.param.liodnBasePerPort[i] = liodnBase;
108957 +#endif /* FM_PARTITION_ARRAY */
108958 +
108959 + if ((i >= phys1GRxPortId[0]) &&
108960 + (i <= phys1GRxPortId[FM_MAX_NUM_OF_1G_RX_PORTS-1]))
108961 + {
108962 + for (j=0; j<ARRAY_SIZE(phys1GRxPortId); j++)
108963 + if (phys1GRxPortId[j] == i)
108964 + break;
108965 + ASSERT_COND(j<ARRAY_SIZE(phys1GRxPortId));
108966 + p_LnxWrpFmDev->rxPorts[j].settings.param.liodnBase = liodnBase;
108967 + }
108968 + else if (FM_MAX_NUM_OF_10G_RX_PORTS &&
108969 + (i >= phys10GRxPortId[0]) &&
108970 + (i <= phys10GRxPortId[FM_MAX_NUM_OF_10G_RX_PORTS-1]))
108971 + {
108972 + for (j=0; j<ARRAY_SIZE(phys10GRxPortId); j++)
108973 + if (phys10GRxPortId[j] == i)
108974 + break;
108975 + ASSERT_COND(j<ARRAY_SIZE(phys10GRxPortId));
108976 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+j].settings.param.liodnBase = liodnBase;
108977 + }
108978 + else if ((i >= physOhPortId[0]) &&
108979 + (i <= physOhPortId[FM_MAX_NUM_OF_OH_PORTS-1]))
108980 + {
108981 + for (j=0; j<ARRAY_SIZE(physOhPortId); j++)
108982 + if (physOhPortId[j] == i)
108983 + break;
108984 + ASSERT_COND(j<ARRAY_SIZE(physOhPortId));
108985 + if (j == 0)
108986 + p_LnxWrpFmDev->hcPort.settings.param.liodnBase = liodnBase;
108987 + else
108988 + p_LnxWrpFmDev->opPorts[j - 1].settings.param.liodnBase = liodnBase;
108989 + }
108990 + else if ((i >= phys1GTxPortId[0]) &&
108991 + (i <= phys1GTxPortId[FM_MAX_NUM_OF_1G_TX_PORTS-1]))
108992 + {
108993 + for (j=0; j<ARRAY_SIZE(phys1GTxPortId); j++)
108994 + if (phys1GTxPortId[j] == i)
108995 + break;
108996 + ASSERT_COND(j<ARRAY_SIZE(phys1GTxPortId));
108997 + p_LnxWrpFmDev->txPorts[j].settings.param.liodnBase = liodnBase;
108998 + }
108999 + else if (FM_MAX_NUM_OF_10G_TX_PORTS &&
109000 + (i >= phys10GTxPortId[0]) &&
109001 + (i <= phys10GTxPortId[FM_MAX_NUM_OF_10G_TX_PORTS-1]))
109002 + {
109003 + for (j=0; j<ARRAY_SIZE(phys10GTxPortId); j++)
109004 + if (phys10GTxPortId[j] == i)
109005 + break;
109006 + ASSERT_COND(j<ARRAY_SIZE(phys10GTxPortId));
109007 + p_LnxWrpFmDev->txPorts[FM_MAX_NUM_OF_1G_TX_PORTS+j].settings.param.liodnBase = liodnBase;
109008 + }
109009 + }
109010 +
109011 + p_Ppids = (t_Ppids *)UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr+FM_BMI_PPIDS_OFFSET);
109012 +
109013 + for (i=0; i<FM_MAX_NUM_OF_1G_RX_PORTS; i++)
109014 + p_LnxWrpFmDev->rxPorts[i].settings.param.specificParams.rxParams.liodnOffset =
109015 + p_Ppids->fmbm_ppid[phys1GRxPortId[i]-1];
109016 +
109017 + for (i=0; i<FM_MAX_NUM_OF_10G_RX_PORTS; i++)
109018 + p_LnxWrpFmDev->rxPorts[FM_MAX_NUM_OF_1G_RX_PORTS+i].settings.param.specificParams.rxParams.liodnOffset =
109019 + p_Ppids->fmbm_ppid[phys10GRxPortId[i]-1];
109020 +
109021 + return E_OK;
109022 +}
109023 +
109024 +/* Structure that defines QE firmware binary files.
109025 + *
109026 + * See Documentation/powerpc/qe_firmware.txt for a description of these
109027 + * fields.
109028 + */
109029 +struct qe_firmware {
109030 + struct qe_header {
109031 + __be32 length; /* Length of the entire structure, in bytes */
109032 + u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */
109033 + u8 version; /* Version of this layout. First ver is '1' */
109034 + } header;
109035 + u8 id[62]; /* Null-terminated identifier string */
109036 + u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */
109037 + u8 count; /* Number of microcode[] structures */
109038 + struct {
109039 + __be16 model; /* The SOC model */
109040 + u8 major; /* The SOC revision major */
109041 + u8 minor; /* The SOC revision minor */
109042 + } __attribute__ ((packed)) soc;
109043 + u8 padding[4]; /* Reserved, for alignment */
109044 + __be64 extended_modes; /* Extended modes */
109045 + __be32 vtraps[8]; /* Virtual trap addresses */
109046 + u8 reserved[4]; /* Reserved, for future expansion */
109047 + struct qe_microcode {
109048 + u8 id[32]; /* Null-terminated identifier */
109049 + __be32 traps[16]; /* Trap addresses, 0 == ignore */
109050 + __be32 eccr; /* The value for the ECCR register */
109051 + __be32 iram_offset; /* Offset into I-RAM for the code */
109052 + __be32 count; /* Number of 32-bit words of the code */
109053 + __be32 code_offset; /* Offset of the actual microcode */
109054 + u8 major; /* The microcode version major */
109055 + u8 minor; /* The microcode version minor */
109056 + u8 revision; /* The microcode version revision */
109057 + u8 padding; /* Reserved, for alignment */
109058 + u8 reserved[4]; /* Reserved, for future expansion */
109059 + } __attribute__ ((packed)) microcode[1];
109060 + /* All microcode binaries should be located here */
109061 + /* CRC32 should be located here, after the microcode binaries */
109062 +} __attribute__ ((packed));
109063 +
109064 +
109065 +/**
109066 + * FindFmanMicrocode - find the Fman microcode
109067 + *
109068 + * This function returns a pointer to the QE Firmware blob that holds
109069 + * the Fman microcode. We use the QE Firmware structure because Fman microcode
109070 + * is similar to QE microcode, so there's no point in defining a new layout.
109071 + *
109072 + * Current versions of U-Boot embed the Fman firmware into the device tree,
109073 + * so we check for that first. Each Fman node in the device tree contains a
109074 + * node or a pointer to node that holds the firmware. Technically, we should
109075 + * be fetching the firmware node for the current Fman, but we don't have that
109076 + * information any more, so we assume that there is only one firmware node in
109077 + * the device tree, and that all Fmen use the same firmware.
109078 + */
109079 +static const struct qe_firmware *FindFmanMicrocode(void)
109080 +{
109081 + static const struct qe_firmware *P4080_UCPatch;
109082 + struct device_node *np;
109083 +
109084 + if (P4080_UCPatch)
109085 + return P4080_UCPatch;
109086 +
109087 + /* The firmware should be inside the device tree. */
109088 + np = of_find_compatible_node(NULL, NULL, "fsl,fman-firmware");
109089 + if (np) {
109090 + P4080_UCPatch = of_get_property(np, "fsl,firmware", NULL);
109091 + of_node_put(np);
109092 + if (P4080_UCPatch)
109093 + return P4080_UCPatch;
109094 + else
109095 + REPORT_ERROR(WARNING, E_NOT_FOUND, ("firmware node is incomplete"));
109096 + }
109097 +
109098 + /* Returning NULL here forces the reuse of the IRAM content */
109099 + return NULL;
109100 +}
109101 +#define SVR_SECURITY_MASK 0x00080000
109102 +#define SVR_PERSONALITY_MASK 0x0000FF00
109103 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
109104 +#define SVR_B4860_REV1_VALUE 0x86800010
109105 +#define SVR_B4860_REV2_VALUE 0x86800020
109106 +#define SVR_T4240_VALUE 0x82400000
109107 +#define SVR_T4120_VALUE 0x82400100
109108 +#define SVR_T4160_VALUE 0x82410000
109109 +#define SVR_T4080_VALUE 0x82410200
109110 +#define SVR_T4_DEVICE_ID 0x82400000
109111 +#define SVR_DEVICE_ID_MASK 0xFFF00000
109112 +
109113 +#define OF_DEV_ID_NUM 2 /* one used, another one zeroed */
109114 +
109115 +/* searches for a subnode with the given name/compatible */
109116 +static bool HasFmPcdOfNode(struct device_node *fm_node,
109117 + struct of_device_id *ids,
109118 + const char *name,
109119 + const char *compatible)
109120 +{
109121 + struct device_node *dev_node;
109122 + bool ret = false;
109123 +
109124 + memset(ids, 0, OF_DEV_ID_NUM*sizeof(struct of_device_id));
109125 + if (WARN_ON(strlen(name) >= sizeof(ids[0].name)))
109126 + return false;
109127 + strcpy(ids[0].name, name);
109128 + if (WARN_ON(strlen(compatible) >= sizeof(ids[0].compatible)))
109129 + return false;
109130 + strcpy(ids[0].compatible, compatible);
109131 + for_each_child_of_node(fm_node, dev_node)
109132 + if (of_match_node(ids, dev_node) != NULL)
109133 + ret = true;
109134 + return ret;
109135 +}
109136 +
109137 +static t_LnxWrpFmDev * ReadFmDevTreeNode (struct platform_device *of_dev)
109138 +{
109139 + t_LnxWrpFmDev *p_LnxWrpFmDev;
109140 + struct device_node *fm_node, *dev_node;
109141 + struct of_device_id ids[OF_DEV_ID_NUM];
109142 + struct resource res;
109143 + struct clk *clk;
109144 + u32 clk_rate;
109145 + const uint32_t *uint32_prop;
109146 + int _errno=0, lenp;
109147 + uint32_t tmp_prop;
109148 +
109149 + fm_node = of_node_get(of_dev->dev.of_node);
109150 +
109151 + uint32_prop = (uint32_t *)of_get_property(fm_node, "cell-index", &lenp);
109152 + if (unlikely(uint32_prop == NULL)) {
109153 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_get_property(%s, cell-index) failed", fm_node->full_name));
109154 + return NULL;
109155 + }
109156 + tmp_prop = be32_to_cpu(*uint32_prop);
109157 +
109158 + if (WARN_ON(lenp != sizeof(uint32_t)))
109159 + return NULL;
109160 +
109161 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
109162 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
109163 + return NULL;
109164 + }
109165 + p_LnxWrpFmDev = CreateFmDev(tmp_prop);
109166 + if (!p_LnxWrpFmDev) {
109167 + REPORT_ERROR(MAJOR, E_NULL_POINTER, NO_MSG);
109168 + return NULL;
109169 + }
109170 + p_LnxWrpFmDev->dev = &of_dev->dev;
109171 + p_LnxWrpFmDev->id = tmp_prop;
109172 +
109173 + /* Get the FM interrupt */
109174 + p_LnxWrpFmDev->irq = of_irq_to_resource(fm_node, 0, NULL);
109175 + if (unlikely(p_LnxWrpFmDev->irq == /*NO_IRQ*/0)) {
109176 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
109177 + DestroyFmDev(p_LnxWrpFmDev);
109178 + return NULL;
109179 + }
109180 +
109181 + /* Get the FM error interrupt */
109182 + p_LnxWrpFmDev->err_irq = of_irq_to_resource(fm_node, 1, NULL);
109183 +
109184 + if (unlikely(p_LnxWrpFmDev->err_irq == /*NO_IRQ*/0)) {
109185 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_irq_to_resource() = %d", NO_IRQ));
109186 + DestroyFmDev(p_LnxWrpFmDev);
109187 + return NULL;
109188 + }
109189 +
109190 + /* Get the FM address */
109191 + _errno = of_address_to_resource(fm_node, 0, &res);
109192 + if (unlikely(_errno < 0)) {
109193 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
109194 + DestroyFmDev(p_LnxWrpFmDev);
109195 + return NULL;
109196 + }
109197 +
109198 +
109199 + p_LnxWrpFmDev->fmBaseAddr = 0;
109200 + p_LnxWrpFmDev->fmPhysBaseAddr = res.start;
109201 + p_LnxWrpFmDev->fmMemSize = res.end + 1 - res.start;
109202 +
109203 + clk = of_clk_get(fm_node, 0);
109204 + if (IS_ERR(clk)) {
109205 + dev_err(&of_dev->dev, "%s: Failed to get FM clock structure\n",
109206 + __func__);
109207 + of_node_put(fm_node);
109208 + DestroyFmDev(p_LnxWrpFmDev);
109209 + return NULL;
109210 + }
109211 +
109212 + clk_rate = clk_get_rate(clk);
109213 + if (!clk_rate) {
109214 + dev_err(&of_dev->dev, "%s: Failed to determine FM clock rate\n",
109215 + __func__);
109216 + of_node_put(fm_node);
109217 + DestroyFmDev(p_LnxWrpFmDev);
109218 + return NULL;
109219 + }
109220 +
109221 + p_LnxWrpFmDev->fmDevSettings.param.fmClkFreq = DIV_ROUND_UP(clk_rate, 1000000); /* In MHz, rounded */
109222 + /* Get the MURAM base address and size */
109223 + memset(ids, 0, sizeof(ids));
109224 + if (WARN_ON(strlen("muram") >= sizeof(ids[0].name)))
109225 + return NULL;
109226 + strcpy(ids[0].name, "muram");
109227 + if (WARN_ON(strlen("fsl,fman-muram") >= sizeof(ids[0].compatible)))
109228 + return NULL;
109229 + strcpy(ids[0].compatible, "fsl,fman-muram");
109230 + for_each_child_of_node(fm_node, dev_node) {
109231 + if (likely(of_match_node(ids, dev_node) != NULL)) {
109232 + _errno = of_address_to_resource(dev_node, 0, &res);
109233 + if (unlikely(_errno < 0)) {
109234 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
109235 + DestroyFmDev(p_LnxWrpFmDev);
109236 + return NULL;
109237 + }
109238 +
109239 + p_LnxWrpFmDev->fmMuramBaseAddr = 0;
109240 + p_LnxWrpFmDev->fmMuramPhysBaseAddr = res.start;
109241 + p_LnxWrpFmDev->fmMuramMemSize = res.end + 1 - res.start;
109242 +
109243 +#ifndef CONFIG_FMAN_ARM
109244 + {
109245 + uint32_t svr;
109246 + svr = mfspr(SPRN_SVR);
109247 +
109248 + if ((svr & ~SVR_VER_IGNORE_MASK) >= SVR_B4860_REV2_VALUE)
109249 + p_LnxWrpFmDev->fmMuramMemSize = 0x80000;
109250 + }
109251 +#endif
109252 + }
109253 + }
109254 +
109255 +#if 0
109256 + /* Get the RTC base address and size */
109257 + memset(ids, 0, sizeof(ids));
109258 + if (WARN_ON(strlen("ptp-timer") >= sizeof(ids[0].name)))
109259 + return NULL;
109260 + strcpy(ids[0].name, "ptp-timer");
109261 + if (WARN_ON(strlen("fsl,fman-ptp-timer") >= sizeof(ids[0].compatible)))
109262 + return NULL;
109263 + strcpy(ids[0].compatible, "fsl,fman-ptp-timer");
109264 + for_each_child_of_node(fm_node, dev_node) {
109265 + if (likely(of_match_node(ids, dev_node) != NULL)) {
109266 + _errno = of_address_to_resource(dev_node, 0, &res);
109267 + if (unlikely(_errno < 0)) {
109268 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
109269 + DestroyFmDev(p_LnxWrpFmDev);
109270 + return NULL;
109271 + }
109272 +
109273 + p_LnxWrpFmDev->fmRtcBaseAddr = 0;
109274 + p_LnxWrpFmDev->fmRtcPhysBaseAddr = res.start;
109275 + p_LnxWrpFmDev->fmRtcMemSize = res.end + 1 - res.start;
109276 + }
109277 + }
109278 +#endif
109279 +
109280 +#if (DPAA_VERSION >= 11)
109281 + /* Get the VSP base address */
109282 + for_each_child_of_node(fm_node, dev_node) {
109283 + if (of_device_is_compatible(dev_node, "fsl,fman-vsps")) {
109284 + _errno = of_address_to_resource(dev_node, 0, &res);
109285 + if (unlikely(_errno < 0)) {
109286 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("of_address_to_resource() = %d", _errno));
109287 + DestroyFmDev(p_LnxWrpFmDev);
109288 + return NULL;
109289 + }
109290 + p_LnxWrpFmDev->fmVspBaseAddr = 0;
109291 + p_LnxWrpFmDev->fmVspPhysBaseAddr = res.start;
109292 + p_LnxWrpFmDev->fmVspMemSize = res.end + 1 - res.start;
109293 + }
109294 + }
109295 +#endif
109296 +
109297 + /* Get all PCD nodes */
109298 + p_LnxWrpFmDev->prsActive = HasFmPcdOfNode(fm_node, ids, "parser", "fsl,fman-parser");
109299 + p_LnxWrpFmDev->kgActive = HasFmPcdOfNode(fm_node, ids, "keygen", "fsl,fman-keygen");
109300 + p_LnxWrpFmDev->ccActive = HasFmPcdOfNode(fm_node, ids, "cc", "fsl,fman-cc");
109301 + p_LnxWrpFmDev->plcrActive = HasFmPcdOfNode(fm_node, ids, "policer", "fsl,fman-policer");
109302 +
109303 + if (p_LnxWrpFmDev->prsActive || p_LnxWrpFmDev->kgActive ||
109304 + p_LnxWrpFmDev->ccActive || p_LnxWrpFmDev->plcrActive)
109305 + p_LnxWrpFmDev->pcdActive = TRUE;
109306 +
109307 + if (p_LnxWrpFmDev->pcdActive)
109308 + {
109309 + const char *str_prop = (char *)of_get_property(fm_node, "fsl,default-pcd", &lenp);
109310 + if (str_prop) {
109311 + if (strncmp(str_prop, "3-tuple", strlen("3-tuple")) == 0)
109312 + p_LnxWrpFmDev->defPcd = e_FM_PCD_3_TUPLE;
109313 + }
109314 + else
109315 + p_LnxWrpFmDev->defPcd = e_NO_PCD;
109316 + }
109317 +
109318 + of_node_put(fm_node);
109319 +
109320 + p_LnxWrpFmDev->hcCh =
109321 + qman_affine_channel(cpumask_first(qman_affine_cpus()));
109322 +
109323 + p_LnxWrpFmDev->active = TRUE;
109324 +
109325 + return p_LnxWrpFmDev;
109326 +}
109327 +
109328 +struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx)
109329 +{
109330 + struct device_node *dev_node;
109331 + const uint32_t *uint32_prop;
109332 + int lenp;
109333 + uint32_t tmp_prop;
109334 +
109335 + for_each_compatible_node(dev_node, NULL, "fsl,fman-extended-args") {
109336 + uint32_prop = (uint32_t *)of_get_property(dev_node, "cell-index", &lenp);
109337 + if (unlikely(uint32_prop == NULL)) {
109338 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
109339 + ("of_get_property(%s, cell-index) failed",
109340 + dev_node->full_name));
109341 + return NULL;
109342 + }
109343 + tmp_prop = be32_to_cpu(*uint32_prop);
109344 + if (WARN_ON(lenp != sizeof(uint32_t)))
109345 + return NULL;
109346 + if (tmp_prop > INTG_MAX_NUM_OF_FM) {
109347 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
109348 + return NULL;
109349 + }
109350 + if (fmIndx == tmp_prop)
109351 + return dev_node;
109352 + }
109353 +
109354 + return NULL;
109355 +}
109356 +
109357 +static t_Error CheckNConfigFmAdvArgs (t_LnxWrpFmDev *p_LnxWrpFmDev)
109358 +{
109359 + struct device_node *dev_node;
109360 + t_Error err = E_INVALID_VALUE;
109361 + const uint32_t *uint32_prop;
109362 + const char *str_prop;
109363 + int lenp;
109364 + uint32_t tmp_prop;
109365 +
109366 + dev_node = GetFmAdvArgsDevTreeNode(p_LnxWrpFmDev->id);
109367 + if (!dev_node) /* no advance parameters for FMan */
109368 + return E_OK;
109369 +
109370 + str_prop = (char *)of_get_property(dev_node, "dma-aid-mode", &lenp);
109371 + if (str_prop) {
109372 + if (strcmp(str_prop, "port") == 0)
109373 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_PORT_ID);
109374 + else if (strcmp(str_prop, "tnum") == 0)
109375 + err = FM_ConfigDmaAidMode(p_LnxWrpFmDev->h_Dev, e_FM_DMA_AID_OUT_TNUM);
109376 +
109377 + if (err != E_OK)
109378 + RETURN_ERROR(MINOR, err, NO_MSG);
109379 + }
109380 +
109381 + uint32_prop = (uint32_t *)of_get_property(dev_node,
109382 + "total-fifo-size", &lenp);
109383 + if (uint32_prop) {
109384 + tmp_prop = be32_to_cpu(*uint32_prop);
109385 + if (WARN_ON(lenp != sizeof(uint32_t)))
109386 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109387 +
109388 + if (FM_ConfigTotalFifoSize(p_LnxWrpFmDev->h_Dev,
109389 + tmp_prop) != E_OK)
109390 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109391 + }
109392 +
109393 + uint32_prop = (uint32_t *)of_get_property(dev_node, "tnum-aging-period",
109394 + &lenp);
109395 + if (uint32_prop) {
109396 + tmp_prop = be32_to_cpu(*uint32_prop);
109397 + if (WARN_ON(lenp != sizeof(uint32_t)))
109398 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
109399 +
109400 + err = FM_ConfigTnumAgingPeriod(p_LnxWrpFmDev->h_Dev,
109401 + (uint16_t)tmp_prop/*tnumAgingPeriod*/);
109402 +
109403 + if (err != E_OK)
109404 + RETURN_ERROR(MINOR, err, NO_MSG);
109405 + }
109406 +
109407 + of_node_put(dev_node);
109408 +
109409 + return E_OK;
109410 +}
109411 +
109412 +static void LnxwrpFmDevExceptionsCb(t_Handle h_App, e_FmExceptions exception)
109413 +{
109414 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
109415 +
109416 + ASSERT_COND(p_LnxWrpFmDev);
109417 +
109418 + DBG(INFO, ("got fm exception %d", exception));
109419 +
109420 + /* do nothing */
109421 + UNUSED(exception);
109422 +}
109423 +
109424 +static void LnxwrpFmDevBusErrorCb(t_Handle h_App,
109425 + e_FmPortType portType,
109426 + uint8_t portId,
109427 + uint64_t addr,
109428 + uint8_t tnum,
109429 + uint16_t liodn)
109430 +{
109431 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *)h_App;
109432 +
109433 + ASSERT_COND(p_LnxWrpFmDev);
109434 +
109435 + /* do nothing */
109436 + UNUSED(portType);UNUSED(portId);UNUSED(addr);UNUSED(tnum);UNUSED(liodn);
109437 +}
109438 +
109439 +static t_Error ConfigureFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
109440 +{
109441 + struct resource *dev_res;
109442 + int _errno;
109443 +
109444 + if (!p_LnxWrpFmDev->active)
109445 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
109446 +
109447 +#ifndef MODULE
109448 + _errno = can_request_irq(p_LnxWrpFmDev->irq, 0);
109449 + if (unlikely(_errno < 0))
109450 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
109451 +#endif
109452 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, fm_irq, IRQF_SHARED, "fman", p_LnxWrpFmDev);
109453 + if (unlikely(_errno < 0))
109454 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->irq, _errno));
109455 +
109456 + enable_irq_wake(p_LnxWrpFmDev->irq);
109457 +
109458 + if (p_LnxWrpFmDev->err_irq != 0) {
109459 +#ifndef MODULE
109460 + _errno = can_request_irq(p_LnxWrpFmDev->err_irq, 0);
109461 + if (unlikely(_errno < 0))
109462 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("can_request_irq() = %d", _errno));
109463 +#endif
109464 + _errno = devm_request_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, fm_err_irq, IRQF_SHARED, "fman-err", p_LnxWrpFmDev);
109465 + if (unlikely(_errno < 0))
109466 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_irq(%d) = %d", p_LnxWrpFmDev->err_irq, _errno));
109467 +
109468 + enable_irq_wake(p_LnxWrpFmDev->err_irq);
109469 + }
109470 +
109471 + p_LnxWrpFmDev->res = devm_request_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize, "fman");
109472 + if (unlikely(p_LnxWrpFmDev->res == NULL))
109473 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("request_mem_region() failed"));
109474 +
109475 + p_LnxWrpFmDev->fmBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize));
109476 + if (unlikely(p_LnxWrpFmDev->fmBaseAddr == 0))
109477 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
109478 +
109479 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmBaseAddr, (uint64_t)p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize) != E_OK)
109480 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM memory map"));
109481 +
109482 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize, "fman-muram");
109483 + if (unlikely(dev_res == NULL))
109484 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
109485 +
109486 + p_LnxWrpFmDev->fmMuramBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize));
109487 + if (unlikely(p_LnxWrpFmDev->fmMuramBaseAddr == 0))
109488 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
109489 +
109490 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmMuramBaseAddr, (uint64_t)p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize) != E_OK)
109491 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM MURAM memory map"));
109492 +
109493 + if (p_LnxWrpFmDev->fmRtcPhysBaseAddr)
109494 + {
109495 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize, "fman-ptp-timer");
109496 + if (unlikely(dev_res == NULL))
109497 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
109498 +
109499 + p_LnxWrpFmDev->fmRtcBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize));
109500 + if (unlikely(p_LnxWrpFmDev->fmRtcBaseAddr == 0))
109501 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
109502 +
109503 + if (SYS_RegisterIoMap((uint64_t)p_LnxWrpFmDev->fmRtcBaseAddr, (uint64_t)p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize) != E_OK)
109504 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC memory map"));
109505 + }
109506 +
109507 +#if (DPAA_VERSION >= 11)
109508 + if (p_LnxWrpFmDev->fmVspPhysBaseAddr) {
109509 + dev_res = __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize, "fman-vsp");
109510 + if (unlikely(dev_res == NULL))
109511 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("__devm_request_region() failed"));
109512 +
109513 + p_LnxWrpFmDev->fmVspBaseAddr = PTR_TO_UINT(devm_ioremap(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmVspPhysBaseAddr, p_LnxWrpFmDev->fmVspMemSize));
109514 + if (unlikely(p_LnxWrpFmDev->fmVspBaseAddr == 0))
109515 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("devm_ioremap() failed"));
109516 + }
109517 +#endif
109518 +
109519 + p_LnxWrpFmDev->fmDevSettings.param.baseAddr = p_LnxWrpFmDev->fmBaseAddr;
109520 + p_LnxWrpFmDev->fmDevSettings.param.fmId = p_LnxWrpFmDev->id;
109521 + p_LnxWrpFmDev->fmDevSettings.param.irq = NO_IRQ;
109522 + p_LnxWrpFmDev->fmDevSettings.param.errIrq = NO_IRQ;
109523 + p_LnxWrpFmDev->fmDevSettings.param.f_Exception = LnxwrpFmDevExceptionsCb;
109524 + p_LnxWrpFmDev->fmDevSettings.param.f_BusError = LnxwrpFmDevBusErrorCb;
109525 + p_LnxWrpFmDev->fmDevSettings.param.h_App = p_LnxWrpFmDev;
109526 +
109527 + return FillRestFmInfo(p_LnxWrpFmDev);
109528 +}
109529 +
109530 +#ifndef CONFIG_FMAN_ARM
109531 +/*
109532 + * Table for matching compatible strings, for device tree
109533 + * guts node, for QorIQ SOCs.
109534 + * "fsl,qoriq-device-config-2.0" corresponds to T4 & B4
109535 + * SOCs. For the older SOCs "fsl,qoriq-device-config-1.0"
109536 + * string would be used.
109537 +*/
109538 +static const struct of_device_id guts_device_ids[] = {
109539 + { .compatible = "fsl,qoriq-device-config-1.0", },
109540 + { .compatible = "fsl,qoriq-device-config-2.0", },
109541 + {}
109542 +};
109543 +
109544 +static unsigned int get_rcwsr(int regnum)
109545 +{
109546 + struct ccsr_guts __iomem *guts_regs = NULL;
109547 + struct device_node *guts_node;
109548 +
109549 + guts_node = of_find_matching_node(NULL, guts_device_ids);
109550 + if (!guts_node) {
109551 + pr_err("could not find GUTS node\n");
109552 + return 0;
109553 + }
109554 + guts_regs = of_iomap(guts_node, 0);
109555 + of_node_put(guts_node);
109556 + if (!guts_regs) {
109557 + pr_err("ioremap of GUTS node failed\n");
109558 + return 0;
109559 + }
109560 +
109561 + return ioread32be(&guts_regs->rcwsr[regnum]);
109562 +}
109563 +
109564 +#define FMAN1_ALL_MACS_MASK 0xFCC00000
109565 +#define FMAN2_ALL_MACS_MASK 0x000FCC00
109566 +
109567 +/**
109568 + * @Function ResetOnInitErrata_A007273
109569 + *
109570 + * @Description Workaround for Errata A-007273
109571 + * This workaround is required to avoid a FMan hang during reset on initialization.
109572 + * Enable all MACs in guts.devdisr2 register,
109573 + * then perform a regular FMan reset and then restore MACs to their original state.
109574 + *
109575 + * @Param[in] h_Fm - FM module descriptor
109576 + *
109577 + * @Return None.
109578 + */
109579 +void ResetOnInitErrata_A007273(t_Handle h_Fm)
109580 +{
109581 + struct ccsr_guts __iomem *guts_regs = NULL;
109582 + struct device_node *guts_node;
109583 + u32 devdisr2, enableMacs;
109584 +
109585 + /* Get guts registers */
109586 + guts_node = of_find_matching_node(NULL, guts_device_ids);
109587 + if (!guts_node) {
109588 + pr_err("could not find GUTS node\n");
109589 + return;
109590 + }
109591 + guts_regs = of_iomap(guts_node, 0);
109592 + of_node_put(guts_node);
109593 + if (!guts_regs) {
109594 + pr_err("ioremap of GUTS node failed\n");
109595 + return;
109596 + }
109597 +
109598 + /* Read current state */
109599 + devdisr2 = ioread32be(&guts_regs->devdisr2);
109600 +
109601 + if (FmGetId(h_Fm) == 0)
109602 + enableMacs = devdisr2 & ~FMAN1_ALL_MACS_MASK;
109603 + else
109604 + enableMacs = devdisr2 & ~FMAN2_ALL_MACS_MASK;
109605 +
109606 + /* Enable all MACs */
109607 + iowrite32be(enableMacs, &guts_regs->devdisr2);
109608 +
109609 + /* Perform standard FMan reset */
109610 + FmReset(h_Fm);
109611 +
109612 + /* Restore devdisr2 value */
109613 + iowrite32be(devdisr2, &guts_regs->devdisr2);
109614 +
109615 + iounmap(guts_regs);
109616 +}
109617 +#endif
109618 +
109619 +static t_Error InitFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
109620 +{
109621 + const struct qe_firmware *fw;
109622 +
109623 + if (!p_LnxWrpFmDev->active)
109624 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM not configured!!!"));
109625 +
109626 + if ((p_LnxWrpFmDev->h_MuramDev = FM_MURAM_ConfigAndInit(p_LnxWrpFmDev->fmMuramBaseAddr, p_LnxWrpFmDev->fmMuramMemSize)) == NULL)
109627 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-MURAM!"));
109628 +
109629 + /* Loading the fman-controller code */
109630 + fw = FindFmanMicrocode();
109631 +
109632 + if (!fw) {
109633 + /* this forces the reuse of the current IRAM content */
109634 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size = 0;
109635 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = NULL;
109636 + } else {
109637 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code =
109638 + (void *) fw + be32_to_cpu(fw->microcode[0].code_offset);
109639 + p_LnxWrpFmDev->fmDevSettings.param.firmware.size =
109640 + sizeof(u32) * be32_to_cpu(fw->microcode[0].count);
109641 + DBG(INFO, ("Loading fman-controller code version %d.%d.%d",
109642 + fw->microcode[0].major,
109643 + fw->microcode[0].minor,
109644 + fw->microcode[0].revision));
109645 + }
109646 +
109647 +#ifdef CONFIG_FMAN_ARM
109648 + { /* endianness adjustments: byteswap the ucode retrieved from the f/w blob */
109649 + int i;
109650 + int usz = p_LnxWrpFmDev->fmDevSettings.param.firmware.size;
109651 + void * p_Code = p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code;
109652 + u32 *dest = kzalloc(usz, GFP_KERNEL);
109653 +
109654 + if (p_Code && dest)
109655 + for(i=0; i < usz / 4; ++i)
109656 + dest[i] = be32_to_cpu(((u32 *)p_Code)[i]);
109657 +
109658 + p_LnxWrpFmDev->fmDevSettings.param.firmware.p_Code = dest;
109659 + }
109660 +#endif
109661 +
109662 + p_LnxWrpFmDev->fmDevSettings.param.h_FmMuram = p_LnxWrpFmDev->h_MuramDev;
109663 +
109664 +#if (DPAA_VERSION >= 11)
109665 + if (p_LnxWrpFmDev->fmVspBaseAddr) {
109666 + p_LnxWrpFmDev->fmDevSettings.param.vspBaseAddr = p_LnxWrpFmDev->fmVspBaseAddr;
109667 + p_LnxWrpFmDev->fmDevSettings.param.partVSPBase = 0;
109668 + p_LnxWrpFmDev->fmDevSettings.param.partNumOfVSPs = FM_VSP_MAX_NUM_OF_ENTRIES;
109669 + }
109670 +#endif
109671 +
109672 +#ifdef CONFIG_FMAN_ARM
109673 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
109674 +#else
109675 + if(p_LnxWrpFmDev->fmDevSettings.param.fmId == 0)
109676 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
109677 + !!(get_rcwsr(4) & 0x2); /* RCW[FM_MAC_RAT0] */
109678 + else
109679 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio =
109680 + !!(get_rcwsr(4) & 0x1); /* RCW[FM_MAC_RAT1] */
109681 +
109682 + {
109683 + /* T4 Devices ClkRatio is always 1 regardless of RCW[FM_MAC_RAT1] */
109684 + uint32_t svr;
109685 + svr = mfspr(SPRN_SVR);
109686 +
109687 + if ((svr & SVR_DEVICE_ID_MASK) == SVR_T4_DEVICE_ID)
109688 + p_LnxWrpFmDev->fmDevSettings.param.fmMacClkRatio = 1;
109689 + }
109690 +#endif /* CONFIG_FMAN_ARM */
109691 +
109692 + if ((p_LnxWrpFmDev->h_Dev = FM_Config(&p_LnxWrpFmDev->fmDevSettings.param)) == NULL)
109693 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM"));
109694 +
109695 +
109696 + if (FM_ConfigResetOnInit(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
109697 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
109698 +
109699 +#ifndef CONFIG_FMAN_ARM
109700 +#ifdef FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273
109701 + if (FM_ConfigResetOnInitOverrideCallback(p_LnxWrpFmDev->h_Dev, ResetOnInitErrata_A007273) != E_OK)
109702 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
109703 +#endif /* FM_HANG_AT_RESET_MAC_CLK_DISABLED_ERRATA_FMAN_A007273 */
109704 +#endif /* CONFIG_FMAN_ARM */
109705 +
109706 +#ifdef CONFIG_FMAN_P1023
109707 + if (FM_ConfigDmaAidOverride(p_LnxWrpFmDev->h_Dev, TRUE) != E_OK)
109708 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
109709 +#endif
109710 +
109711 +
109712 + CheckNConfigFmAdvArgs(p_LnxWrpFmDev);
109713 +
109714 + if (FM_Init(p_LnxWrpFmDev->h_Dev) != E_OK)
109715 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM"));
109716 +
109717 + /* TODO: Why we mask these interrupts? */
109718 + if (p_LnxWrpFmDev->err_irq == 0) {
109719 + FM_SetException(p_LnxWrpFmDev->h_Dev, e_FM_EX_DMA_BUS_ERROR,FALSE);
109720 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_READ_ECC,FALSE);
109721 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SYSTEM_WRITE_ECC,FALSE);
109722 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_FM_WRITE_ECC,FALSE);
109723 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_DMA_SINGLE_PORT_ECC, FALSE);
109724 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_STALL_ON_TASKS , FALSE);
109725 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_SINGLE_ECC, FALSE);
109726 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_FPM_DOUBLE_ECC,FALSE);
109727 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_SINGLE_ECC, FALSE);
109728 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DOUBLE_ECC,FALSE);
109729 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,FALSE);
109730 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_LIST_RAM_ECC,FALSE);
109731 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STORAGE_PROFILE_ECC, FALSE);
109732 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_STATISTICS_RAM_ECC, FALSE);
109733 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_BMI_DISPATCH_RAM_ECC, FALSE);
109734 + FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_IRAM_ECC,FALSE);
109735 + /* TODO: FmDisableRamsEcc assert for ramsEccOwners.
109736 + * FM_SetException(p_LnxWrpFmDev->h_Dev,e_FM_EX_MURAM_ECC,FALSE);*/
109737 + }
109738 +
109739 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
109740 + {
109741 + t_FmRtcParams fmRtcParam;
109742 +
109743 + memset(&fmRtcParam, 0, sizeof(fmRtcParam));
109744 + fmRtcParam.h_App = p_LnxWrpFmDev;
109745 + fmRtcParam.h_Fm = p_LnxWrpFmDev->h_Dev;
109746 + fmRtcParam.baseAddress = p_LnxWrpFmDev->fmRtcBaseAddr;
109747 +
109748 + if(!(p_LnxWrpFmDev->h_RtcDev = FM_RTC_Config(&fmRtcParam)))
109749 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-RTC"));
109750 +
109751 + if (FM_RTC_ConfigPeriod(p_LnxWrpFmDev->h_RtcDev, DPA_PTP_NOMINAL_FREQ_PERIOD_NS) != E_OK)
109752 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
109753 +
109754 + if (FM_RTC_Init(p_LnxWrpFmDev->h_RtcDev) != E_OK)
109755 + RETURN_ERROR(MAJOR, E_INVALID_STATE, ("FM-RTC"));
109756 + }
109757 +
109758 + return E_OK;
109759 +}
109760 +
109761 +/* TODO: to be moved back here */
109762 +extern void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev);
109763 +
109764 +static void FreeFmDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
109765 +{
109766 + if (!p_LnxWrpFmDev->active)
109767 + return;
109768 +
109769 + FreeFmPcdDev(p_LnxWrpFmDev);
109770 +
109771 + if (p_LnxWrpFmDev->h_RtcDev)
109772 + FM_RTC_Free(p_LnxWrpFmDev->h_RtcDev);
109773 +
109774 + if (p_LnxWrpFmDev->h_Dev)
109775 + FM_Free(p_LnxWrpFmDev->h_Dev);
109776 +
109777 + if (p_LnxWrpFmDev->h_MuramDev)
109778 + FM_MURAM_Free(p_LnxWrpFmDev->h_MuramDev);
109779 +
109780 + if (p_LnxWrpFmDev->fmRtcBaseAddr)
109781 + {
109782 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmRtcBaseAddr);
109783 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmRtcBaseAddr));
109784 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmRtcPhysBaseAddr, p_LnxWrpFmDev->fmRtcMemSize);
109785 + }
109786 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmMuramBaseAddr);
109787 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmMuramBaseAddr));
109788 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res, p_LnxWrpFmDev->fmMuramPhysBaseAddr, p_LnxWrpFmDev->fmMuramMemSize);
109789 + SYS_UnregisterIoMap(p_LnxWrpFmDev->fmBaseAddr);
109790 + devm_iounmap(p_LnxWrpFmDev->dev, UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr));
109791 + devm_release_mem_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->fmPhysBaseAddr, p_LnxWrpFmDev->fmMemSize);
109792 + if (p_LnxWrpFmDev->err_irq != 0) {
109793 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->err_irq, p_LnxWrpFmDev);
109794 + }
109795 +
109796 + devm_free_irq(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->irq, p_LnxWrpFmDev);
109797 +}
109798 +
109799 +/* FMan character device file operations */
109800 +extern struct file_operations fm_fops;
109801 +
109802 +static int /*__devinit*/ fm_probe(struct platform_device *of_dev)
109803 +{
109804 + t_LnxWrpFmDev *p_LnxWrpFmDev;
109805 +
109806 + if ((p_LnxWrpFmDev = ReadFmDevTreeNode(of_dev)) == NULL)
109807 + return -EIO;
109808 + if (ConfigureFmDev(p_LnxWrpFmDev) != E_OK)
109809 + return -EIO;
109810 + if (InitFmDev(p_LnxWrpFmDev) != E_OK)
109811 + return -EIO;
109812 +
109813 + /* IOCTL ABI checking */
109814 + LnxWrpPCDIOCTLEnumChecking();
109815 + LnxWrpPCDIOCTLTypeChecking();
109816 +
109817 + Sprint (p_LnxWrpFmDev->name, "%s%d", DEV_FM_NAME, p_LnxWrpFmDev->id);
109818 +
109819 + /* Register to the /dev for IOCTL API */
109820 + /* Register dynamically a new major number for the character device: */
109821 + if ((p_LnxWrpFmDev->major = register_chrdev(0, p_LnxWrpFmDev->name, &fm_fops)) <= 0) {
109822 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Failed to allocate a major number for device \"%s\"", p_LnxWrpFmDev->name));
109823 + return -EIO;
109824 + }
109825 +
109826 + /* Creating classes for FM */
109827 + DBG(TRACE ,("class_create fm_class"));
109828 + p_LnxWrpFmDev->fm_class = class_create(THIS_MODULE, p_LnxWrpFmDev->name);
109829 + if (IS_ERR(p_LnxWrpFmDev->fm_class)) {
109830 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
109831 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("class_create error fm_class"));
109832 + return -EIO;
109833 + }
109834 +
109835 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE), NULL,
109836 + "fm%d", p_LnxWrpFmDev->id);
109837 + device_create(p_LnxWrpFmDev->fm_class, NULL, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE), NULL,
109838 + "fm%d-pcd", p_LnxWrpFmDev->id);
109839 + dev_set_drvdata(p_LnxWrpFmDev->dev, p_LnxWrpFmDev);
109840 +
109841 + /* create sysfs entries for stats and regs */
109842 + if ( fm_sysfs_create(p_LnxWrpFmDev->dev) !=0 )
109843 + {
109844 + FreeFmDev(p_LnxWrpFmDev);
109845 + REPORT_ERROR(MAJOR, E_INVALID_STATE, ("Unable to create sysfs entry - fm!!!"));
109846 + return -EIO;
109847 + }
109848 +
109849 +#ifdef CONFIG_PM
109850 + device_set_wakeup_capable(p_LnxWrpFmDev->dev, true);
109851 +#endif
109852 +
109853 + DBG(TRACE, ("FM%d probed", p_LnxWrpFmDev->id));
109854 +
109855 + return 0;
109856 +}
109857 +
109858 +static int fm_remove(struct platform_device *of_dev)
109859 +{
109860 + t_LnxWrpFmDev *p_LnxWrpFmDev;
109861 + struct device *dev;
109862 +
109863 + dev = &of_dev->dev;
109864 + p_LnxWrpFmDev = dev_get_drvdata(dev);
109865 +
109866 + fm_sysfs_destroy(dev);
109867 +
109868 + DBG(TRACE, ("destroy fm_class"));
109869 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_MINOR_BASE));
109870 + device_destroy(p_LnxWrpFmDev->fm_class, MKDEV(p_LnxWrpFmDev->major, DEV_FM_PCD_MINOR_BASE));
109871 + class_destroy(p_LnxWrpFmDev->fm_class);
109872 +
109873 + /* Destroy chardev */
109874 + unregister_chrdev(p_LnxWrpFmDev->major, p_LnxWrpFmDev->name);
109875 +
109876 + FreeFmDev(p_LnxWrpFmDev);
109877 +
109878 + DestroyFmDev(p_LnxWrpFmDev);
109879 +
109880 + dev_set_drvdata(dev, NULL);
109881 +
109882 + return 0;
109883 +}
109884 +
109885 +static const struct of_device_id fm_match[] = {
109886 + {
109887 + .compatible = "fsl,fman"
109888 + },
109889 + {}
109890 +};
109891 +#ifndef MODULE
109892 +MODULE_DEVICE_TABLE(of, fm_match);
109893 +#endif /* !MODULE */
109894 +
109895 +#if defined CONFIG_PM && (defined CONFIG_PPC || defined CONFIG_PPC64)
109896 +
109897 +#define SCFG_FMCLKDPSLPCR_ADDR 0xFFE0FC00C
109898 +#define SCFG_FMCLKDPSLPCR_DS_VAL 0x48402000
109899 +#define SCFG_FMCLKDPSLPCR_NORMAL_VAL 0x00402000
109900 +
109901 +struct device *g_fm_dev;
109902 +
109903 +static int fm_soc_suspend(struct device *dev)
109904 +{
109905 + int err = 0;
109906 + uint32_t *fmclk;
109907 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
109908 + g_fm_dev = dev;
109909 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
109910 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_DS_VAL);
109911 + if (p_LnxWrpFmDev->h_DsarRxPort)
109912 + {
109913 +#ifdef CONFIG_FSL_QORIQ_PM
109914 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 1);
109915 +#endif
109916 + err = FM_PORT_EnterDsarFinal(p_LnxWrpFmDev->h_DsarRxPort,
109917 + p_LnxWrpFmDev->h_DsarTxPort);
109918 + }
109919 + return err;
109920 +}
109921 +
109922 +static int fm_soc_resume(struct device *dev)
109923 +{
109924 + t_LnxWrpFmDev *p_LnxWrpFmDev = dev_get_drvdata(get_device(dev));
109925 + uint32_t *fmclk;
109926 + fmclk = ioremap(SCFG_FMCLKDPSLPCR_ADDR, 4);
109927 + WRITE_UINT32(*fmclk, SCFG_FMCLKDPSLPCR_NORMAL_VAL);
109928 + if (p_LnxWrpFmDev->h_DsarRxPort)
109929 + {
109930 +#ifdef CONFIG_FSL_QORIQ_PM
109931 + device_set_wakeup_enable(p_LnxWrpFmDev->dev, 0);
109932 +#endif
109933 + FM_PORT_ExitDsar(p_LnxWrpFmDev->h_DsarRxPort,
109934 + p_LnxWrpFmDev->h_DsarTxPort);
109935 + p_LnxWrpFmDev->h_DsarRxPort = 0;
109936 + p_LnxWrpFmDev->h_DsarTxPort = 0;
109937 + }
109938 + return 0;
109939 +}
109940 +
109941 +static const struct dev_pm_ops fm_pm_ops = {
109942 + .suspend = fm_soc_suspend,
109943 + .resume = fm_soc_resume,
109944 +};
109945 +
109946 +#define FM_PM_OPS (&fm_pm_ops)
109947 +
109948 +#else /* CONFIG_PM && (CONFIG_PPC || CONFIG_PPC64) */
109949 +
109950 +#define FM_PM_OPS NULL
109951 +
109952 +#endif /* CONFIG_PM && (CONFIG_PPC || CONFIG_PPC64) */
109953 +
109954 +static struct platform_driver fm_driver = {
109955 + .driver = {
109956 + .name = "fsl-fman",
109957 + .of_match_table = fm_match,
109958 + .owner = THIS_MODULE,
109959 + .pm = FM_PM_OPS,
109960 + },
109961 + .probe = fm_probe,
109962 + .remove = fm_remove
109963 +};
109964 +
109965 +t_Handle LNXWRP_FM_Init(void)
109966 +{
109967 + memset(&lnxWrpFm, 0, sizeof(lnxWrpFm));
109968 + mutex_init(&lnxwrp_mutex);
109969 +
109970 + /* Register to the DTB for basic FM API */
109971 + platform_driver_register(&fm_driver);
109972 +
109973 + return &lnxWrpFm;
109974 +}
109975 +
109976 +t_Error LNXWRP_FM_Free(t_Handle h_LnxWrpFm)
109977 +{
109978 + platform_driver_unregister(&fm_driver);
109979 + mutex_destroy(&lnxwrp_mutex);
109980 +
109981 + return E_OK;
109982 +}
109983 +
109984 +
109985 +struct fm * fm_bind(struct device *fm_dev)
109986 +{
109987 + return (struct fm *)(dev_get_drvdata(get_device(fm_dev)));
109988 +}
109989 +EXPORT_SYMBOL(fm_bind);
109990 +
109991 +void fm_unbind(struct fm *fm)
109992 +{
109993 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
109994 +
109995 + put_device(p_LnxWrpFmDev->dev);
109996 +}
109997 +EXPORT_SYMBOL(fm_unbind);
109998 +
109999 +struct resource * fm_get_mem_region(struct fm *fm)
110000 +{
110001 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
110002 +
110003 + return p_LnxWrpFmDev->res;
110004 +}
110005 +EXPORT_SYMBOL(fm_get_mem_region);
110006 +
110007 +void * fm_get_handle(struct fm *fm)
110008 +{
110009 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
110010 +
110011 + return (void *)p_LnxWrpFmDev->h_Dev;
110012 +}
110013 +EXPORT_SYMBOL(fm_get_handle);
110014 +
110015 +void * fm_get_rtc_handle(struct fm *fm)
110016 +{
110017 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev*)fm;
110018 +
110019 + return (void *)p_LnxWrpFmDev->h_RtcDev;
110020 +}
110021 +EXPORT_SYMBOL(fm_get_rtc_handle);
110022 +
110023 +struct fm_port * fm_port_bind (struct device *fm_port_dev)
110024 +{
110025 + return (struct fm_port *)(dev_get_drvdata(get_device(fm_port_dev)));
110026 +}
110027 +EXPORT_SYMBOL(fm_port_bind);
110028 +
110029 +void fm_port_unbind(struct fm_port *port)
110030 +{
110031 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
110032 +
110033 + put_device(p_LnxWrpFmPortDev->dev);
110034 +}
110035 +EXPORT_SYMBOL(fm_port_unbind);
110036 +
110037 +void *fm_port_get_handle(const struct fm_port *port)
110038 +{
110039 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
110040 +
110041 + return (void *)p_LnxWrpFmPortDev->h_Dev;
110042 +}
110043 +EXPORT_SYMBOL(fm_port_get_handle);
110044 +
110045 +u64 *fm_port_get_buffer_time_stamp(const struct fm_port *port,
110046 + const void *data)
110047 +{
110048 + return FM_PORT_GetBufferTimeStamp(fm_port_get_handle(port),
110049 + (void *)data);
110050 +}
110051 +EXPORT_SYMBOL(fm_port_get_buffer_time_stamp);
110052 +
110053 +void fm_port_get_base_addr(const struct fm_port *port, uint64_t *base_addr)
110054 +{
110055 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110056 +
110057 + *base_addr = p_LnxWrpFmPortDev->settings.param.baseAddr;
110058 +}
110059 +EXPORT_SYMBOL(fm_port_get_base_addr);
110060 +
110061 +void fm_port_pcd_bind (struct fm_port *port, struct fm_port_pcd_param *params)
110062 +{
110063 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
110064 +
110065 + p_LnxWrpFmPortDev->pcd_owner_params.cba = params->cba;
110066 + p_LnxWrpFmPortDev->pcd_owner_params.cbf = params->cbf;
110067 + p_LnxWrpFmPortDev->pcd_owner_params.dev = params->dev;
110068 +}
110069 +EXPORT_SYMBOL(fm_port_pcd_bind);
110070 +
110071 +void fm_port_get_buff_layout_ext_params(struct fm_port *port, struct fm_port_params *params)
110072 +{
110073 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110074 + struct device_node *fm_node, *port_node;
110075 + const uint32_t *uint32_prop;
110076 + int lenp;
110077 +
110078 + params->data_align = 0;
110079 + params->manip_extra_space = 0;
110080 +
110081 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
110082 + if (!fm_node) /* no advance parameters for FMan */
110083 + return;
110084 +
110085 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
110086 + p_LnxWrpFmPortDev->settings.param.portType,
110087 + p_LnxWrpFmPortDev->settings.param.portId);
110088 + if (!port_node) /* no advance parameters for FMan-Port */
110089 + return;
110090 +
110091 + uint32_prop = (uint32_t *)of_get_property(port_node, "buffer-layout", &lenp);
110092 + if (uint32_prop) {
110093 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
110094 + return;
110095 +
110096 + params->manip_extra_space = (uint8_t)be32_to_cpu(uint32_prop[0]);
110097 + params->data_align = (uint16_t)be32_to_cpu(uint32_prop[1]);
110098 + }
110099 +
110100 + of_node_put(port_node);
110101 + of_node_put(fm_node);
110102 +}
110103 +EXPORT_SYMBOL(fm_port_get_buff_layout_ext_params);
110104 +
110105 +uint16_t fm_get_tx_port_channel(struct fm_port *port)
110106 +{
110107 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
110108 +
110109 + return p_LnxWrpFmPortDev->txCh;
110110 +}
110111 +EXPORT_SYMBOL(fm_get_tx_port_channel);
110112 +
110113 +int fm_port_enable (struct fm_port *port)
110114 +{
110115 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
110116 + t_Error err = FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
110117 +
110118 + return GET_ERROR_TYPE(err);
110119 +}
110120 +EXPORT_SYMBOL(fm_port_enable);
110121 +
110122 +int fm_port_disable(struct fm_port *port)
110123 +{
110124 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)port;
110125 + t_Error err = FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
110126 +
110127 + return GET_ERROR_TYPE(err);
110128 +}
110129 +EXPORT_SYMBOL(fm_port_disable);
110130 +
110131 +int fm_port_set_rate_limit(struct fm_port *port,
110132 + uint16_t max_burst_size,
110133 + uint32_t rate_limit)
110134 +{
110135 + t_FmPortRateLimit param;
110136 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110137 + int err = 0;
110138 +
110139 + param.maxBurstSize = max_burst_size;
110140 + param.rateLimit = rate_limit;
110141 + param.rateLimitDivider = 0;
110142 +
110143 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, &param);
110144 + return err;
110145 +}
110146 +EXPORT_SYMBOL(fm_port_set_rate_limit);
110147 +
110148 +int fm_port_del_rate_limit(struct fm_port *port)
110149 +{
110150 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110151 +
110152 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
110153 + return 0;
110154 +}
110155 +EXPORT_SYMBOL(fm_port_del_rate_limit);
110156 +
110157 +void FM_PORT_Dsar_DumpRegs(void);
110158 +int ar_showmem(struct file *file, const char __user *buffer,
110159 + unsigned long count, void *data)
110160 +{
110161 + FM_PORT_Dsar_DumpRegs();
110162 + return 2;
110163 +}
110164 +
110165 +struct auto_res_tables_sizes *fm_port_get_autores_maxsize(
110166 + struct fm_port *port)
110167 +{
110168 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110169 + return &p_LnxWrpFmPortDev->dsar_table_sizes;
110170 +}
110171 +EXPORT_SYMBOL(fm_port_get_autores_maxsize);
110172 +
110173 +int fm_port_enter_autores_for_deepsleep(struct fm_port *port,
110174 + struct auto_res_port_params *params)
110175 +{
110176 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110177 + t_LnxWrpFmDev* p_LnxWrpFmDev = (t_LnxWrpFmDev*)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
110178 + p_LnxWrpFmDev->h_DsarRxPort = p_LnxWrpFmPortDev->h_Dev;
110179 + p_LnxWrpFmDev->h_DsarTxPort = params->h_FmPortTx;
110180 +
110181 + /*Register other under /proc/autoresponse */
110182 + if (WARN_ON(sizeof(t_FmPortDsarParams) != sizeof(struct auto_res_port_params)))
110183 + return -EFAULT;
110184 +
110185 + FM_PORT_EnterDsar(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarParams*)params);
110186 + return 0;
110187 +}
110188 +EXPORT_SYMBOL(fm_port_enter_autores_for_deepsleep);
110189 +
110190 +void fm_port_exit_auto_res_for_deep_sleep(struct fm_port *port_rx,
110191 + struct fm_port *port_tx)
110192 +{
110193 +}
110194 +EXPORT_SYMBOL(fm_port_exit_auto_res_for_deep_sleep);
110195 +
110196 +int fm_port_get_autores_stats(struct fm_port *port,
110197 + struct auto_res_port_stats *stats)
110198 +{
110199 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110200 + if (WARN_ON(sizeof(t_FmPortDsarStats) != sizeof(struct auto_res_port_stats)))
110201 + return -EFAULT;
110202 + return FM_PORT_GetDsarStats(p_LnxWrpFmPortDev->h_Dev, (t_FmPortDsarStats*)stats);
110203 +}
110204 +EXPORT_SYMBOL(fm_port_get_autores_stats);
110205 +
110206 +int fm_port_suspend(struct fm_port *port)
110207 +{
110208 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110209 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
110210 + return FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
110211 + else
110212 + return 0;
110213 +}
110214 +EXPORT_SYMBOL(fm_port_suspend);
110215 +
110216 +int fm_port_resume(struct fm_port *port)
110217 +{
110218 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110219 + if (!FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev))
110220 + return FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
110221 + else
110222 + return 0;
110223 +}
110224 +EXPORT_SYMBOL(fm_port_resume);
110225 +
110226 +bool fm_port_is_in_auto_res_mode(struct fm_port *port)
110227 +{
110228 + return FM_PORT_IsInDsar(port);
110229 +}
110230 +EXPORT_SYMBOL(fm_port_is_in_auto_res_mode);
110231 +
110232 +#ifdef CONFIG_FMAN_PFC
110233 +int fm_port_set_pfc_priorities_mapping_to_qman_wq(struct fm_port *port,
110234 + uint8_t prio, uint8_t wq)
110235 +{
110236 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110237 + int err;
110238 + int _errno;
110239 +
110240 + err = FM_PORT_SetPfcPrioritiesMappingToQmanWQ(p_LnxWrpFmPortDev->h_Dev,
110241 + prio, wq);
110242 + _errno = -GET_ERROR_TYPE(err);
110243 + if (unlikely(_errno < 0))
110244 + pr_err("FM_PORT_SetPfcPrioritiesMappingToQmanWQ() = 0x%08x\n", err);
110245 +
110246 + return _errno;
110247 +}
110248 +EXPORT_SYMBOL(fm_port_set_pfc_priorities_mapping_to_qman_wq);
110249 +#endif
110250 +
110251 +int fm_mac_set_exception(struct fm_mac_dev *fm_mac_dev,
110252 + e_FmMacExceptions exception, bool enable)
110253 +{
110254 + int err;
110255 + int _errno;
110256 +
110257 + err = FM_MAC_SetException(fm_mac_dev, exception, enable);
110258 +
110259 + _errno = -GET_ERROR_TYPE(err);
110260 + if (unlikely(_errno < 0))
110261 + pr_err("FM_MAC_SetException() = 0x%08x\n", err);
110262 +
110263 + return _errno;
110264 +}
110265 +EXPORT_SYMBOL(fm_mac_set_exception);
110266 +
110267 +int fm_mac_free(struct fm_mac_dev *fm_mac_dev)
110268 +{
110269 + int err;
110270 + int _error;
110271 +
110272 + err = FM_MAC_Free(fm_mac_dev);
110273 + _error = -GET_ERROR_TYPE(err);
110274 +
110275 + if (unlikely(_error < 0))
110276 + pr_err("FM_MAC_Free() = 0x%08x\n", err);
110277 +
110278 + return _error;
110279 +}
110280 +EXPORT_SYMBOL(fm_mac_free);
110281 +
110282 +struct fm_mac_dev *fm_mac_config(t_FmMacParams *params)
110283 +{
110284 + struct fm_mac_dev *fm_mac_dev;
110285 +
110286 + fm_mac_dev = FM_MAC_Config(params);
110287 + if (unlikely(fm_mac_dev == NULL))
110288 + pr_err("FM_MAC_Config() failed\n");
110289 +
110290 + return fm_mac_dev;
110291 +}
110292 +EXPORT_SYMBOL(fm_mac_config);
110293 +
110294 +int fm_mac_config_max_frame_length(struct fm_mac_dev *fm_mac_dev,
110295 + int len)
110296 +{
110297 + int err;
110298 + int _errno;
110299 +
110300 + err = FM_MAC_ConfigMaxFrameLength(fm_mac_dev, len);
110301 + _errno = -GET_ERROR_TYPE(err);
110302 + if (unlikely(_errno < 0))
110303 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
110304 +
110305 + return _errno;
110306 +}
110307 +EXPORT_SYMBOL(fm_mac_config_max_frame_length);
110308 +
110309 +int fm_mac_config_pad_and_crc(struct fm_mac_dev *fm_mac_dev, bool enable)
110310 +{
110311 + int err;
110312 + int _errno;
110313 +
110314 + err = FM_MAC_ConfigPadAndCrc(fm_mac_dev, enable);
110315 + _errno = -GET_ERROR_TYPE(err);
110316 + if (unlikely(_errno < 0))
110317 + pr_err("FM_MAC_ConfigPadAndCrc() = 0x%08x\n", err);
110318 +
110319 + return _errno;
110320 +}
110321 +EXPORT_SYMBOL(fm_mac_config_pad_and_crc);
110322 +
110323 +int fm_mac_config_half_duplex(struct fm_mac_dev *fm_mac_dev, bool enable)
110324 +{
110325 + int err;
110326 + int _errno;
110327 +
110328 + err = FM_MAC_ConfigHalfDuplex(fm_mac_dev, enable);
110329 + _errno = -GET_ERROR_TYPE(err);
110330 + if (unlikely(_errno < 0))
110331 + pr_err("FM_MAC_ConfigHalfDuplex() = 0x%08x\n", err);
110332 +
110333 + return _errno;
110334 +}
110335 +EXPORT_SYMBOL(fm_mac_config_half_duplex);
110336 +
110337 +int fm_mac_config_reset_on_init(struct fm_mac_dev *fm_mac_dev, bool enable)
110338 +{
110339 + int err;
110340 + int _errno;
110341 +
110342 + err = FM_MAC_ConfigResetOnInit(fm_mac_dev, enable);
110343 + _errno = -GET_ERROR_TYPE(err);
110344 + if (unlikely(_errno < 0))
110345 + pr_err("FM_MAC_ConfigResetOnInit() = 0x%08x\n", err);
110346 +
110347 + return _errno;
110348 +}
110349 +EXPORT_SYMBOL(fm_mac_config_reset_on_init);
110350 +
110351 +int fm_mac_init(struct fm_mac_dev *fm_mac_dev)
110352 +{
110353 + int err;
110354 + int _errno;
110355 +
110356 + err = FM_MAC_Init(fm_mac_dev);
110357 + _errno = -GET_ERROR_TYPE(err);
110358 + if (unlikely(_errno < 0))
110359 + pr_err("FM_MAC_Init() = 0x%08x\n", err);
110360 +
110361 + return _errno;
110362 +}
110363 +EXPORT_SYMBOL(fm_mac_init);
110364 +
110365 +int fm_mac_get_version(struct fm_mac_dev *fm_mac_dev, uint32_t *version)
110366 +{
110367 + int err;
110368 + int _errno;
110369 +
110370 + err = FM_MAC_GetVesrion(fm_mac_dev, version);
110371 + _errno = -GET_ERROR_TYPE(err);
110372 + if (unlikely(_errno < 0))
110373 + pr_err("FM_MAC_GetVesrion() = 0x%08x\n", err);
110374 +
110375 + return _errno;
110376 +}
110377 +EXPORT_SYMBOL(fm_mac_get_version);
110378 +
110379 +int fm_mac_enable(struct fm_mac_dev *fm_mac_dev)
110380 +{
110381 + int _errno;
110382 + t_Error err;
110383 +
110384 + err = FM_MAC_Enable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
110385 + _errno = -GET_ERROR_TYPE(err);
110386 + if (unlikely(_errno < 0))
110387 + pr_err("FM_MAC_Enable() = 0x%08x\n", err);
110388 +
110389 + return _errno;
110390 +}
110391 +EXPORT_SYMBOL(fm_mac_enable);
110392 +
110393 +int fm_mac_disable(struct fm_mac_dev *fm_mac_dev)
110394 +{
110395 + int _errno;
110396 + t_Error err;
110397 +
110398 + err = FM_MAC_Disable(fm_mac_dev, e_COMM_MODE_RX_AND_TX);
110399 + _errno = -GET_ERROR_TYPE(err);
110400 + if (unlikely(_errno < 0))
110401 + pr_err("FM_MAC_Disable() = 0x%08x\n", err);
110402 +
110403 + return _errno;
110404 +}
110405 +EXPORT_SYMBOL(fm_mac_disable);
110406 +
110407 +int fm_mac_resume(struct fm_mac_dev *fm_mac_dev)
110408 +{
110409 + int _errno;
110410 + t_Error err;
110411 +
110412 + err = FM_MAC_Resume(fm_mac_dev);
110413 + _errno = -GET_ERROR_TYPE(err);
110414 + if (unlikely(_errno < 0))
110415 + pr_err("FM_MAC_Resume() = 0x%08x\n", err);
110416 +
110417 + return _errno;
110418 +}
110419 +EXPORT_SYMBOL(fm_mac_resume);
110420 +
110421 +int fm_mac_set_promiscuous(struct fm_mac_dev *fm_mac_dev,
110422 + bool enable)
110423 +{
110424 + int _errno;
110425 + t_Error err;
110426 +
110427 + err = FM_MAC_SetPromiscuous(fm_mac_dev, enable);
110428 + _errno = -GET_ERROR_TYPE(err);
110429 + if (unlikely(_errno < 0))
110430 + pr_err("FM_MAC_SetPromiscuous() = 0x%08x\n", err);
110431 +
110432 + return _errno;
110433 +}
110434 +EXPORT_SYMBOL(fm_mac_set_promiscuous);
110435 +
110436 +int fm_mac_remove_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
110437 + t_EnetAddr *mac_addr)
110438 +{
110439 + int _errno;
110440 + t_Error err;
110441 +
110442 + err = FM_MAC_RemoveHashMacAddr(fm_mac_dev, mac_addr);
110443 + _errno = -GET_ERROR_TYPE(err);
110444 + if (_errno < 0) {
110445 + pr_err("FM_MAC_RemoveHashMacAddr() = 0x%08x\n", err);
110446 + return _errno;
110447 + }
110448 +
110449 + return 0;
110450 +}
110451 +EXPORT_SYMBOL(fm_mac_remove_hash_mac_addr);
110452 +
110453 +int fm_mac_add_hash_mac_addr(struct fm_mac_dev *fm_mac_dev,
110454 + t_EnetAddr *mac_addr)
110455 +{
110456 + int _errno;
110457 + t_Error err;
110458 +
110459 + err = FM_MAC_AddHashMacAddr(fm_mac_dev, mac_addr);
110460 + _errno = -GET_ERROR_TYPE(err);
110461 + if (_errno < 0) {
110462 + pr_err("FM_MAC_AddHashMacAddr() = 0x%08x\n", err);
110463 + return _errno;
110464 + }
110465 +
110466 + return 0;
110467 +}
110468 +EXPORT_SYMBOL(fm_mac_add_hash_mac_addr);
110469 +
110470 +int fm_mac_modify_mac_addr(struct fm_mac_dev *fm_mac_dev,
110471 + uint8_t *addr)
110472 +{
110473 + int _errno;
110474 + t_Error err;
110475 +
110476 + err = FM_MAC_ModifyMacAddr(fm_mac_dev, (t_EnetAddr *)addr);
110477 + _errno = -GET_ERROR_TYPE(err);
110478 + if (_errno < 0)
110479 + pr_err("FM_MAC_ModifyMacAddr() = 0x%08x\n", err);
110480 +
110481 + return _errno;
110482 +}
110483 +EXPORT_SYMBOL(fm_mac_modify_mac_addr);
110484 +
110485 +int fm_mac_adjust_link(struct fm_mac_dev *fm_mac_dev,
110486 + bool link, int speed, bool duplex)
110487 +{
110488 + int _errno;
110489 + t_Error err;
110490 +
110491 + if (!link) {
110492 +#if (DPAA_VERSION < 11)
110493 + FM_MAC_RestartAutoneg(fm_mac_dev);
110494 +#endif
110495 + return 0;
110496 + }
110497 +
110498 + err = FM_MAC_AdjustLink(fm_mac_dev, speed, duplex);
110499 + _errno = -GET_ERROR_TYPE(err);
110500 + if (unlikely(_errno < 0))
110501 + pr_err("FM_MAC_AdjustLink() = 0x%08x\n", err);
110502 +
110503 + return _errno;
110504 +}
110505 +EXPORT_SYMBOL(fm_mac_adjust_link);
110506 +
110507 +int fm_mac_enable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
110508 +{
110509 + int _errno;
110510 + t_Error err;
110511 +
110512 + err = FM_MAC_Enable1588TimeStamp(fm_mac_dev);
110513 + _errno = -GET_ERROR_TYPE(err);
110514 + if (unlikely(_errno < 0))
110515 + pr_err("FM_MAC_Enable1588TimeStamp() = 0x%08x\n", err);
110516 + return _errno;
110517 +}
110518 +EXPORT_SYMBOL(fm_mac_enable_1588_time_stamp);
110519 +
110520 +int fm_mac_disable_1588_time_stamp(struct fm_mac_dev *fm_mac_dev)
110521 +{
110522 + int _errno;
110523 + t_Error err;
110524 +
110525 + err = FM_MAC_Disable1588TimeStamp(fm_mac_dev);
110526 + _errno = -GET_ERROR_TYPE(err);
110527 + if (unlikely(_errno < 0))
110528 + pr_err("FM_MAC_Disable1588TimeStamp() = 0x%08x\n", err);
110529 + return _errno;
110530 +}
110531 +EXPORT_SYMBOL(fm_mac_disable_1588_time_stamp);
110532 +
110533 +int fm_mac_set_rx_pause_frames(
110534 + struct fm_mac_dev *fm_mac_dev, bool en)
110535 +{
110536 + int _errno;
110537 + t_Error err;
110538 +
110539 + /* if rx pause is enabled, do NOT ignore pause frames */
110540 + err = FM_MAC_SetRxIgnorePauseFrames(fm_mac_dev, !en);
110541 +
110542 + _errno = -GET_ERROR_TYPE(err);
110543 + if (_errno < 0)
110544 + pr_err("FM_MAC_SetRxIgnorePauseFrames() = 0x%08x\n", err);
110545 +
110546 + return _errno;
110547 +}
110548 +EXPORT_SYMBOL(fm_mac_set_rx_pause_frames);
110549 +
110550 +#ifdef CONFIG_FMAN_PFC
110551 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
110552 + bool en)
110553 +{
110554 + int _errno, i;
110555 + t_Error err;
110556 +
110557 + if (en)
110558 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
110559 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
110560 + i, fsl_fm_pfc_quanta[i],
110561 + FSL_FM_PAUSE_THRESH_DEFAULT);
110562 + _errno = -GET_ERROR_TYPE(err);
110563 + if (_errno < 0) {
110564 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
110565 + return _errno;
110566 + }
110567 + }
110568 + else
110569 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++) {
110570 + err = FM_MAC_SetTxPauseFrames(fm_mac_dev,
110571 + i, FSL_FM_PAUSE_TIME_DISABLE,
110572 + FSL_FM_PAUSE_THRESH_DEFAULT);
110573 + _errno = -GET_ERROR_TYPE(err);
110574 + if (_errno < 0) {
110575 + pr_err("FM_MAC_SetTxPauseFrames() = 0x%08x\n", err);
110576 + return _errno;
110577 + }
110578 + }
110579 +
110580 + return _errno;
110581 +}
110582 +#else
110583 +int fm_mac_set_tx_pause_frames(struct fm_mac_dev *fm_mac_dev,
110584 + bool en)
110585 +{
110586 + int _errno;
110587 + t_Error err;
110588 +
110589 + if (en)
110590 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
110591 + FSL_FM_PAUSE_TIME_ENABLE);
110592 + else
110593 + err = FM_MAC_SetTxAutoPauseFrames(fm_mac_dev,
110594 + FSL_FM_PAUSE_TIME_DISABLE);
110595 +
110596 + _errno = -GET_ERROR_TYPE(err);
110597 + if (_errno < 0)
110598 + pr_err("FM_MAC_SetTxAutoPauseFrames() = 0x%08x\n", err);
110599 +
110600 + return _errno;
110601 +}
110602 +#endif
110603 +EXPORT_SYMBOL(fm_mac_set_tx_pause_frames);
110604 +
110605 +int fm_rtc_enable(struct fm *fm_dev)
110606 +{
110607 + int _errno;
110608 + t_Error err;
110609 +
110610 + err = FM_RTC_Enable(fm_get_rtc_handle(fm_dev), 0);
110611 + _errno = -GET_ERROR_TYPE(err);
110612 + if (unlikely(_errno < 0))
110613 + pr_err("FM_RTC_Enable = 0x%08x\n", err);
110614 +
110615 + return _errno;
110616 +}
110617 +EXPORT_SYMBOL(fm_rtc_enable);
110618 +
110619 +int fm_rtc_disable(struct fm *fm_dev)
110620 +{
110621 + int _errno;
110622 + t_Error err;
110623 +
110624 + err = FM_RTC_Disable(fm_get_rtc_handle(fm_dev));
110625 + _errno = -GET_ERROR_TYPE(err);
110626 + if (unlikely(_errno < 0))
110627 + pr_err("FM_RTC_Disable = 0x%08x\n", err);
110628 +
110629 + return _errno;
110630 +}
110631 +EXPORT_SYMBOL(fm_rtc_disable);
110632 +
110633 +int fm_rtc_get_cnt(struct fm *fm_dev, uint64_t *ts)
110634 +{
110635 + int _errno;
110636 + t_Error err;
110637 +
110638 + err = FM_RTC_GetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
110639 + _errno = -GET_ERROR_TYPE(err);
110640 + if (unlikely(_errno < 0))
110641 + pr_err("FM_RTC_GetCurrentTime = 0x%08x\n", err);
110642 +
110643 + return _errno;
110644 +}
110645 +EXPORT_SYMBOL(fm_rtc_get_cnt);
110646 +
110647 +int fm_rtc_set_cnt(struct fm *fm_dev, uint64_t ts)
110648 +{
110649 + int _errno;
110650 + t_Error err;
110651 +
110652 + err = FM_RTC_SetCurrentTime(fm_get_rtc_handle(fm_dev), ts);
110653 + _errno = -GET_ERROR_TYPE(err);
110654 + if (unlikely(_errno < 0))
110655 + pr_err("FM_RTC_SetCurrentTime = 0x%08x\n", err);
110656 +
110657 + return _errno;
110658 +}
110659 +EXPORT_SYMBOL(fm_rtc_set_cnt);
110660 +
110661 +int fm_rtc_get_drift(struct fm *fm_dev, uint32_t *drift)
110662 +{
110663 + int _errno;
110664 + t_Error err;
110665 +
110666 + err = FM_RTC_GetFreqCompensation(fm_get_rtc_handle(fm_dev),
110667 + drift);
110668 + _errno = -GET_ERROR_TYPE(err);
110669 + if (unlikely(_errno < 0))
110670 + pr_err("FM_RTC_GetFreqCompensation = 0x%08x\n", err);
110671 +
110672 + return _errno;
110673 +}
110674 +EXPORT_SYMBOL(fm_rtc_get_drift);
110675 +
110676 +int fm_rtc_set_drift(struct fm *fm_dev, uint32_t drift)
110677 +{
110678 + int _errno;
110679 + t_Error err;
110680 +
110681 + err = FM_RTC_SetFreqCompensation(fm_get_rtc_handle(fm_dev),
110682 + drift);
110683 + _errno = -GET_ERROR_TYPE(err);
110684 + if (unlikely(_errno < 0))
110685 + pr_err("FM_RTC_SetFreqCompensation = 0x%08x\n", err);
110686 +
110687 + return _errno;
110688 +}
110689 +EXPORT_SYMBOL(fm_rtc_set_drift);
110690 +
110691 +int fm_rtc_set_alarm(struct fm *fm_dev, uint32_t id,
110692 + uint64_t time)
110693 +{
110694 + t_FmRtcAlarmParams alarm;
110695 + int _errno;
110696 + t_Error err;
110697 +
110698 + alarm.alarmId = id;
110699 + alarm.alarmTime = time;
110700 + alarm.f_AlarmCallback = NULL;
110701 + err = FM_RTC_SetAlarm(fm_get_rtc_handle(fm_dev),
110702 + &alarm);
110703 + _errno = -GET_ERROR_TYPE(err);
110704 + if (unlikely(_errno < 0))
110705 + pr_err("FM_RTC_SetAlarm = 0x%08x\n", err);
110706 +
110707 + return _errno;
110708 +}
110709 +EXPORT_SYMBOL(fm_rtc_set_alarm);
110710 +
110711 +int fm_rtc_set_fiper(struct fm *fm_dev, uint32_t id,
110712 + uint64_t fiper)
110713 +{
110714 + t_FmRtcPeriodicPulseParams pp;
110715 + int _errno;
110716 + t_Error err;
110717 +
110718 + pp.periodicPulseId = id;
110719 + pp.periodicPulsePeriod = fiper;
110720 + pp.f_PeriodicPulseCallback = NULL;
110721 + err = FM_RTC_SetPeriodicPulse(fm_get_rtc_handle(fm_dev), &pp);
110722 + _errno = -GET_ERROR_TYPE(err);
110723 + if (unlikely(_errno < 0))
110724 + pr_err("FM_RTC_SetPeriodicPulse = 0x%08x\n", err);
110725 +
110726 + return _errno;
110727 +}
110728 +EXPORT_SYMBOL(fm_rtc_set_fiper);
110729 +
110730 +#ifdef CONFIG_PTP_1588_CLOCK_DPAA
110731 +int fm_rtc_enable_interrupt(struct fm *fm_dev, uint32_t events)
110732 +{
110733 + int _errno;
110734 + t_Error err;
110735 +
110736 + err = FM_RTC_EnableInterrupt(fm_get_rtc_handle(fm_dev),
110737 + events);
110738 + _errno = -GET_ERROR_TYPE(err);
110739 + if (unlikely(_errno < 0))
110740 + pr_err("FM_RTC_EnableInterrupt = 0x%08x\n", err);
110741 +
110742 + return _errno;
110743 +}
110744 +EXPORT_SYMBOL(fm_rtc_enable_interrupt);
110745 +
110746 +int fm_rtc_disable_interrupt(struct fm *fm_dev, uint32_t events)
110747 +{
110748 + int _errno;
110749 + t_Error err;
110750 +
110751 + err = FM_RTC_DisableInterrupt(fm_get_rtc_handle(fm_dev),
110752 + events);
110753 + _errno = -GET_ERROR_TYPE(err);
110754 + if (unlikely(_errno < 0))
110755 + pr_err("FM_RTC_DisableInterrupt = 0x%08x\n", err);
110756 +
110757 + return _errno;
110758 +}
110759 +EXPORT_SYMBOL(fm_rtc_disable_interrupt);
110760 +#endif
110761 +
110762 +int fm_mac_set_wol(struct fm_port *port, struct fm_mac_dev *fm_mac_dev, bool en)
110763 +{
110764 + int _errno;
110765 + t_Error err;
110766 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)port;
110767 +
110768 + /* Do not set WoL on AR ports */
110769 + if (FM_PORT_IsInDsar(p_LnxWrpFmPortDev->h_Dev)) {
110770 + printk(KERN_WARNING "Port is AutoResponse enabled! WoL will not be set on this port!\n");
110771 + return 0;
110772 + }
110773 +
110774 + err = FM_MAC_SetWakeOnLan(fm_mac_dev, en);
110775 +
110776 + _errno = -GET_ERROR_TYPE(err);
110777 + if (_errno < 0)
110778 + pr_err("FM_MAC_SetWakeOnLan() = 0x%08x\n", err);
110779 +
110780 + return _errno;
110781 +}
110782 +EXPORT_SYMBOL(fm_mac_set_wol);
110783 +
110784 +void fm_mutex_lock(void)
110785 +{
110786 + mutex_lock(&lnxwrp_mutex);
110787 +}
110788 +EXPORT_SYMBOL(fm_mutex_lock);
110789 +
110790 +void fm_mutex_unlock(void)
110791 +{
110792 + mutex_unlock(&lnxwrp_mutex);
110793 +}
110794 +EXPORT_SYMBOL(fm_mutex_unlock);
110795 +
110796 +/*Macsec wrapper functions*/
110797 +struct fm_macsec_dev *fm_macsec_config(struct fm_macsec_params *fm_params)
110798 +{
110799 + struct fm_macsec_dev *fm_macsec_dev;
110800 +
110801 + fm_macsec_dev = FM_MACSEC_Config((t_FmMacsecParams *)fm_params);
110802 + if (unlikely(fm_macsec_dev == NULL))
110803 + pr_err("FM_MACSEC_Config() failed\n");
110804 +
110805 + return fm_macsec_dev;
110806 +}
110807 +EXPORT_SYMBOL(fm_macsec_config);
110808 +
110809 +int fm_macsec_init(struct fm_macsec_dev *fm_macsec_dev)
110810 +{
110811 + int err;
110812 + int _errno;
110813 +
110814 + err = FM_MACSEC_Init(fm_macsec_dev);
110815 + _errno = -GET_ERROR_TYPE(err);
110816 + if (unlikely(_errno < 0))
110817 + pr_err("FM_MACSEC_Init() = 0x%08x\n", err);
110818 +
110819 + return _errno;
110820 +}
110821 +EXPORT_SYMBOL(fm_macsec_init);
110822 +
110823 +int fm_macsec_free(struct fm_macsec_dev *fm_macsec_dev)
110824 +{
110825 + int err;
110826 + int _error;
110827 +
110828 + err = FM_MACSEC_Free(fm_macsec_dev);
110829 + _error = -GET_ERROR_TYPE(err);
110830 +
110831 + if (unlikely(_error < 0))
110832 + pr_err("FM_MACSEC_Free() = 0x%08x\n", err);
110833 +
110834 + return _error;
110835 +}
110836 +EXPORT_SYMBOL(fm_macsec_free);
110837 +
110838 +int fm_macsec_config_unknown_sci_frame_treatment(struct fm_macsec_dev
110839 + *fm_macsec_dev,
110840 + fm_macsec_unknown_sci_frame_treatment treat_mode)
110841 +{
110842 + int err;
110843 + int _errno;
110844 +
110845 + err = FM_MACSEC_ConfigUnknownSciFrameTreatment(fm_macsec_dev,
110846 + treat_mode);
110847 + _errno = -GET_ERROR_TYPE(err);
110848 + if (unlikely(_errno < 0))
110849 + pr_err("FM_MACSEC_ConfigUnknownSciFrameTreatmen() = 0x%08x\n", err);
110850 +
110851 + return _errno;
110852 +}
110853 +EXPORT_SYMBOL(fm_macsec_config_unknown_sci_frame_treatment);
110854 +
110855 +int fm_macsec_config_invalid_tags_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
110856 + bool deliver_uncontrolled)
110857 +{
110858 + int err;
110859 + int _errno;
110860 +
110861 + err = FM_MACSEC_ConfigInvalidTagsFrameTreatment(fm_macsec_dev,
110862 + deliver_uncontrolled);
110863 + _errno = -GET_ERROR_TYPE(err);
110864 + if (unlikely(_errno < 0))
110865 + pr_err("FM_MAC_ConfigMaxFrameLength() = 0x%08x\n", err);
110866 +
110867 + return _errno;
110868 +}
110869 +EXPORT_SYMBOL(fm_macsec_config_invalid_tags_frame_treatment);
110870 +
110871 +int fm_macsec_config_kay_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
110872 + bool discard_uncontrolled)
110873 +{
110874 + int err;
110875 + int _errno;
110876 +
110877 + err = FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatment(fm_macsec_dev,
110878 + discard_uncontrolled);
110879 + _errno = -GET_ERROR_TYPE(err);
110880 + if (unlikely(_errno < 0))
110881 + pr_err("FM_MACSEC_ConfigEncryptWithNoChangedTextFrameTreatmen() = 0x%08x\n", err);
110882 +
110883 + return _errno;
110884 +}
110885 +EXPORT_SYMBOL(fm_macsec_config_kay_frame_treatment);
110886 +
110887 +int fm_macsec_config_untag_frame_treatment(struct fm_macsec_dev *fm_macsec_dev,
110888 + fm_macsec_untag_frame_treatment treat_mode)
110889 +{
110890 + int err;
110891 + int _errno;
110892 +
110893 + err = FM_MACSEC_ConfigUntagFrameTreatment(fm_macsec_dev, treat_mode);
110894 + _errno = -GET_ERROR_TYPE(err);
110895 + if (unlikely(_errno < 0))
110896 + pr_err("FM_MACSEC_ConfigUntagFrameTreatment() = 0x%08x\n", err);
110897 +
110898 + return _errno;
110899 +}
110900 +EXPORT_SYMBOL(fm_macsec_config_untag_frame_treatment);
110901 +
110902 +int fm_macsec_config_pn_exhaustion_threshold(struct fm_macsec_dev *fm_macsec_dev,
110903 + uint32_t pn_exh_thr)
110904 +{
110905 + int err;
110906 + int _errno;
110907 +
110908 + err = FM_MACSEC_ConfigPnExhaustionThreshold(fm_macsec_dev, pn_exh_thr);
110909 + _errno = -GET_ERROR_TYPE(err);
110910 + if (unlikely(_errno < 0))
110911 + pr_err("FM_MACSEC_ConfigPnExhaustionThreshold() = 0x%08x\n", err);
110912 +
110913 + return _errno;
110914 +}
110915 +EXPORT_SYMBOL(fm_macsec_config_pn_exhaustion_threshold);
110916 +
110917 +int fm_macsec_config_keys_unreadable(struct fm_macsec_dev *fm_macsec_dev)
110918 +{
110919 + int err;
110920 + int _errno;
110921 +
110922 + err = FM_MACSEC_ConfigKeysUnreadable(fm_macsec_dev);
110923 + _errno = -GET_ERROR_TYPE(err);
110924 + if (unlikely(_errno < 0))
110925 + pr_err("FM_MACSEC_ConfigKeysUnreadable() = 0x%08x\n", err);
110926 +
110927 + return _errno;
110928 +}
110929 +EXPORT_SYMBOL(fm_macsec_config_keys_unreadable);
110930 +
110931 +int fm_macsec_config_sectag_without_sci(struct fm_macsec_dev *fm_macsec_dev)
110932 +{
110933 + int err;
110934 + int _errno;
110935 +
110936 + err = FM_MACSEC_ConfigSectagWithoutSCI(fm_macsec_dev);
110937 + _errno = -GET_ERROR_TYPE(err);
110938 + if (unlikely(_errno < 0))
110939 + pr_err("FM_MACSEC_ConfigSectagWithoutSCI() = 0x%08x\n", err);
110940 +
110941 + return _errno;
110942 +}
110943 +EXPORT_SYMBOL(fm_macsec_config_sectag_without_sci);
110944 +
110945 +int fm_macsec_config_exception(struct fm_macsec_dev *fm_macsec_dev,
110946 + fm_macsec_exception exception, bool enable)
110947 +{
110948 + int err;
110949 + int _errno;
110950 +
110951 + err = FM_MACSEC_ConfigException(fm_macsec_dev, exception, enable);
110952 + _errno = -GET_ERROR_TYPE(err);
110953 + if (unlikely(_errno < 0))
110954 + pr_err("FM_MACSEC_ConfigException() = 0x%08x\n", err);
110955 +
110956 + return _errno;
110957 +}
110958 +EXPORT_SYMBOL(fm_macsec_config_exception);
110959 +
110960 +int fm_macsec_get_revision(struct fm_macsec_dev *fm_macsec_dev,
110961 + int *macsec_revision)
110962 +{
110963 + int err;
110964 + int _errno;
110965 +
110966 + err = FM_MACSEC_GetRevision(fm_macsec_dev, macsec_revision);
110967 + _errno = -GET_ERROR_TYPE(err);
110968 + if (unlikely(_errno < 0))
110969 + pr_err("FM_MACSEC_GetRevision() = 0x%08x\n", err);
110970 +
110971 + return _errno;
110972 +}
110973 +EXPORT_SYMBOL(fm_macsec_get_revision);
110974 +
110975 +int fm_macsec_enable(struct fm_macsec_dev *fm_macsec_dev)
110976 +{
110977 + int err;
110978 + int _errno;
110979 +
110980 + err = FM_MACSEC_Enable(fm_macsec_dev);
110981 + _errno = -GET_ERROR_TYPE(err);
110982 + if (unlikely(_errno < 0))
110983 + pr_err("FM_MACSEC_Enable() = 0x%08x\n", err);
110984 +
110985 + return _errno;
110986 +}
110987 +EXPORT_SYMBOL(fm_macsec_enable);
110988 +
110989 +int fm_macsec_disable(struct fm_macsec_dev *fm_macsec_dev)
110990 +{
110991 + int err;
110992 + int _errno;
110993 +
110994 + err = FM_MACSEC_Disable(fm_macsec_dev);
110995 + _errno = -GET_ERROR_TYPE(err);
110996 + if (unlikely(_errno < 0))
110997 + pr_err("FM_MACSEC_Disable() = 0x%08x\n", err);
110998 +
110999 + return _errno;
111000 +}
111001 +EXPORT_SYMBOL(fm_macsec_disable);
111002 +
111003 +int fm_macsec_set_exception(struct fm_macsec_dev *fm_macsec_dev,
111004 + fm_macsec_exception exception, bool enable)
111005 +{
111006 + int err;
111007 + int _errno;
111008 +
111009 + err = FM_MACSEC_SetException(fm_macsec_dev, exception, enable);
111010 + _errno = -GET_ERROR_TYPE(err);
111011 + if (unlikely(_errno < 0))
111012 + pr_err("FM_MACSEC_SetException() = 0x%08x\n", err);
111013 +
111014 + return _errno;
111015 +}
111016 +EXPORT_SYMBOL(fm_macsec_set_exception);
111017 +
111018 +/* Macsec SECY wrapper API */
111019 +struct fm_macsec_secy_dev *fm_macsec_secy_config(struct fm_macsec_secy_params *secy_params)
111020 +{
111021 + struct fm_macsec_secy_dev *fm_macsec_secy;
111022 +
111023 + fm_macsec_secy = FM_MACSEC_SECY_Config((t_FmMacsecSecYParams *)secy_params);
111024 + if (unlikely(fm_macsec_secy < 0))
111025 + pr_err("FM_MACSEC_SECY_Config() failed\n");
111026 +
111027 + return fm_macsec_secy;
111028 +}
111029 +EXPORT_SYMBOL(fm_macsec_secy_config);
111030 +
111031 +int fm_macsec_secy_init(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
111032 +{
111033 + int err;
111034 + int _errno;
111035 +
111036 + err = FM_MACSEC_SECY_Init(fm_macsec_secy_dev);
111037 + _errno = -GET_ERROR_TYPE(err);
111038 + if (unlikely(_errno < 0))
111039 + pr_err("FM_MACSEC_SECY_Init() = 0x%08x\n", err);
111040 +
111041 + return _errno;
111042 +}
111043 +EXPORT_SYMBOL(fm_macsec_secy_init);
111044 +
111045 +int fm_macsec_secy_free(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
111046 +{
111047 + int err;
111048 + int _errno;
111049 +
111050 + err = FM_MACSEC_SECY_Free(fm_macsec_secy_dev);
111051 + _errno = -GET_ERROR_TYPE(err);
111052 + if (unlikely(_errno < 0))
111053 + pr_err("FM_MACSEC_SECY_Free() = 0x%08x\n", err);
111054 +
111055 + return _errno;
111056 +}
111057 +EXPORT_SYMBOL(fm_macsec_secy_free);
111058 +
111059 +int fm_macsec_secy_config_sci_insertion_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111060 + fm_macsec_sci_insertion_mode sci_insertion_mode)
111061 +{
111062 + int err;
111063 + int _errno;
111064 +
111065 + err = FM_MACSEC_SECY_ConfigSciInsertionMode(fm_macsec_secy_dev,
111066 + sci_insertion_mode);
111067 + _errno = -GET_ERROR_TYPE(err);
111068 + if (unlikely(_errno < 0))
111069 + pr_err("FM_MACSEC_SECY_ConfigSciInsertionMode() = 0x%08x\n", err);
111070 +
111071 + return _errno;
111072 +}
111073 +EXPORT_SYMBOL(fm_macsec_secy_config_sci_insertion_mode);
111074 +
111075 +int fm_macsec_secy_config_protect_frames(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111076 + bool protect_frames)
111077 +{
111078 + int err;
111079 + int _errno;
111080 +
111081 + err = FM_MACSEC_SECY_ConfigProtectFrames(fm_macsec_secy_dev,
111082 + protect_frames);
111083 + _errno = -GET_ERROR_TYPE(err);
111084 + if (unlikely(_errno < 0))
111085 + pr_err("FM_MACSEC_SECY_ConfigProtectFrames() = 0x%08x\n", err);
111086 +
111087 + return _errno;
111088 +}
111089 +EXPORT_SYMBOL(fm_macsec_secy_config_protect_frames);
111090 +
111091 +int fm_macsec_secy_config_replay_window(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111092 + bool replay_protect, uint32_t replay_window)
111093 +{
111094 + int err;
111095 + int _errno;
111096 +
111097 + err = FM_MACSEC_SECY_ConfigReplayWindow(fm_macsec_secy_dev,
111098 + replay_protect, replay_window);
111099 + _errno = -GET_ERROR_TYPE(err);
111100 + if (unlikely(_errno < 0))
111101 + pr_err("FM_MACSEC_SECY_ConfigReplayWindow() = 0x%08x\n", err);
111102 +
111103 + return _errno;
111104 +}
111105 +EXPORT_SYMBOL(fm_macsec_secy_config_replay_window);
111106 +
111107 +int fm_macsec_secy_config_validation_mode(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111108 + fm_macsec_valid_frame_behavior validate_frames)
111109 +{
111110 + int err;
111111 + int _errno;
111112 +
111113 + err = FM_MACSEC_SECY_ConfigValidationMode(fm_macsec_secy_dev,
111114 + validate_frames);
111115 + _errno = -GET_ERROR_TYPE(err);
111116 + if (unlikely(_errno < 0))
111117 + pr_err("FM_MACSEC_SECY_ConfigValidationMode() = 0x%08x\n", err);
111118 +
111119 + return _errno;
111120 +}
111121 +EXPORT_SYMBOL(fm_macsec_secy_config_validation_mode);
111122 +
111123 +int fm_macsec_secy_config_confidentiality(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111124 + bool confidentiality_enable,
111125 + uint32_t confidentiality_offset)
111126 +{
111127 + int err;
111128 + int _errno;
111129 +
111130 + err = FM_MACSEC_SECY_ConfigConfidentiality(fm_macsec_secy_dev,
111131 + confidentiality_enable,
111132 + confidentiality_offset);
111133 + _errno = -GET_ERROR_TYPE(err);
111134 + if (unlikely(_errno < 0))
111135 + pr_err("FM_MACSEC_SECY_ConfigConfidentiality() = 0x%08x\n",
111136 + err);
111137 +
111138 + return _errno;
111139 +}
111140 +EXPORT_SYMBOL(fm_macsec_secy_config_confidentiality);
111141 +
111142 +int fm_macsec_secy_config_point_to_point(struct fm_macsec_secy_dev *fm_macsec_secy_dev)
111143 +{
111144 + int err;
111145 + int _errno;
111146 +
111147 + err = FM_MACSEC_SECY_ConfigPointToPoint(fm_macsec_secy_dev);
111148 + _errno = -GET_ERROR_TYPE(err);
111149 + if (unlikely(_errno < 0))
111150 + pr_err("FM_MACSEC_SECY_ConfigPointToPoint() = 0x%08x\n",
111151 + err);
111152 +
111153 + return _errno;
111154 +}
111155 +EXPORT_SYMBOL(fm_macsec_secy_config_point_to_point);
111156 +
111157 +int fm_macsec_secy_config_exception(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111158 + fm_macsec_secy_exception exception,
111159 + bool enable)
111160 +{
111161 + int err;
111162 + int _errno;
111163 +
111164 + err = FM_MACSEC_SECY_ConfigException(fm_macsec_secy_dev, exception,
111165 + enable);
111166 + _errno = -GET_ERROR_TYPE(err);
111167 + if (unlikely(_errno < 0))
111168 + pr_err("FM_MACSEC_SECY_ConfigException() = 0x%08x\n",
111169 + err);
111170 +
111171 + return _errno;
111172 +}
111173 +EXPORT_SYMBOL(fm_macsec_secy_config_exception);
111174 +
111175 +int fm_macsec_secy_config_event(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111176 + fm_macsec_secy_event event,
111177 + bool enable)
111178 +{
111179 + int err;
111180 + int _errno;
111181 +
111182 + err = FM_MACSEC_SECY_ConfigEvent(fm_macsec_secy_dev, event, enable);
111183 + _errno = -GET_ERROR_TYPE(err);
111184 + if (unlikely(_errno < 0))
111185 + pr_err("FM_MACSEC_SECY_ConfigEvent() = 0x%08x\n",
111186 + err);
111187 +
111188 + return _errno;
111189 +}
111190 +EXPORT_SYMBOL(fm_macsec_secy_config_event);
111191 +
111192 +struct rx_sc_dev *fm_macsec_secy_create_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111193 + struct fm_macsec_secy_sc_params *params)
111194 +{
111195 + struct rx_sc_dev *rx_sc_dev;
111196 +
111197 + rx_sc_dev = FM_MACSEC_SECY_CreateRxSc(fm_macsec_secy_dev, (t_FmMacsecSecYSCParams *)params);
111198 + if (unlikely(rx_sc_dev == NULL))
111199 + pr_err("FM_MACSEC_SECY_CreateRxSc() failed\n");
111200 +
111201 + return rx_sc_dev;
111202 +}
111203 +EXPORT_SYMBOL(fm_macsec_secy_create_rxsc);
111204 +
111205 +int fm_macsec_secy_delete_rxsc(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111206 + struct rx_sc_dev *sc)
111207 +{
111208 + int err;
111209 + int _errno;
111210 +
111211 + err = FM_MACSEC_SECY_DeleteRxSc(fm_macsec_secy_dev, sc);
111212 + _errno = -GET_ERROR_TYPE(err);
111213 + if (unlikely(_errno < 0))
111214 + pr_err("FM_MACSEC_SECY_DeleteRxSc() = 0x%08x\n",
111215 + err);
111216 +
111217 + return _errno;
111218 +}
111219 +EXPORT_SYMBOL(fm_macsec_secy_delete_rxsc);
111220 +
111221 +int fm_macsec_secy_create_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111222 + struct rx_sc_dev *sc, macsec_an_t an,
111223 + uint32_t lowest_pn, macsec_sa_key_t key)
111224 +{
111225 + int err;
111226 + int _errno;
111227 +
111228 + err = FM_MACSEC_SECY_CreateRxSa(fm_macsec_secy_dev, sc, an,
111229 + lowest_pn, key);
111230 + _errno = -GET_ERROR_TYPE(err);
111231 + if (unlikely(_errno < 0))
111232 + pr_err("FM_MACSEC_SECY_CreateRxSa() = 0x%08x\n",
111233 + err);
111234 +
111235 + return _errno;
111236 +}
111237 +EXPORT_SYMBOL(fm_macsec_secy_create_rx_sa);
111238 +
111239 +int fm_macsec_secy_delete_rx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111240 + struct rx_sc_dev *sc, macsec_an_t an)
111241 +{
111242 + int err;
111243 + int _errno;
111244 +
111245 + err = FM_MACSEC_SECY_DeleteRxSa(fm_macsec_secy_dev, sc, an);
111246 + _errno = -GET_ERROR_TYPE(err);
111247 + if (unlikely(_errno < 0))
111248 + pr_err("FM_MACSEC_SECY_DeleteRxSa() = 0x%08x\n",
111249 + err);
111250 +
111251 + return _errno;
111252 +}
111253 +EXPORT_SYMBOL(fm_macsec_secy_delete_rx_sa);
111254 +
111255 +int fm_macsec_secy_rxsa_enable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111256 + struct rx_sc_dev *sc,
111257 + macsec_an_t an)
111258 +{
111259 + int err;
111260 + int _errno;
111261 +
111262 + err = FM_MACSEC_SECY_RxSaEnableReceive(fm_macsec_secy_dev, sc, an);
111263 + _errno = -GET_ERROR_TYPE(err);
111264 + if (unlikely(_errno < 0))
111265 + pr_err("FM_MACSEC_SECY_RxSaEnableReceive() = 0x%08x\n",
111266 + err);
111267 +
111268 + return _errno;
111269 +}
111270 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_enable_receive);
111271 +
111272 +int fm_macsec_secy_rxsa_disable_receive(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111273 + struct rx_sc_dev *sc,
111274 + macsec_an_t an)
111275 +{
111276 + int err;
111277 + int _errno;
111278 +
111279 + err = FM_MACSEC_SECY_RxSaDisableReceive(fm_macsec_secy_dev, sc, an);
111280 + _errno = -GET_ERROR_TYPE(err);
111281 + if (unlikely(_errno < 0))
111282 + pr_err("FM_MACSEC_SECY_RxSaDisableReceive() = 0x%08x\n",
111283 + err);
111284 +
111285 + return _errno;
111286 +}
111287 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_disable_receive);
111288 +
111289 +int fm_macsec_secy_rxsa_update_next_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111290 + struct rx_sc_dev *sc,
111291 + macsec_an_t an, uint32_t updt_next_pn)
111292 +{
111293 + int err;
111294 + int _errno;
111295 +
111296 + err = FM_MACSEC_SECY_RxSaUpdateNextPn(fm_macsec_secy_dev, sc, an,
111297 + updt_next_pn);
111298 + _errno = -GET_ERROR_TYPE(err);
111299 + if (unlikely(_errno < 0))
111300 + pr_err("FM_MACSEC_SECY_RxSaUpdateNextPn() = 0x%08x\n", err);
111301 +
111302 + return _errno;
111303 +}
111304 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_next_pn);
111305 +
111306 +int fm_macsec_secy_rxsa_update_lowest_pn(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111307 + struct rx_sc_dev *sc,
111308 + macsec_an_t an, uint32_t updt_lowest_pn)
111309 +{
111310 + int err;
111311 + int _errno;
111312 +
111313 + err = FM_MACSEC_SECY_RxSaUpdateLowestPn(fm_macsec_secy_dev, sc, an,
111314 + updt_lowest_pn);
111315 + _errno = -GET_ERROR_TYPE(err);
111316 + if (unlikely(_errno < 0))
111317 + pr_err("FM_MACSEC_SECY_RxSaUpdateLowestPn() = 0x%08x\n",
111318 + err);
111319 +
111320 + return _errno;
111321 +}
111322 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_update_lowest_pn);
111323 +
111324 +int fm_macsec_secy_rxsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111325 + struct rx_sc_dev *sc,
111326 + macsec_an_t an, macsec_sa_key_t key)
111327 +{
111328 + int err;
111329 + int _errno;
111330 +
111331 + err = FM_MACSEC_SECY_RxSaModifyKey(fm_macsec_secy_dev, sc, an, key);
111332 + _errno = -GET_ERROR_TYPE(err);
111333 + if (unlikely(_errno < 0))
111334 + pr_err("FM_MACSEC_SECY_RxSaModifyKey() = 0x%08x\n",
111335 + err);
111336 +
111337 + return _errno;
111338 +}
111339 +EXPORT_SYMBOL(fm_macsec_secy_rxsa_modify_key);
111340 +
111341 +int fm_macsec_secy_create_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111342 + macsec_an_t an, macsec_sa_key_t key)
111343 +{
111344 + int err;
111345 + int _errno;
111346 +
111347 + err = FM_MACSEC_SECY_CreateTxSa(fm_macsec_secy_dev, an, key);
111348 + _errno = -GET_ERROR_TYPE(err);
111349 + if (unlikely(_errno < 0))
111350 + pr_err("FM_MACSEC_SECY_CreateTxSa() = 0x%08x\n",
111351 + err);
111352 +
111353 + return _errno;
111354 +}
111355 +EXPORT_SYMBOL(fm_macsec_secy_create_tx_sa);
111356 +
111357 +int fm_macsec_secy_delete_tx_sa(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111358 + macsec_an_t an)
111359 +{
111360 + int err;
111361 + int _errno;
111362 +
111363 + err = FM_MACSEC_SECY_DeleteTxSa(fm_macsec_secy_dev, an);
111364 + _errno = -GET_ERROR_TYPE(err);
111365 + if (unlikely(_errno < 0))
111366 + pr_err("FM_MACSEC_SECY_DeleteTxSa() = 0x%08x\n",
111367 + err);
111368 +
111369 + return _errno;
111370 +}
111371 +EXPORT_SYMBOL(fm_macsec_secy_delete_tx_sa);
111372 +
111373 +int fm_macsec_secy_txsa_modify_key(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111374 + macsec_an_t next_active_an,
111375 + macsec_sa_key_t key)
111376 +{
111377 + int err;
111378 + int _errno;
111379 +
111380 + err = FM_MACSEC_SECY_TxSaModifyKey(fm_macsec_secy_dev, next_active_an,
111381 + key);
111382 + _errno = -GET_ERROR_TYPE(err);
111383 + if (unlikely(_errno < 0))
111384 + pr_err("FM_MACSEC_SECY_TxSaModifyKey() = 0x%08x\n",
111385 + err);
111386 +
111387 + return _errno;
111388 +}
111389 +EXPORT_SYMBOL(fm_macsec_secy_txsa_modify_key);
111390 +
111391 +int fm_macsec_secy_txsa_set_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111392 + macsec_an_t an)
111393 +{
111394 + int err;
111395 + int _errno;
111396 +
111397 + err = FM_MACSEC_SECY_TxSaSetActive(fm_macsec_secy_dev, an);
111398 + _errno = -GET_ERROR_TYPE(err);
111399 + if (unlikely(_errno < 0))
111400 + pr_err("FM_MACSEC_SECY_TxSaSetActive() = 0x%08x\n",
111401 + err);
111402 +
111403 + return _errno;
111404 +}
111405 +EXPORT_SYMBOL(fm_macsec_secy_txsa_set_active);
111406 +
111407 +int fm_macsec_secy_txsa_get_active(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111408 + macsec_an_t *p_an)
111409 +{
111410 + int err;
111411 + int _errno;
111412 +
111413 + err = FM_MACSEC_SECY_TxSaGetActive(fm_macsec_secy_dev, p_an);
111414 + _errno = -GET_ERROR_TYPE(err);
111415 + if (unlikely(_errno < 0))
111416 + pr_err("FM_MACSEC_SECY_TxSaGetActive() = 0x%08x\n",
111417 + err);
111418 +
111419 + return _errno;
111420 +}
111421 +EXPORT_SYMBOL(fm_macsec_secy_txsa_get_active);
111422 +
111423 +int fm_macsec_secy_get_rxsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111424 + struct rx_sc_dev *sc, uint32_t *sc_phys_id)
111425 +{
111426 + int err;
111427 + int _errno;
111428 +
111429 + err = FM_MACSEC_SECY_GetRxScPhysId(fm_macsec_secy_dev, sc, sc_phys_id);
111430 + _errno = -GET_ERROR_TYPE(err);
111431 + if (unlikely(_errno < 0))
111432 + pr_err("FM_MACSEC_SECY_GetRxScPhysId() = 0x%08x\n",
111433 + err);
111434 +
111435 + return _errno;
111436 +}
111437 +EXPORT_SYMBOL(fm_macsec_secy_get_rxsc_phys_id);
111438 +
111439 +int fm_macsec_secy_get_txsc_phys_id(struct fm_macsec_secy_dev *fm_macsec_secy_dev,
111440 + uint32_t *sc_phys_id)
111441 +{
111442 + int err;
111443 + int _errno;
111444 +
111445 + err = FM_MACSEC_SECY_GetTxScPhysId(fm_macsec_secy_dev, sc_phys_id);
111446 + _errno = -GET_ERROR_TYPE(err);
111447 + if (unlikely(_errno < 0))
111448 + pr_err("FM_MACSEC_SECY_GetTxScPhysId() = 0x%08x\n",
111449 + err);
111450 +
111451 + return _errno;
111452 +}
111453 +EXPORT_SYMBOL(fm_macsec_secy_get_txsc_phys_id);
111454 +
111455 +static t_Handle h_FmLnxWrp;
111456 +
111457 +static int __init __cold fm_load (void)
111458 +{
111459 + if ((h_FmLnxWrp = LNXWRP_FM_Init()) == NULL)
111460 + {
111461 + printk("Failed to init FM wrapper!\n");
111462 + return -ENODEV;
111463 + }
111464 +
111465 + printk(KERN_CRIT "Freescale FM module," \
111466 + " FMD API version %d.%d.%d\n",
111467 + FMD_API_VERSION_MAJOR,
111468 + FMD_API_VERSION_MINOR,
111469 + FMD_API_VERSION_RESPIN);
111470 + return 0;
111471 +}
111472 +
111473 +static void __exit __cold fm_unload (void)
111474 +{
111475 + if (h_FmLnxWrp)
111476 + LNXWRP_FM_Free(h_FmLnxWrp);
111477 +}
111478 +
111479 +module_init (fm_load);
111480 +module_exit (fm_unload);
111481 --- /dev/null
111482 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm.h
111483 @@ -0,0 +1,294 @@
111484 +/*
111485 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111486 + *
111487 + * Redistribution and use in source and binary forms, with or without
111488 + * modification, are permitted provided that the following conditions are met:
111489 + * * Redistributions of source code must retain the above copyright
111490 + * notice, this list of conditions and the following disclaimer.
111491 + * * Redistributions in binary form must reproduce the above copyright
111492 + * notice, this list of conditions and the following disclaimer in the
111493 + * documentation and/or other materials provided with the distribution.
111494 + * * Neither the name of Freescale Semiconductor nor the
111495 + * names of its contributors may be used to endorse or promote products
111496 + * derived from this software without specific prior written permission.
111497 + *
111498 + *
111499 + * ALTERNATIVELY, this software may be distributed under the terms of the
111500 + * GNU General Public License ("GPL") as published by the Free Software
111501 + * Foundation, either version 2 of that License or (at your option) any
111502 + * later version.
111503 + *
111504 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111505 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111506 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111507 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111508 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111509 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111510 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111511 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111512 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111513 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111514 + */
111515 +
111516 +/*
111517 + @File lnxwrp_fm.h
111518 +
111519 + @Author Shlomi Gridish
111520 +
111521 + @Description FM Linux wrapper functions.
111522 +
111523 +*/
111524 +
111525 +#ifndef __LNXWRP_FM_H__
111526 +#define __LNXWRP_FM_H__
111527 +
111528 +#include <linux/fsl_qman.h> /* struct qman_fq */
111529 +
111530 +#include "std_ext.h"
111531 +#include "error_ext.h"
111532 +#include "list_ext.h"
111533 +
111534 +#include "lnxwrp_fm_ext.h"
111535 +
111536 +#define FM_MAX_NUM_OF_ADV_SETTINGS 10
111537 +
111538 +#define LNXWRP_FM_NUM_OF_SHARED_PROFILES 16
111539 +
111540 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
111541 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
111542 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
111543 +#else
111544 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
111545 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
111546 +#endif
111547 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
111548 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
111549 +
111550 +#define FRAG_MANIP_SPACE 128
111551 +#define FRAG_DATA_ALIGN 64
111552 +
111553 +#ifndef CONFIG_FSL_FM_MAX_FRAME_SIZE
111554 +#define CONFIG_FSL_FM_MAX_FRAME_SIZE 0
111555 +#endif
111556 +
111557 +#ifndef CONFIG_FSL_FM_RX_EXTRA_HEADROOM
111558 +#define CONFIG_FSL_FM_RX_EXTRA_HEADROOM 16
111559 +#endif
111560 +
111561 +typedef enum {
111562 + e_NO_PCD = 0,
111563 + e_FM_PCD_3_TUPLE
111564 +} e_LnxWrpFmPortPcdDefUseCase;
111565 +
111566 +
111567 +typedef struct t_FmTestFq {
111568 + struct qman_fq fq_base;
111569 + t_Handle h_Arg;
111570 +} t_FmTestFq;
111571 +
111572 +typedef struct {
111573 + uint8_t id; /* sw port id, see SW_PORT_ID_TO_HW_PORT_ID() in fm_common.h */
111574 + int minor;
111575 + char name[20];
111576 + bool active;
111577 + uint64_t phys_baseAddr;
111578 + uint64_t baseAddr; /* Port's *virtual* address */
111579 + uint32_t memSize;
111580 + t_WrpFmPortDevSettings settings;
111581 + t_FmExtPools opExtPools;
111582 + uint8_t totalNumOfSchemes;
111583 + uint8_t schemesBase;
111584 + uint8_t numOfSchemesUsed;
111585 + uint32_t pcdBaseQ;
111586 + uint16_t pcdNumOfQs;
111587 + struct fm_port_pcd_param pcd_owner_params;
111588 + e_LnxWrpFmPortPcdDefUseCase defPcd;
111589 + t_Handle h_DefNetEnv;
111590 + t_Handle h_Schemes[FM_PCD_KG_NUM_OF_SCHEMES];
111591 + t_FmBufferPrefixContent buffPrefixContent;
111592 + t_Handle h_Dev;
111593 + t_Handle h_DfltVsp;
111594 + t_Handle h_LnxWrpFmDev;
111595 + uint16_t txCh;
111596 + struct device *dev;
111597 + struct device_attribute *dev_attr_stats;
111598 + struct device_attribute *dev_attr_regs;
111599 + struct device_attribute *dev_attr_bmi_regs;
111600 + struct device_attribute *dev_attr_qmi_regs;
111601 +#if (DPAA_VERSION >= 11)
111602 + struct device_attribute *dev_attr_ipv4_opt;
111603 +#endif
111604 + struct device_attribute *dev_attr_dsar_regs;
111605 + struct device_attribute *dev_attr_dsar_mem;
111606 + struct auto_res_tables_sizes dsar_table_sizes;
111607 +} t_LnxWrpFmPortDev;
111608 +
111609 +typedef struct {
111610 + uint8_t id;
111611 + bool active;
111612 + uint64_t baseAddr;
111613 + uint32_t memSize;
111614 + t_WrpFmMacDevSettings settings;
111615 + t_Handle h_Dev;
111616 + t_Handle h_LnxWrpFmDev;
111617 +} t_LnxWrpFmMacDev;
111618 +
111619 +/* information about all active ports for an FMan.
111620 + * !Some ports may be disabled by u-boot, thus will not be available */
111621 +struct fm_active_ports {
111622 + uint32_t num_oh_ports;
111623 + uint32_t num_tx_ports;
111624 + uint32_t num_rx_ports;
111625 + uint32_t num_tx25_ports;
111626 + uint32_t num_rx25_ports;
111627 + uint32_t num_tx10_ports;
111628 + uint32_t num_rx10_ports;
111629 +};
111630 +
111631 +/* FMan resources precalculated at fm probe based
111632 + * on available FMan port. */
111633 +struct fm_resource_settings {
111634 + /* buffers - fifo sizes */
111635 + uint32_t tx1g_num_buffers;
111636 + uint32_t rx1g_num_buffers;
111637 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
111638 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
111639 + uint32_t tx10g_num_buffers;
111640 + uint32_t rx10g_num_buffers;
111641 + uint32_t oh_num_buffers;
111642 + uint32_t shared_ext_buffers;
111643 +
111644 + /* open DMAs */
111645 + uint32_t tx_1g_dmas;
111646 + uint32_t rx_1g_dmas;
111647 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
111648 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
111649 + uint32_t tx_10g_dmas;
111650 + uint32_t rx_10g_dmas;
111651 + uint32_t oh_dmas;
111652 + uint32_t shared_ext_open_dma;
111653 +
111654 + /* Tnums */
111655 + uint32_t tx_1g_tnums;
111656 + uint32_t rx_1g_tnums;
111657 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
111658 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
111659 + uint32_t tx_10g_tnums;
111660 + uint32_t rx_10g_tnums;
111661 + uint32_t oh_tnums;
111662 + uint32_t shared_ext_tnums;
111663 +};
111664 +
111665 +typedef struct {
111666 + uint8_t id;
111667 + char name[10];
111668 + bool active;
111669 + bool pcdActive;
111670 + bool prsActive;
111671 + bool kgActive;
111672 + bool ccActive;
111673 + bool plcrActive;
111674 + e_LnxWrpFmPortPcdDefUseCase defPcd;
111675 + uint32_t usedSchemes;
111676 + uint8_t totalNumOfSharedSchemes;
111677 + uint8_t sharedSchemesBase;
111678 + uint8_t numOfSchemesUsed;
111679 + uint8_t defNetEnvId;
111680 + uint64_t fmPhysBaseAddr;
111681 + uint64_t fmBaseAddr;
111682 + uint32_t fmMemSize;
111683 + uint64_t fmMuramPhysBaseAddr;
111684 + uint64_t fmMuramBaseAddr;
111685 + uint32_t fmMuramMemSize;
111686 + uint64_t fmRtcPhysBaseAddr;
111687 + uint64_t fmRtcBaseAddr;
111688 + uint32_t fmRtcMemSize;
111689 + uint64_t fmVspPhysBaseAddr;
111690 + uint64_t fmVspBaseAddr;
111691 + uint32_t fmVspMemSize;
111692 + int irq;
111693 + int err_irq;
111694 + t_WrpFmDevSettings fmDevSettings;
111695 + t_WrpFmPcdDevSettings fmPcdDevSettings;
111696 + t_Handle h_Dev;
111697 + uint16_t hcCh;
111698 +
111699 + t_Handle h_MuramDev;
111700 + t_Handle h_PcdDev;
111701 + t_Handle h_RtcDev;
111702 +
111703 + t_Handle h_DsarRxPort;
111704 + t_Handle h_DsarTxPort;
111705 +
111706 + t_LnxWrpFmPortDev hcPort;
111707 + t_LnxWrpFmPortDev opPorts[FM_MAX_NUM_OF_OH_PORTS-1];
111708 + t_LnxWrpFmPortDev rxPorts[FM_MAX_NUM_OF_RX_PORTS];
111709 + t_LnxWrpFmPortDev txPorts[FM_MAX_NUM_OF_TX_PORTS];
111710 + t_LnxWrpFmMacDev macs[FM_MAX_NUM_OF_MACS];
111711 + struct fm_active_ports fm_active_ports_info;
111712 + struct fm_resource_settings fm_resource_settings_info;
111713 +
111714 + struct device *dev;
111715 + struct resource *res;
111716 + int major;
111717 + struct class *fm_class;
111718 + struct device_attribute *dev_attr_stats;
111719 + struct device_attribute *dev_attr_regs;
111720 + struct device_attribute *dev_attr_risc_load;
111721 +
111722 + struct device_attribute *dev_pcd_attr_stats;
111723 + struct device_attribute *dev_plcr_attr_regs;
111724 + struct device_attribute *dev_prs_attr_regs;
111725 + struct device_attribute *dev_fm_fpm_attr_regs;
111726 + struct device_attribute *dev_fm_kg_attr_regs;
111727 + struct device_attribute *dev_fm_kg_pe_attr_regs;
111728 + struct device_attribute *dev_attr_muram_free_size;
111729 + struct device_attribute *dev_attr_fm_ctrl_code_ver;
111730 +
111731 +
111732 + struct qman_fq *hc_tx_conf_fq, *hc_tx_err_fq, *hc_tx_fq;
111733 +} t_LnxWrpFmDev;
111734 +
111735 +typedef struct {
111736 + t_LnxWrpFmDev *p_FmDevs[INTG_MAX_NUM_OF_FM];
111737 +} t_LnxWrpFm;
111738 +#define LNXWRP_FM_OBJECT(ptr) LIST_OBJECT(ptr, t_LnxWrpFm, fms[((t_LnxWrpFmDev *)ptr)->id])
111739 +
111740 +
111741 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat);
111742 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat);
111743 +
111744 +
111745 +#if 0
111746 +static __inline__ t_Error AllocSchemesForPort(t_LnxWrpFmDev *p_LnxWrpFmDev, uint8_t numSchemes, uint8_t *p_BaseSchemeNum)
111747 +{
111748 + uint32_t schemeMask;
111749 + uint8_t i;
111750 +
111751 + if (!numSchemes)
111752 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
111753 +
111754 + schemeMask = 0x80000000;
111755 + *p_BaseSchemeNum = 0xff;
111756 +
111757 + for (i=0; schemeMask && numSchemes; schemeMask>>=1, i++)
111758 + if ((p_LnxWrpFmDev->usedSchemes & schemeMask) == 0)
111759 + {
111760 + p_LnxWrpFmDev->usedSchemes |= schemeMask;
111761 + numSchemes--;
111762 + if (*p_BaseSchemeNum==0xff)
111763 + *p_BaseSchemeNum = i;
111764 + }
111765 + else if (*p_BaseSchemeNum!=0xff)
111766 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("Fragmentation on schemes array!!!"));
111767 +
111768 + if (numSchemes)
111769 + RETURN_ERROR(MINOR, E_FULL, ("schemes!!!"));
111770 + return E_OK;
111771 +}
111772 +#endif
111773 +
111774 +void LnxWrpPCDIOCTLTypeChecking(void);
111775 +void LnxWrpPCDIOCTLEnumChecking(void);
111776 +
111777 +#endif /* __LNXWRP_FM_H__ */
111778 --- /dev/null
111779 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_fm_port.c
111780 @@ -0,0 +1,1512 @@
111781 +/*
111782 + * Copyright 2008-2012 Freescale Semiconductor Inc.
111783 + *
111784 + * Redistribution and use in source and binary forms, with or without
111785 + * modification, are permitted provided that the following conditions are met:
111786 + * * Redistributions of source code must retain the above copyright
111787 + * notice, this list of conditions and the following disclaimer.
111788 + * * Redistributions in binary form must reproduce the above copyright
111789 + * notice, this list of conditions and the following disclaimer in the
111790 + * documentation and/or other materials provided with the distribution.
111791 + * * Neither the name of Freescale Semiconductor nor the
111792 + * names of its contributors may be used to endorse or promote products
111793 + * derived from this software without specific prior written permission.
111794 + *
111795 + *
111796 + * ALTERNATIVELY, this software may be distributed under the terms of the
111797 + * GNU General Public License ("GPL") as published by the Free Software
111798 + * Foundation, either version 2 of that License or (at your option) any
111799 + * later version.
111800 + *
111801 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
111802 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
111803 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
111804 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
111805 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
111806 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
111807 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
111808 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111809 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
111810 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
111811 + */
111812 +
111813 +/*
111814 + @File lnxwrp_fm_port.c
111815 +
111816 + @Description FMD wrapper - FMan port functions.
111817 +
111818 +*/
111819 +
111820 +#include <linux/version.h>
111821 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
111822 +#define MODVERSIONS
111823 +#endif
111824 +#ifdef MODVERSIONS
111825 +#include <config/modversions.h>
111826 +#endif /* MODVERSIONS */
111827 +#include <linux/kernel.h>
111828 +#include <linux/module.h>
111829 +#include <linux/of_platform.h>
111830 +#include <linux/of_address.h>
111831 +#include <linux/cdev.h>
111832 +#include <linux/slab.h>
111833 +#include <linux/spinlock.h>
111834 +#ifndef CONFIG_FMAN_ARM
111835 +#include <linux/fsl/svr.h>
111836 +#endif
111837 +#include <linux/io.h>
111838 +
111839 +#include "sprint_ext.h"
111840 +#include "fm_common.h"
111841 +#include "lnxwrp_fsl_fman.h"
111842 +#include "fm_port_ext.h"
111843 +#if (DPAA_VERSION >= 11)
111844 +#include "fm_vsp_ext.h"
111845 +#endif /* DPAA_VERSION >= 11 */
111846 +#include "fm_ioctls.h"
111847 +#include "lnxwrp_resources.h"
111848 +#include "lnxwrp_sysfs_fm_port.h"
111849 +
111850 +#define __ERR_MODULE__ MODULE_FM
111851 +
111852 +extern struct device_node *GetFmAdvArgsDevTreeNode (uint8_t fmIndx);
111853 +
111854 +/* TODO: duplicated, see lnxwrp_fm.c */
111855 +#define ADD_ADV_CONFIG_NO_RET(_func, _param)\
111856 +do {\
111857 + if (i < max) {\
111858 + p_Entry = &p_Entrys[i];\
111859 + p_Entry->p_Function = _func;\
111860 + _param\
111861 + i++;\
111862 + } else {\
111863 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,\
111864 + ("Number of advanced-configuration entries exceeded"));\
111865 + } \
111866 +} while (0)
111867 +
111868 +#ifndef CONFIG_FMAN_ARM
111869 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
111870 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
111871 +#endif
111872 +
111873 +static volatile int hcFrmRcv/* = 0 */;
111874 +static spinlock_t lock;
111875 +
111876 +static enum qman_cb_dqrr_result qm_tx_conf_dqrr_cb(struct qman_portal *portal,
111877 + struct qman_fq *fq,
111878 + const struct qm_dqrr_entry
111879 + *dq)
111880 +{
111881 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_FmTestFq *) fq)->h_Arg;
111882 + unsigned long flags;
111883 +
111884 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
111885 +{
111886 + /* extract the HC frame address */
111887 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *)&dq->fd));
111888 + int hcf_l = ((struct qm_fd *)&dq->fd)->length20;
111889 + int i;
111890 +
111891 + /* 32b byteswap of all data in the HC Frame */
111892 + for(i = 0; i < hcf_l / 4; ++i)
111893 + hcf_va[i] =
111894 + ___constant_swab32(hcf_va[i]);
111895 +}
111896 +#endif
111897 + FM_PCD_HcTxConf(p_LnxWrpFmDev->h_PcdDev, (t_DpaaFD *)&dq->fd);
111898 + spin_lock_irqsave(&lock, flags);
111899 + hcFrmRcv--;
111900 + spin_unlock_irqrestore(&lock, flags);
111901 +
111902 + return qman_cb_dqrr_consume;
111903 +}
111904 +
111905 +static enum qman_cb_dqrr_result qm_tx_dqrr_cb(struct qman_portal *portal,
111906 + struct qman_fq *fq,
111907 + const struct qm_dqrr_entry *dq)
111908 +{
111909 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
111910 + __func__);
111911 + return qman_cb_dqrr_consume;
111912 +}
111913 +
111914 +static void qm_err_cb(struct qman_portal *portal,
111915 + struct qman_fq *fq, const struct qm_mr_entry *msg)
111916 +{
111917 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
111918 + __func__);
111919 +}
111920 +
111921 +static struct qman_fq *FqAlloc(t_LnxWrpFmDev * p_LnxWrpFmDev,
111922 + uint32_t fqid,
111923 + uint32_t flags, uint16_t channel, uint8_t wq)
111924 +{
111925 + int _errno;
111926 + struct qman_fq *fq = NULL;
111927 + t_FmTestFq *p_FmtFq;
111928 + struct qm_mcc_initfq initfq;
111929 +
111930 + p_FmtFq = (t_FmTestFq *) XX_Malloc(sizeof(t_FmTestFq));
111931 + if (!p_FmtFq) {
111932 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj!!!"));
111933 + return NULL;
111934 + }
111935 +
111936 + p_FmtFq->fq_base.cb.dqrr = ((flags & QMAN_FQ_FLAG_NO_ENQUEUE)
111937 + ? qm_tx_conf_dqrr_cb
111938 + : qm_tx_dqrr_cb);
111939 + p_FmtFq->fq_base.cb.ern = qm_err_cb;
111940 + /* p_FmtFq->fq_base.cb.fqs = qm_err_cb; */
111941 + /* qm_err_cb wrongly called when the FQ is parked */
111942 + p_FmtFq->fq_base.cb.fqs = NULL;
111943 + p_FmtFq->h_Arg = (t_Handle) p_LnxWrpFmDev;
111944 + if (fqid == 0) {
111945 + flags |= QMAN_FQ_FLAG_DYNAMIC_FQID;
111946 + flags &= ~QMAN_FQ_FLAG_NO_MODIFY;
111947 + } else {
111948 + flags &= ~QMAN_FQ_FLAG_DYNAMIC_FQID;
111949 + }
111950 +
111951 + if (qman_create_fq(fqid, flags, &p_FmtFq->fq_base)) {
111952 + REPORT_ERROR(MAJOR, E_NO_MEMORY, ("FQ obj - qman_new_fq!!!"));
111953 + XX_Free(p_FmtFq);
111954 + return NULL;
111955 + }
111956 + fq = &p_FmtFq->fq_base;
111957 +
111958 + if (!(flags & QMAN_FQ_FLAG_NO_MODIFY)) {
111959 + initfq.we_mask = QM_INITFQ_WE_DESTWQ;
111960 + initfq.fqd.dest.channel = channel;
111961 + initfq.fqd.dest.wq = wq;
111962 +
111963 + _errno = qman_init_fq(fq, QMAN_INITFQ_FLAG_SCHED, &initfq);
111964 + if (unlikely(_errno < 0)) {
111965 + REPORT_ERROR(MAJOR, E_NO_MEMORY,
111966 + ("FQ obj - qman_init_fq!!!"));
111967 + qman_destroy_fq(fq, 0);
111968 + XX_Free(p_FmtFq);
111969 + return NULL;
111970 + }
111971 + }
111972 +
111973 + DBG(TRACE,
111974 + ("fqid %d, flags 0x%08x, channel %d, wq %d", qman_fq_fqid(fq),
111975 + flags, channel, wq));
111976 +
111977 + return fq;
111978 +}
111979 +
111980 +static void FqFree(struct qman_fq *fq)
111981 +{
111982 + int _errno;
111983 +
111984 + _errno = qman_retire_fq(fq, NULL);
111985 + if (unlikely(_errno < 0))
111986 + printk(KERN_WARNING "qman_retire_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
111987 +
111988 + _errno = qman_oos_fq(fq);
111989 + if (unlikely(_errno < 0))
111990 + printk(KERN_WARNING "qman_oos_fq(%u) = %d\n", qman_fq_fqid(fq), _errno);
111991 +
111992 + qman_destroy_fq(fq, 0);
111993 + XX_Free((t_FmTestFq *) fq);
111994 +}
111995 +
111996 +static t_Error QmEnqueueCB(t_Handle h_Arg, void *p_Fd)
111997 +{
111998 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_Arg;
111999 + int _errno, timeout = 1000000;
112000 + unsigned long flags;
112001 +
112002 + ASSERT_COND(p_LnxWrpFmDev);
112003 +
112004 + spin_lock_irqsave(&lock, flags);
112005 + hcFrmRcv++;
112006 + spin_unlock_irqrestore(&lock, flags);
112007 +
112008 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
112009 +{
112010 + /* extract the HC frame address */
112011 + uint32_t *hcf_va = XX_PhysToVirt(qm_fd_addr((struct qm_fd *) p_Fd));
112012 + int hcf_l = ((struct qm_fd *)p_Fd)->length20;
112013 + int i;
112014 +
112015 + /* 32b byteswap of all data in the HC Frame */
112016 + for(i = 0; i < hcf_l / 4; ++i)
112017 + hcf_va[i] =
112018 + ___constant_swab32(hcf_va[i]);
112019 +}
112020 +#endif
112021 +
112022 + _errno = qman_enqueue(p_LnxWrpFmDev->hc_tx_fq, (struct qm_fd *) p_Fd,
112023 + 0);
112024 + if (_errno)
112025 + RETURN_ERROR(MINOR, E_INVALID_STATE,
112026 + ("qman_enqueue() failed"));
112027 +
112028 + while (hcFrmRcv && --timeout) {
112029 + udelay(1);
112030 + cpu_relax();
112031 + }
112032 + if (timeout == 0) {
112033 + dump_stack();
112034 + RETURN_ERROR(MINOR, E_WRITE_FAILED,
112035 + ("timeout waiting for Tx confirmation"));
112036 + return E_WRITE_FAILED;
112037 + }
112038 +
112039 + return E_OK;
112040 +}
112041 +
112042 +static t_LnxWrpFmPortDev *ReadFmPortDevTreeNode(struct platform_device
112043 + *of_dev)
112044 +{
112045 + t_LnxWrpFmDev *p_LnxWrpFmDev;
112046 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
112047 + struct device_node *fm_node, *port_node;
112048 + struct resource res;
112049 + const uint32_t *uint32_prop;
112050 + int _errno = 0, lenp;
112051 + uint32_t tmp_prop;
112052 +
112053 +#ifdef CONFIG_FMAN_P1023
112054 + static unsigned char have_oh_port/* = 0 */;
112055 +#endif
112056 +
112057 + port_node = of_node_get(of_dev->dev.of_node);
112058 +
112059 + /* Get the FM node */
112060 + fm_node = of_get_parent(port_node);
112061 + if (unlikely(fm_node == NULL)) {
112062 + REPORT_ERROR(MAJOR, E_NO_DEVICE,
112063 + ("of_get_parent() = %d", _errno));
112064 + return NULL;
112065 + }
112066 +
112067 + p_LnxWrpFmDev =
112068 + dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
112069 + of_node_put(fm_node);
112070 +
112071 + /* if fm_probe() failed, no point in going further with port probing */
112072 + if (p_LnxWrpFmDev == NULL)
112073 + return NULL;
112074 +
112075 + uint32_prop =
112076 + (uint32_t *) of_get_property(port_node, "cell-index", &lenp);
112077 + if (unlikely(uint32_prop == NULL)) {
112078 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112079 + ("of_get_property(%s, cell-index) failed",
112080 + port_node->full_name));
112081 + return NULL;
112082 + }
112083 + tmp_prop = be32_to_cpu(*uint32_prop);
112084 + if (WARN_ON(lenp != sizeof(uint32_t)))
112085 + return NULL;
112086 + if (of_device_is_compatible(port_node, "fsl,fman-port-oh") ||
112087 + of_device_is_compatible(port_node, "fsl,fman-v2-port-oh") ||
112088 + of_device_is_compatible(port_node, "fsl,fman-v3-port-oh")) {
112089 +#ifndef CONFIG_FMAN_ARM
112090 +#ifdef CONFIG_FMAN_P3040_P4080_P5020
112091 + /* On PPC FMan v2, OH ports start from cell-index 0x1 */
112092 + tmp_prop -= 0x1;
112093 +#else
112094 + /* On PPC FMan v3 (Low and High), OH ports start from
112095 + * cell-index 0x2
112096 + */
112097 + tmp_prop -= 0x2;
112098 +#endif // CONFIG_FMAN_P3040_P4080_P5020
112099 +#endif // CONFIG_FMAN_ARM
112100 +
112101 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_OH_PORTS)) {
112102 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112103 + ("of_get_property(%s, cell-index) failed",
112104 + port_node->full_name));
112105 + return NULL;
112106 + }
112107 +
112108 +#ifdef CONFIG_FMAN_P1023
112109 + /* Beware, this can be done when there is only
112110 + one FMan to be initialized */
112111 + if (!have_oh_port) {
112112 + have_oh_port = 1; /* first OP/HC port
112113 + is used for host command */
112114 +#else
112115 + /* Here it is hardcoded the use of the OH port 1
112116 + (with cell-index 0) */
112117 + if (tmp_prop == 0) {
112118 +#endif
112119 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
112120 + p_LnxWrpFmPortDev->id = 0;
112121 + /*
112122 + p_LnxWrpFmPortDev->id = *uint32_prop-1;
112123 + p_LnxWrpFmPortDev->id = *uint32_prop;
112124 + */
112125 + p_LnxWrpFmPortDev->settings.param.portType =
112126 + e_FM_PORT_TYPE_OH_HOST_COMMAND;
112127 + } else {
112128 + p_LnxWrpFmPortDev =
112129 + &p_LnxWrpFmDev->opPorts[tmp_prop - 1];
112130 + p_LnxWrpFmPortDev->id = tmp_prop- 1;
112131 + p_LnxWrpFmPortDev->settings.param.portType =
112132 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING;
112133 + }
112134 + p_LnxWrpFmPortDev->settings.param.portId = tmp_prop;
112135 +
112136 + uint32_prop =
112137 + (uint32_t *) of_get_property(port_node,
112138 + "fsl,qman-channel-id",
112139 + &lenp);
112140 + if (uint32_prop == NULL) {
112141 + /*
112142 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("missing fsl,qman-channel-id"));
112143 + */
112144 + XX_Print("FM warning: missing fsl,qman-channel-id"
112145 + " for OH port.\n");
112146 + return NULL;
112147 + }
112148 + tmp_prop = be32_to_cpu(*uint32_prop);
112149 + if (WARN_ON(lenp != sizeof(uint32_t)))
112150 + return NULL;
112151 + p_LnxWrpFmPortDev->txCh = tmp_prop;
112152 +
112153 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
112154 + qmChannel = p_LnxWrpFmPortDev->txCh;
112155 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-tx")) {
112156 + tmp_prop -= 0x28;
112157 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_TX_PORTS)) {
112158 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112159 + ("of_get_property(%s, cell-index) failed",
112160 + port_node->full_name));
112161 + return NULL;
112162 + }
112163 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
112164 +
112165 + p_LnxWrpFmPortDev->id = tmp_prop;
112166 + p_LnxWrpFmPortDev->settings.param.portId =
112167 + p_LnxWrpFmPortDev->id;
112168 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_TX;
112169 +
112170 + uint32_prop = (uint32_t *) of_get_property(port_node,
112171 + "fsl,qman-channel-id", &lenp);
112172 + if (uint32_prop == NULL) {
112173 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112174 + ("missing fsl,qman-channel-id"));
112175 + return NULL;
112176 + }
112177 + tmp_prop = be32_to_cpu(*uint32_prop);
112178 + if (WARN_ON(lenp != sizeof(uint32_t)))
112179 + return NULL;
112180 + p_LnxWrpFmPortDev->txCh = tmp_prop;
112181 + p_LnxWrpFmPortDev->
112182 + settings.param.specificParams.nonRxParams.qmChannel =
112183 + p_LnxWrpFmPortDev->txCh;
112184 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-tx")) {
112185 +#ifndef CONFIG_FMAN_ARM
112186 + /* On T102x, the 10G TX port IDs start from 0x28 */
112187 + if (IS_T1023_T1024)
112188 + tmp_prop -= 0x28;
112189 + else
112190 +#endif
112191 + tmp_prop -= 0x30;
112192 +
112193 + if (unlikely(tmp_prop>= FM_MAX_NUM_OF_10G_TX_PORTS)) {
112194 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112195 + ("of_get_property(%s, cell-index) failed",
112196 + port_node->full_name));
112197 + return NULL;
112198 + }
112199 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop +
112200 + FM_MAX_NUM_OF_1G_TX_PORTS];
112201 +#ifndef CONFIG_FMAN_ARM
112202 + if (IS_T1023_T1024)
112203 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[tmp_prop];
112204 +#endif
112205 +
112206 + p_LnxWrpFmPortDev->id = tmp_prop;
112207 + p_LnxWrpFmPortDev->settings.param.portId =
112208 + p_LnxWrpFmPortDev->id;
112209 + p_LnxWrpFmPortDev->settings.param.portType =
112210 + e_FM_PORT_TYPE_TX_10G;
112211 + uint32_prop = (uint32_t *) of_get_property(port_node,
112212 + "fsl,qman-channel-id", &lenp);
112213 + if (uint32_prop == NULL) {
112214 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112215 + ("missing fsl,qman-channel-id"));
112216 + return NULL;
112217 + }
112218 + tmp_prop = be32_to_cpu(*uint32_prop);
112219 + if (WARN_ON(lenp != sizeof(uint32_t)))
112220 + return NULL;
112221 + p_LnxWrpFmPortDev->txCh = tmp_prop;
112222 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
112223 + qmChannel = p_LnxWrpFmPortDev->txCh;
112224 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-1g-rx")) {
112225 + tmp_prop -= 0x08;
112226 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_1G_RX_PORTS)) {
112227 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112228 + ("of_get_property(%s, cell-index) failed",
112229 + port_node->full_name));
112230 + return NULL;
112231 + }
112232 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
112233 +
112234 + p_LnxWrpFmPortDev->id = tmp_prop;
112235 + p_LnxWrpFmPortDev->settings.param.portId =
112236 + p_LnxWrpFmPortDev->id;
112237 + p_LnxWrpFmPortDev->settings.param.portType = e_FM_PORT_TYPE_RX;
112238 + if (p_LnxWrpFmDev->pcdActive)
112239 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
112240 + } else if (of_device_is_compatible(port_node, "fsl,fman-port-10g-rx")) {
112241 +#ifndef CONFIG_FMAN_ARM
112242 + /* On T102x, the 10G RX port IDs start from 0x08 */
112243 + if (IS_T1023_T1024)
112244 + tmp_prop -= 0x8;
112245 + else
112246 +#endif
112247 + tmp_prop -= 0x10;
112248 +
112249 + if (unlikely(tmp_prop >= FM_MAX_NUM_OF_10G_RX_PORTS)) {
112250 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112251 + ("of_get_property(%s, cell-index) failed",
112252 + port_node->full_name));
112253 + return NULL;
112254 + }
112255 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop +
112256 + FM_MAX_NUM_OF_1G_RX_PORTS];
112257 +
112258 +#ifndef CONFIG_FMAN_ARM
112259 + if (IS_T1023_T1024)
112260 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[tmp_prop];
112261 +#endif
112262 +
112263 + p_LnxWrpFmPortDev->id = tmp_prop;
112264 + p_LnxWrpFmPortDev->settings.param.portId =
112265 + p_LnxWrpFmPortDev->id;
112266 + p_LnxWrpFmPortDev->settings.param.portType =
112267 + e_FM_PORT_TYPE_RX_10G;
112268 + if (p_LnxWrpFmDev->pcdActive)
112269 + p_LnxWrpFmPortDev->defPcd = p_LnxWrpFmDev->defPcd;
112270 + } else {
112271 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("Illegal port type"));
112272 + return NULL;
112273 + }
112274 +
112275 + _errno = of_address_to_resource(port_node, 0, &res);
112276 + if (unlikely(_errno < 0)) {
112277 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112278 + ("of_address_to_resource() = %d", _errno));
112279 + return NULL;
112280 + }
112281 +
112282 + p_LnxWrpFmPortDev->dev = &of_dev->dev;
112283 + p_LnxWrpFmPortDev->baseAddr = 0;
112284 + p_LnxWrpFmPortDev->phys_baseAddr = res.start;
112285 + p_LnxWrpFmPortDev->memSize = res.end + 1 - res.start;
112286 + p_LnxWrpFmPortDev->settings.param.h_Fm = p_LnxWrpFmDev->h_Dev;
112287 + p_LnxWrpFmPortDev->h_LnxWrpFmDev = (t_Handle) p_LnxWrpFmDev;
112288 +
112289 + of_node_put(port_node);
112290 +
112291 + p_LnxWrpFmPortDev->active = TRUE;
112292 +
112293 +#if defined(CONFIG_FMAN_DISABLE_OH_TO_REUSE_RESOURCES)
112294 + /* for performance mode no OH port available. */
112295 + if (p_LnxWrpFmPortDev->settings.param.portType ==
112296 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
112297 + p_LnxWrpFmPortDev->active = FALSE;
112298 +#endif
112299 +
112300 + return p_LnxWrpFmPortDev;
112301 +}
112302 +
112303 +struct device_node * GetFmPortAdvArgsDevTreeNode (struct device_node *fm_node,
112304 + e_FmPortType portType,
112305 + uint8_t portId)
112306 +{
112307 + struct device_node *port_node;
112308 + const uint32_t *uint32_prop;
112309 + int lenp;
112310 + char *portTypeString;
112311 + uint32_t tmp_prop;
112312 +
112313 + switch(portType) {
112314 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
112315 + portTypeString = "fsl,fman-port-op-extended-args";
112316 + break;
112317 + case e_FM_PORT_TYPE_TX:
112318 + portTypeString = "fsl,fman-port-1g-tx-extended-args";
112319 + break;
112320 + case e_FM_PORT_TYPE_TX_10G:
112321 + portTypeString = "fsl,fman-port-10g-tx-extended-args";
112322 + break;
112323 + case e_FM_PORT_TYPE_RX:
112324 + portTypeString = "fsl,fman-port-1g-rx-extended-args";
112325 + break;
112326 + case e_FM_PORT_TYPE_RX_10G:
112327 + portTypeString = "fsl,fman-port-10g-rx-extended-args";
112328 + break;
112329 + default:
112330 + return NULL;
112331 + }
112332 +
112333 + for_each_child_of_node(fm_node, port_node) {
112334 + uint32_prop = (uint32_t *)of_get_property(port_node, "cell-index", &lenp);
112335 + if (unlikely(uint32_prop == NULL)) {
112336 + REPORT_ERROR(MAJOR, E_INVALID_VALUE,
112337 + ("of_get_property(%s, cell-index) failed",
112338 + port_node->full_name));
112339 + return NULL;
112340 + }
112341 + tmp_prop = be32_to_cpu(*uint32_prop);
112342 + if (WARN_ON(lenp != sizeof(uint32_t)))
112343 + return NULL;
112344 + if ((portId == tmp_prop) &&
112345 + (of_device_is_compatible(port_node, portTypeString))) {
112346 + return port_node;
112347 + }
112348 + }
112349 +
112350 + return NULL;
112351 +}
112352 +
112353 +static t_Error CheckNConfigFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
112354 +{
112355 + struct device_node *fm_node, *port_node;
112356 + t_Error err;
112357 + t_FmPortRsrc portRsrc;
112358 + const uint32_t *uint32_prop;
112359 + /*const char *str_prop;*/
112360 + int lenp;
112361 +#ifdef CONFIG_FMAN_PFC
112362 + uint8_t i, id, num_pools;
112363 + t_FmBufPoolDepletion poolDepletion;
112364 +
112365 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
112366 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G) {
112367 + memset(&poolDepletion, 0, sizeof(t_FmBufPoolDepletion));
112368 + poolDepletion.singlePoolModeEnable = true;
112369 + num_pools = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
112370 + extBufPools.numOfPoolsUsed;
112371 + for (i = 0; i < num_pools; i++) {
112372 + id = p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
112373 + extBufPools.extBufPool[i].id;
112374 + poolDepletion.poolsToConsiderForSingleMode[id] = true;
112375 + }
112376 +
112377 + for (i = 0; i < CONFIG_FMAN_PFC_COS_COUNT; i++)
112378 + poolDepletion.pfcPrioritiesEn[i] = true;
112379 +
112380 + err = FM_PORT_ConfigPoolDepletion(p_LnxWrpFmPortDev->h_Dev,
112381 + &poolDepletion);
112382 + if (err != E_OK)
112383 + RETURN_ERROR(MAJOR, err, ("FM_PORT_ConfigPoolDepletion() failed"));
112384 + }
112385 +#endif
112386 +
112387 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
112388 + if (!fm_node) /* no advance parameters for FMan */
112389 + return E_OK;
112390 +
112391 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
112392 + p_LnxWrpFmPortDev->settings.param.portType,
112393 + p_LnxWrpFmPortDev->settings.param.portId);
112394 + if (!port_node) /* no advance parameters for FMan-Port */
112395 + return E_OK;
112396 +
112397 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-tnums", &lenp);
112398 + if (uint32_prop) {
112399 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
112400 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112401 +
112402 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
112403 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
112404 +
112405 + if ((err = FM_PORT_ConfigNumOfTasks(p_LnxWrpFmPortDev->h_Dev,
112406 + &portRsrc)) != E_OK)
112407 + RETURN_ERROR(MINOR, err, NO_MSG);
112408 + }
112409 +
112410 + uint32_prop = (uint32_t *)of_get_property(port_node, "num-dmas", &lenp);
112411 + if (uint32_prop) {
112412 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
112413 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112414 +
112415 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
112416 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
112417 +
112418 + if ((err = FM_PORT_ConfigNumOfOpenDmas(p_LnxWrpFmPortDev->h_Dev,
112419 + &portRsrc)) != E_OK)
112420 + RETURN_ERROR(MINOR, err, NO_MSG);
112421 + }
112422 +
112423 + uint32_prop = (uint32_t *)of_get_property(port_node, "fifo-size", &lenp);
112424 + if (uint32_prop) {
112425 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
112426 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112427 +
112428 + portRsrc.num = be32_to_cpu(uint32_prop[0]);
112429 + portRsrc.extra = be32_to_cpu(uint32_prop[1]);
112430 +
112431 + if ((err = FM_PORT_ConfigSizeOfFifo(p_LnxWrpFmPortDev->h_Dev,
112432 + &portRsrc)) != E_OK)
112433 + RETURN_ERROR(MINOR, err, NO_MSG);
112434 + }
112435 +
112436 + uint32_prop = (uint32_t *)of_get_property(port_node, "errors-to-discard", &lenp);
112437 + if (uint32_prop) {
112438 + if (WARN_ON(lenp != sizeof(uint32_t)))
112439 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112440 + if ((err = FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev,
112441 + be32_to_cpu(uint32_prop[0]))) != E_OK)
112442 + RETURN_ERROR(MINOR, err, NO_MSG);
112443 + }
112444 +
112445 + uint32_prop = (uint32_t *)of_get_property(port_node, "ar-tables-sizes",
112446 + &lenp);
112447 + if (uint32_prop) {
112448 +
112449 + if (WARN_ON(lenp != sizeof(uint32_t)*8))
112450 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112451 + if (WARN_ON(p_LnxWrpFmPortDev->settings.param.portType !=
112452 + e_FM_PORT_TYPE_RX) &&
112453 + (p_LnxWrpFmPortDev->settings.param.portType !=
112454 + e_FM_PORT_TYPE_RX_10G))
112455 + RETURN_ERROR(MINOR, E_INVALID_VALUE,
112456 + ("Auto Response is an Rx port atribute."));
112457 +
112458 + memset(&p_LnxWrpFmPortDev->dsar_table_sizes, 0, sizeof(struct auto_res_tables_sizes));
112459 +
112460 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_arp_entries =
112461 + (uint16_t)be32_to_cpu(uint32_prop[0]);
112462 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv4_entries =
112463 + (uint16_t)be32_to_cpu(uint32_prop[1]);
112464 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ndp_entries =
112465 + (uint16_t)be32_to_cpu(uint32_prop[2]);
112466 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_echo_ipv6_entries =
112467 + (uint16_t)be32_to_cpu(uint32_prop[3]);
112468 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv4_entries =
112469 + (uint16_t)be32_to_cpu(uint32_prop[4]);
112470 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_ipv6_entries =
112471 + (uint16_t)be32_to_cpu(uint32_prop[5]);
112472 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_oid_entries =
112473 + (uint16_t)be32_to_cpu(uint32_prop[6]);
112474 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_snmp_char =
112475 + (uint16_t)be32_to_cpu(uint32_prop[7]);
112476 +
112477 + uint32_prop = (uint32_t *)of_get_property(port_node,
112478 + "ar-filters-sizes", &lenp);
112479 + if (uint32_prop) {
112480 + if (WARN_ON(lenp != sizeof(uint32_t)*3))
112481 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112482 +
112483 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_ip_prot_filtering =
112484 + (uint16_t)be32_to_cpu(uint32_prop[0]);
112485 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_tcp_port_filtering =
112486 + (uint16_t)be32_to_cpu(uint32_prop[1]);
112487 + p_LnxWrpFmPortDev->dsar_table_sizes.max_num_of_udp_port_filtering =
112488 + (uint16_t)be32_to_cpu(uint32_prop[2]);
112489 + }
112490 +
112491 + if ((err = FM_PORT_ConfigDsarSupport(p_LnxWrpFmPortDev->h_Dev,
112492 + (t_FmPortDsarTablesSizes*)&p_LnxWrpFmPortDev->dsar_table_sizes)) != E_OK)
112493 + RETURN_ERROR(MINOR, err, NO_MSG);
112494 + }
112495 +
112496 + of_node_put(port_node);
112497 + of_node_put(fm_node);
112498 +
112499 + return E_OK;
112500 +}
112501 +
112502 +static t_Error CheckNSetFmPortAdvArgs (t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
112503 +{
112504 + struct device_node *fm_node, *port_node;
112505 + t_Error err;
112506 + const uint32_t *uint32_prop;
112507 + /*const char *str_prop;*/
112508 + int lenp;
112509 +
112510 + fm_node = GetFmAdvArgsDevTreeNode(((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev)->id);
112511 + if (!fm_node) /* no advance parameters for FMan */
112512 + return E_OK;
112513 +
112514 + port_node = GetFmPortAdvArgsDevTreeNode(fm_node,
112515 + p_LnxWrpFmPortDev->settings.param.portType,
112516 + p_LnxWrpFmPortDev->settings.param.portId);
112517 + if (!port_node) /* no advance parameters for FMan-Port */
112518 + return E_OK;
112519 +
112520 +#if (DPAA_VERSION >= 11)
112521 + uint32_prop = (uint32_t *)of_get_property(port_node, "vsp-window", &lenp);
112522 + if (uint32_prop) {
112523 + t_FmPortVSPAllocParams portVSPAllocParams;
112524 + t_FmVspParams fmVspParams;
112525 + t_LnxWrpFmDev *p_LnxWrpFmDev;
112526 + uint8_t portId;
112527 +
112528 + p_LnxWrpFmDev = ((t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev);
112529 +
112530 + if (WARN_ON(lenp != sizeof(uint32_t)*2))
112531 + RETURN_ERROR(MINOR, E_INVALID_VALUE, NO_MSG);
112532 +
112533 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX) ||
112534 + (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_TX_10G) ||
112535 + ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
112536 + p_LnxWrpFmPortDev->settings.frag_enabled))
112537 + return E_OK;
112538 +
112539 + memset(&portVSPAllocParams, 0, sizeof(portVSPAllocParams));
112540 + memset(&fmVspParams, 0, sizeof(fmVspParams));
112541 +
112542 + portVSPAllocParams.numOfProfiles = (uint8_t)be32_to_cpu(uint32_prop[0]);
112543 + portVSPAllocParams.dfltRelativeId = (uint8_t)be32_to_cpu(uint32_prop[1]);
112544 + fmVspParams.h_Fm = p_LnxWrpFmDev->h_Dev;
112545 +
112546 + fmVspParams.portParams.portType = p_LnxWrpFmPortDev->settings.param.portType;
112547 + fmVspParams.portParams.portId = p_LnxWrpFmPortDev->settings.param.portId;
112548 + fmVspParams.relativeProfileId = portVSPAllocParams.dfltRelativeId;
112549 +
112550 + if (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_OH_OFFLINE_PARSING)
112551 + {
112552 + portId = fmVspParams.portParams.portId;
112553 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G){
112554 +#ifndef CONFIG_FMAN_ARM
112555 + if (!(IS_T1023_T1024))
112556 +#endif
112557 + portId += FM_MAX_NUM_OF_1G_RX_PORTS;
112558 + }
112559 + portVSPAllocParams.h_FmTxPort =
112560 + p_LnxWrpFmDev->txPorts[portId].h_Dev;
112561 + fmVspParams.liodnOffset =
112562 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
112563 + memcpy(&fmVspParams.extBufPools,
112564 + &p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools,
112565 + sizeof(t_FmExtPools));
112566 + }
112567 + else
112568 + {
112569 + memcpy(&fmVspParams.extBufPools,
112570 + &p_LnxWrpFmPortDev->opExtPools,
112571 + sizeof(t_FmExtPools));
112572 + }
112573 +
112574 + if ((err = FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev,
112575 + &portVSPAllocParams)) != E_OK)
112576 + RETURN_ERROR(MINOR, err, NO_MSG);
112577 +
112578 + /* We're initializing only the default VSP that are being used by the Linux-Ethernet-driver */
112579 + if ((p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
112580 + !p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed)
112581 + return E_OK;
112582 +
112583 + p_LnxWrpFmPortDev->h_DfltVsp = FM_VSP_Config(&fmVspParams);
112584 + if (!p_LnxWrpFmPortDev->h_DfltVsp)
112585 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("default-VSP for port!"));
112586 +
112587 + if ((err = FM_VSP_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_DfltVsp,
112588 + &p_LnxWrpFmPortDev->buffPrefixContent)) != E_OK)
112589 + RETURN_ERROR(MINOR, err, NO_MSG);
112590 +
112591 + if ((err = FM_VSP_Init(p_LnxWrpFmPortDev->h_DfltVsp)) != E_OK)
112592 + RETURN_ERROR(MINOR, err, NO_MSG);
112593 + }
112594 +#else
112595 +UNUSED(err); UNUSED(uint32_prop); UNUSED(lenp);
112596 +#endif /* (DPAA_VERSION >= 11) */
112597 +
112598 + of_node_put(port_node);
112599 + of_node_put(fm_node);
112600 +
112601 + return E_OK;
112602 +}
112603 +
112604 +static t_Error ConfigureFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
112605 +{
112606 + t_LnxWrpFmDev *p_LnxWrpFmDev =
112607 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
112608 + struct resource *dev_res;
112609 +
112610 + if (!p_LnxWrpFmPortDev->active)
112611 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
112612 + ("FM port not configured!!!"));
112613 +
112614 + dev_res =
112615 + __devm_request_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
112616 + p_LnxWrpFmPortDev->phys_baseAddr,
112617 + p_LnxWrpFmPortDev->memSize,
112618 + "fman-port-hc");
112619 + if (unlikely(dev_res == NULL))
112620 + RETURN_ERROR(MAJOR, E_INVALID_STATE,
112621 + ("__devm_request_region() failed"));
112622 + p_LnxWrpFmPortDev->baseAddr =
112623 + PTR_TO_UINT(devm_ioremap
112624 + (p_LnxWrpFmDev->dev,
112625 + p_LnxWrpFmPortDev->phys_baseAddr,
112626 + p_LnxWrpFmPortDev->memSize));
112627 + if (unlikely(p_LnxWrpFmPortDev->baseAddr == 0))
112628 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
112629 + ("devm_ioremap() failed"));
112630 +
112631 + p_LnxWrpFmPortDev->settings.param.baseAddr =
112632 + p_LnxWrpFmPortDev->baseAddr;
112633 +
112634 + return E_OK;
112635 +}
112636 +
112637 +static t_Error InitFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
112638 +{
112639 +#define MY_ADV_CONFIG_CHECK_END \
112640 + RETURN_ERROR(MAJOR, E_INVALID_SELECTION,\
112641 + ("Advanced configuration routine"));\
112642 + if (errCode != E_OK)\
112643 + RETURN_ERROR(MAJOR, errCode, NO_MSG);\
112644 + }
112645 +
112646 + int i = 0;
112647 +
112648 + if (!p_LnxWrpFmPortDev->active || p_LnxWrpFmPortDev->h_Dev)
112649 + return E_INVALID_STATE;
112650 +
112651 + p_LnxWrpFmPortDev->h_Dev =
112652 + FM_PORT_Config(&p_LnxWrpFmPortDev->settings.param);
112653 + if (p_LnxWrpFmPortDev->h_Dev == NULL)
112654 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM-port"));
112655 +
112656 +#ifndef FM_QMI_NO_DEQ_OPTIONS_SUPPORT
112657 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
112658 + e_FM_PORT_TYPE_TX_10G)
112659 + || (p_LnxWrpFmPortDev->settings.param.portType ==
112660 + e_FM_PORT_TYPE_TX)) {
112661 + t_Error errCode = E_OK;
112662 + errCode =
112663 + FM_PORT_ConfigDeqHighPriority(p_LnxWrpFmPortDev->h_Dev,
112664 + TRUE);
112665 + if (errCode != E_OK)
112666 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
112667 + errCode =
112668 + FM_PORT_ConfigDeqPrefetchOption(p_LnxWrpFmPortDev->h_Dev,
112669 + e_FM_PORT_DEQ_FULL_PREFETCH);
112670 + if (errCode
112671 + != E_OK)
112672 + RETURN_ERROR(MAJOR, errCode, NO_MSG);
112673 + }
112674 +#endif /* !FM_QMI_NO_DEQ_OPTIONS_SUPPORT */
112675 +
112676 +#ifndef CONFIG_FMAN_ARM
112677 +#ifdef FM_BCB_ERRATA_BMI_SW001
112678 +/* Configure BCB workaround on Rx ports, only for B4860 rev1 */
112679 +#define SVR_SECURITY_MASK 0x00080000
112680 +#define SVR_PERSONALITY_MASK 0x0000FF00
112681 +#define SVR_VER_IGNORE_MASK (SVR_SECURITY_MASK | SVR_PERSONALITY_MASK)
112682 +#define SVR_B4860_REV1_VALUE 0x86800010
112683 +
112684 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
112685 + e_FM_PORT_TYPE_RX_10G) ||
112686 + (p_LnxWrpFmPortDev->settings.param.portType ==
112687 + e_FM_PORT_TYPE_RX)) {
112688 + unsigned int svr;
112689 +
112690 + svr = mfspr(SPRN_SVR);
112691 +
112692 + if ((svr & ~SVR_VER_IGNORE_MASK) == SVR_B4860_REV1_VALUE)
112693 + FM_PORT_ConfigBCBWorkaround(p_LnxWrpFmPortDev->h_Dev);
112694 + }
112695 +#endif /* FM_BCB_ERRATA_BMI_SW001 */
112696 +#endif /* CONFIG_FMAN_ARM */
112697 +/* Call the driver's advanced configuration routines, if requested:
112698 + Compare the function pointer of each entry to the available routines,
112699 + and invoke the matching routine with proper casting of arguments. */
112700 + while (p_LnxWrpFmPortDev->settings.advConfig[i].p_Function
112701 + && (i < FM_MAX_NUM_OF_ADV_SETTINGS)) {
112702 +
112703 +/* TODO: Change this MACRO */
112704 + ADV_CONFIG_CHECK_START(
112705 + &(p_LnxWrpFmPortDev->settings.advConfig[i]))
112706 +
112707 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
112708 + FM_PORT_ConfigBufferPrefixContent,
112709 + NCSW_PARAMS(1,
112710 + (t_FmBufferPrefixContent *)))
112711 +
112712 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
112713 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
112714 + (p_LnxWrpFmPortDev->settings.frag_enabled == TRUE)) {
112715 +
112716 + ADV_CONFIG_CHECK(p_LnxWrpFmPortDev->h_Dev,
112717 + FM_PORT_ConfigExtBufPools,
112718 + NCSW_PARAMS(1, (t_FmExtPools *)))
112719 +
112720 + /* this define contains an else */
112721 + MY_ADV_CONFIG_CHECK_END
112722 + }
112723 +
112724 + /* Advance to next advanced configuration entry */
112725 + i++;
112726 + }
112727 +
112728 +
112729 + if ((p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX) &&
112730 + (p_LnxWrpFmPortDev->settings.param.portType != e_FM_PORT_TYPE_TX_10G)) {
112731 + if (FM_PORT_ConfigErrorsToDiscard(p_LnxWrpFmPortDev->h_Dev, (FM_PORT_FRM_ERR_IPRE |
112732 + FM_PORT_FRM_ERR_IPR_NCSP |
112733 + FM_PORT_FRM_ERR_CLS_DISCARD)) !=E_OK)
112734 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112735 + }
112736 +
112737 + if (CheckNConfigFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
112738 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112739 +
112740 + if (FM_PORT_Init(p_LnxWrpFmPortDev->h_Dev) != E_OK)
112741 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112742 +
112743 + if (CheckNSetFmPortAdvArgs(p_LnxWrpFmPortDev) != E_OK)
112744 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112745 +
112746 +/* FMan Fifo sizes behind the scene":
112747 + * Using the following formulae (*), under a set of simplifying assumptions (.):
112748 + * . all ports are configured in Normal Mode (rather than Independent Mode)
112749 + * . the DPAA Eth driver allocates buffers of size:
112750 + * . MAXFRM + NET_IP_ALIGN + DPA_PRIV_DATA_SIZE + DPA_PARSE_RESULTS_SIZE
112751 + * + DPA_HASH_RESULTS_SIZE, i.e.:
112752 + * MAXFRM + 2 + 16 + sizeof(t_FmPrsResult) + 16, i.e.:
112753 + * MAXFRM + 66
112754 + * . excessive buffer pools not accounted for
112755 + *
112756 + * * for Rx ports on P4080:
112757 + * . IFSZ = ceil(max(FMBM_EBMPI[PBS]) / 256) * 256 + 7 * 256
112758 + * . no internal frame offset (FMBM_RIM[FOF] == 0) - otherwise,
112759 + * add up to 256 to the above
112760 + *
112761 + * * for Rx ports on P1023:
112762 + * . IFSZ = ceil(second_largest(FMBM_EBMPI[PBS] / 256)) * 256 + 7 * 256,
112763 + * if at least 2 bpools are configured
112764 + * . IFSZ = 8 * 256, if only a single bpool is configured
112765 + *
112766 + * * for Tx ports:
112767 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256
112768 + * + FMBM_TFP[DPDE] * 256, i.e.:
112769 + * IFSZ = ceil(MAXFRM / 256) * 256 + 3 x 256 + FMBM_TFP[DPDE] * 256
112770 + *
112771 + * * for OH ports on P4080:
112772 + * . IFSZ = ceil(frame_size / 256) * 256 + 1 * 256 + FMBM_PP[MXT] * 256
112773 + * * for OH ports on P1023:
112774 + * . IFSZ = ceil(frame_size / 256) * 256 + 3 * 256 + FMBM_TFP[DPDE] * 256
112775 + * * for both P4080 and P1023:
112776 + * . (conservative decisions, assuming that BMI must bring the entire
112777 + * frame, not only the frame header)
112778 + * . no internal frame offset (FMBM_OIM[FOF] == 0) - otherwise,
112779 + * add up to 256 to the above
112780 + *
112781 + * . for P4080/P5020/P3041/P2040, DPDE is:
112782 + * > 0 or 1, for 1Gb ports, HW default: 0
112783 + * > 2..7 (recommended: 3..7) for 10Gb ports, HW default: 3
112784 + * . for P1023, DPDE should be 1
112785 + *
112786 + * . for P1023, MXT is in range (0..31)
112787 + * . for P4080, MXT is in range (0..63)
112788 + *
112789 + */
112790 +#if 0
112791 + if ((p_LnxWrpFmPortDev->defPcd != e_NO_PCD) &&
112792 + (InitFmPort3TupleDefPcd(p_LnxWrpFmPortDev) != E_OK))
112793 + RETURN_ERROR(MAJOR, E_INVALID_STATE, NO_MSG);
112794 +#endif
112795 + return E_OK;
112796 +}
112797 +
112798 +void fm_set_rx_port_params(struct fm_port *port,
112799 + struct fm_port_params *params)
112800 +{
112801 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
112802 + int i;
112803 +
112804 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.errFqid =
112805 + params->errq;
112806 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.dfltFqid =
112807 + params->defq;
112808 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.extBufPools.
112809 + numOfPoolsUsed = params->num_pools;
112810 + for (i = 0; i < params->num_pools; i++) {
112811 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
112812 + extBufPools.extBufPool[i].id =
112813 + params->pool_param[i].id;
112814 + p_LnxWrpFmPortDev->settings.param.specificParams.rxParams.
112815 + extBufPools.extBufPool[i].size =
112816 + params->pool_param[i].size;
112817 + }
112818 +
112819 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
112820 + params->priv_data_size;
112821 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
112822 + params->parse_results;
112823 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
112824 + params->hash_results;
112825 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
112826 + params->time_stamp;
112827 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
112828 + params->data_align;
112829 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
112830 + params->manip_extra_space;
112831 +
112832 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
112833 + FM_MAX_NUM_OF_ADV_SETTINGS)
112834 +
112835 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
112836 + ARGS(1,
112837 + (&p_LnxWrpFmPortDev->
112838 + buffPrefixContent)));
112839 +
112840 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
112841 +}
112842 +EXPORT_SYMBOL(fm_set_rx_port_params);
112843 +
112844 +/* this function is called from oh_probe as well, thus it contains oh port
112845 + * specific parameters (make sure everything is checked) */
112846 +void fm_set_tx_port_params(struct fm_port *port,
112847 + struct fm_port_params *params)
112848 +{
112849 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) port;
112850 +
112851 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.errFqid =
112852 + params->errq;
112853 + p_LnxWrpFmPortDev->settings.param.specificParams.nonRxParams.
112854 + dfltFqid = params->defq;
112855 +
112856 + p_LnxWrpFmPortDev->buffPrefixContent.privDataSize =
112857 + params->priv_data_size;
112858 + p_LnxWrpFmPortDev->buffPrefixContent.passPrsResult =
112859 + params->parse_results;
112860 + p_LnxWrpFmPortDev->buffPrefixContent.passHashResult =
112861 + params->hash_results;
112862 + p_LnxWrpFmPortDev->buffPrefixContent.passTimeStamp =
112863 + params->time_stamp;
112864 + p_LnxWrpFmPortDev->settings.frag_enabled =
112865 + params->frag_enable;
112866 + p_LnxWrpFmPortDev->buffPrefixContent.dataAlign =
112867 + params->data_align;
112868 + p_LnxWrpFmPortDev->buffPrefixContent.manipExtraSpace =
112869 + params->manip_extra_space;
112870 +
112871 + ADD_ADV_CONFIG_START(p_LnxWrpFmPortDev->settings.advConfig,
112872 + FM_MAX_NUM_OF_ADV_SETTINGS)
112873 +
112874 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigBufferPrefixContent,
112875 + ARGS(1,
112876 + (&p_LnxWrpFmPortDev->
112877 + buffPrefixContent)));
112878 +
112879 + /* oh port specific parameter (for fragmentation only) */
112880 + if ((p_LnxWrpFmPortDev->settings.param.portType ==
112881 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) &&
112882 + params->num_pools) {
112883 + int i;
112884 +
112885 + p_LnxWrpFmPortDev->opExtPools.numOfPoolsUsed = params->num_pools;
112886 + for (i = 0; i < params->num_pools; i++) {
112887 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].id = params->pool_param[i].id;
112888 + p_LnxWrpFmPortDev->opExtPools.extBufPool[i].size = params->pool_param[i].size;
112889 + }
112890 +
112891 + if (p_LnxWrpFmPortDev->settings.frag_enabled)
112892 + ADD_ADV_CONFIG_NO_RET(FM_PORT_ConfigExtBufPools,
112893 + ARGS(1, (&p_LnxWrpFmPortDev->opExtPools)));
112894 + }
112895 +
112896 + ADD_ADV_CONFIG_END InitFmPortDev(p_LnxWrpFmPortDev);
112897 +}
112898 +EXPORT_SYMBOL(fm_set_tx_port_params);
112899 +
112900 +void fm_mac_set_handle(t_Handle h_lnx_wrp_fm_dev,
112901 + t_Handle h_fm_mac,
112902 + int mac_id)
112903 +{
112904 + t_LnxWrpFmDev *p_lnx_wrp_fm_dev = (t_LnxWrpFmDev *)h_lnx_wrp_fm_dev;
112905 +
112906 + p_lnx_wrp_fm_dev->macs[mac_id].h_Dev = h_fm_mac;
112907 + p_lnx_wrp_fm_dev->macs[mac_id].h_LnxWrpFmDev = h_lnx_wrp_fm_dev;
112908 +}
112909 +EXPORT_SYMBOL(fm_mac_set_handle);
112910 +
112911 +static void LnxwrpFmPcdDevExceptionsCb(t_Handle h_App,
112912 + e_FmPcdExceptions exception)
112913 +{
112914 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
112915 +
112916 + ASSERT_COND(p_LnxWrpFmDev);
112917 +
112918 + DBG(INFO, ("got fm-pcd exception %d", exception));
112919 +
112920 + /* do nothing */
112921 + UNUSED(exception);
112922 +}
112923 +
112924 +static void LnxwrpFmPcdDevIndexedExceptionsCb(t_Handle h_App,
112925 + e_FmPcdExceptions exception,
112926 + uint16_t index)
112927 +{
112928 + t_LnxWrpFmDev *p_LnxWrpFmDev = (t_LnxWrpFmDev *) h_App;
112929 +
112930 + ASSERT_COND(p_LnxWrpFmDev);
112931 +
112932 + DBG(INFO,
112933 + ("got fm-pcd-indexed exception %d, indx %d", exception, index));
112934 +
112935 + /* do nothing */
112936 + UNUSED(exception);
112937 + UNUSED(index);
112938 +}
112939 +
112940 +static t_Error InitFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
112941 +{
112942 + spin_lock_init(&lock);
112943 +
112944 + if (p_LnxWrpFmDev->pcdActive) {
112945 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
112946 + t_FmPcdParams fmPcdParams;
112947 + t_Error err;
112948 +
112949 + memset(&fmPcdParams, 0, sizeof(fmPcdParams));
112950 + fmPcdParams.h_Fm = p_LnxWrpFmDev->h_Dev;
112951 + fmPcdParams.prsSupport = p_LnxWrpFmDev->prsActive;
112952 + fmPcdParams.kgSupport = p_LnxWrpFmDev->kgActive;
112953 + fmPcdParams.plcrSupport = p_LnxWrpFmDev->plcrActive;
112954 + fmPcdParams.ccSupport = p_LnxWrpFmDev->ccActive;
112955 + fmPcdParams.numOfSchemes = FM_PCD_KG_NUM_OF_SCHEMES;
112956 +
112957 +#ifndef CONFIG_GUEST_PARTITION
112958 + fmPcdParams.f_Exception = LnxwrpFmPcdDevExceptionsCb;
112959 + if (fmPcdParams.kgSupport)
112960 + fmPcdParams.f_ExceptionId =
112961 + LnxwrpFmPcdDevIndexedExceptionsCb;
112962 + fmPcdParams.h_App = p_LnxWrpFmDev;
112963 +#endif /* !CONFIG_GUEST_PARTITION */
112964 +
112965 +#ifdef CONFIG_MULTI_PARTITION_SUPPORT
112966 + fmPcdParams.numOfSchemes = 0;
112967 + fmPcdParams.numOfClsPlanEntries = 0;
112968 + fmPcdParams.partitionId = 0;
112969 +#endif /* CONFIG_MULTI_PARTITION_SUPPORT */
112970 + fmPcdParams.useHostCommand = TRUE;
112971 +
112972 + p_LnxWrpFmDev->hc_tx_fq =
112973 + FqAlloc(p_LnxWrpFmDev,
112974 + 0,
112975 + QMAN_FQ_FLAG_TO_DCPORTAL,
112976 + p_LnxWrpFmPortDev->txCh, 0);
112977 + if (!p_LnxWrpFmDev->hc_tx_fq)
112978 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
112979 + ("Frame queue allocation failed..."));
112980 +
112981 + p_LnxWrpFmDev->hc_tx_conf_fq =
112982 + FqAlloc(p_LnxWrpFmDev,
112983 + 0,
112984 + QMAN_FQ_FLAG_NO_ENQUEUE,
112985 + p_LnxWrpFmDev->hcCh, 1);
112986 + if (!p_LnxWrpFmDev->hc_tx_conf_fq)
112987 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
112988 + ("Frame queue allocation failed..."));
112989 +
112990 + p_LnxWrpFmDev->hc_tx_err_fq =
112991 + FqAlloc(p_LnxWrpFmDev,
112992 + 0,
112993 + QMAN_FQ_FLAG_NO_ENQUEUE,
112994 + p_LnxWrpFmDev->hcCh, 2);
112995 + if (!p_LnxWrpFmDev->hc_tx_err_fq)
112996 + RETURN_ERROR(MAJOR, E_NULL_POINTER,
112997 + ("Frame queue allocation failed..."));
112998 +
112999 + fmPcdParams.hc.portBaseAddr = p_LnxWrpFmPortDev->baseAddr;
113000 + fmPcdParams.hc.portId =
113001 + p_LnxWrpFmPortDev->settings.param.portId;
113002 + fmPcdParams.hc.liodnBase =
113003 + p_LnxWrpFmPortDev->settings.param.liodnBase;
113004 + fmPcdParams.hc.errFqid =
113005 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_err_fq);
113006 + fmPcdParams.hc.confFqid =
113007 + qman_fq_fqid(p_LnxWrpFmDev->hc_tx_conf_fq);
113008 + fmPcdParams.hc.qmChannel = p_LnxWrpFmPortDev->txCh;
113009 + fmPcdParams.hc.f_QmEnqueue = QmEnqueueCB;
113010 + fmPcdParams.hc.h_QmArg = (t_Handle) p_LnxWrpFmDev;
113011 +
113012 + p_LnxWrpFmDev->h_PcdDev = FM_PCD_Config(&fmPcdParams);
113013 + if (!p_LnxWrpFmDev->h_PcdDev)
113014 + RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("FM PCD!"));
113015 +
113016 + err =
113017 + FM_PCD_ConfigPlcrNumOfSharedProfiles(p_LnxWrpFmDev->h_PcdDev,
113018 + LNXWRP_FM_NUM_OF_SHARED_PROFILES);
113019 + if (err != E_OK)
113020 + RETURN_ERROR(MAJOR, err, NO_MSG);
113021 +
113022 + err = FM_PCD_Init(p_LnxWrpFmDev->h_PcdDev);
113023 + if (err != E_OK)
113024 + RETURN_ERROR(MAJOR, err, NO_MSG);
113025 +
113026 + if (p_LnxWrpFmDev->err_irq == 0) {
113027 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
113028 + e_FM_PCD_KG_EXCEPTION_DOUBLE_ECC,
113029 + FALSE);
113030 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
113031 + e_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW,
113032 + FALSE);
113033 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
113034 + e_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR,
113035 + FALSE);
113036 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
113037 + e_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC,
113038 + FALSE);
113039 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
113040 + e_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC,
113041 + FALSE);
113042 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
113043 + e_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE,
113044 + FALSE);
113045 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
113046 + e_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE,
113047 + FALSE);
113048 + FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev,
113049 + e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC,
113050 + FALSE);
113051 + }
113052 + }
113053 +
113054 + return E_OK;
113055 +}
113056 +
113057 +void FreeFmPcdDev(t_LnxWrpFmDev *p_LnxWrpFmDev)
113058 +{
113059 +
113060 + if (p_LnxWrpFmDev->h_PcdDev)
113061 + FM_PCD_Free(p_LnxWrpFmDev->h_PcdDev);
113062 +
113063 + if (p_LnxWrpFmDev->hc_tx_err_fq)
113064 + FqFree(p_LnxWrpFmDev->hc_tx_err_fq);
113065 +
113066 + if (p_LnxWrpFmDev->hc_tx_conf_fq)
113067 + FqFree(p_LnxWrpFmDev->hc_tx_conf_fq);
113068 +
113069 + if (p_LnxWrpFmDev->hc_tx_fq)
113070 + FqFree(p_LnxWrpFmDev->hc_tx_fq);
113071 +}
113072 +
113073 +static void FreeFmPortDev(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev)
113074 +{
113075 + t_LnxWrpFmDev *p_LnxWrpFmDev =
113076 + (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
113077 +
113078 + if (!p_LnxWrpFmPortDev->active)
113079 + return;
113080 +
113081 + if (p_LnxWrpFmPortDev->h_Dev)
113082 + FM_PORT_Free(p_LnxWrpFmPortDev->h_Dev);
113083 +
113084 + devm_iounmap(p_LnxWrpFmDev->dev,
113085 + UINT_TO_PTR(p_LnxWrpFmPortDev->baseAddr));
113086 + __devm_release_region(p_LnxWrpFmDev->dev, p_LnxWrpFmDev->res,
113087 + p_LnxWrpFmPortDev->phys_baseAddr,
113088 + p_LnxWrpFmPortDev->memSize);
113089 +}
113090 +
113091 +static int /*__devinit*/ fm_port_probe(struct platform_device *of_dev)
113092 +{
113093 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
113094 + t_LnxWrpFmDev *p_LnxWrpFmDev;
113095 + struct device *dev;
113096 +
113097 + dev = &of_dev->dev;
113098 +
113099 + p_LnxWrpFmPortDev = ReadFmPortDevTreeNode(of_dev);
113100 + if (p_LnxWrpFmPortDev == NULL)
113101 + return -EIO;
113102 + /* Port can be inactive, thus will not be probed:
113103 + - in performance mode, OH ports are disabled
113104 + ...
113105 + */
113106 + if (!p_LnxWrpFmPortDev->active)
113107 + return 0;
113108 +
113109 + if (ConfigureFmPortDev(p_LnxWrpFmPortDev) != E_OK)
113110 + return -EIO;
113111 +
113112 + dev_set_drvdata(dev, p_LnxWrpFmPortDev);
113113 +
113114 + if (p_LnxWrpFmPortDev->settings.param.portType ==
113115 + e_FM_PORT_TYPE_OH_HOST_COMMAND)
113116 + InitFmPcdDev((t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev);
113117 +
113118 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
113119 +
113120 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX) {
113121 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
113122 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
113123 + p_LnxWrpFmPortDev->minor =
113124 + p_LnxWrpFmPortDev->id + DEV_FM_RX_PORTS_MINOR_BASE;
113125 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
113126 + e_FM_PORT_TYPE_RX_10G) {
113127 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
113128 + p_LnxWrpFmDev->name,
113129 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS);
113130 + p_LnxWrpFmPortDev->minor =
113131 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_RX_PORTS +
113132 + DEV_FM_RX_PORTS_MINOR_BASE;
113133 +#ifndef CONFIG_FMAN_ARM
113134 + if (IS_T1023_T1024) {
113135 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-rx%d",
113136 + p_LnxWrpFmDev->name,
113137 + p_LnxWrpFmPortDev->id);
113138 + p_LnxWrpFmPortDev->minor =
113139 + p_LnxWrpFmPortDev->id +
113140 + DEV_FM_RX_PORTS_MINOR_BASE;
113141 + }
113142 +#endif
113143 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
113144 + e_FM_PORT_TYPE_TX) {
113145 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
113146 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
113147 + p_LnxWrpFmPortDev->minor =
113148 + p_LnxWrpFmPortDev->id + DEV_FM_TX_PORTS_MINOR_BASE;
113149 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
113150 + e_FM_PORT_TYPE_TX_10G) {
113151 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
113152 + p_LnxWrpFmDev->name,
113153 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS);
113154 + p_LnxWrpFmPortDev->minor =
113155 + p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_TX_PORTS +
113156 + DEV_FM_TX_PORTS_MINOR_BASE;
113157 +#ifndef CONFIG_FMAN_ARM
113158 + if (IS_T1023_T1024) {
113159 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-tx%d",
113160 + p_LnxWrpFmDev->name,
113161 + p_LnxWrpFmPortDev->id);
113162 + p_LnxWrpFmPortDev->minor =
113163 + p_LnxWrpFmPortDev->id +
113164 + DEV_FM_TX_PORTS_MINOR_BASE;
113165 + }
113166 +#endif
113167 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
113168 + e_FM_PORT_TYPE_OH_HOST_COMMAND) {
113169 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
113170 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id);
113171 + p_LnxWrpFmPortDev->minor =
113172 + p_LnxWrpFmPortDev->id + DEV_FM_OH_PORTS_MINOR_BASE;
113173 + } else if (p_LnxWrpFmPortDev->settings.param.portType ==
113174 + e_FM_PORT_TYPE_OH_OFFLINE_PARSING) {
113175 + Sprint(p_LnxWrpFmPortDev->name, "%s-port-oh%d",
113176 + p_LnxWrpFmDev->name, p_LnxWrpFmPortDev->id + 1);
113177 + p_LnxWrpFmPortDev->minor =
113178 + p_LnxWrpFmPortDev->id + 1 +
113179 + DEV_FM_OH_PORTS_MINOR_BASE;
113180 + }
113181 +
113182 + device_create(p_LnxWrpFmDev->fm_class, NULL,
113183 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor),
113184 + NULL, p_LnxWrpFmPortDev->name);
113185 +
113186 + /* create sysfs entries for stats and regs */
113187 +
113188 + if (fm_port_sysfs_create(dev) != 0) {
113189 + FreeFmPortDev(p_LnxWrpFmPortDev);
113190 + REPORT_ERROR(MAJOR, E_INVALID_STATE,
113191 + ("Unable to create sys entry - fm port!!!"));
113192 + return -EIO;
113193 + }
113194 +
113195 +#ifdef FM_TX_INVALID_ECC_ERRATA_10GMAC_A009
113196 + FM_DisableRamsEcc(p_LnxWrpFmDev->h_Dev);
113197 +#endif /* FM_TX_INVALID_ECC_ERRATA_10GMAC_A009 */
113198 +
113199 + DBG(TRACE, ("%s probed", p_LnxWrpFmPortDev->name));
113200 +
113201 + return 0;
113202 +}
113203 +
113204 +static int fm_port_remove(struct platform_device *of_dev)
113205 +{
113206 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
113207 + t_LnxWrpFmDev *p_LnxWrpFmDev;
113208 + struct device *dev;
113209 +
113210 + dev = &of_dev->dev;
113211 + p_LnxWrpFmPortDev = dev_get_drvdata(dev);
113212 +
113213 + fm_port_sysfs_destroy(dev);
113214 +
113215 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
113216 + device_destroy(p_LnxWrpFmDev->fm_class,
113217 + MKDEV(p_LnxWrpFmDev->major, p_LnxWrpFmPortDev->minor));
113218 +
113219 + FreeFmPortDev(p_LnxWrpFmPortDev);
113220 +
113221 + dev_set_drvdata(dev, NULL);
113222 +
113223 + return 0;
113224 +}
113225 +
113226 +static const struct of_device_id fm_port_match[] = {
113227 + {
113228 + .compatible = "fsl,fman-port-oh"},
113229 + {
113230 + .compatible = "fsl,fman-v2-port-oh"},
113231 + {
113232 + .compatible = "fsl,fman-v3-port-oh"},
113233 + {
113234 + .compatible = "fsl,fman-port-1g-rx"},
113235 + {
113236 + .compatible = "fsl,fman-port-10g-rx"},
113237 + {
113238 + .compatible = "fsl,fman-port-1g-tx"},
113239 + {
113240 + .compatible = "fsl,fman-port-10g-tx"},
113241 + {}
113242 +};
113243 +
113244 +#ifndef MODULE
113245 +MODULE_DEVICE_TABLE(of, fm_port_match);
113246 +#endif /* !MODULE */
113247 +
113248 +static struct platform_driver fm_port_driver = {
113249 +
113250 + .driver = {
113251 + .name = "fsl-fman-port",
113252 + .of_match_table = fm_port_match,
113253 + .owner = THIS_MODULE,
113254 + },
113255 + .probe = fm_port_probe,
113256 + .remove = fm_port_remove
113257 +};
113258 +
113259 +
113260 +t_Error LNXWRP_FM_Port_Init(void)
113261 +{
113262 + /* Register to the DTB for basic FM port API */
113263 + if (platform_driver_register(&fm_port_driver))
113264 + return E_NO_DEVICE;
113265 +
113266 + return E_OK;
113267 +}
113268 +
113269 +void LNXWRP_FM_Port_Free(void)
113270 +{
113271 + platform_driver_unregister(&fm_port_driver);
113272 +}
113273 +
113274 +static int __init __cold fm_port_load(void)
113275 +{
113276 + if (LNXWRP_FM_Port_Init() != E_OK) {
113277 + printk(KERN_CRIT "Failed to init FM Ports wrapper!\n");
113278 + return -ENODEV;
113279 + }
113280 +
113281 + printk(KERN_CRIT "Freescale FM Ports module\n");
113282 +
113283 + return 0;
113284 +}
113285 +
113286 +static void __exit __cold fm_port_unload(void)
113287 +{
113288 + LNXWRP_FM_Port_Free();
113289 +}
113290 +
113291 +module_init(fm_port_load);
113292 +module_exit(fm_port_unload);
113293 --- /dev/null
113294 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm.c
113295 @@ -0,0 +1,4854 @@
113296 +/*
113297 + * Copyright 2008-2012 Freescale Semiconductor Inc.
113298 + *
113299 + * Redistribution and use in source and binary forms, with or without
113300 + * modification, are permitted provided that the following conditions are met:
113301 + * * Redistributions of source code must retain the above copyright
113302 + * notice, this list of conditions and the following disclaimer.
113303 + * * Redistributions in binary form must reproduce the above copyright
113304 + * notice, this list of conditions and the following disclaimer in the
113305 + * documentation and/or other materials provided with the distribution.
113306 + * * Neither the name of Freescale Semiconductor nor the
113307 + * names of its contributors may be used to endorse or promote products
113308 + * derived from this software without specific prior written permission.
113309 + *
113310 + *
113311 + * ALTERNATIVELY, this software may be distributed under the terms of the
113312 + * GNU General Public License ("GPL") as published by the Free Software
113313 + * Foundation, either version 2 of that License or (at your option) any
113314 + * later version.
113315 + *
113316 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
113317 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
113318 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
113319 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
113320 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
113321 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
113322 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
113323 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
113324 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
113325 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
113326 + */
113327 +
113328 +/*
113329 + @File lnxwrp_ioctls_fm.c
113330 + @Author Shlomi Gridish
113331 + @Description FM Linux wrapper functions.
113332 +*/
113333 +
113334 +/* Linux Headers ------------------- */
113335 +#include <linux/version.h>
113336 +
113337 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
113338 +#define MODVERSIONS
113339 +#endif
113340 +#ifdef MODVERSIONS
113341 +#include <config/modversions.h>
113342 +#endif /* MODVERSIONS */
113343 +
113344 +#include <linux/kernel.h>
113345 +#include <linux/module.h>
113346 +#include <linux/slab.h>
113347 +#include <linux/fs.h>
113348 +#include <linux/cdev.h>
113349 +#include <linux/device.h>
113350 +#include <linux/irq.h>
113351 +#include <linux/interrupt.h>
113352 +#include <linux/io.h>
113353 +#include <linux/ioport.h>
113354 +#include <linux/of_platform.h>
113355 +#include <linux/uaccess.h>
113356 +#include <asm/errno.h>
113357 +#ifndef CONFIG_FMAN_ARM
113358 +#include <sysdev/fsl_soc.h>
113359 +#include <linux/fsl/svr.h>
113360 +#endif
113361 +
113362 +#if defined(CONFIG_COMPAT)
113363 +#include <linux/compat.h>
113364 +#endif
113365 +
113366 +#include "part_ext.h"
113367 +#include "fm_ioctls.h"
113368 +#include "fm_pcd_ioctls.h"
113369 +#include "fm_port_ioctls.h"
113370 +#include "fm_vsp_ext.h"
113371 +
113372 +#ifndef CONFIG_FMAN_ARM
113373 +#define IS_T1023_T1024 (SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1024 || \
113374 + SVR_SOC_VER(mfspr(SPRN_SVR)) == SVR_T1023)
113375 +#endif
113376 +
113377 +#define __ERR_MODULE__ MODULE_FM
113378 +
113379 +#if defined(CONFIG_COMPAT)
113380 +#include "lnxwrp_ioctls_fm_compat.h"
113381 +#endif
113382 +
113383 +#include "lnxwrp_fm.h"
113384 +
113385 +#define CMP_IOC_DEFINE(def) (IOC_##def != def)
113386 +
113387 +/* fm_pcd_ioctls.h === fm_pcd_ext.h assertions */
113388 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
113389 +#error Error: please synchronize IOC_ defines!
113390 +#endif
113391 +
113392 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_HDRS)
113393 +#error Error: please synchronize IOC_ defines!
113394 +#endif
113395 +
113396 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS)
113397 +#error Error: please synchronize IOC_ defines!
113398 +#endif
113399 +
113400 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS)
113401 +#error Error: please synchronize IOC_ defines!
113402 +#endif
113403 +
113404 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_GENERIC_REGS)
113405 +#error Error: please synchronize IOC_ defines!
113406 +#endif
113407 +
113408 +#if CMP_IOC_DEFINE(FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY)
113409 +#error Error: please synchronize IOC_ defines!
113410 +#endif
113411 +
113412 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_EXTRACT_MASKS)
113413 +#error Error: please synchronize IOC_ defines!
113414 +#endif
113415 +
113416 +#if CMP_IOC_DEFINE(FM_PCD_KG_NUM_OF_DEFAULT_GROUPS)
113417 +#error Error: please synchronize IOC_ defines!
113418 +#endif
113419 +
113420 +#if CMP_IOC_DEFINE(FM_PCD_PRS_NUM_OF_LABELS)
113421 +#error Error: please synchronize IOC_ defines!
113422 +#endif
113423 +
113424 +#if CMP_IOC_DEFINE(FM_PCD_SW_PRS_SIZE)
113425 +#error Error: please synchronize IOC_ defines!
113426 +#endif
113427 +
113428 +#if CMP_IOC_DEFINE(FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE)
113429 +#error Error: please synchronize IOC_ defines!
113430 +#endif
113431 +
113432 +#if DPAA_VERSION >= 11
113433 +#if CMP_IOC_DEFINE(FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES)
113434 +#error Error: please synchronize IOC_ defines!
113435 +#endif
113436 +#endif
113437 +
113438 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_TREES)
113439 +#error Error: please synchronize IOC_ defines!
113440 +#endif
113441 +
113442 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_GROUPS)
113443 +#error Error: please synchronize IOC_ defines!
113444 +#endif
113445 +
113446 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_UNITS)
113447 +#error Error: please synchronize IOC_ defines!
113448 +#endif
113449 +
113450 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_KEYS)
113451 +#error Error: please synchronize IOC_ defines!
113452 +#endif
113453 +
113454 +#if CMP_IOC_DEFINE(FM_PCD_MAX_SIZE_OF_KEY)
113455 +#error Error: please synchronize IOC_ defines!
113456 +#endif
113457 +
113458 +#if CMP_IOC_DEFINE(FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP)
113459 +#error Error: please synchronize IOC_ defines!
113460 +#endif
113461 +
113462 +#if CMP_IOC_DEFINE(FM_PCD_LAST_KEY_INDEX)
113463 +#error Error: please synchronize IOC_ defines!
113464 +#endif
113465 +
113466 +/* net_ioctls.h === net_ext.h assertions */
113467 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_PID)
113468 +#error Error: please synchronize IOC_ defines!
113469 +#endif
113470 +
113471 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_COMPRESSED)
113472 +#error Error: please synchronize IOC_ defines!
113473 +#endif
113474 +
113475 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPP_ALL_FIELDS)
113476 +#error Error: please synchronize IOC_ defines!
113477 +#endif
113478 +
113479 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPoE_ALL_FIELDS)
113480 +#error Error: please synchronize IOC_ defines!
113481 +#endif
113482 +
113483 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_ALL_FIELDS)
113484 +#error Error: please synchronize IOC_ defines!
113485 +#endif
113486 +
113487 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS)
113488 +#error Error: please synchronize IOC_ defines!
113489 +#endif
113490 +
113491 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ETH_ALL_FIELDS)
113492 +#error Error: please synchronize IOC_ defines!
113493 +#endif
113494 +
113495 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv4_ALL_FIELDS)
113496 +#error Error: please synchronize IOC_ defines!
113497 +#endif
113498 +
113499 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPv6_ALL_FIELDS)
113500 +#error Error: please synchronize IOC_ defines!
113501 +#endif
113502 +
113503 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ICMP_ALL_FIELDS)
113504 +#error Error: please synchronize IOC_ defines!
113505 +#endif
113506 +
113507 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IGMP_ALL_FIELDS)
113508 +#error Error: please synchronize IOC_ defines!
113509 +#endif
113510 +
113511 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_TCP_ALL_FIELDS)
113512 +#error Error: please synchronize IOC_ defines!
113513 +#endif
113514 +
113515 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_ALL_FIELDS)
113516 +#error Error: please synchronize IOC_ defines!
113517 +#endif
113518 +
113519 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_DCCP_ALL_FIELDS)
113520 +#error Error: please synchronize IOC_ defines!
113521 +#endif
113522 +
113523 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ALL_FIELDS)
113524 +#error Error: please synchronize IOC_ defines!
113525 +#endif
113526 +
113527 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS)
113528 +#error Error: please synchronize IOC_ defines!
113529 +#endif
113530 +
113531 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPHC_ALL_FIELDS)
113532 +#error Error: please synchronize IOC_ defines!
113533 +#endif
113534 +
113535 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS)
113536 +#error Error: please synchronize IOC_ defines!
113537 +#endif
113538 +
113539 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv2_ALL_FIELDS)
113540 +#error Error: please synchronize IOC_ defines!
113541 +#endif
113542 +
113543 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS)
113544 +#error Error: please synchronize IOC_ defines!
113545 +#endif
113546 +
113547 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS)
113548 +#error Error: please synchronize IOC_ defines!
113549 +#endif
113550 +
113551 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_VLAN_ALL_FIELDS)
113552 +#error Error: please synchronize IOC_ defines!
113553 +#endif
113554 +
113555 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_ALL_FIELDS)
113556 +#error Error: please synchronize IOC_ defines!
113557 +#endif
113558 +
113559 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_NLPID_ALL_FIELDS)
113560 +#error Error: please synchronize IOC_ defines!
113561 +#endif
113562 +
113563 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_SNAP_ALL_FIELDS)
113564 +#error Error: please synchronize IOC_ defines!
113565 +#endif
113566 +
113567 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS)
113568 +#warning Error: please synchronize IOC_ defines!
113569 +#endif
113570 +
113571 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_ARP_ALL_FIELDS)
113572 +#error Error: please synchronize IOC_ defines!
113573 +#endif
113574 +
113575 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_RFC2684_ALL_FIELDS)
113576 +#error Error: please synchronize IOC_ defines!
113577 +#endif
113578 +
113579 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS)
113580 +#error Error: please synchronize IOC_ defines!
113581 +#endif
113582 +
113583 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS)
113584 +#error Error: please synchronize IOC_ defines!
113585 +#endif
113586 +
113587 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_GRE_ALL_FIELDS)
113588 +#error Error: please synchronize IOC_ defines!
113589 +#endif
113590 +
113591 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MINENCAP_ALL_FIELDS)
113592 +#error Error: please synchronize IOC_ defines!
113593 +#endif
113594 +
113595 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS)
113596 +#error Error: please synchronize IOC_ defines!
113597 +#endif
113598 +
113599 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS)
113600 +#error Error: please synchronize IOC_ defines!
113601 +#endif
113602 +
113603 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS)
113604 +#error Error: please synchronize IOC_ defines!
113605 +#endif
113606 +
113607 +#if CMP_IOC_DEFINE(NET_HEADER_FIELD_MACSEC_ALL_FIELDS)
113608 +#error Error: please synchronize IOC_ defines!
113609 +#endif
113610 +
113611 +/* fm_ioctls.h === fm_ext.h assertions */
113612 +#if CMP_IOC_DEFINE(FM_MAX_NUM_OF_VALID_PORTS)
113613 +#error Error: please synchronize IOC_ defines!
113614 +#endif
113615 +
113616 +void LnxWrpPCDIOCTLTypeChecking(void)
113617 +{
113618 + /* fm_ext.h == fm_ioctls.h */
113619 + ASSERT_COND(sizeof(ioc_fm_port_bandwidth_params) == sizeof(t_FmPortsBandwidthParams));
113620 + ASSERT_COND(sizeof(ioc_fm_revision_info_t) == sizeof(t_FmRevisionInfo));
113621 +
113622 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
113623 + /*ioc_fm_pcd_counters_params_t : NOT USED */
113624 + /*ioc_fm_pcd_exception_params_t : private */
113625 +#if (DPAA_VERSION >= 11)
113626 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_params_t) == sizeof(t_FmPcdManipFragCapwapParams));
113627 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_params_t) == sizeof(t_FmPcdManipReassemCapwapParams));
113628 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t) == sizeof(t_FmPcdManipHdrInsrtByHdrParams));
113629 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_ip_params_t) == sizeof(t_FmPcdManipHdrInsrtIpParams));
113630 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_t) == sizeof(t_FmPcdManipHdrInsrt));
113631 + ASSERT_COND(sizeof(ioc_fm_manip_hdr_info_t) == sizeof(t_FmManipHdrInfo));
113632 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t) == sizeof(t_FmPcdManipHdrRmvByHdrParams));
113633 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_capwap_params_t) == sizeof(t_FmPcdManipSpecialOffloadCapwapParams));
113634 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_capwap_stats_t) == sizeof(t_FmPcdManipFragCapwapStats));
113635 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_capwap_stats_t) == sizeof(t_FmPcdManipReassemCapwapStats));
113636 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
113637 +#endif /* (DPAA_VERSION >= 11) */
113638 +
113639 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_label_params_t) == sizeof(t_FmPcdPrsLabelParams));
113640 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_sw_params_t) == sizeof(t_FmPcdPrsSwParams));
113641 + /*ioc_fm_pcd_kg_dflt_value_params_t : private */
113642 + ASSERT_COND(sizeof(ioc_fm_pcd_hdr_protocol_opt_u) == sizeof(u_FmPcdHdrProtocolOpt));
113643 + ASSERT_COND(sizeof(ioc_fm_pcd_fields_u) == sizeof(t_FmPcdFields));
113644 + ASSERT_COND(sizeof(ioc_fm_pcd_from_hdr_t) == sizeof(t_FmPcdFromHdr));
113645 + ASSERT_COND(sizeof(ioc_fm_pcd_from_field_t) == sizeof(t_FmPcdFromField));
113646 + ASSERT_COND(sizeof(ioc_fm_pcd_distinction_unit_t) == sizeof(t_FmPcdDistinctionUnit));
113647 +
113648 +#if defined(CONFIG_ARM64)
113649 + /* different alignment */
113650 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *) + 4);
113651 +#else
113652 +#if !defined(CONFIG_COMPAT)
113653 + /* different alignment */
113654 + ASSERT_COND(sizeof(ioc_fm_pcd_net_env_params_t) == sizeof(t_FmPcdNetEnvParams) + sizeof(void *));
113655 +#endif
113656 +#endif
113657 + ASSERT_COND(sizeof(ioc_fm_pcd_extract_entry_t) == sizeof(t_FmPcdExtractEntry));
113658 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_mask_t) == sizeof(t_FmPcdKgExtractMask));
113659 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extract_dflt_t) == sizeof(t_FmPcdKgExtractDflt));
113660 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t) == sizeof(t_FmPcdKgKeyExtractAndHashParams));
113661 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_extracted_or_params_t) == sizeof(t_FmPcdKgExtractedOrParams));
113662 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_counter_t) == sizeof(t_FmPcdKgSchemeCounter));
113663 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_plcr_profile_t) == sizeof(t_FmPcdKgPlcrProfile));
113664 +#if (DPAA_VERSION >= 11)
113665 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_storage_profile_t) == sizeof(t_FmPcdKgStorageProfile));
113666 +#endif
113667 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_cc_t) == sizeof(t_FmPcdKgCc));
113668 +#if !defined(CONFIG_COMPAT)
113669 + /* different alignment */
113670 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_params_t) == sizeof(t_FmPcdKgSchemeParams) + sizeof(void *));
113671 +#endif
113672 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_cc_params_t) == sizeof(t_FmPcdCcNextCcParams));
113673 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_plcr_params_t) == sizeof(t_FmPcdCcNextPlcrParams));
113674 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_enqueue_params_t) == sizeof(t_FmPcdCcNextEnqueueParams));
113675 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_kg_params_t) == sizeof(t_FmPcdCcNextKgParams));
113676 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_next_engine_params_t) == sizeof(t_FmPcdCcNextEngineParams));
113677 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_key_params_t) == sizeof(t_FmPcdCcKeyParams));
113678 + ASSERT_COND(sizeof(ioc_keys_params_t) == sizeof(t_KeysParams));
113679 +#if !defined(CONFIG_COMPAT)
113680 + /* different alignment */
113681 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_node_params_t) == sizeof(t_FmPcdCcNodeParams) + sizeof(void *));
113682 + ASSERT_COND(sizeof(ioc_fm_pcd_hash_table_params_t) == sizeof(t_FmPcdHashTableParams) + sizeof(void *));
113683 +#endif
113684 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_grp_params_t) == sizeof(t_FmPcdCcGrpParams));
113685 +#if !defined(CONFIG_COMPAT)
113686 + /* different alignment */
113687 + ASSERT_COND(sizeof(ioc_fm_pcd_cc_tree_params_t) == sizeof(t_FmPcdCcTreeParams) + sizeof(void *));
113688 +#endif
113689 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_byte_rate_mode_param_t) == sizeof(t_FmPcdPlcrByteRateModeParams));
113690 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t) == sizeof(t_FmPcdPlcrNonPassthroughAlgParams));
113691 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_next_engine_params_u) == sizeof(u_FmPcdPlcrNextEngineParams));
113692 + /*ioc_fm_pcd_port_params_t : private */
113693 + ASSERT_COND(sizeof(ioc_fm_pcd_plcr_profile_params_t) == sizeof(t_FmPcdPlcrProfileParams) + sizeof(void *));
113694 + /*ioc_fm_pcd_cc_tree_modify_next_engine_params_t : private */
113695 +
113696 +#ifdef FM_CAPWAP_SUPPORT
113697 +#error TODO: unsupported feature
113698 +/*
113699 + ASSERT_COND(sizeof(TODO) == sizeof(t_FmPcdManipHdrInsrtByTemplateParams));
113700 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapFragmentationParams));
113701 + ASSERT_COND(sizeof(TODO) == sizeof(t_CapwapReassemblyParams));
113702 +*/
113703 +#endif
113704 +
113705 + /*ioc_fm_pcd_cc_node_modify_next_engine_params_t : private */
113706 + /*ioc_fm_pcd_cc_node_remove_key_params_t : private */
113707 + /*ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t : private */
113708 + /*ioc_fm_pcd_cc_node_modify_key_params_t : private */
113709 + /*ioc_fm_manip_hdr_info_t : private */
113710 + /*ioc_fm_pcd_hash_table_set_t : private */
113711 +
113712 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_params_t) == sizeof(t_FmPcdManipFragIpParams));
113713 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_params_t) == sizeof(t_FmPcdManipReassemIpParams));
113714 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_ipsec_params_t) == sizeof(t_FmPcdManipSpecialOffloadIPSecParams));
113715 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_special_offload_params_t) == sizeof(t_FmPcdManipSpecialOffloadParams));
113716 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_generic_params_t) == sizeof(t_FmPcdManipHdrRmvGenericParams));
113717 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_generic_params_t) == sizeof(t_FmPcdManipHdrInsrtGenericParams));
113718 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_insrt_params_t) == sizeof(t_FmPcdManipHdrInsrtParams));
113719 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_rmv_params_t) == sizeof(t_FmPcdManipHdrRmvParams));
113720 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_hdr_params_t) == sizeof(t_FmPcdManipHdrParams));
113721 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_params_t) == sizeof(t_FmPcdManipFragParams));
113722 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_params_t) == sizeof(t_FmPcdManipReassemParams));
113723 +#if !defined(CONFIG_COMPAT)
113724 + /* different alignment */
113725 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_params_t) == sizeof(t_FmPcdManipParams) + sizeof(void *));
113726 +#endif
113727 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_ip_stats_t) == sizeof(t_FmPcdManipReassemIpStats));
113728 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_ip_stats_t) == sizeof(t_FmPcdManipFragIpStats));
113729 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_reassem_stats_t) == sizeof(t_FmPcdManipReassemStats));
113730 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_frag_stats_t) == sizeof(t_FmPcdManipFragStats));
113731 + ASSERT_COND(sizeof(ioc_fm_pcd_manip_stats_t) == sizeof(t_FmPcdManipStats));
113732 +#if DPAA_VERSION >= 11
113733 + ASSERT_COND(sizeof(ioc_fm_pcd_frm_replic_group_params_t) == sizeof(t_FmPcdFrmReplicGroupParams) + sizeof(void *));
113734 +#endif
113735 +
113736 + /* fm_port_ext.h == fm_port_ioctls.h */
113737 + ASSERT_COND(sizeof(ioc_fm_port_rate_limit_t) == sizeof(t_FmPortRateLimit));
113738 + ASSERT_COND(sizeof(ioc_fm_port_pcd_params_t) == sizeof(t_FmPortPcdParams));
113739 + ASSERT_COND(sizeof(ioc_fm_pcd_kg_scheme_select_t) == sizeof(t_FmPcdKgSchemeSelect));
113740 + ASSERT_COND(sizeof(ioc_fm_pcd_port_schemes_params_t) == sizeof(t_FmPcdPortSchemesParams));
113741 + ASSERT_COND(sizeof(ioc_fm_pcd_prs_start_t) == sizeof(t_FmPcdPrsStart));
113742 +
113743 + return;
113744 +}
113745 +
113746 +#define ASSERT_IOC_NET_ENUM(def) ASSERT_COND((unsigned long)e_IOC_NET_##def == (unsigned long)def)
113747 +
113748 +void LnxWrpPCDIOCTLEnumChecking(void)
113749 +{
113750 + /* net_ext.h == net_ioctls.h : sampling checks */
113751 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_MACSEC);
113752 + ASSERT_IOC_NET_ENUM(HEADER_TYPE_PPP);
113753 + ASSERT_IOC_NET_ENUM(MAX_HEADER_TYPE_COUNT);
113754 +
113755 + /* fm_ext.h == fm_ioctls.h */
113756 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_TYPE_DUMMY == (unsigned long)e_FM_PORT_TYPE_DUMMY);
113757 + ASSERT_COND((unsigned long)e_IOC_EX_MURAM_ECC == (unsigned long)e_FM_EX_MURAM_ECC);
113758 + ASSERT_COND((unsigned long)e_IOC_FM_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_COUNTERS_DEQ_CONFIRM);
113759 +
113760 + /* fm_pcd_ext.h == fm_pcd_ioctls.h */
113761 + 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);
113762 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC == (unsigned long)e_FM_PCD_PRS_EXCEPTION_SINGLE_ECC);
113763 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PRS == (unsigned long)e_FM_PCD_PRS);
113764 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FULL_FIELD == (unsigned long)e_FM_PCD_EXTRACT_FULL_FIELD);
113765 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID == (unsigned long)e_FM_PCD_EXTRACT_FROM_FLOW_ID);
113766 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO == (unsigned long)e_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO);
113767 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_DFLT_ILLEGAL == (unsigned long)e_FM_PCD_KG_DFLT_ILLEGAL);
113768 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA == (unsigned long)e_FM_PCD_KG_GENERIC_NOT_FROM_DATA);
113769 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_HDR_INDEX_LAST == (unsigned long)e_FM_PCD_HDR_INDEX_LAST);
113770 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_SHARED == (unsigned long)e_FM_PCD_PLCR_SHARED);
113771 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_RFC_4115 == (unsigned long)e_FM_PCD_PLCR_RFC_4115);
113772 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_COLOR_AWARE == (unsigned long)e_FM_PCD_PLCR_COLOR_AWARE);
113773 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_OVERRIDE == (unsigned long)e_FM_PCD_PLCR_OVERRIDE);
113774 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_FULL_FRM_LEN);
113775 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN == (unsigned long)e_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN);
113776 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_PLCR_PACKET_MODE == (unsigned long)e_FM_PCD_PLCR_PACKET_MODE);
113777 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_DROP_FRAME == (unsigned long)e_FM_PCD_DROP_FRAME);
113778 + 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);
113779 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP == (unsigned long)e_FM_PCD_ACTION_INDEXED_LOOKUP);
113780 + 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);
113781 +#if !defined(FM_CAPWAP_SUPPORT)
113782 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_GENERIC == (unsigned long)e_FM_PCD_MANIP_INSRT_GENERIC);
113783 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_GENERIC == (unsigned long)e_FM_PCD_MANIP_RMV_GENERIC);
113784 +#else
113785 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE == (unsigned long)e_FM_PCD_MANIP_INSRT_BY_TEMPLATE);
113786 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_RMV_BY_HDR == (unsigned long)e_FM_PCD_MANIP_RMV_BY_HDR);
113787 + 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);
113788 +#endif
113789 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG == (unsigned long)e_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG);
113790 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH == (unsigned long)e_FM_PCD_MANIP_EIGHT_WAYS_HASH);
113791 +
113792 +#ifdef FM_CAPWAP_SUPPORT
113793 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_STATS_PER_FLOWID == (unsigned long)e_FM_PCD_STATS_PER_FLOWID);
113794 +#endif
113795 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD);
113796 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_CC_STATS_MODE_FRAME == (unsigned long)e_FM_PCD_CC_STATS_MODE_FRAME);
113797 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG == (unsigned long)e_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG);
113798 + ASSERT_COND((unsigned long)e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC == (unsigned long)e_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC);
113799 +
113800 + /* fm_port_ext.h == fm_port_ioctls.h */
113801 +#if !defined(FM_CAPWAP_SUPPORT)
113802 + 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);
113803 +#else
113804 + 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);
113805 +#endif
113806 + ASSERT_COND((unsigned long)e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM == (unsigned long)e_FM_PORT_COUNTERS_DEQ_CONFIRM);
113807 + 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);
113808 +
113809 + return;
113810 +}
113811 +
113812 +static t_Error LnxwrpFmPcdIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
113813 +{
113814 + t_Error err = E_OK;
113815 +
113816 +/*
113817 +Status: PCD API to fmlib (file: drivers/net/dpa/NetCommSw/inc/Peripherals/fm_pcd_ext.h):
113818 +
113819 + FM_PCD_PrsLoadSw
113820 + FM_PCD_SetAdvancedOffloadSupport
113821 + FM_PCD_Enable
113822 + FM_PCD_Disable
113823 + FM_PCD_ForceIntr
113824 + FM_PCD_SetException
113825 + FM_PCD_KgSetAdditionalDataAfterParsing
113826 + FM_PCD_KgSetDfltValue
113827 + FM_PCD_NetEnvCharacteristicsSet
113828 + FM_PCD_NetEnvCharacteristicsDelete
113829 + FM_PCD_KgSchemeSet
113830 + FM_PCD_KgSchemeDelete
113831 + FM_PCD_MatchTableSet
113832 + FM_PCD_MatchTableDelete
113833 + FM_PCD_CcRootBuild
113834 + FM_PCD_CcRootDelete
113835 + FM_PCD_PlcrProfileSet
113836 + FM_PCD_PlcrProfileDelete
113837 + FM_PCD_CcRootModifyNextEngine
113838 + FM_PCD_MatchTableModifyNextEngine
113839 + FM_PCD_MatchTableModifyMissNextEngine
113840 + FM_PCD_MatchTableRemoveKey
113841 + FM_PCD_MatchTableAddKey
113842 + FM_PCD_MatchTableModifyKeyAndNextEngine
113843 + FM_PCD_HashTableSet
113844 + FM_PCD_HashTableDelete
113845 + FM_PCD_HashTableAddKey
113846 + FM_PCD_HashTableRemoveKey
113847 + FM_PCD_MatchTableModifyKey
113848 + FM_PCD_ManipNodeReplace
113849 + FM_PCD_ManipNodeSet
113850 + FM_PCD_ManipNodeDelete
113851 +
113852 +Status: not exported, should be thru sysfs
113853 + FM_PCD_KgSchemeGetCounter
113854 + FM_PCD_KgSchemeSetCounter
113855 + FM_PCD_PlcrProfileGetCounter
113856 + FM_PCD_PlcrProfileSetCounter
113857 +
113858 +Status: not exported
113859 + FM_PCD_MatchTableFindNRemoveKey
113860 + FM_PCD_MatchTableFindNModifyNextEngine
113861 + FM_PCD_MatchTableFindNModifyKeyAndNextEngine
113862 + FM_PCD_MatchTableFindNModifyKey
113863 + FM_PCD_MatchTableGetIndexedHashBucket
113864 + FM_PCD_MatchTableGetNextEngine
113865 + FM_PCD_MatchTableGetKeyCounter
113866 +
113867 +Status: not exported, would be nice to have
113868 + FM_PCD_HashTableModifyNextEngine
113869 + FM_PCD_HashTableModifyMissNextEngine
113870 + FM_PCD_HashTableGetMissNextEngine
113871 + FM_PCD_ManipGetStatistics
113872 +
113873 +Status: not exported
113874 +#if DPAA_VERSION >= 11
113875 +
113876 + FM_VSP_GetStatistics -- it's not available yet
113877 +#endif
113878 +
113879 +Status: feature not supported
113880 +#ifdef FM_CAPWAP_SUPPORT
113881 +#error unsupported feature
113882 + FM_PCD_StatisticsSetNode
113883 +#endif
113884 +
113885 + */
113886 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
113887 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 20);
113888 +
113889 + switch (cmd)
113890 + {
113891 +#if defined(CONFIG_COMPAT)
113892 + case FM_PCD_IOC_PRS_LOAD_SW_COMPAT:
113893 +#endif
113894 + case FM_PCD_IOC_PRS_LOAD_SW:
113895 + {
113896 + ioc_fm_pcd_prs_sw_params_t *param;
113897 + uint8_t *p_code;
113898 +
113899 + param = (ioc_fm_pcd_prs_sw_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_prs_sw_params_t));
113900 + if (!param)
113901 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113902 +
113903 + memset(param, 0, sizeof(ioc_fm_pcd_prs_sw_params_t));
113904 +
113905 +#if defined(CONFIG_COMPAT)
113906 + if (compat)
113907 + {
113908 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param;
113909 +
113910 + compat_param = (ioc_compat_fm_pcd_prs_sw_params_t *) XX_Malloc(
113911 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
113912 + if (!compat_param)
113913 + {
113914 + XX_Free(param);
113915 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113916 + }
113917 +
113918 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_prs_sw_params_t));
113919 + if (copy_from_user(compat_param,
113920 + (ioc_compat_fm_pcd_prs_sw_params_t *) compat_ptr(arg),
113921 + sizeof(ioc_compat_fm_pcd_prs_sw_params_t)))
113922 + {
113923 + XX_Free(compat_param);
113924 + XX_Free(param);
113925 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113926 + }
113927 +
113928 + compat_fm_pcd_prs_sw(compat_param, param, COMPAT_US_TO_K);
113929 +
113930 + XX_Free(compat_param);
113931 + }
113932 + else
113933 +#endif
113934 + {
113935 + if (copy_from_user(param, (ioc_fm_pcd_prs_sw_params_t *)arg,
113936 + sizeof(ioc_fm_pcd_prs_sw_params_t)))
113937 + {
113938 + XX_Free(param);
113939 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113940 + }
113941 + }
113942 +
113943 + if (!param->p_code || !param->size)
113944 + {
113945 + XX_Free(param);
113946 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113947 + }
113948 +
113949 + p_code = (uint8_t *) XX_Malloc(param->size);
113950 + if (!p_code)
113951 + {
113952 + XX_Free(param);
113953 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
113954 + }
113955 +
113956 + memset(p_code, 0, param->size);
113957 + if (copy_from_user(p_code, param->p_code, param->size))
113958 + {
113959 + XX_Free(p_code);
113960 + XX_Free(param);
113961 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113962 + }
113963 +
113964 + param->p_code = p_code;
113965 +
113966 + err = FM_PCD_PrsLoadSw(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPrsSwParams*)param);
113967 +
113968 + XX_Free(p_code);
113969 + XX_Free(param);
113970 + break;
113971 + }
113972 +
113973 + case FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT:
113974 + err = FM_PCD_SetAdvancedOffloadSupport(p_LnxWrpFmDev->h_PcdDev);
113975 + break;
113976 +
113977 + case FM_PCD_IOC_ENABLE:
113978 + err = FM_PCD_Enable(p_LnxWrpFmDev->h_PcdDev);
113979 + break;
113980 +
113981 + case FM_PCD_IOC_DISABLE:
113982 + err = FM_PCD_Disable(p_LnxWrpFmDev->h_PcdDev);
113983 + break;
113984 +
113985 + case FM_PCD_IOC_FORCE_INTR:
113986 + {
113987 + int exception;
113988 +
113989 +#if defined(CONFIG_COMPAT)
113990 + if (compat)
113991 + {
113992 + if (get_user(exception, (int *) compat_ptr(arg)))
113993 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
113994 + }
113995 + else
113996 +#endif
113997 + {
113998 + if (get_user(exception, (int *)arg))
113999 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114000 + }
114001 +
114002 + err = FM_PCD_ForceIntr(p_LnxWrpFmDev->h_PcdDev, (e_FmPcdExceptions)exception);
114003 + break;
114004 + }
114005 +
114006 + case FM_PCD_IOC_SET_EXCEPTION:
114007 + {
114008 + ioc_fm_pcd_exception_params_t *param;
114009 +
114010 + param = (ioc_fm_pcd_exception_params_t *) XX_Malloc(
114011 + sizeof(ioc_fm_pcd_exception_params_t));
114012 + if (!param)
114013 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114014 +
114015 + memset(param, 0, sizeof(ioc_fm_pcd_exception_params_t));
114016 +
114017 +#if defined(CONFIG_COMPAT)
114018 + if (compat)
114019 + {
114020 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)compat_ptr(arg),
114021 + sizeof(ioc_fm_pcd_exception_params_t)))
114022 + {
114023 + XX_Free(param);
114024 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114025 + }
114026 + }
114027 + else
114028 +#endif
114029 + {
114030 + if (copy_from_user(param, (ioc_fm_pcd_exception_params_t *)arg,
114031 + sizeof(ioc_fm_pcd_exception_params_t)))
114032 + {
114033 + XX_Free(param);
114034 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114035 + }
114036 + }
114037 +
114038 + err = FM_PCD_SetException(p_LnxWrpFmDev->h_PcdDev, param->exception, param->enable);
114039 +
114040 + XX_Free(param);
114041 + break;
114042 + }
114043 +
114044 + case FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING:
114045 + {
114046 + uint8_t payloadOffset;
114047 +
114048 +#if defined(CONFIG_COMPAT)
114049 + if (compat)
114050 + {
114051 + if (get_user(payloadOffset, (uint8_t*) compat_ptr(arg)))
114052 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114053 + }
114054 + else
114055 +#endif
114056 + {
114057 + if (get_user(payloadOffset, (uint8_t*) arg))
114058 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114059 + }
114060 +
114061 + err = FM_PCD_KgSetAdditionalDataAfterParsing(p_LnxWrpFmDev->h_PcdDev, payloadOffset);
114062 + break;
114063 + }
114064 +
114065 + case FM_PCD_IOC_KG_SET_DFLT_VALUE:
114066 + {
114067 + ioc_fm_pcd_kg_dflt_value_params_t *param;
114068 +
114069 + param = (ioc_fm_pcd_kg_dflt_value_params_t *) XX_Malloc(
114070 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
114071 + if (!param)
114072 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114073 +
114074 + memset(param, 0, sizeof(ioc_fm_pcd_kg_dflt_value_params_t));
114075 +
114076 +#if defined(CONFIG_COMPAT)
114077 + if (compat)
114078 + {
114079 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)compat_ptr(arg),
114080 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
114081 + {
114082 + XX_Free(param);
114083 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114084 + }
114085 + }
114086 + else
114087 +#endif
114088 + {
114089 + if (copy_from_user(param, (ioc_fm_pcd_kg_dflt_value_params_t *)arg,
114090 + sizeof(ioc_fm_pcd_kg_dflt_value_params_t)))
114091 + {
114092 + XX_Free(param);
114093 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114094 + }
114095 + }
114096 +
114097 + err = FM_PCD_KgSetDfltValue(p_LnxWrpFmDev->h_PcdDev, param->valueId, param->value);
114098 +
114099 + XX_Free(param);
114100 + break;
114101 + }
114102 +
114103 +#if defined(CONFIG_COMPAT)
114104 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT:
114105 +#endif
114106 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET:
114107 + {
114108 + ioc_fm_pcd_net_env_params_t *param;
114109 +
114110 + param = (ioc_fm_pcd_net_env_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_net_env_params_t));
114111 + if (!param)
114112 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114113 +
114114 + memset(param, 0, sizeof(ioc_fm_pcd_net_env_params_t));
114115 +
114116 +#if defined(CONFIG_COMPAT)
114117 + if (compat)
114118 + {
114119 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
114120 +
114121 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
114122 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
114123 + if (!compat_param)
114124 + {
114125 + XX_Free(param);
114126 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114127 + }
114128 +
114129 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
114130 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
114131 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
114132 + {
114133 + XX_Free(compat_param);
114134 + XX_Free(param);
114135 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114136 + }
114137 +
114138 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_US_TO_K);
114139 + XX_Free(compat_param);
114140 + }
114141 + else
114142 +#endif
114143 + {
114144 + if (copy_from_user(param, (ioc_fm_pcd_net_env_params_t *) arg,
114145 + sizeof(ioc_fm_pcd_net_env_params_t)))
114146 + {
114147 + XX_Free(param);
114148 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114149 + }
114150 + }
114151 +
114152 + param->id = FM_PCD_NetEnvCharacteristicsSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdNetEnvParams*)param);
114153 +
114154 + if (!param->id)
114155 + {
114156 + XX_Free(param);
114157 + err = E_INVALID_VALUE;
114158 + /* Since the LLD has no errno-style error reporting,
114159 + we're left here with no other option than to report
114160 + a generic E_INVALID_VALUE */
114161 + break;
114162 + }
114163 +
114164 +#if defined(CONFIG_COMPAT)
114165 + if (compat)
114166 + {
114167 + ioc_compat_fm_pcd_net_env_params_t *compat_param;
114168 +
114169 + compat_param = (ioc_compat_fm_pcd_net_env_params_t *) XX_Malloc(
114170 + sizeof(ioc_compat_fm_pcd_net_env_params_t));
114171 + if (!compat_param)
114172 + {
114173 + XX_Free(param);
114174 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114175 + }
114176 +
114177 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_net_env_params_t));
114178 + compat_copy_fm_pcd_net_env(compat_param, param, COMPAT_K_TO_US);
114179 +
114180 + if (copy_to_user((ioc_compat_fm_pcd_net_env_params_t *) compat_ptr(arg),
114181 + compat_param,
114182 + sizeof(ioc_compat_fm_pcd_net_env_params_t)))
114183 + err = E_READ_FAILED;
114184 +
114185 + XX_Free(compat_param);
114186 + }
114187 + else
114188 +#endif
114189 + {
114190 + if (copy_to_user((ioc_fm_pcd_net_env_params_t *)arg,
114191 + param,
114192 + sizeof(ioc_fm_pcd_net_env_params_t)))
114193 + err = E_READ_FAILED;
114194 + }
114195 +
114196 + XX_Free(param);
114197 + break;
114198 + }
114199 +
114200 +#if defined(CONFIG_COMPAT)
114201 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT:
114202 +#endif
114203 + case FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE:
114204 + {
114205 + ioc_fm_obj_t id;
114206 +
114207 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114208 +
114209 +#if defined(CONFIG_COMPAT)
114210 + if (compat)
114211 + {
114212 + ioc_compat_fm_obj_t compat_id;
114213 +
114214 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114215 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114216 +
114217 + compat_obj_delete(&compat_id, &id);
114218 + }
114219 + else
114220 +#endif
114221 + {
114222 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114223 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114224 + }
114225 +
114226 + err = FM_PCD_NetEnvCharacteristicsDelete(id.obj);
114227 + break;
114228 + }
114229 +
114230 +#if defined(CONFIG_COMPAT)
114231 + case FM_PCD_IOC_KG_SCHEME_SET_COMPAT:
114232 +#endif
114233 + case FM_PCD_IOC_KG_SCHEME_SET:
114234 + {
114235 + ioc_fm_pcd_kg_scheme_params_t *param;
114236 +
114237 + param = (ioc_fm_pcd_kg_scheme_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_params_t));
114238 + if (!param)
114239 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114240 +
114241 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_params_t));
114242 +
114243 +#if defined(CONFIG_COMPAT)
114244 + if (compat)
114245 + {
114246 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param = NULL;
114247 +
114248 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
114249 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
114250 + if (!compat_param)
114251 + {
114252 + XX_Free(param);
114253 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114254 + }
114255 +
114256 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
114257 +
114258 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_params_t *) compat_ptr(arg),
114259 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
114260 + {
114261 + XX_Free(compat_param);
114262 + XX_Free(param);
114263 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114264 + }
114265 +
114266 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_US_TO_K);
114267 +
114268 + XX_Free(compat_param);
114269 + }
114270 + else
114271 +#endif
114272 + {
114273 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_params_t *)arg,
114274 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
114275 + {
114276 + XX_Free(param);
114277 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114278 + }
114279 + }
114280 +
114281 + param->id = FM_PCD_KgSchemeSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdKgSchemeParams*)param);
114282 +
114283 + if (!param->id)
114284 + {
114285 + XX_Free(param);
114286 + err = E_INVALID_VALUE;
114287 + /* Since the LLD has no errno-style error reporting,
114288 + we're left here with no other option than to report
114289 + a generic E_INVALID_VALUE */
114290 + break;
114291 + }
114292 +
114293 +#if defined(CONFIG_COMPAT)
114294 + if (compat)
114295 + {
114296 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param;
114297 +
114298 + compat_param = (ioc_compat_fm_pcd_kg_scheme_params_t *) XX_Malloc(
114299 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
114300 + if (!compat_param)
114301 + {
114302 + XX_Free(param);
114303 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114304 + }
114305 +
114306 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_params_t));
114307 + compat_copy_fm_pcd_kg_scheme(compat_param, param, COMPAT_K_TO_US);
114308 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_params_t *)compat_ptr(arg),
114309 + compat_param,
114310 + sizeof(ioc_compat_fm_pcd_kg_scheme_params_t)))
114311 + err = E_READ_FAILED;
114312 +
114313 + XX_Free(compat_param);
114314 + }
114315 + else
114316 +#endif
114317 + {
114318 + if (copy_to_user((ioc_fm_pcd_kg_scheme_params_t *)arg,
114319 + param,
114320 + sizeof(ioc_fm_pcd_kg_scheme_params_t)))
114321 + err = E_READ_FAILED;
114322 + }
114323 +
114324 + XX_Free(param);
114325 + break;
114326 + }
114327 +
114328 +#if defined(CONFIG_COMPAT)
114329 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR_COMPAT:
114330 +#endif
114331 + case FM_PCD_IOC_KG_SCHEME_GET_CNTR:
114332 + {
114333 + ioc_fm_pcd_kg_scheme_spc_t *param;
114334 +
114335 + param = (ioc_fm_pcd_kg_scheme_spc_t *) XX_Malloc(sizeof(ioc_fm_pcd_kg_scheme_spc_t));
114336 + if (!param)
114337 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114338 +
114339 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_spc_t));
114340 +
114341 +#if defined(CONFIG_COMPAT)
114342 + if (compat)
114343 + {
114344 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param = NULL;
114345 +
114346 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
114347 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
114348 + if (!compat_param)
114349 + {
114350 + XX_Free(param);
114351 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114352 + }
114353 +
114354 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
114355 +
114356 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_kg_scheme_spc_t *) compat_ptr(arg),
114357 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
114358 + {
114359 + XX_Free(compat_param);
114360 + XX_Free(param);
114361 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114362 + }
114363 +
114364 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_US_TO_K);
114365 +
114366 + XX_Free(compat_param);
114367 + }
114368 + else
114369 +#endif
114370 + {
114371 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_spc_t *)arg,
114372 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
114373 + {
114374 + XX_Free(param);
114375 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114376 + }
114377 + }
114378 +
114379 + param->val = FM_PCD_KgSchemeGetCounter((t_Handle)param->id);
114380 +
114381 +#if defined(CONFIG_COMPAT)
114382 + if (compat)
114383 + {
114384 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param;
114385 +
114386 + compat_param = (ioc_compat_fm_pcd_kg_scheme_spc_t *) XX_Malloc(
114387 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
114388 + if (!compat_param)
114389 + {
114390 + XX_Free(param);
114391 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114392 + }
114393 +
114394 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t));
114395 + compat_copy_fm_pcd_kg_scheme_spc(compat_param, param, COMPAT_K_TO_US);
114396 + if (copy_to_user((ioc_compat_fm_pcd_kg_scheme_spc_t *)compat_ptr(arg),
114397 + compat_param,
114398 + sizeof(ioc_compat_fm_pcd_kg_scheme_spc_t)))
114399 + err = E_READ_FAILED;
114400 +
114401 + XX_Free(compat_param);
114402 + }
114403 + else
114404 +#endif
114405 + {
114406 + if (copy_to_user((ioc_fm_pcd_kg_scheme_spc_t *)arg,
114407 + param,
114408 + sizeof(ioc_fm_pcd_kg_scheme_spc_t)))
114409 + err = E_READ_FAILED;
114410 + }
114411 +
114412 + XX_Free(param);
114413 + break;
114414 + }
114415 +
114416 +#if defined(CONFIG_COMPAT)
114417 + case FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT:
114418 +#endif
114419 + case FM_PCD_IOC_KG_SCHEME_DELETE:
114420 + {
114421 + ioc_fm_obj_t id;
114422 +
114423 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114424 +
114425 +#if defined(CONFIG_COMPAT)
114426 + if (compat)
114427 + {
114428 + ioc_compat_fm_obj_t compat_id;
114429 +
114430 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114431 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114432 +
114433 + compat_obj_delete(&compat_id, &id);
114434 + }
114435 + else
114436 +#endif
114437 + {
114438 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114439 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114440 + }
114441 +
114442 + err = FM_PCD_KgSchemeDelete(id.obj);
114443 + break;
114444 + }
114445 +
114446 +#if defined(CONFIG_COMPAT)
114447 + case FM_PCD_IOC_MATCH_TABLE_SET_COMPAT:
114448 +#endif
114449 + case FM_PCD_IOC_MATCH_TABLE_SET:
114450 + {
114451 + ioc_fm_pcd_cc_node_params_t *param;
114452 + uint8_t *keys;
114453 + uint8_t *masks;
114454 + int i,k;
114455 +
114456 + param = (ioc_fm_pcd_cc_node_params_t *) XX_Malloc(
114457 + sizeof(ioc_fm_pcd_cc_node_params_t) +
114458 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114459 + if (!param)
114460 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114461 +
114462 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_params_t) +
114463 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114464 +
114465 + keys = (uint8_t *) (param + 1);
114466 + masks = keys + IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY;
114467 +
114468 +#if defined(CONFIG_COMPAT)
114469 + if (compat)
114470 + {
114471 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
114472 +
114473 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
114474 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
114475 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114476 + if (!compat_param)
114477 + {
114478 + XX_Free(param);
114479 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114480 + }
114481 +
114482 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
114483 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114484 +
114485 + if (copy_from_user(compat_param,
114486 + (ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
114487 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
114488 + {
114489 + XX_Free(compat_param);
114490 + XX_Free(param);
114491 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114492 + }
114493 +
114494 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_US_TO_K);
114495 +
114496 + XX_Free(compat_param);
114497 + }
114498 + else
114499 +#endif
114500 + {
114501 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_params_t *)arg, sizeof(ioc_fm_pcd_cc_node_params_t)))
114502 + {
114503 + XX_Free(param);
114504 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114505 + }
114506 + }
114507 +
114508 + ASSERT_COND(param->keys_params.num_of_keys <= IOC_FM_PCD_MAX_NUM_OF_KEYS);
114509 + ASSERT_COND(param->keys_params.key_size <= IOC_FM_PCD_MAX_SIZE_OF_KEY);
114510 +
114511 + /* support for indexed lookup */
114512 + if( !(param->extract_cc_params.type == e_IOC_FM_PCD_EXTRACT_NON_HDR &&
114513 + param->extract_cc_params.extract_params.extract_non_hdr.src == e_IOC_FM_PCD_EXTRACT_FROM_HASH &&
114514 + param->extract_cc_params.extract_params.extract_non_hdr.action == e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP))
114515 + {
114516 + for (i=0, k=0;
114517 + i < param->keys_params.num_of_keys;
114518 + i++, k += IOC_FM_PCD_MAX_SIZE_OF_KEY)
114519 + {
114520 + if (param->keys_params.key_params[i].p_key &&
114521 + param->keys_params.key_size)
114522 + {
114523 + if (copy_from_user(&keys[k],
114524 + param->keys_params.key_params[i].p_key,
114525 + param->keys_params.key_size))
114526 + {
114527 + XX_Free(param);
114528 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114529 + }
114530 +
114531 + param->keys_params.key_params[i].p_key = &keys[k];
114532 + }
114533 +
114534 + if (param->keys_params.key_params[i].p_mask)
114535 + {
114536 + if (copy_from_user(&masks[k],
114537 + param->keys_params.key_params[i].p_mask,
114538 + param->keys_params.key_size))
114539 + {
114540 + XX_Free(param);
114541 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114542 + }
114543 +
114544 + param->keys_params.key_params[i].p_mask = &masks[k];
114545 + }
114546 + }
114547 + }
114548 +
114549 + param->id = FM_PCD_MatchTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcNodeParams*)param);
114550 +
114551 + if (!param->id) {
114552 + XX_Free(param);
114553 + err = E_INVALID_VALUE;
114554 + /* Since the LLD has no errno-style error reporting,
114555 + we're left here with no other option than to report
114556 + a generic E_INVALID_VALUE */
114557 + break;
114558 + }
114559 +
114560 +#if defined(CONFIG_COMPAT)
114561 + if (compat)
114562 + {
114563 + ioc_compat_fm_pcd_cc_node_params_t *compat_param;
114564 + compat_param = (ioc_compat_fm_pcd_cc_node_params_t *) XX_Malloc(
114565 + sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
114566 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114567 + if (!compat_param)
114568 + {
114569 + XX_Free(param);
114570 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114571 + }
114572 +
114573 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_params_t) +
114574 + 2 * IOC_FM_PCD_MAX_NUM_OF_KEYS * IOC_FM_PCD_MAX_SIZE_OF_KEY);
114575 + compat_copy_fm_pcd_cc_node(compat_param, param, COMPAT_K_TO_US);
114576 +
114577 + if (copy_to_user((ioc_compat_fm_pcd_cc_node_params_t *)compat_ptr(arg),
114578 + compat_param,
114579 + sizeof(ioc_compat_fm_pcd_cc_node_params_t)))
114580 + err = E_READ_FAILED;
114581 +
114582 + XX_Free(compat_param);
114583 + }
114584 + else
114585 +#endif
114586 + {
114587 + if (copy_to_user((ioc_fm_pcd_cc_node_params_t *)arg,
114588 + param,
114589 + sizeof(ioc_fm_pcd_cc_node_params_t)))
114590 + err = E_READ_FAILED;
114591 + }
114592 +
114593 + XX_Free(param);
114594 + break;
114595 + }
114596 +
114597 +#if defined(CONFIG_COMPAT)
114598 + case FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT:
114599 +#endif
114600 + case FM_PCD_IOC_MATCH_TABLE_DELETE:
114601 + {
114602 + ioc_fm_obj_t id;
114603 +
114604 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114605 +
114606 +#if defined(CONFIG_COMPAT)
114607 + if (compat)
114608 + {
114609 + ioc_compat_fm_obj_t compat_id;
114610 +
114611 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114612 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114613 +
114614 + compat_obj_delete(&compat_id, &id);
114615 + }
114616 + else
114617 +#endif
114618 + {
114619 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114620 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114621 + }
114622 +
114623 + err = FM_PCD_MatchTableDelete(id.obj);
114624 + break;
114625 + }
114626 +
114627 +#if defined(CONFIG_COMPAT)
114628 + case FM_PCD_IOC_CC_ROOT_BUILD_COMPAT:
114629 +#endif
114630 + case FM_PCD_IOC_CC_ROOT_BUILD:
114631 + {
114632 + ioc_fm_pcd_cc_tree_params_t *param;
114633 +
114634 + param = (ioc_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_fm_pcd_cc_tree_params_t));
114635 + if (!param)
114636 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114637 +
114638 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_params_t));
114639 +
114640 +#if defined(CONFIG_COMPAT)
114641 + if (compat)
114642 + {
114643 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
114644 +
114645 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(
114646 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
114647 + if (!compat_param)
114648 + {
114649 + XX_Free(param);
114650 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114651 + }
114652 +
114653 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
114654 + if (copy_from_user(compat_param,
114655 + (ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
114656 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
114657 + {
114658 + XX_Free(compat_param);
114659 + XX_Free(param);
114660 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114661 + }
114662 +
114663 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_US_TO_K);
114664 +
114665 + XX_Free(compat_param);
114666 + }
114667 + else
114668 +#endif
114669 + {
114670 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_params_t *)arg,
114671 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
114672 + {
114673 + XX_Free(param);
114674 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114675 + }
114676 + }
114677 +
114678 + param->id = FM_PCD_CcRootBuild(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdCcTreeParams*)param);
114679 +
114680 + if (!param->id) {
114681 + XX_Free(param);
114682 + err = E_INVALID_VALUE;
114683 + /* Since the LLD has no errno-style error reporting,
114684 + we're left here with no other option than to report
114685 + a generic E_INVALID_VALUE */
114686 + break;
114687 + }
114688 +
114689 +#if defined(CONFIG_COMPAT)
114690 + if (compat)
114691 + {
114692 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param;
114693 +
114694 + compat_param = (ioc_compat_fm_pcd_cc_tree_params_t *) XX_Malloc(sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
114695 + if (!compat_param)
114696 + {
114697 + XX_Free(param);
114698 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114699 + }
114700 +
114701 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_params_t));
114702 +
114703 + compat_copy_fm_pcd_cc_tree(compat_param, param, COMPAT_K_TO_US);
114704 +
114705 + if (copy_to_user((ioc_compat_fm_pcd_cc_tree_params_t *)compat_ptr(arg),
114706 + compat_param,
114707 + sizeof(ioc_compat_fm_pcd_cc_tree_params_t)))
114708 + err = E_READ_FAILED;
114709 +
114710 + XX_Free(compat_param);
114711 + }
114712 + else
114713 +#endif
114714 + {
114715 + if (copy_to_user((ioc_fm_pcd_cc_tree_params_t *)arg,
114716 + param,
114717 + sizeof(ioc_fm_pcd_cc_tree_params_t)))
114718 + err = E_READ_FAILED;
114719 + }
114720 +
114721 + XX_Free(param);
114722 + break;
114723 + }
114724 +
114725 +#if defined(CONFIG_COMPAT)
114726 + case FM_PCD_IOC_CC_ROOT_DELETE_COMPAT:
114727 +#endif
114728 + case FM_PCD_IOC_CC_ROOT_DELETE:
114729 + {
114730 + ioc_fm_obj_t id;
114731 +
114732 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114733 +
114734 +#if defined(CONFIG_COMPAT)
114735 + if (compat)
114736 + {
114737 + ioc_compat_fm_obj_t compat_id;
114738 +
114739 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114740 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114741 +
114742 + compat_obj_delete(&compat_id, &id);
114743 + }
114744 + else
114745 +#endif
114746 + {
114747 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114748 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114749 + }
114750 +
114751 + err = FM_PCD_CcRootDelete(id.obj);
114752 + break;
114753 + }
114754 +
114755 +#if defined(CONFIG_COMPAT)
114756 + case FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT:
114757 +#endif
114758 + case FM_PCD_IOC_PLCR_PROFILE_SET:
114759 + {
114760 + ioc_fm_pcd_plcr_profile_params_t *param;
114761 +
114762 + param = (ioc_fm_pcd_plcr_profile_params_t *) XX_Malloc(
114763 + sizeof(ioc_fm_pcd_plcr_profile_params_t));
114764 + if (!param)
114765 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114766 +
114767 + memset(param, 0, sizeof(ioc_fm_pcd_plcr_profile_params_t));
114768 +
114769 +#if defined(CONFIG_COMPAT)
114770 + if (compat)
114771 + {
114772 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
114773 +
114774 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
114775 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
114776 + if (!compat_param)
114777 + {
114778 + XX_Free(param);
114779 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114780 + }
114781 +
114782 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
114783 + if (copy_from_user(compat_param, (
114784 + ioc_compat_fm_pcd_plcr_profile_params_t *)compat_ptr(arg),
114785 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
114786 + {
114787 + XX_Free(compat_param);
114788 + XX_Free(param);
114789 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114790 + }
114791 +
114792 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_US_TO_K);
114793 +
114794 + XX_Free(compat_param);
114795 + }
114796 + else
114797 +#endif
114798 + {
114799 + if (copy_from_user(param, (ioc_fm_pcd_plcr_profile_params_t *)arg,
114800 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
114801 + {
114802 + XX_Free(param);
114803 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114804 + }
114805 + }
114806 +
114807 + if (!param->modify &&
114808 + (((t_FmPcdPlcrProfileParams*)param)->id.newParams.profileType != e_FM_PCD_PLCR_SHARED))
114809 + {
114810 + t_Handle h_Port;
114811 + ioc_fm_pcd_port_params_t *port_params;
114812 +
114813 + port_params = (ioc_fm_pcd_port_params_t*) XX_Malloc(sizeof(ioc_fm_pcd_port_params_t));
114814 + if (!port_params)
114815 + {
114816 + XX_Free(param);
114817 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114818 + }
114819 +
114820 + memset(port_params, 0, sizeof(ioc_fm_pcd_port_params_t));
114821 + if (copy_from_user(port_params, (ioc_fm_pcd_port_params_t*)((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort,
114822 + sizeof(ioc_fm_pcd_port_params_t)))
114823 + {
114824 + XX_Free(port_params);
114825 + XX_Free(param);
114826 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114827 + }
114828 +
114829 + switch(port_params->port_type)
114830 + {
114831 + case (e_IOC_FM_PORT_TYPE_RX):
114832 + if (port_params->port_id < FM_MAX_NUM_OF_1G_RX_PORTS) {
114833 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
114834 + break;
114835 + }
114836 + goto invalid_port_id;
114837 +
114838 + case (e_IOC_FM_PORT_TYPE_RX_10G):
114839 + if (port_params->port_id < FM_MAX_NUM_OF_10G_RX_PORTS) {
114840 +#ifndef CONFIG_FMAN_ARM
114841 + if (IS_T1023_T1024) {
114842 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id].h_Dev;
114843 + } else {
114844 +#else
114845 + {
114846 +#endif
114847 + h_Port = p_LnxWrpFmDev->rxPorts[port_params->port_id + FM_MAX_NUM_OF_1G_RX_PORTS].h_Dev;
114848 + }
114849 + break;
114850 + }
114851 + goto invalid_port_id;
114852 +
114853 + case (e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING):
114854 + if (port_params->port_id && port_params->port_id < FM_MAX_NUM_OF_OH_PORTS) {
114855 + h_Port = p_LnxWrpFmDev->opPorts[port_params->port_id - 1].h_Dev;
114856 + break;
114857 + }
114858 + goto invalid_port_id;
114859 +
114860 + default:
114861 +invalid_port_id:
114862 + XX_Free(port_params);
114863 + XX_Free(param);
114864 + RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
114865 + }
114866 +
114867 + ((t_FmPcdPlcrProfileParams*)param)->id.newParams.h_FmPort = h_Port;
114868 + XX_Free(port_params);
114869 + }
114870 +
114871 + param->id = FM_PCD_PlcrProfileSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdPlcrProfileParams*)param);
114872 +
114873 + if (!param->id) {
114874 + XX_Free(param);
114875 + err = E_INVALID_VALUE;
114876 + /* Since the LLD has no errno-style error reporting,
114877 + we're left here with no other option than to report
114878 + a generic E_INVALID_VALUE */
114879 + break;
114880 + }
114881 +
114882 +#if defined(CONFIG_COMPAT)
114883 + if (compat)
114884 + {
114885 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param;
114886 +
114887 + compat_param = (ioc_compat_fm_pcd_plcr_profile_params_t *) XX_Malloc(
114888 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
114889 + if (!compat_param)
114890 + {
114891 + XX_Free(param);
114892 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114893 + }
114894 +
114895 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_plcr_profile_params_t));
114896 + compat_copy_fm_pcd_plcr_profile(compat_param, param, COMPAT_K_TO_US);
114897 + if (copy_to_user((ioc_compat_fm_pcd_plcr_profile_params_t *) compat_ptr(arg),
114898 + compat_param,
114899 + sizeof(ioc_compat_fm_pcd_plcr_profile_params_t)))
114900 + err = E_READ_FAILED;
114901 +
114902 + XX_Free(compat_param);
114903 + }
114904 + else
114905 +#endif
114906 + {
114907 + if (copy_to_user((ioc_fm_pcd_plcr_profile_params_t *)arg,
114908 + param,
114909 + sizeof(ioc_fm_pcd_plcr_profile_params_t)))
114910 + err = E_READ_FAILED;
114911 + }
114912 +
114913 + XX_Free(param);
114914 + break;
114915 + }
114916 +
114917 +#if defined(CONFIG_COMPAT)
114918 + case FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT:
114919 +#endif
114920 + case FM_PCD_IOC_PLCR_PROFILE_DELETE:
114921 + {
114922 + ioc_fm_obj_t id;
114923 +
114924 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
114925 +
114926 +#if defined(CONFIG_COMPAT)
114927 + if (compat)
114928 + {
114929 + ioc_compat_fm_obj_t compat_id;
114930 +
114931 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
114932 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114933 +
114934 + compat_obj_delete(&compat_id, &id);
114935 + }
114936 + else
114937 +#endif
114938 + {
114939 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
114940 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114941 + }
114942 +
114943 + err = FM_PCD_PlcrProfileDelete(id.obj);
114944 + break;
114945 + }
114946 +
114947 +#if defined(CONFIG_COMPAT)
114948 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT:
114949 +#endif
114950 + case FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE:
114951 + {
114952 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param;
114953 +
114954 + param = (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
114955 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
114956 + if (!param)
114957 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114958 +
114959 + memset(param, 0, sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t));
114960 +
114961 +#if defined(CONFIG_COMPAT)
114962 + if (compat)
114963 + {
114964 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param;
114965 +
114966 + compat_param = (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) XX_Malloc(
114967 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
114968 + if (!compat_param)
114969 + {
114970 + XX_Free(param);
114971 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
114972 + }
114973 +
114974 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t));
114975 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *) compat_ptr(arg),
114976 + sizeof(ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t)))
114977 + {
114978 + XX_Free(compat_param);
114979 + XX_Free(param);
114980 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114981 + }
114982 +
114983 + compat_fm_pcd_cc_tree_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
114984 +
114985 + XX_Free(compat_param);
114986 + }
114987 + else
114988 +#endif
114989 + {
114990 + if (copy_from_user(param, (ioc_fm_pcd_cc_tree_modify_next_engine_params_t *)arg,
114991 + sizeof(ioc_fm_pcd_cc_tree_modify_next_engine_params_t)))
114992 + {
114993 + XX_Free(param);
114994 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
114995 + }
114996 + }
114997 +
114998 + err = FM_PCD_CcRootModifyNextEngine(param->id,
114999 + param->grp_indx,
115000 + param->indx,
115001 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
115002 +
115003 + XX_Free(param);
115004 + break;
115005 + }
115006 +
115007 +#if defined(CONFIG_COMPAT)
115008 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT:
115009 +#endif
115010 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE:
115011 + {
115012 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
115013 +
115014 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
115015 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
115016 + if (!param)
115017 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115018 +
115019 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
115020 +
115021 +#if defined(CONFIG_COMPAT)
115022 + if (compat)
115023 + {
115024 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
115025 +
115026 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
115027 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
115028 + if (!compat_param)
115029 + {
115030 + XX_Free(param);
115031 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115032 + }
115033 +
115034 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
115035 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
115036 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
115037 + {
115038 + XX_Free(compat_param);
115039 + XX_Free(param);
115040 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115041 + }
115042 +
115043 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
115044 +
115045 + XX_Free(compat_param);
115046 + }
115047 + else
115048 +#endif
115049 + {
115050 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *)arg,
115051 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
115052 + {
115053 + XX_Free(param);
115054 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115055 + }
115056 + }
115057 +
115058 + err = FM_PCD_MatchTableModifyNextEngine(param->id,
115059 + param->key_indx,
115060 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
115061 +
115062 + XX_Free(param);
115063 + break;
115064 + }
115065 +
115066 +#if defined(CONFIG_COMPAT)
115067 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT:
115068 +#endif
115069 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE:
115070 + {
115071 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param;
115072 +
115073 + param = (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
115074 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
115075 + if (!param)
115076 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115077 +
115078 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t));
115079 +
115080 +#if defined(CONFIG_COMPAT)
115081 + if (compat)
115082 + {
115083 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param;
115084 +
115085 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) XX_Malloc(
115086 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
115087 + if (!compat_param)
115088 + {
115089 + XX_Free(param);
115090 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115091 + }
115092 +
115093 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t));
115094 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *) compat_ptr(arg),
115095 + sizeof(ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t)))
115096 + {
115097 + XX_Free(compat_param);
115098 + XX_Free(param);
115099 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115100 + }
115101 +
115102 + compat_copy_fm_pcd_cc_node_modify_next_engine(compat_param, param, COMPAT_US_TO_K);
115103 +
115104 + XX_Free(compat_param);
115105 + }
115106 + else
115107 +#endif
115108 + {
115109 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_next_engine_params_t *) arg,
115110 + sizeof(ioc_fm_pcd_cc_node_modify_next_engine_params_t)))
115111 + {
115112 + XX_Free(param);
115113 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115114 + }
115115 + }
115116 +
115117 + err = FM_PCD_MatchTableModifyMissNextEngine(param->id,
115118 + (t_FmPcdCcNextEngineParams*)(&param->cc_next_engine_params));
115119 +
115120 + XX_Free(param);
115121 + break;
115122 + }
115123 +
115124 +#if defined(CONFIG_COMPAT)
115125 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT:
115126 +#endif
115127 + case FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY:
115128 + {
115129 + ioc_fm_pcd_cc_node_remove_key_params_t *param;
115130 +
115131 + param = (ioc_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
115132 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
115133 + if (!param)
115134 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115135 +
115136 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_remove_key_params_t));
115137 +
115138 +#if defined(CONFIG_COMPAT)
115139 + if (compat)
115140 + {
115141 + ioc_compat_fm_pcd_cc_node_remove_key_params_t *compat_param;
115142 +
115143 + compat_param = (ioc_compat_fm_pcd_cc_node_remove_key_params_t *) XX_Malloc(
115144 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
115145 + if (!compat_param)
115146 + {
115147 + XX_Free(param);
115148 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115149 + }
115150 +
115151 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t));
115152 + if (copy_from_user(compat_param,
115153 + (ioc_compat_fm_pcd_cc_node_remove_key_params_t *)compat_ptr(arg),
115154 + sizeof(ioc_compat_fm_pcd_cc_node_remove_key_params_t)))
115155 + {
115156 + XX_Free(compat_param);
115157 + XX_Free(param);
115158 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115159 + }
115160 +
115161 + param->id = compat_ptr(compat_param->id);
115162 + param->key_indx = compat_param->key_indx;
115163 +
115164 + XX_Free(compat_param);
115165 + }
115166 + else
115167 +#endif
115168 + {
115169 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_remove_key_params_t *) arg,
115170 + sizeof(ioc_fm_pcd_cc_node_remove_key_params_t)))
115171 + {
115172 + XX_Free(param);
115173 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115174 + }
115175 + }
115176 +
115177 + err = FM_PCD_MatchTableRemoveKey(param->id, param->key_indx);
115178 +
115179 + XX_Free(param);
115180 + break;
115181 + }
115182 +#if defined(CONFIG_COMPAT)
115183 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT:
115184 +#endif
115185 + case FM_PCD_IOC_MATCH_TABLE_ADD_KEY:
115186 + {
115187 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
115188 +
115189 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
115190 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
115191 + if (!param)
115192 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115193 +
115194 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
115195 +
115196 +#if defined(CONFIG_COMPAT)
115197 + if (compat)
115198 + {
115199 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
115200 +
115201 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
115202 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
115203 + if (!compat_param)
115204 + {
115205 + XX_Free(param);
115206 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115207 + }
115208 +
115209 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
115210 + if (copy_from_user(compat_param,
115211 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
115212 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
115213 + {
115214 + XX_Free(compat_param);
115215 + XX_Free(param);
115216 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115217 + }
115218 +
115219 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
115220 +
115221 + XX_Free(compat_param);
115222 + }
115223 + else
115224 +#endif
115225 + {
115226 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
115227 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
115228 + {
115229 + XX_Free(param);
115230 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115231 + }
115232 + }
115233 +
115234 + if (param->key_size)
115235 + {
115236 + int size = 0;
115237 +
115238 + if (param->key_params.p_key) size += param->key_size;
115239 + if (param->key_params.p_mask) size += param->key_size;
115240 +
115241 + if (size)
115242 + {
115243 + uint8_t *p_tmp;
115244 +
115245 + p_tmp = (uint8_t*) XX_Malloc(size);
115246 + if (!p_tmp)
115247 + {
115248 + XX_Free(param);
115249 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
115250 + }
115251 +
115252 + if (param->key_params.p_key)
115253 + {
115254 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
115255 + {
115256 + XX_Free(p_tmp);
115257 + XX_Free(param);
115258 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115259 + }
115260 +
115261 + param->key_params.p_key = p_tmp;
115262 + }
115263 +
115264 + if (param->key_params.p_mask)
115265 + {
115266 + p_tmp += param->key_size;
115267 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
115268 + {
115269 + XX_Free(p_tmp - param->key_size);
115270 + XX_Free(param);
115271 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115272 + }
115273 +
115274 + param->key_params.p_mask = p_tmp;
115275 + }
115276 + }
115277 + }
115278 +
115279 + err = FM_PCD_MatchTableAddKey(
115280 + param->id,
115281 + param->key_indx,
115282 + param->key_size,
115283 + (t_FmPcdCcKeyParams*)&param->key_params);
115284 +
115285 + if (param->key_params.p_key)
115286 + XX_Free(param->key_params.p_key);
115287 + XX_Free(param);
115288 + break;
115289 + }
115290 +
115291 +#if defined(CONFIG_COMPAT)
115292 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT:
115293 +#endif
115294 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE:
115295 + {
115296 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param;
115297 +
115298 + param = (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
115299 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
115300 + if (!param)
115301 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115302 +
115303 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
115304 +
115305 +#if defined(CONFIG_COMPAT)
115306 + if (compat)
115307 + {
115308 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param;
115309 +
115310 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *) XX_Malloc(
115311 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
115312 + if (!compat_param)
115313 + {
115314 + XX_Free(param);
115315 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115316 + }
115317 +
115318 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t));
115319 + if (copy_from_user(compat_param,
115320 + (ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)compat_ptr(arg),
115321 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
115322 + {
115323 + XX_Free(compat_param);
115324 + XX_Free(param);
115325 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115326 + }
115327 +
115328 + compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(compat_param, param, COMPAT_US_TO_K);
115329 +
115330 + XX_Free(compat_param);
115331 + }
115332 + else
115333 +#endif
115334 + {
115335 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *)arg,
115336 + sizeof(ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t)))
115337 + {
115338 + XX_Free(param);
115339 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115340 + }
115341 + }
115342 +
115343 + err = FM_PCD_MatchTableModifyKeyAndNextEngine(param->id,
115344 + param->key_indx,
115345 + param->key_size,
115346 + (t_FmPcdCcKeyParams*)(&param->key_params));
115347 +
115348 + XX_Free(param);
115349 + break;
115350 + }
115351 +
115352 +
115353 +#if defined(CONFIG_COMPAT)
115354 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT_COMPAT:
115355 +#endif
115356 + case FM_PCD_IOC_MATCH_TABLE_GET_KEY_STAT:
115357 + {
115358 + ioc_fm_pcd_cc_tbl_get_stats_t param;
115359 +
115360 +#if defined(CONFIG_COMPAT)
115361 + if (compat)
115362 + {
115363 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115364 +
115365 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
115366 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115367 + if (!compat_param)
115368 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115369 +
115370 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115371 + if (copy_from_user(compat_param,
115372 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
115373 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
115374 + {
115375 + XX_Free(compat_param);
115376 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115377 + }
115378 +
115379 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
115380 +
115381 + XX_Free(compat_param);
115382 + }
115383 + else
115384 +#endif
115385 + {
115386 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115387 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115388 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115389 + }
115390 +
115391 +
115392 + err = FM_PCD_MatchTableGetKeyStatistics((t_Handle) param.id,
115393 + param.key_index,
115394 + (t_FmPcdCcKeyStatistics *) &param.statistics);
115395 +
115396 +#if defined(CONFIG_COMPAT)
115397 + if (compat)
115398 + {
115399 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115400 +
115401 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
115402 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115403 + if (!compat_param)
115404 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115405 +
115406 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115407 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
115408 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
115409 + compat_param,
115410 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
115411 + XX_Free(compat_param);
115412 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115413 + }
115414 + XX_Free(compat_param);
115415 + }
115416 + else
115417 +#endif
115418 + {
115419 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115420 + &param,
115421 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115422 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115423 + }
115424 +
115425 + break;
115426 + }
115427 +
115428 +
115429 +#if defined(CONFIG_COMPAT)
115430 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT_COMPAT:
115431 +#endif
115432 + case FM_PCD_IOC_MATCH_TABLE_GET_MISS_STAT:
115433 + {
115434 + ioc_fm_pcd_cc_tbl_get_stats_t param;
115435 +
115436 +#if defined(CONFIG_COMPAT)
115437 + if (compat)
115438 + {
115439 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115440 +
115441 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
115442 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115443 + if (!compat_param)
115444 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115445 +
115446 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115447 + if (copy_from_user(compat_param,
115448 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
115449 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
115450 + {
115451 + XX_Free(compat_param);
115452 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115453 + }
115454 +
115455 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
115456 +
115457 + XX_Free(compat_param);
115458 + }
115459 + else
115460 +#endif
115461 + {
115462 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115463 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115464 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115465 + }
115466 +
115467 +
115468 + err = FM_PCD_MatchTableGetMissStatistics((t_Handle) param.id,
115469 + (t_FmPcdCcKeyStatistics *) &param.statistics);
115470 +
115471 +#if defined(CONFIG_COMPAT)
115472 + if (compat)
115473 + {
115474 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115475 +
115476 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
115477 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115478 + if (!compat_param)
115479 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115480 +
115481 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115482 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
115483 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
115484 + compat_param,
115485 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
115486 + XX_Free(compat_param);
115487 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115488 + }
115489 + XX_Free(compat_param);
115490 + }
115491 + else
115492 +#endif
115493 + {
115494 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115495 + &param,
115496 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115497 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115498 + }
115499 +
115500 + break;
115501 + }
115502 +
115503 +
115504 +#if defined(CONFIG_COMPAT)
115505 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT_COMPAT:
115506 +#endif
115507 + case FM_PCD_IOC_HASH_TABLE_GET_MISS_STAT:
115508 + {
115509 + ioc_fm_pcd_cc_tbl_get_stats_t param;
115510 +
115511 +#if defined(CONFIG_COMPAT)
115512 + if (compat)
115513 + {
115514 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115515 +
115516 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t *) XX_Malloc(
115517 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115518 + if (!compat_param)
115519 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115520 +
115521 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115522 + if (copy_from_user(compat_param,
115523 + (ioc_compat_fm_pcd_cc_tbl_get_stats_t *)compat_ptr(arg),
115524 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t)))
115525 + {
115526 + XX_Free(compat_param);
115527 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115528 + }
115529 +
115530 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_US_TO_K);
115531 +
115532 + XX_Free(compat_param);
115533 + }
115534 + else
115535 +#endif
115536 + {
115537 + if (copy_from_user(&param, (ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115538 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115539 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115540 + }
115541 +
115542 +
115543 + err = FM_PCD_HashTableGetMissStatistics((t_Handle) param.id,
115544 + (t_FmPcdCcKeyStatistics *) &param.statistics);
115545 +
115546 +#if defined(CONFIG_COMPAT)
115547 + if (compat)
115548 + {
115549 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param;
115550 +
115551 + compat_param = (ioc_compat_fm_pcd_cc_tbl_get_stats_t*) XX_Malloc(
115552 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115553 + if (!compat_param)
115554 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115555 +
115556 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t));
115557 + compat_copy_fm_pcd_cc_tbl_get_stats(compat_param, &param, COMPAT_K_TO_US);
115558 + if (copy_to_user((ioc_compat_fm_pcd_cc_tbl_get_stats_t*) compat_ptr(arg),
115559 + compat_param,
115560 + sizeof(ioc_compat_fm_pcd_cc_tbl_get_stats_t))){
115561 + XX_Free(compat_param);
115562 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115563 + }
115564 + XX_Free(compat_param);
115565 + }
115566 + else
115567 +#endif
115568 + {
115569 + if (copy_to_user((ioc_fm_pcd_cc_tbl_get_stats_t *)arg,
115570 + &param,
115571 + sizeof(ioc_fm_pcd_cc_tbl_get_stats_t)))
115572 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
115573 + }
115574 +
115575 + break;
115576 + }
115577 +
115578 +#if defined(CONFIG_COMPAT)
115579 + case FM_PCD_IOC_HASH_TABLE_SET_COMPAT:
115580 +#endif
115581 + case FM_PCD_IOC_HASH_TABLE_SET:
115582 + {
115583 + ioc_fm_pcd_hash_table_params_t *param;
115584 +
115585 + param = (ioc_fm_pcd_hash_table_params_t*) XX_Malloc(
115586 + sizeof(ioc_fm_pcd_hash_table_params_t));
115587 + if (!param)
115588 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115589 +
115590 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_params_t));
115591 +
115592 +#if defined(CONFIG_COMPAT)
115593 + if (compat)
115594 + {
115595 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
115596 +
115597 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
115598 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
115599 + if (!compat_param)
115600 + {
115601 + XX_Free(param);
115602 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115603 + }
115604 +
115605 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
115606 + if (copy_from_user(compat_param,
115607 + (ioc_compat_fm_pcd_hash_table_params_t*)compat_ptr(arg),
115608 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
115609 + {
115610 + XX_Free(compat_param);
115611 + XX_Free(param);
115612 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115613 + }
115614 +
115615 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_US_TO_K);
115616 +
115617 + XX_Free(compat_param);
115618 + }
115619 + else
115620 +#endif
115621 + {
115622 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_params_t *)arg,
115623 + sizeof(ioc_fm_pcd_hash_table_params_t)))
115624 + {
115625 + XX_Free(param);
115626 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115627 + }
115628 + }
115629 +
115630 + param->id = FM_PCD_HashTableSet(p_LnxWrpFmDev->h_PcdDev, (t_FmPcdHashTableParams *) param);
115631 +
115632 + if (!param->id)
115633 + {
115634 + XX_Free(param);
115635 + err = E_INVALID_VALUE;
115636 + /* Since the LLD has no errno-style error reporting,
115637 + we're left here with no other option than to report
115638 + a generic E_INVALID_VALUE */
115639 + break;
115640 + }
115641 +
115642 +#if defined(CONFIG_COMPAT)
115643 + if (compat)
115644 + {
115645 + ioc_compat_fm_pcd_hash_table_params_t *compat_param;
115646 +
115647 + compat_param = (ioc_compat_fm_pcd_hash_table_params_t*) XX_Malloc(
115648 + sizeof(ioc_compat_fm_pcd_hash_table_params_t));
115649 + if (!compat_param)
115650 + {
115651 + XX_Free(param);
115652 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115653 + }
115654 +
115655 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_params_t));
115656 + compat_copy_fm_pcd_hash_table(compat_param, param, COMPAT_K_TO_US);
115657 + if (copy_to_user((ioc_compat_fm_pcd_hash_table_params_t*) compat_ptr(arg),
115658 + compat_param,
115659 + sizeof(ioc_compat_fm_pcd_hash_table_params_t)))
115660 + err = E_READ_FAILED;
115661 +
115662 + XX_Free(compat_param);
115663 + }
115664 + else
115665 +#endif
115666 + {
115667 + if (copy_to_user((ioc_fm_pcd_hash_table_params_t *)arg,
115668 + param,
115669 + sizeof(ioc_fm_pcd_hash_table_params_t)))
115670 + err = E_READ_FAILED;
115671 + }
115672 +
115673 + XX_Free(param);
115674 + break;
115675 + }
115676 +
115677 +#if defined(CONFIG_COMPAT)
115678 + case FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT:
115679 +#endif
115680 + case FM_PCD_IOC_HASH_TABLE_DELETE:
115681 + {
115682 + ioc_fm_obj_t id;
115683 +
115684 + memset(&id, 0, sizeof(ioc_fm_obj_t));
115685 +
115686 +#if defined(CONFIG_COMPAT)
115687 + if (compat)
115688 + {
115689 + ioc_compat_fm_obj_t compat_id;
115690 +
115691 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
115692 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115693 +
115694 + id.obj = compat_pcd_id2ptr(compat_id.obj);
115695 + }
115696 + else
115697 +#endif
115698 + {
115699 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
115700 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115701 + }
115702 +
115703 + err = FM_PCD_HashTableDelete(id.obj);
115704 + break;
115705 + }
115706 +
115707 +#if defined(CONFIG_COMPAT)
115708 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY_COMPAT:
115709 +#endif
115710 + case FM_PCD_IOC_HASH_TABLE_ADD_KEY:
115711 + {
115712 + ioc_fm_pcd_hash_table_add_key_params_t *param = NULL;
115713 +
115714 + param = (ioc_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
115715 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
115716 + if (!param)
115717 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115718 +
115719 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_add_key_params_t));
115720 +
115721 +#if defined(CONFIG_COMPAT)
115722 + if (compat)
115723 + {
115724 + ioc_compat_fm_pcd_hash_table_add_key_params_t *compat_param;
115725 +
115726 + compat_param = (ioc_compat_fm_pcd_hash_table_add_key_params_t*) XX_Malloc(
115727 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
115728 + if (!compat_param)
115729 + {
115730 + XX_Free(param);
115731 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115732 + }
115733 +
115734 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t));
115735 + if (copy_from_user(compat_param,
115736 + (ioc_compat_fm_pcd_hash_table_add_key_params_t*) compat_ptr(arg),
115737 + sizeof(ioc_compat_fm_pcd_hash_table_add_key_params_t)))
115738 + {
115739 + XX_Free(compat_param);
115740 + XX_Free(param);
115741 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115742 + }
115743 +
115744 + if (compat_param->key_size)
115745 + {
115746 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
115747 + param->key_size = compat_param->key_size;
115748 +
115749 + compat_copy_fm_pcd_cc_key(&compat_param->key_params, &param->key_params, COMPAT_US_TO_K);
115750 + }
115751 + else
115752 + {
115753 + XX_Free(compat_param);
115754 + XX_Free(param);
115755 + err = E_INVALID_VALUE;
115756 + break;
115757 + }
115758 +
115759 + XX_Free(compat_param);
115760 + }
115761 + else
115762 +#endif
115763 + {
115764 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_add_key_params_t*) arg,
115765 + sizeof(ioc_fm_pcd_hash_table_add_key_params_t)))
115766 + {
115767 + XX_Free(param);
115768 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115769 + }
115770 + }
115771 +
115772 + if (param->key_size)
115773 + {
115774 + int size = 0;
115775 +
115776 + if (param->key_params.p_key) size += param->key_size;
115777 + if (param->key_params.p_mask) size += param->key_size;
115778 +
115779 + if (size)
115780 + {
115781 + uint8_t *p_tmp;
115782 +
115783 + p_tmp = (uint8_t*) XX_Malloc(size);
115784 + if (!p_tmp)
115785 + {
115786 + XX_Free(param);
115787 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
115788 + }
115789 +
115790 + if (param->key_params.p_key)
115791 + {
115792 + if (copy_from_user(p_tmp, param->key_params.p_key, param->key_size))
115793 + {
115794 + XX_Free(p_tmp);
115795 + XX_Free(param);
115796 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115797 + }
115798 +
115799 + param->key_params.p_key = p_tmp;
115800 + }
115801 +
115802 + if (param->key_params.p_mask)
115803 + {
115804 + p_tmp += param->key_size;
115805 + if (copy_from_user(p_tmp, param->key_params.p_mask, param->key_size))
115806 + {
115807 + XX_Free(p_tmp - param->key_size);
115808 + XX_Free(param);
115809 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115810 + }
115811 +
115812 + param->key_params.p_mask = p_tmp;
115813 + }
115814 + }
115815 + }
115816 +
115817 + err = FM_PCD_HashTableAddKey(
115818 + param->p_hash_tbl,
115819 + param->key_size,
115820 + (t_FmPcdCcKeyParams*)&param->key_params);
115821 +
115822 + if (param->key_params.p_key)
115823 + XX_Free(param->key_params.p_key);
115824 + XX_Free(param);
115825 + break;
115826 + }
115827 +
115828 +#if defined(CONFIG_COMPAT)
115829 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY_COMPAT:
115830 +#endif
115831 + case FM_PCD_IOC_HASH_TABLE_REMOVE_KEY:
115832 + {
115833 + ioc_fm_pcd_hash_table_remove_key_params_t *param = NULL;
115834 +
115835 + param = (ioc_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
115836 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
115837 + if (!param)
115838 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115839 +
115840 + memset(param, 0, sizeof(ioc_fm_pcd_hash_table_remove_key_params_t));
115841 +
115842 +#if defined(CONFIG_COMPAT)
115843 + if (compat)
115844 + {
115845 + ioc_compat_fm_pcd_hash_table_remove_key_params_t *compat_param;
115846 +
115847 + compat_param = (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) XX_Malloc(
115848 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
115849 + if (!compat_param)
115850 + {
115851 + XX_Free(param);
115852 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115853 + }
115854 +
115855 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t));
115856 + if (copy_from_user(compat_param,
115857 + (ioc_compat_fm_pcd_hash_table_remove_key_params_t*) compat_ptr(arg),
115858 + sizeof(ioc_compat_fm_pcd_hash_table_remove_key_params_t)))
115859 + {
115860 + XX_Free(compat_param);
115861 + XX_Free(param);
115862 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115863 + }
115864 +
115865 + param->p_hash_tbl = compat_pcd_id2ptr(compat_param->p_hash_tbl);
115866 + param->key_size = compat_param->key_size;
115867 +
115868 + XX_Free(compat_param);
115869 + }
115870 + else
115871 +#endif
115872 + {
115873 + if (copy_from_user(param, (ioc_fm_pcd_hash_table_remove_key_params_t*)arg,
115874 + sizeof(ioc_fm_pcd_hash_table_remove_key_params_t)))
115875 + {
115876 + XX_Free(param);
115877 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115878 + }
115879 + }
115880 +
115881 + if (param->key_size)
115882 + {
115883 + uint8_t *p_key;
115884 +
115885 + p_key = (uint8_t*) XX_Malloc(param->key_size);
115886 + if (!p_key)
115887 + {
115888 + XX_Free(param);
115889 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115890 + }
115891 +
115892 + if (param->p_key && copy_from_user(p_key, param->p_key, param->key_size))
115893 + {
115894 + XX_Free(p_key);
115895 + XX_Free(param);
115896 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115897 + }
115898 + param->p_key = p_key;
115899 + }
115900 +
115901 + err = FM_PCD_HashTableRemoveKey(
115902 + param->p_hash_tbl,
115903 + param->key_size,
115904 + param->p_key);
115905 +
115906 + if (param->p_key)
115907 + XX_Free(param->p_key);
115908 + XX_Free(param);
115909 + break;
115910 + }
115911 +
115912 +#if defined(CONFIG_COMPAT)
115913 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT:
115914 +#endif
115915 + case FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY:
115916 + {
115917 + ioc_fm_pcd_cc_node_modify_key_params_t *param;
115918 +
115919 + param = (ioc_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
115920 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
115921 + if (!param)
115922 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115923 +
115924 + memset(param, 0, sizeof(ioc_fm_pcd_cc_node_modify_key_params_t));
115925 +
115926 +#if defined(CONFIG_COMPAT)
115927 + if (compat)
115928 + {
115929 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param;
115930 +
115931 + compat_param = (ioc_compat_fm_pcd_cc_node_modify_key_params_t *) XX_Malloc(
115932 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
115933 + if (!compat_param)
115934 + {
115935 + XX_Free(param);
115936 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
115937 + }
115938 +
115939 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t));
115940 + if (copy_from_user(compat_param, (ioc_compat_fm_pcd_cc_node_modify_key_params_t *)compat_ptr(arg),
115941 + sizeof(ioc_compat_fm_pcd_cc_node_modify_key_params_t)))
115942 + {
115943 + XX_Free(compat_param);
115944 + XX_Free(param);
115945 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115946 + }
115947 +
115948 + compat_copy_fm_pcd_cc_node_modify_key(compat_param, param, COMPAT_US_TO_K);
115949 +
115950 + XX_Free(compat_param);
115951 + }
115952 + else
115953 +#endif
115954 + {
115955 + if (copy_from_user(param, (ioc_fm_pcd_cc_node_modify_key_params_t *)arg,
115956 + sizeof(ioc_fm_pcd_cc_node_modify_key_params_t)))
115957 + {
115958 + XX_Free(param);
115959 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115960 + }
115961 + }
115962 +
115963 + if (param->key_size)
115964 + {
115965 + int size = 0;
115966 +
115967 + if (param->p_key) size += param->key_size;
115968 + if (param->p_mask) size += param->key_size;
115969 +
115970 + if (size)
115971 + {
115972 + uint8_t *p_tmp;
115973 +
115974 + p_tmp = (uint8_t*) XX_Malloc(size);
115975 + if (!p_tmp)
115976 + {
115977 + XX_Free(param);
115978 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD key/mask"));
115979 + }
115980 +
115981 + if (param->p_key)
115982 + {
115983 + if (copy_from_user(p_tmp, param->p_key, param->key_size))
115984 + {
115985 + XX_Free(p_tmp);
115986 + XX_Free(param);
115987 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
115988 + }
115989 +
115990 + param->p_key = p_tmp;
115991 + }
115992 +
115993 + if (param->p_mask)
115994 + {
115995 + p_tmp += param->key_size;
115996 + if (copy_from_user(p_tmp, param->p_mask, param->key_size))
115997 + {
115998 + XX_Free(p_tmp - param->key_size);
115999 + XX_Free(param);
116000 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116001 + }
116002 +
116003 + param->p_mask = p_tmp;
116004 + }
116005 + }
116006 + }
116007 +
116008 + err = FM_PCD_MatchTableModifyKey(param->id,
116009 + param->key_indx,
116010 + param->key_size,
116011 + param->p_key,
116012 + param->p_mask);
116013 +
116014 + if (param->p_key)
116015 + XX_Free(param->p_key);
116016 + else if (param->p_mask)
116017 + XX_Free(param->p_mask);
116018 + XX_Free(param);
116019 + break;
116020 + }
116021 +
116022 +#if defined(CONFIG_COMPAT)
116023 + case FM_PCD_IOC_MANIP_NODE_SET_COMPAT:
116024 +#endif
116025 + case FM_PCD_IOC_MANIP_NODE_SET:
116026 + {
116027 + ioc_fm_pcd_manip_params_t *param;
116028 + uint8_t *p_data = NULL;
116029 + uint8_t size;
116030 +
116031 + param = (ioc_fm_pcd_manip_params_t *) XX_Malloc(
116032 + sizeof(ioc_fm_pcd_manip_params_t));
116033 +
116034 + if (!param)
116035 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116036 +
116037 + memset(param, 0, sizeof(ioc_fm_pcd_manip_params_t));
116038 +
116039 +#if defined(CONFIG_COMPAT)
116040 + if (compat)
116041 + {
116042 + ioc_compat_fm_pcd_manip_params_t *compat_param;
116043 +
116044 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
116045 + sizeof(ioc_compat_fm_pcd_manip_params_t));
116046 + if (!compat_param)
116047 + {
116048 + XX_Free(param);
116049 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116050 + }
116051 +
116052 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
116053 + if (copy_from_user(compat_param,
116054 + (ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
116055 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
116056 + {
116057 + XX_Free(compat_param);
116058 + XX_Free(param);
116059 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116060 + }
116061 +
116062 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_US_TO_K);
116063 +
116064 + XX_Free(compat_param);
116065 + }
116066 + else
116067 +#endif
116068 + {
116069 + if (copy_from_user(param, (ioc_fm_pcd_manip_params_t *)arg,
116070 + sizeof(ioc_fm_pcd_manip_params_t)))
116071 + {
116072 + XX_Free(param);
116073 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116074 + }
116075 + }
116076 +
116077 + if (param->type == e_IOC_FM_PCD_MANIP_HDR)
116078 + {
116079 + size = param->u.hdr.insrt_params.u.generic.size;
116080 + p_data = (uint8_t *) XX_Malloc(size);
116081 + if (!p_data )
116082 + {
116083 + XX_Free(param);
116084 + RETURN_ERROR(MINOR, E_NO_MEMORY, NO_MSG);
116085 + }
116086 +
116087 + if (param->u.hdr.insrt_params.u.generic.p_data &&
116088 + copy_from_user(p_data,
116089 + param->u.hdr.insrt_params.u.generic.p_data, size))
116090 + {
116091 + XX_Free(p_data);
116092 + XX_Free(param);
116093 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116094 + }
116095 +
116096 + param->u.hdr.insrt_params.u.generic.p_data = p_data;
116097 + }
116098 +
116099 + if (param->id)
116100 + {
116101 + /* Security Hole: the user can pass any piece of garbage
116102 + in 'param->id', and that will go straight through to the LLD,
116103 + no checks being done by the wrapper! */
116104 + err = FM_PCD_ManipNodeReplace(
116105 + (t_Handle) param->id,
116106 + (t_FmPcdManipParams*) param);
116107 + if (err)
116108 + {
116109 + if (p_data)
116110 + XX_Free(p_data);
116111 + XX_Free(param);
116112 + break;
116113 + }
116114 + }
116115 + else
116116 + {
116117 + param->id = FM_PCD_ManipNodeSet(
116118 + p_LnxWrpFmDev->h_PcdDev,
116119 + (t_FmPcdManipParams*) param);
116120 + if (!param->id)
116121 + {
116122 + if (p_data)
116123 + XX_Free(p_data);
116124 + XX_Free(param);
116125 + err = E_INVALID_VALUE;
116126 + /* Since the LLD has no errno-style error reporting,
116127 + we're left here with no other option than to report
116128 + a generic E_INVALID_VALUE */
116129 + break;
116130 + }
116131 + }
116132 +
116133 +#if defined(CONFIG_COMPAT)
116134 + if (compat)
116135 + {
116136 + ioc_compat_fm_pcd_manip_params_t *compat_param;
116137 +
116138 + compat_param = (ioc_compat_fm_pcd_manip_params_t *) XX_Malloc(
116139 + sizeof(ioc_compat_fm_pcd_manip_params_t));
116140 + if (!compat_param)
116141 + {
116142 + if (p_data)
116143 + XX_Free(p_data);
116144 + XX_Free(param);
116145 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116146 + }
116147 +
116148 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_params_t));
116149 +
116150 + compat_fm_pcd_manip_set_node(compat_param, param, COMPAT_K_TO_US);
116151 +
116152 + if (copy_to_user((ioc_compat_fm_pcd_manip_params_t *) compat_ptr(arg),
116153 + compat_param,
116154 + sizeof(ioc_compat_fm_pcd_manip_params_t)))
116155 + err = E_READ_FAILED;
116156 +
116157 + XX_Free(compat_param);
116158 + }
116159 + else
116160 +#endif
116161 + {
116162 + if (copy_to_user((ioc_fm_pcd_manip_params_t *)arg,
116163 + param, sizeof(ioc_fm_pcd_manip_params_t)))
116164 + err = E_READ_FAILED;
116165 + }
116166 +
116167 + if (p_data)
116168 + XX_Free(p_data);
116169 + XX_Free(param);
116170 + break;
116171 + }
116172 +
116173 +#if defined(CONFIG_COMPAT)
116174 + case FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT:
116175 +#endif
116176 + case FM_PCD_IOC_MANIP_NODE_DELETE:
116177 + {
116178 + ioc_fm_obj_t id;
116179 +
116180 + memset(&id, 0, sizeof(ioc_fm_obj_t));
116181 +#if defined(CONFIG_COMPAT)
116182 + if (compat)
116183 + {
116184 + ioc_compat_fm_obj_t compat_id;
116185 +
116186 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
116187 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116188 +
116189 + compat_obj_delete(&compat_id, &id);
116190 + }
116191 + else
116192 +#endif
116193 + {
116194 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
116195 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116196 + }
116197 +
116198 + err = FM_PCD_ManipNodeDelete(id.obj);
116199 + break;
116200 + }
116201 +
116202 +#if defined(CONFIG_COMPAT)
116203 + case FM_PCD_IOC_MANIP_GET_STATS_COMPAT:
116204 +#endif
116205 + case FM_PCD_IOC_MANIP_GET_STATS:
116206 + {
116207 + ioc_fm_pcd_manip_get_stats_t param;
116208 +
116209 +#if defined(CONFIG_COMPAT)
116210 + if (compat)
116211 + {
116212 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
116213 +
116214 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t *) XX_Malloc(
116215 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
116216 + if (!compat_param)
116217 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116218 +
116219 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
116220 + if (copy_from_user(compat_param,
116221 + (ioc_compat_fm_pcd_manip_get_stats_t *)compat_ptr(arg),
116222 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t)))
116223 + {
116224 + XX_Free(compat_param);
116225 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116226 + }
116227 +
116228 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_US_TO_K);
116229 +
116230 + XX_Free(compat_param);
116231 + }
116232 + else
116233 +#endif
116234 + {
116235 + if (copy_from_user(&param, (ioc_fm_pcd_manip_get_stats_t *)arg,
116236 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
116237 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116238 + }
116239 +
116240 + err = FM_PCD_ManipGetStatistics((t_Handle) param.id,
116241 + (t_FmPcdManipStats*) &param.stats);
116242 +
116243 +#if defined(CONFIG_COMPAT)
116244 + if (compat)
116245 + {
116246 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param;
116247 +
116248 + compat_param = (ioc_compat_fm_pcd_manip_get_stats_t*) XX_Malloc(
116249 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
116250 + if (!compat_param)
116251 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116252 +
116253 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_manip_get_stats_t));
116254 + compat_copy_fm_pcd_manip_get_stats(compat_param, &param, COMPAT_K_TO_US);
116255 + if (copy_to_user((ioc_compat_fm_pcd_manip_get_stats_t*) compat_ptr(arg),
116256 + compat_param,
116257 + sizeof(ioc_compat_fm_pcd_manip_get_stats_t))){
116258 + XX_Free(compat_param);
116259 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
116260 + }
116261 + XX_Free(compat_param);
116262 + }
116263 + else
116264 +#endif
116265 + if (copy_to_user((ioc_fm_pcd_manip_get_stats_t *)arg,
116266 + &param,
116267 + sizeof(ioc_fm_pcd_manip_get_stats_t)))
116268 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
116269 +
116270 + break;
116271 + }
116272 +
116273 +#if (DPAA_VERSION >= 11)
116274 +#if defined(CONFIG_COMPAT)
116275 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET_COMPAT:
116276 +#endif
116277 + case FM_PCD_IOC_FRM_REPLIC_GROUP_SET:
116278 + {
116279 + ioc_fm_pcd_frm_replic_group_params_t *param;
116280 +
116281 + param = (ioc_fm_pcd_frm_replic_group_params_t *) XX_Malloc(
116282 + sizeof(ioc_fm_pcd_frm_replic_group_params_t));
116283 + if (!param)
116284 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116285 +
116286 + memset(param, 0, sizeof(ioc_fm_pcd_frm_replic_group_params_t));
116287 +
116288 +#if defined(CONFIG_COMPAT)
116289 + if (compat)
116290 + {
116291 + ioc_compat_fm_pcd_frm_replic_group_params_t
116292 + *compat_param;
116293 +
116294 + compat_param =
116295 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
116296 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
116297 + if (!compat_param)
116298 + {
116299 + XX_Free(param);
116300 + RETURN_ERROR(MINOR, E_NO_MEMORY,
116301 + ("IOCTL FM PCD"));
116302 + }
116303 +
116304 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
116305 + if (copy_from_user(compat_param,
116306 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
116307 + compat_ptr(arg),
116308 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t))) {
116309 + XX_Free(compat_param);
116310 + XX_Free(param);
116311 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
116312 + }
116313 +
116314 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
116315 + param, COMPAT_US_TO_K);
116316 +
116317 + XX_Free(compat_param);
116318 + }
116319 + else
116320 +#endif
116321 + {
116322 + if (copy_from_user(param,
116323 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
116324 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
116325 + {
116326 + XX_Free(param);
116327 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
116328 + }
116329 + }
116330 +
116331 + param->id = FM_PCD_FrmReplicSetGroup(p_LnxWrpFmDev->h_PcdDev,
116332 + (t_FmPcdFrmReplicGroupParams*)param);
116333 +
116334 + if (!param->id) {
116335 + XX_Free(param);
116336 + err = E_INVALID_VALUE;
116337 + /*
116338 + * Since the LLD has no errno-style error reporting,
116339 + * we're left here with no other option than to report
116340 + * a generic E_INVALID_VALUE
116341 + */
116342 + break;
116343 + }
116344 +
116345 +#if defined(CONFIG_COMPAT)
116346 + if (compat)
116347 + {
116348 + ioc_compat_fm_pcd_frm_replic_group_params_t
116349 + *compat_param;
116350 +
116351 + compat_param =
116352 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
116353 + XX_Malloc(sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
116354 + if (!compat_param)
116355 + {
116356 + XX_Free(param);
116357 + RETURN_ERROR(MINOR, E_NO_MEMORY,
116358 + ("IOCTL FM PCD"));
116359 + }
116360 +
116361 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t));
116362 + compat_copy_fm_pcd_frm_replic_group_params(compat_param,
116363 + param, COMPAT_K_TO_US);
116364 + if (copy_to_user(
116365 + (ioc_compat_fm_pcd_frm_replic_group_params_t *)
116366 + compat_ptr(arg),
116367 + compat_param,
116368 + sizeof(ioc_compat_fm_pcd_frm_replic_group_params_t)))
116369 + err = E_WRITE_FAILED;
116370 +
116371 + XX_Free(compat_param);
116372 + }
116373 + else
116374 +#endif
116375 + {
116376 + if (copy_to_user(
116377 + (ioc_fm_pcd_frm_replic_group_params_t *)arg,
116378 + param,
116379 + sizeof(ioc_fm_pcd_frm_replic_group_params_t)))
116380 + err = E_WRITE_FAILED;
116381 + }
116382 +
116383 + XX_Free(param);
116384 + break;
116385 + }
116386 + break;
116387 +
116388 +#if defined(CONFIG_COMPAT)
116389 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT:
116390 +#endif
116391 + case FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE:
116392 + {
116393 + ioc_fm_obj_t id;
116394 +
116395 + memset(&id, 0, sizeof(ioc_fm_obj_t));
116396 +#if defined(CONFIG_COMPAT)
116397 + if (compat)
116398 + {
116399 + ioc_compat_fm_obj_t compat_id;
116400 +
116401 + if (copy_from_user(&compat_id,
116402 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
116403 + sizeof(ioc_compat_fm_obj_t)))
116404 + break;
116405 + compat_obj_delete(&compat_id, &id);
116406 + }
116407 + else
116408 +#endif
116409 + {
116410 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
116411 + sizeof(ioc_fm_obj_t)))
116412 + break;
116413 + }
116414 +
116415 + return FM_PCD_FrmReplicDeleteGroup(id.obj);
116416 + }
116417 + break;
116418 +
116419 +#if defined(CONFIG_COMPAT)
116420 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD_COMPAT:
116421 +#endif
116422 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_ADD:
116423 + {
116424 + ioc_fm_pcd_frm_replic_member_params_t param;
116425 +
116426 +#if defined(CONFIG_COMPAT)
116427 + if (compat)
116428 + {
116429 + ioc_compat_fm_pcd_frm_replic_member_params_t compat_param;
116430 +
116431 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116432 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116433 +
116434 + compat_copy_fm_pcd_frm_replic_member_params(&compat_param, &param, COMPAT_US_TO_K);
116435 + }
116436 + else
116437 +#endif
116438 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116439 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116440 +
116441 + return FM_PCD_FrmReplicAddMember(param.member.h_replic_group,
116442 + param.member.member_index,
116443 + (t_FmPcdCcNextEngineParams*)&param.next_engine_params);
116444 + }
116445 + break;
116446 +
116447 +#if defined(CONFIG_COMPAT)
116448 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE_COMPAT:
116449 +#endif
116450 + case FM_PCD_IOC_FRM_REPLIC_MEMBER_REMOVE:
116451 + {
116452 + ioc_fm_pcd_frm_replic_member_t param;
116453 +
116454 +#if defined(CONFIG_COMPAT)
116455 + if (compat)
116456 + {
116457 + ioc_compat_fm_pcd_frm_replic_member_t compat_param;
116458 +
116459 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116460 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116461 +
116462 + compat_copy_fm_pcd_frm_replic_member(&compat_param, &param, COMPAT_US_TO_K);
116463 + }
116464 + else
116465 +#endif
116466 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116467 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116468 +
116469 + return FM_PCD_FrmReplicRemoveMember(param.h_replic_group, param.member_index);
116470 + }
116471 + break;
116472 +
116473 +#if defined(CONFIG_COMPAT)
116474 + case FM_IOC_VSP_CONFIG_COMPAT:
116475 +#endif
116476 + case FM_IOC_VSP_CONFIG:
116477 + {
116478 + ioc_fm_vsp_params_t param;
116479 +
116480 +#if defined(CONFIG_COMPAT)
116481 + if (compat)
116482 + {
116483 + ioc_compat_fm_vsp_params_t compat_param;
116484 +
116485 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116486 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116487 +
116488 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_US_TO_K);
116489 + }
116490 + else
116491 +#endif
116492 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116493 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116494 + {
116495 + uint8_t portId = param.port_params.port_id;
116496 + param.liodn_offset =
116497 + p_LnxWrpFmDev->rxPorts[portId].settings.param.specificParams.rxParams.liodnOffset;
116498 + }
116499 + param.p_fm = p_LnxWrpFmDev->h_Dev;
116500 + param.id = FM_VSP_Config((t_FmVspParams *)&param);
116501 +
116502 +#if defined(CONFIG_COMPAT)
116503 + if (compat)
116504 + {
116505 + ioc_compat_fm_vsp_params_t compat_param;
116506 +
116507 + memset(&compat_param, 0, sizeof(compat_param));
116508 + compat_copy_fm_vsp_params(&compat_param, &param, COMPAT_K_TO_US);
116509 +
116510 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
116511 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116512 + }
116513 + else
116514 +#endif
116515 + if (copy_to_user((void *)arg, &param, sizeof(param)))
116516 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116517 + break;
116518 + }
116519 +
116520 +#if defined(CONFIG_COMPAT)
116521 + case FM_IOC_VSP_INIT_COMPAT:
116522 +#endif
116523 + case FM_IOC_VSP_INIT:
116524 + {
116525 + ioc_fm_obj_t id;
116526 +
116527 + memset(&id, 0, sizeof(ioc_fm_obj_t));
116528 +#if defined(CONFIG_COMPAT)
116529 + if (compat)
116530 + {
116531 + ioc_compat_fm_obj_t compat_id;
116532 +
116533 + if (copy_from_user(&compat_id,
116534 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
116535 + sizeof(ioc_compat_fm_obj_t)))
116536 + break;
116537 + id.obj = compat_pcd_id2ptr(compat_id.obj);
116538 + }
116539 + else
116540 +#endif
116541 + {
116542 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
116543 + sizeof(ioc_fm_obj_t)))
116544 + break;
116545 + }
116546 +
116547 + return FM_VSP_Init(id.obj);
116548 + }
116549 +
116550 +#if defined(CONFIG_COMPAT)
116551 + case FM_IOC_VSP_FREE_COMPAT:
116552 +#endif
116553 + case FM_IOC_VSP_FREE:
116554 + {
116555 + ioc_fm_obj_t id;
116556 +
116557 + memset(&id, 0, sizeof(ioc_fm_obj_t));
116558 +#if defined(CONFIG_COMPAT)
116559 + if (compat)
116560 + {
116561 + ioc_compat_fm_obj_t compat_id;
116562 +
116563 + if (copy_from_user(&compat_id,
116564 + (ioc_compat_fm_obj_t *) compat_ptr(arg),
116565 + sizeof(ioc_compat_fm_obj_t)))
116566 + break;
116567 + compat_obj_delete(&compat_id, &id);
116568 + }
116569 + else
116570 +#endif
116571 + {
116572 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg,
116573 + sizeof(ioc_fm_obj_t)))
116574 + break;
116575 + }
116576 +
116577 + return FM_VSP_Free(id.obj);
116578 + }
116579 +
116580 +#if defined(CONFIG_COMPAT)
116581 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION_COMPAT:
116582 +#endif
116583 + case FM_IOC_VSP_CONFIG_POOL_DEPLETION:
116584 + {
116585 + ioc_fm_buf_pool_depletion_params_t param;
116586 +
116587 +#if defined(CONFIG_COMPAT)
116588 + if (compat)
116589 + {
116590 + ioc_compat_fm_buf_pool_depletion_params_t compat_param;
116591 +
116592 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116593 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116594 +
116595 + compat_copy_fm_buf_pool_depletion_params(&compat_param, &param, COMPAT_US_TO_K);
116596 + }
116597 + else
116598 +#endif
116599 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116600 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116601 +
116602 + if (FM_VSP_ConfigPoolDepletion(param.p_fm_vsp,
116603 + (t_FmBufPoolDepletion *)&param.fm_buf_pool_depletion))
116604 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116605 +
116606 + break;
116607 + }
116608 +
116609 +
116610 +#if defined(CONFIG_COMPAT)
116611 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT_COMPAT:
116612 +#endif
116613 + case FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT:
116614 + {
116615 + ioc_fm_buffer_prefix_content_params_t param;
116616 +
116617 +#if defined(CONFIG_COMPAT)
116618 + if (compat)
116619 + {
116620 + ioc_compat_fm_buffer_prefix_content_params_t compat_param;
116621 +
116622 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116623 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116624 +
116625 + compat_copy_fm_buffer_prefix_content_params(&compat_param, &param, COMPAT_US_TO_K);
116626 + }
116627 + else
116628 +#endif
116629 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116630 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116631 +
116632 + if (FM_VSP_ConfigBufferPrefixContent(param.p_fm_vsp,
116633 + (t_FmBufferPrefixContent *)&param.fm_buffer_prefix_content))
116634 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116635 +
116636 + break;
116637 + }
116638 +
116639 +#if defined(CONFIG_COMPAT)
116640 + case FM_IOC_VSP_CONFIG_NO_SG_COMPAT:
116641 +#endif
116642 + case FM_IOC_VSP_CONFIG_NO_SG:
116643 + {
116644 + ioc_fm_vsp_config_no_sg_params_t param;
116645 +
116646 +#if defined(CONFIG_COMPAT)
116647 + if (compat)
116648 + {
116649 + ioc_compat_fm_vsp_config_no_sg_params_t compat_param;
116650 +
116651 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116652 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116653 +
116654 + compat_copy_fm_vsp_config_no_sg_params(&compat_param, &param, COMPAT_US_TO_K);
116655 + }
116656 + else
116657 +#endif
116658 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116659 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116660 +
116661 + if (FM_VSP_ConfigNoScatherGather(param.p_fm_vsp, param.no_sg))
116662 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116663 +
116664 + break;
116665 + }
116666 +
116667 +#if defined(CONFIG_COMPAT)
116668 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT_COMPAT:
116669 +#endif
116670 + case FM_IOC_VSP_GET_BUFFER_PRS_RESULT:
116671 + {
116672 + ioc_fm_vsp_prs_result_params_t param;
116673 +
116674 +#if defined(CONFIG_COMPAT)
116675 + if (compat)
116676 + {
116677 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
116678 +
116679 + if (copy_from_user(&compat_param, compat_ptr(arg), sizeof(compat_param)))
116680 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116681 +
116682 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_US_TO_K);
116683 + }
116684 + else
116685 +#endif
116686 + if (copy_from_user(&param, (void *)arg, sizeof(param)))
116687 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116688 +
116689 + /* this call just adds the parse results offset to p_data */
116690 + param.p_data = FM_VSP_GetBufferPrsResult(param.p_fm_vsp, param.p_data);
116691 +
116692 + if (!param.p_data)
116693 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116694 +
116695 +#if defined(CONFIG_COMPAT)
116696 + if (compat)
116697 + {
116698 + ioc_compat_fm_vsp_prs_result_params_t compat_param;
116699 +
116700 + memset(&compat_param, 0, sizeof(compat_param));
116701 + compat_copy_fm_vsp_prs_result_params(&compat_param, &param, COMPAT_K_TO_US);
116702 +
116703 + if (copy_to_user(compat_ptr(arg), &compat_param, sizeof(compat_param)))
116704 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116705 + }
116706 + else
116707 +#endif
116708 + if (copy_to_user((void *)arg, &param, sizeof(param)))
116709 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116710 +
116711 + break;
116712 + }
116713 +#endif /* (DPAA_VERSION >= 11) */
116714 +
116715 +#ifdef FM_CAPWAP_SUPPORT
116716 +#warning "feature not supported!"
116717 +#if defined(CONFIG_COMPAT)
116718 + case FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT:
116719 +#endif
116720 + case FM_PCD_IOC_STATISTICS_SET_NODE:
116721 + {
116722 +/* ioc_fm_pcd_stats_params_t param;
116723 + ...
116724 + param->id = FM_PCD_StatisticsSetNode(p_LnxWrpFmDev->h_PcdDev,
116725 + (t_FmPcdStatsParams *)&param);
116726 +*/
116727 + err = E_NOT_SUPPORTED;
116728 + break;
116729 + }
116730 +#endif /* FM_CAPWAP_SUPPORT */
116731 +
116732 + default:
116733 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
116734 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr: %d.\n",
116735 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
116736 + }
116737 +
116738 + if (err)
116739 + RETURN_ERROR(MINOR, err, ("IOCTL FM PCD"));
116740 +
116741 + return E_OK;
116742 +}
116743 +
116744 +void FM_Get_Api_Version(ioc_fm_api_version_t *p_version)
116745 +{
116746 + p_version->version.major = FMD_API_VERSION_MAJOR;
116747 + p_version->version.minor = FMD_API_VERSION_MINOR;
116748 + p_version->version.respin = FMD_API_VERSION_RESPIN;
116749 + p_version->version.reserved = 0;
116750 +}
116751 +
116752 +t_Error LnxwrpFmIOCTL(t_LnxWrpFmDev *p_LnxWrpFmDev, unsigned int cmd, unsigned long arg, bool compat)
116753 +{
116754 + t_Error err = E_OK;
116755 +
116756 + switch (cmd)
116757 + {
116758 + case FM_IOC_SET_PORTS_BANDWIDTH:
116759 + {
116760 + ioc_fm_port_bandwidth_params *param;
116761 +
116762 + param = (ioc_fm_port_bandwidth_params*) XX_Malloc(sizeof(ioc_fm_port_bandwidth_params));
116763 + if (!param)
116764 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116765 +
116766 + memset(param, 0, sizeof(ioc_fm_port_bandwidth_params));
116767 +
116768 +#if defined(CONFIG_COMPAT)
116769 + if (compat)
116770 + {
116771 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)compat_ptr(arg), sizeof(ioc_fm_port_bandwidth_params)))
116772 + {
116773 + XX_Free(param);
116774 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116775 + }
116776 + }
116777 + else
116778 +#endif
116779 + {
116780 + if (copy_from_user(param, (ioc_fm_port_bandwidth_params*)arg, sizeof(ioc_fm_port_bandwidth_params)))
116781 + {
116782 + XX_Free(param);
116783 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116784 + }
116785 + }
116786 +
116787 + err = FM_SetPortsBandwidth(p_LnxWrpFmDev->h_Dev, (t_FmPortsBandwidthParams*) param);
116788 +
116789 + XX_Free(param);
116790 + break;
116791 + }
116792 +
116793 + case FM_IOC_GET_REVISION:
116794 + {
116795 + ioc_fm_revision_info_t *param;
116796 +
116797 + param = (ioc_fm_revision_info_t *) XX_Malloc(sizeof(ioc_fm_revision_info_t));
116798 + if (!param)
116799 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116800 +
116801 + FM_GetRevision(p_LnxWrpFmDev->h_Dev, (t_FmRevisionInfo*)param);
116802 + /* This one never returns anything other than E_OK */
116803 +
116804 +#if defined(CONFIG_COMPAT)
116805 + if (compat)
116806 + {
116807 + if (copy_to_user((ioc_fm_revision_info_t *)compat_ptr(arg),
116808 + param,
116809 + sizeof(ioc_fm_revision_info_t))){
116810 + XX_Free(param);
116811 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
116812 + }
116813 + }
116814 + else
116815 +#endif
116816 + {
116817 + if (copy_to_user((ioc_fm_revision_info_t *)arg,
116818 + param,
116819 + sizeof(ioc_fm_revision_info_t))){
116820 + XX_Free(param);
116821 + RETURN_ERROR(MINOR, E_READ_FAILED, NO_MSG);
116822 + }
116823 + }
116824 + XX_Free(param);
116825 + break;
116826 + }
116827 +
116828 + case FM_IOC_SET_COUNTER:
116829 + {
116830 + ioc_fm_counters_params_t *param;
116831 +
116832 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
116833 + if (!param)
116834 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116835 +
116836 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
116837 +
116838 +#if defined(CONFIG_COMPAT)
116839 + if (compat)
116840 + {
116841 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
116842 + {
116843 + XX_Free(param);
116844 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116845 + }
116846 + }
116847 + else
116848 +#endif
116849 + {
116850 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
116851 + {
116852 + XX_Free(param);
116853 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116854 + }
116855 + }
116856 +
116857 + err = FM_ModifyCounter(p_LnxWrpFmDev->h_Dev, param->cnt, param->val);
116858 +
116859 + XX_Free(param);
116860 + break;
116861 + }
116862 +
116863 + case FM_IOC_GET_COUNTER:
116864 + {
116865 + ioc_fm_counters_params_t *param;
116866 +
116867 + param = (ioc_fm_counters_params_t *) XX_Malloc(sizeof(ioc_fm_counters_params_t));
116868 + if (!param)
116869 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PCD"));
116870 +
116871 + memset(param, 0, sizeof(ioc_fm_counters_params_t));
116872 +
116873 +#if defined(CONFIG_COMPAT)
116874 + if (compat)
116875 + {
116876 + if (copy_from_user(param, (ioc_fm_counters_params_t *)compat_ptr(arg), sizeof(ioc_fm_counters_params_t)))
116877 + {
116878 + XX_Free(param);
116879 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116880 + }
116881 + }
116882 + else
116883 +#endif
116884 + {
116885 + if (copy_from_user(param, (ioc_fm_counters_params_t *)arg, sizeof(ioc_fm_counters_params_t)))
116886 + {
116887 + XX_Free(param);
116888 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116889 + }
116890 + }
116891 +
116892 + param->val = FM_GetCounter(p_LnxWrpFmDev->h_Dev, param->cnt);
116893 +
116894 +#if defined(CONFIG_COMPAT)
116895 + if (compat)
116896 + {
116897 + if (copy_to_user((ioc_fm_counters_params_t *)compat_ptr(arg), param, sizeof(ioc_fm_counters_params_t)))
116898 + err = E_READ_FAILED;
116899 + }
116900 + else
116901 +#endif
116902 + {
116903 + if (copy_to_user((ioc_fm_counters_params_t *)arg, param, sizeof(ioc_fm_counters_params_t)))
116904 + err = E_READ_FAILED;
116905 + }
116906 +
116907 + XX_Free(param);
116908 + break;
116909 + }
116910 +
116911 + case FM_IOC_FORCE_INTR:
116912 + {
116913 + ioc_fm_exceptions param;
116914 +
116915 +#if defined(CONFIG_COMPAT)
116916 + if (compat)
116917 + {
116918 + if (get_user(param, (ioc_fm_exceptions*) compat_ptr(arg)))
116919 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116920 + }
116921 + else
116922 +#endif
116923 + {
116924 + if (get_user(param, (ioc_fm_exceptions*)arg))
116925 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116926 + }
116927 +
116928 + err = FM_ForceIntr(p_LnxWrpFmDev->h_Dev, (e_FmExceptions)param);
116929 + break;
116930 + }
116931 +
116932 + case FM_IOC_GET_API_VERSION:
116933 + {
116934 + ioc_fm_api_version_t version;
116935 +
116936 + FM_Get_Api_Version(&version);
116937 +
116938 +#if defined(CONFIG_COMPAT)
116939 + if (compat)
116940 + {
116941 + if (copy_to_user(
116942 + (ioc_fm_api_version_t *)compat_ptr(arg),
116943 + &version, sizeof(version)))
116944 + err = E_READ_FAILED;
116945 + }
116946 + else
116947 +#endif
116948 + {
116949 + if (copy_to_user((ioc_fm_api_version_t *)arg,
116950 + &version, sizeof(version)))
116951 + err = E_READ_FAILED;
116952 + }
116953 + }
116954 + break;
116955 +
116956 + case FM_IOC_CTRL_MON_START:
116957 + {
116958 + FM_CtrlMonStart(p_LnxWrpFmDev->h_Dev);
116959 + }
116960 + break;
116961 +
116962 + case FM_IOC_CTRL_MON_STOP:
116963 + {
116964 + FM_CtrlMonStop(p_LnxWrpFmDev->h_Dev);
116965 + }
116966 + break;
116967 +
116968 +#if defined(CONFIG_COMPAT)
116969 + case FM_IOC_CTRL_MON_GET_COUNTERS_COMPAT:
116970 +#endif
116971 + case FM_IOC_CTRL_MON_GET_COUNTERS:
116972 + {
116973 + ioc_fm_ctrl_mon_counters_params_t param;
116974 + t_FmCtrlMon mon;
116975 +
116976 +#if defined(CONFIG_COMPAT)
116977 + ioc_compat_fm_ctrl_mon_counters_params_t compat_param;
116978 +
116979 + if (compat)
116980 + {
116981 + if (copy_from_user(&compat_param, (void *)compat_ptr(arg),
116982 + sizeof(compat_param)))
116983 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116984 +
116985 + param.fm_ctrl_index = compat_param.fm_ctrl_index;
116986 + param.p_mon = (fm_ctrl_mon_t *)compat_ptr(compat_param.p_mon);
116987 + }
116988 + else
116989 +#endif
116990 + {
116991 + if (copy_from_user(&param, (void *)arg, sizeof(ioc_fm_ctrl_mon_counters_params_t)))
116992 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116993 + }
116994 +
116995 + if (FM_CtrlMonGetCounters(p_LnxWrpFmDev->h_Dev, param.fm_ctrl_index, &mon))
116996 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
116997 +
116998 + if (copy_to_user(param.p_mon, &mon, sizeof(t_FmCtrlMon)))
116999 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117000 + }
117001 + break;
117002 +
117003 + default:
117004 + return LnxwrpFmPcdIOCTL(p_LnxWrpFmDev, cmd, arg, compat);
117005 + }
117006 +
117007 + if (err)
117008 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM"));
117009 +
117010 + return E_OK;
117011 +}
117012 +
117013 +t_Error LnxwrpFmPortIOCTL(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev, unsigned int cmd, unsigned long arg, bool compat)
117014 +{
117015 + t_Error err = E_OK;
117016 +
117017 + _fm_ioctl_dbg("cmd:0x%08x(type:0x%02x, nr:%u).\n",
117018 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd) - 70);
117019 +
117020 + switch (cmd)
117021 + {
117022 + case FM_PORT_IOC_DISABLE:
117023 + FM_PORT_Disable(p_LnxWrpFmPortDev->h_Dev);
117024 + /* deliberately ignoring error codes here */
117025 + return E_OK;
117026 +
117027 + case FM_PORT_IOC_ENABLE:
117028 + FM_PORT_Enable(p_LnxWrpFmPortDev->h_Dev);
117029 + /* deliberately ignoring error codes here */
117030 + return E_OK;
117031 +
117032 + case FM_PORT_IOC_SET_ERRORS_ROUTE:
117033 + {
117034 + ioc_fm_port_frame_err_select_t errs;
117035 +
117036 +#if defined(CONFIG_COMPAT)
117037 + if (compat)
117038 + {
117039 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)compat_ptr(arg)))
117040 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117041 + }
117042 + else
117043 +#endif
117044 + {
117045 + if (get_user(errs, (ioc_fm_port_frame_err_select_t*)arg))
117046 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117047 + }
117048 +
117049 + err = FM_PORT_SetErrorsRoute(p_LnxWrpFmPortDev->h_Dev, (fmPortFrameErrSelect_t)errs);
117050 + break;
117051 + }
117052 +
117053 + case FM_PORT_IOC_SET_RATE_LIMIT:
117054 + {
117055 + ioc_fm_port_rate_limit_t *param;
117056 +
117057 + param = (ioc_fm_port_rate_limit_t *) XX_Malloc(sizeof(ioc_fm_port_rate_limit_t));
117058 + if (!param)
117059 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117060 +
117061 + memset(param, 0, sizeof(ioc_fm_port_rate_limit_t));
117062 +
117063 +#if defined(CONFIG_COMPAT)
117064 + if (compat)
117065 + {
117066 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)compat_ptr(arg), sizeof(ioc_fm_port_rate_limit_t)))
117067 + {
117068 + XX_Free(param);
117069 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117070 + }
117071 + }
117072 + else
117073 +#endif
117074 + {
117075 + if (copy_from_user(param, (ioc_fm_port_rate_limit_t *)arg, sizeof(ioc_fm_port_rate_limit_t)))
117076 + {
117077 + XX_Free(param);
117078 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117079 + }
117080 + }
117081 +
117082 + err = FM_PORT_SetRateLimit(p_LnxWrpFmPortDev->h_Dev, (t_FmPortRateLimit *)param);
117083 +
117084 + XX_Free(param);
117085 + break;
117086 + }
117087 +
117088 + case FM_PORT_IOC_REMOVE_RATE_LIMIT:
117089 + FM_PORT_DeleteRateLimit(p_LnxWrpFmPortDev->h_Dev);
117090 + /* deliberately ignoring error codes here */
117091 + return E_OK;
117092 +
117093 + case FM_PORT_IOC_ALLOC_PCD_FQIDS:
117094 + {
117095 + ioc_fm_port_pcd_fqids_params_t *param;
117096 +
117097 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cba)
117098 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
117099 +
117100 + param = (ioc_fm_port_pcd_fqids_params_t *) XX_Malloc(sizeof(ioc_fm_port_pcd_fqids_params_t));
117101 + if (!param)
117102 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117103 +
117104 + memset(param, 0, sizeof(ioc_fm_port_pcd_fqids_params_t));
117105 +
117106 +#if defined(CONFIG_COMPAT)
117107 + if (compat)
117108 + {
117109 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
117110 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
117111 + {
117112 + XX_Free(param);
117113 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117114 + }
117115 + }
117116 + else
117117 +#endif
117118 + {
117119 + if (copy_from_user(param, (ioc_fm_port_pcd_fqids_params_t *)arg,
117120 + sizeof(ioc_fm_port_pcd_fqids_params_t)))
117121 + {
117122 + XX_Free(param);
117123 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117124 + }
117125 + }
117126 +
117127 + if (p_LnxWrpFmPortDev->pcd_owner_params.cba(p_LnxWrpFmPortDev->pcd_owner_params.dev,
117128 + param->num_fqids,
117129 + param->alignment,
117130 + &param->base_fqid))
117131 + {
117132 + XX_Free(param);
117133 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("can't allocate fqids for PCD!!!"));
117134 + }
117135 +
117136 +#if defined(CONFIG_COMPAT)
117137 + if (compat)
117138 + {
117139 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)compat_ptr(arg),
117140 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
117141 + err = E_READ_FAILED;
117142 + }
117143 + else
117144 +#endif
117145 + {
117146 + if (copy_to_user((ioc_fm_port_pcd_fqids_params_t *)arg,
117147 + param, sizeof(ioc_fm_port_pcd_fqids_params_t)))
117148 + err = E_READ_FAILED;
117149 + }
117150 +
117151 + XX_Free(param);
117152 + break;
117153 + }
117154 +
117155 + case FM_PORT_IOC_FREE_PCD_FQIDS:
117156 + {
117157 + uint32_t base_fqid;
117158 +
117159 + if (!p_LnxWrpFmPortDev->pcd_owner_params.cbf)
117160 + RETURN_ERROR(MINOR, E_INVALID_STATE, ("No one to listen on this PCD!!!"));
117161 +
117162 +#if defined(CONFIG_COMPAT)
117163 + if (compat)
117164 + {
117165 + if (get_user(base_fqid, (uint32_t*) compat_ptr(arg)))
117166 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117167 + }
117168 + else
117169 +#endif
117170 + {
117171 + if (get_user(base_fqid, (uint32_t*)arg))
117172 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117173 + }
117174 +
117175 + if (p_LnxWrpFmPortDev->pcd_owner_params.cbf(p_LnxWrpFmPortDev->pcd_owner_params.dev, base_fqid))
117176 + err = E_WRITE_FAILED;
117177 +
117178 + break;
117179 + }
117180 +
117181 +#if defined(CONFIG_COMPAT)
117182 + case FM_PORT_IOC_SET_PCD_COMPAT:
117183 +#endif
117184 + case FM_PORT_IOC_SET_PCD:
117185 + {
117186 + ioc_fm_port_pcd_params_t *port_pcd_params;
117187 + ioc_fm_port_pcd_prs_params_t *port_pcd_prs_params;
117188 + ioc_fm_port_pcd_cc_params_t *port_pcd_cc_params;
117189 + ioc_fm_port_pcd_kg_params_t *port_pcd_kg_params;
117190 + ioc_fm_port_pcd_plcr_params_t *port_pcd_plcr_params;
117191 +
117192 + port_pcd_params = (ioc_fm_port_pcd_params_t *) XX_Malloc(
117193 + sizeof(ioc_fm_port_pcd_params_t) +
117194 + sizeof(ioc_fm_port_pcd_prs_params_t) +
117195 + sizeof(ioc_fm_port_pcd_cc_params_t) +
117196 + sizeof(ioc_fm_port_pcd_kg_params_t) +
117197 + sizeof(ioc_fm_port_pcd_plcr_params_t));
117198 + if (!port_pcd_params)
117199 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117200 +
117201 + memset(port_pcd_params, 0,
117202 + sizeof(ioc_fm_port_pcd_params_t) +
117203 + sizeof(ioc_fm_port_pcd_prs_params_t) +
117204 + sizeof(ioc_fm_port_pcd_cc_params_t) +
117205 + sizeof(ioc_fm_port_pcd_kg_params_t) +
117206 + sizeof(ioc_fm_port_pcd_plcr_params_t));
117207 +
117208 + port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (port_pcd_params + 1);
117209 + port_pcd_cc_params = (ioc_fm_port_pcd_cc_params_t *) (port_pcd_prs_params + 1);
117210 + port_pcd_kg_params = (ioc_fm_port_pcd_kg_params_t *) (port_pcd_cc_params + 1);
117211 + port_pcd_plcr_params = (ioc_fm_port_pcd_plcr_params_t *) (port_pcd_kg_params + 1);
117212 +
117213 +#if defined(CONFIG_COMPAT)
117214 + if (compat)
117215 + {
117216 + ioc_compat_fm_port_pcd_params_t *compat_port_pcd_params;
117217 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
117218 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
117219 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
117220 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
117221 +
117222 + compat_port_pcd_params = (ioc_compat_fm_port_pcd_params_t *) XX_Malloc(
117223 + sizeof(ioc_compat_fm_port_pcd_params_t) +
117224 + sizeof(ioc_fm_port_pcd_prs_params_t) +
117225 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
117226 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
117227 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
117228 + if (!compat_port_pcd_params)
117229 + {
117230 + XX_Free(port_pcd_params);
117231 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117232 + }
117233 +
117234 + memset(compat_port_pcd_params, 0,
117235 + sizeof(ioc_compat_fm_port_pcd_params_t) +
117236 + sizeof(ioc_fm_port_pcd_prs_params_t) +
117237 + sizeof(ioc_compat_fm_port_pcd_cc_params_t) +
117238 + sizeof(ioc_compat_fm_port_pcd_kg_params_t) +
117239 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t));
117240 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_port_pcd_params + 1);
117241 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
117242 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
117243 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
117244 +
117245 + if (copy_from_user(compat_port_pcd_params,
117246 + (ioc_compat_fm_port_pcd_params_t*) compat_ptr(arg),
117247 + sizeof(ioc_compat_fm_port_pcd_params_t)))
117248 + err = E_WRITE_FAILED;
117249 +
117250 + while (!err) /* pseudo-while */
117251 + {
117252 + /* set pointers from where to copy from: */
117253 + port_pcd_params->p_prs_params = compat_ptr(compat_port_pcd_params->p_prs_params); /* same structure */
117254 + port_pcd_params->p_cc_params = compat_ptr(compat_port_pcd_params->p_cc_params);
117255 + port_pcd_params->p_kg_params = compat_ptr(compat_port_pcd_params->p_kg_params);
117256 + port_pcd_params->p_plcr_params = compat_ptr(compat_port_pcd_params->p_plcr_params);
117257 + port_pcd_params->p_ip_reassembly_manip = compat_ptr(compat_port_pcd_params->p_ip_reassembly_manip);
117258 +#if (DPAA_VERSION >= 11)
117259 + port_pcd_params->p_capwap_reassembly_manip = compat_ptr(compat_port_pcd_params->p_capwap_reassembly_manip);
117260 +#endif
117261 + /* the prs member is the same, no compat structure...memcpy only */
117262 + if (port_pcd_params->p_prs_params)
117263 + {
117264 + if (copy_from_user(same_port_pcd_prs_params,
117265 + port_pcd_params->p_prs_params,
117266 + sizeof(ioc_fm_port_pcd_prs_params_t)))
117267 + {
117268 + err = E_WRITE_FAILED;
117269 + break; /* from pseudo-while */
117270 + }
117271 +
117272 + memcpy(port_pcd_prs_params, same_port_pcd_prs_params, sizeof(ioc_fm_port_pcd_prs_params_t));
117273 + port_pcd_params->p_prs_params = port_pcd_prs_params;
117274 + }
117275 +
117276 + if (port_pcd_params->p_cc_params)
117277 + {
117278 + if (copy_from_user(compat_port_pcd_cc_params,
117279 + port_pcd_params->p_cc_params,
117280 + sizeof(ioc_compat_fm_port_pcd_cc_params_t)))
117281 + {
117282 + err = E_WRITE_FAILED;
117283 + break; /* from pseudo-while */
117284 + }
117285 +
117286 + port_pcd_params->p_cc_params = port_pcd_cc_params;
117287 + }
117288 +
117289 + if (port_pcd_params->p_kg_params)
117290 + {
117291 + if (copy_from_user(compat_port_pcd_kg_params,
117292 + port_pcd_params->p_kg_params,
117293 + sizeof(ioc_compat_fm_port_pcd_kg_params_t)))
117294 + {
117295 + err = E_WRITE_FAILED;
117296 + break; /* from pseudo-while */
117297 + }
117298 +
117299 + port_pcd_params->p_kg_params = port_pcd_kg_params;
117300 + }
117301 +
117302 + if (port_pcd_params->p_plcr_params)
117303 + {
117304 + if (copy_from_user(compat_port_pcd_plcr_params,
117305 + port_pcd_params->p_plcr_params,
117306 + sizeof(ioc_compat_fm_port_pcd_plcr_params_t)))
117307 + {
117308 + err = E_WRITE_FAILED;
117309 + break; /* from pseudo-while */
117310 + }
117311 +
117312 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
117313 + }
117314 +
117315 + break; /* pseudo-while: always run once! */
117316 + }
117317 +
117318 + if (!err)
117319 + compat_copy_fm_port_pcd(compat_port_pcd_params, port_pcd_params, COMPAT_US_TO_K);
117320 +
117321 + XX_Free(compat_port_pcd_params);
117322 + }
117323 + else
117324 +#endif
117325 + {
117326 + if (copy_from_user(port_pcd_params,
117327 + (ioc_fm_port_pcd_params_t*) arg,
117328 + sizeof(ioc_fm_port_pcd_params_t)))
117329 + err = E_WRITE_FAILED;
117330 +
117331 + while (!err) /* pseudo-while */
117332 + {
117333 + if (port_pcd_params->p_prs_params)
117334 + {
117335 + if (copy_from_user(port_pcd_prs_params,
117336 + port_pcd_params->p_prs_params,
117337 + sizeof(ioc_fm_port_pcd_prs_params_t)))
117338 + {
117339 + err = E_WRITE_FAILED;
117340 + break; /* from pseudo-while */
117341 + }
117342 +
117343 + port_pcd_params->p_prs_params = port_pcd_prs_params;
117344 + }
117345 +
117346 + if (port_pcd_params->p_cc_params)
117347 + {
117348 + if (copy_from_user(port_pcd_cc_params,
117349 + port_pcd_params->p_cc_params,
117350 + sizeof(ioc_fm_port_pcd_cc_params_t)))
117351 + {
117352 + err = E_WRITE_FAILED;
117353 + break; /* from pseudo-while */
117354 + }
117355 +
117356 + port_pcd_params->p_cc_params = port_pcd_cc_params;
117357 + }
117358 +
117359 + if (port_pcd_params->p_kg_params)
117360 + {
117361 + if (copy_from_user(port_pcd_kg_params,
117362 + port_pcd_params->p_kg_params,
117363 + sizeof(ioc_fm_port_pcd_kg_params_t)))
117364 + {
117365 + err = E_WRITE_FAILED;
117366 + break; /* from pseudo-while */
117367 + }
117368 +
117369 + port_pcd_params->p_kg_params = port_pcd_kg_params;
117370 + }
117371 +
117372 + if (port_pcd_params->p_plcr_params)
117373 + {
117374 + if (copy_from_user(port_pcd_plcr_params,
117375 + port_pcd_params->p_plcr_params,
117376 + sizeof(ioc_fm_port_pcd_plcr_params_t)))
117377 + {
117378 + err = E_WRITE_FAILED;
117379 + break; /* from pseudo-while */
117380 + }
117381 +
117382 + port_pcd_params->p_plcr_params = port_pcd_plcr_params;
117383 + }
117384 +
117385 + break; /* pseudo-while: always run once! */
117386 + }
117387 + }
117388 +
117389 + if (!err)
117390 + err = FM_PORT_SetPCD(p_LnxWrpFmPortDev->h_Dev, (t_FmPortPcdParams*) port_pcd_params);
117391 +
117392 + XX_Free(port_pcd_params);
117393 + break;
117394 + }
117395 +
117396 + case FM_PORT_IOC_DELETE_PCD:
117397 + err = FM_PORT_DeletePCD(p_LnxWrpFmPortDev->h_Dev);
117398 + break;
117399 +
117400 +#if defined(CONFIG_COMPAT)
117401 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME_COMPAT:
117402 +#endif
117403 + case FM_PORT_IOC_PCD_KG_MODIFY_INITIAL_SCHEME:
117404 + {
117405 + ioc_fm_pcd_kg_scheme_select_t *param;
117406 +
117407 + param = (ioc_fm_pcd_kg_scheme_select_t *) XX_Malloc(
117408 + sizeof(ioc_fm_pcd_kg_scheme_select_t));
117409 + if (!param)
117410 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117411 +
117412 + memset(param, 0, sizeof(ioc_fm_pcd_kg_scheme_select_t));
117413 +
117414 +#if defined(CONFIG_COMPAT)
117415 + if (compat)
117416 + {
117417 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param;
117418 +
117419 + compat_param = (ioc_compat_fm_pcd_kg_scheme_select_t *) XX_Malloc(
117420 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
117421 + if (!compat_param)
117422 + {
117423 + XX_Free(param);
117424 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117425 + }
117426 +
117427 + memset(compat_param, 0, sizeof(ioc_compat_fm_pcd_kg_scheme_select_t));
117428 + if (copy_from_user(compat_param,
117429 + (ioc_compat_fm_pcd_kg_scheme_select_t *) compat_ptr(arg),
117430 + sizeof(ioc_compat_fm_pcd_kg_scheme_select_t)))
117431 + {
117432 + XX_Free(compat_param);
117433 + XX_Free(param);
117434 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117435 + }
117436 +
117437 + compat_copy_fm_pcd_kg_scheme_select(compat_param, param, COMPAT_US_TO_K);
117438 +
117439 + XX_Free(compat_param);
117440 + }
117441 + else
117442 +#endif
117443 + {
117444 + if (copy_from_user(param, (ioc_fm_pcd_kg_scheme_select_t *)arg,
117445 + sizeof(ioc_fm_pcd_kg_scheme_select_t)))
117446 + {
117447 + XX_Free(param);
117448 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117449 + }
117450 + }
117451 +
117452 + err = FM_PORT_PcdKgModifyInitialScheme(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdKgSchemeSelect *)param);
117453 +
117454 + XX_Free(param);
117455 + break;
117456 + }
117457 +
117458 +#if defined(CONFIG_COMPAT)
117459 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE_COMPAT:
117460 +#endif
117461 + case FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE:
117462 + {
117463 + ioc_fm_obj_t id;
117464 +
117465 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
117466 +
117467 +#if defined(CONFIG_COMPAT)
117468 + if (compat)
117469 + {
117470 + ioc_compat_fm_obj_t compat_id;
117471 +
117472 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
117473 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117474 +
117475 + id.obj = compat_ptr(compat_id.obj);
117476 + }
117477 + else
117478 +#endif
117479 + {
117480 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
117481 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117482 + }
117483 +
117484 + err = FM_PORT_PcdPlcrModifyInitialProfile(p_LnxWrpFmPortDev->h_Dev, id.obj);
117485 + break;
117486 + }
117487 +
117488 +#if defined(CONFIG_COMPAT)
117489 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES_COMPAT:
117490 +#endif
117491 + case FM_PORT_IOC_PCD_KG_BIND_SCHEMES:
117492 + {
117493 + ioc_fm_pcd_port_schemes_params_t *param;
117494 +
117495 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
117496 + sizeof(ioc_fm_pcd_port_schemes_params_t));
117497 + if (!param)
117498 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117499 +
117500 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
117501 +
117502 +#if defined(CONFIG_COMPAT)
117503 + if (compat)
117504 + {
117505 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
117506 +
117507 + if (copy_from_user(&compat_param,
117508 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
117509 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
117510 + {
117511 + XX_Free(param);
117512 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117513 + }
117514 +
117515 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
117516 + }
117517 + else
117518 +#endif
117519 + {
117520 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
117521 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
117522 + {
117523 + XX_Free(param);
117524 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117525 + }
117526 + }
117527 +
117528 + err = FM_PORT_PcdKgBindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
117529 +
117530 + XX_Free(param);
117531 + break;
117532 + }
117533 +
117534 +#if defined(CONFIG_COMPAT)
117535 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES_COMPAT:
117536 +#endif
117537 + case FM_PORT_IOC_PCD_KG_UNBIND_SCHEMES:
117538 + {
117539 + ioc_fm_pcd_port_schemes_params_t *param;
117540 +
117541 + param = (ioc_fm_pcd_port_schemes_params_t *) XX_Malloc(
117542 + sizeof(ioc_fm_pcd_port_schemes_params_t));
117543 + if (!param)
117544 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117545 +
117546 + memset(param, 0 , sizeof(ioc_fm_pcd_port_schemes_params_t));
117547 +
117548 +#if defined(CONFIG_COMPAT)
117549 + if (compat)
117550 + {
117551 + ioc_compat_fm_pcd_port_schemes_params_t compat_param;
117552 +
117553 + if (copy_from_user(&compat_param,
117554 + (ioc_compat_fm_pcd_port_schemes_params_t *) compat_ptr(arg),
117555 + sizeof(ioc_compat_fm_pcd_port_schemes_params_t)))
117556 + {
117557 + XX_Free(param);
117558 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117559 + }
117560 +
117561 + compat_copy_fm_pcd_kg_schemes_params(&compat_param, param, COMPAT_US_TO_K);
117562 + }
117563 + else
117564 +#endif
117565 + {
117566 + if (copy_from_user(param, (ioc_fm_pcd_port_schemes_params_t *) arg,
117567 + sizeof(ioc_fm_pcd_port_schemes_params_t)))
117568 + {
117569 + XX_Free(param);
117570 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117571 + }
117572 + }
117573 +
117574 + err = FM_PORT_PcdKgUnbindSchemes(p_LnxWrpFmPortDev->h_Dev, (t_FmPcdPortSchemesParams *)param);
117575 +
117576 + XX_Free(param);
117577 + break;
117578 + }
117579 +
117580 + case FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES:
117581 + {
117582 + uint16_t num;
117583 + if (get_user(num, (uint16_t*) arg))
117584 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117585 +
117586 + err = FM_PORT_PcdPlcrAllocProfiles(p_LnxWrpFmPortDev->h_Dev, num);
117587 + break;
117588 + }
117589 +
117590 + case FM_PORT_IOC_PCD_PLCR_FREE_PROFILES:
117591 + err = FM_PORT_PcdPlcrFreeProfiles(p_LnxWrpFmPortDev->h_Dev);
117592 + break;
117593 +
117594 + case FM_PORT_IOC_DETACH_PCD:
117595 + err = FM_PORT_DetachPCD(p_LnxWrpFmPortDev->h_Dev);
117596 + break;
117597 +
117598 + case FM_PORT_IOC_ATTACH_PCD:
117599 + err = FM_PORT_AttachPCD(p_LnxWrpFmPortDev->h_Dev);
117600 + break;
117601 +
117602 +#if defined(CONFIG_COMPAT)
117603 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT:
117604 +#endif
117605 + case FM_PORT_IOC_PCD_CC_MODIFY_TREE:
117606 + {
117607 + ioc_fm_obj_t id;
117608 +
117609 + memset(&id, 0 , sizeof(ioc_fm_obj_t));
117610 +
117611 +#if defined(CONFIG_COMPAT)
117612 + if (compat)
117613 + {
117614 + ioc_compat_fm_obj_t compat_id;
117615 +
117616 + if (copy_from_user(&compat_id, (ioc_compat_fm_obj_t *) compat_ptr(arg), sizeof(ioc_compat_fm_obj_t)))
117617 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117618 +
117619 + compat_copy_fm_port_pcd_modify_tree(&compat_id, &id, COMPAT_US_TO_K);
117620 + }
117621 + else
117622 +#endif
117623 + {
117624 + if (copy_from_user(&id, (ioc_fm_obj_t *) arg, sizeof(ioc_fm_obj_t)))
117625 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117626 + }
117627 +
117628 + err = FM_PORT_PcdCcModifyTree(p_LnxWrpFmPortDev->h_Dev, id.obj);
117629 + break;
117630 + }
117631 +
117632 + case FM_PORT_IOC_ADD_CONGESTION_GRPS:
117633 + case FM_PORT_IOC_REMOVE_CONGESTION_GRPS:
117634 + {
117635 + ioc_fm_port_congestion_groups_t *param;
117636 +
117637 + param = (ioc_fm_port_congestion_groups_t*) XX_Malloc(sizeof(ioc_fm_port_congestion_groups_t));
117638 + if (!param)
117639 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117640 +
117641 + memset(param, 0, sizeof(ioc_fm_port_congestion_groups_t));
117642 +
117643 +#if defined(CONFIG_COMPAT)
117644 + if (compat)
117645 + {
117646 + if (copy_from_user(param, (t_FmPortCongestionGrps*) compat_ptr(arg),
117647 + sizeof(t_FmPortCongestionGrps)))
117648 + {
117649 + XX_Free(param);
117650 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117651 + }
117652 + }
117653 + else
117654 +#endif /* CONFIG_COMPAT */
117655 + {
117656 + if (copy_from_user(param, (t_FmPortCongestionGrps*) arg,
117657 + sizeof(t_FmPortCongestionGrps)))
117658 + {
117659 + XX_Free(param);
117660 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117661 + }
117662 + }
117663 +
117664 + err = (cmd == FM_PORT_IOC_ADD_CONGESTION_GRPS)
117665 + ? FM_PORT_AddCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
117666 + : FM_PORT_RemoveCongestionGrps(p_LnxWrpFmPortDev->h_Dev, (t_FmPortCongestionGrps*) param)
117667 + ;
117668 +
117669 + XX_Free(param);
117670 + break;
117671 + }
117672 +
117673 + case FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR:
117674 + case FM_PORT_IOC_REMOVE_RX_HASH_MAC_ADDR:
117675 + {
117676 + ioc_fm_port_mac_addr_params_t *param;
117677 +
117678 + param = (ioc_fm_port_mac_addr_params_t*) XX_Malloc(
117679 + sizeof(ioc_fm_port_mac_addr_params_t));
117680 + if (!param)
117681 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117682 +
117683 + memset(param, 0, sizeof(ioc_fm_port_mac_addr_params_t));
117684 +
117685 +#if defined(CONFIG_COMPAT)
117686 + if (compat)
117687 + {
117688 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) compat_ptr(arg),
117689 + sizeof(ioc_fm_port_mac_addr_params_t)))
117690 + {
117691 + XX_Free(param);
117692 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117693 + }
117694 + }
117695 + else
117696 +#endif /* CONFIG_COMPAT */
117697 + {
117698 + if (copy_from_user(param, (ioc_fm_port_mac_addr_params_t*) arg,
117699 + sizeof(ioc_fm_port_mac_addr_params_t)))
117700 + {
117701 + XX_Free(param);
117702 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117703 + }
117704 + }
117705 +
117706 + if (p_LnxWrpFmPortDev->pcd_owner_params.dev)
117707 + {
117708 + int id = -1;
117709 +
117710 + switch(p_LnxWrpFmPortDev->settings.param.portType)
117711 + {
117712 + case e_FM_PORT_TYPE_RX:
117713 + case e_FM_PORT_TYPE_TX:
117714 + id = p_LnxWrpFmPortDev->id;
117715 + break;
117716 + case e_FM_PORT_TYPE_RX_10G:
117717 + case e_FM_PORT_TYPE_TX_10G:
117718 + id = p_LnxWrpFmPortDev->id + FM_MAX_NUM_OF_1G_MACS;
117719 + break;
117720 + default:
117721 + err = E_NOT_AVAILABLE;
117722 + REPORT_ERROR(MINOR, err, ("Attempt to add/remove hash MAC addr. to/from MAC-less port!"));
117723 + }
117724 + if (id >= 0)
117725 + {
117726 + t_LnxWrpFmDev *fm = (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117727 + t_Handle mac_handle = fm->macs[id].h_Dev;
117728 +
117729 + err = (cmd == FM_PORT_IOC_ADD_RX_HASH_MAC_ADDR)
117730 + ? FM_MAC_AddHashMacAddr(mac_handle, (t_EnetAddr*) param)
117731 + : FM_MAC_RemoveHashMacAddr(mac_handle, (t_EnetAddr*) param);
117732 + }
117733 + }
117734 + else
117735 + {
117736 + err = E_NOT_AVAILABLE;
117737 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!?!?"));
117738 + }
117739 +
117740 + XX_Free(param);
117741 + break;
117742 + }
117743 +
117744 + case FM_PORT_IOC_SET_TX_PAUSE_FRAMES:
117745 + {
117746 + t_LnxWrpFmDev *p_LnxWrpFmDev =
117747 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117748 + ioc_fm_port_tx_pause_frames_params_t param;
117749 + int mac_id = p_LnxWrpFmPortDev->id;
117750 +
117751 + if(&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev)
117752 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
117753 +
117754 + if (copy_from_user(&param, (ioc_fm_port_tx_pause_frames_params_t *)arg,
117755 + sizeof(ioc_fm_port_tx_pause_frames_params_t)))
117756 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117757 +
117758 + if (p_LnxWrpFmDev && p_LnxWrpFmDev->macs[mac_id].h_Dev)
117759 + {
117760 + FM_MAC_SetTxPauseFrames(p_LnxWrpFmDev->macs[mac_id].h_Dev,
117761 + param.priority,
117762 + param.pause_time,
117763 + param.thresh_time);
117764 + }
117765 + else
117766 + {
117767 + err = E_NOT_AVAILABLE;
117768 + REPORT_ERROR(MINOR, err, ("Port not initialized or other error!"));
117769 + }
117770 +
117771 + break;
117772 + }
117773 +
117774 + case FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT:
117775 + {
117776 + ioc_fm_buffer_prefix_content_t *param;
117777 +
117778 + param = (ioc_fm_buffer_prefix_content_t*) XX_Malloc(sizeof(ioc_fm_buffer_prefix_content_t));
117779 + if (!param)
117780 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117781 +
117782 + memset(param, 0, sizeof(ioc_fm_buffer_prefix_content_t));
117783 +
117784 + if (copy_from_user(param, (ioc_fm_buffer_prefix_content_t*) arg,
117785 + sizeof(ioc_fm_buffer_prefix_content_t)))
117786 + {
117787 + XX_Free(param);
117788 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117789 + }
117790 +
117791 + if (FM_PORT_ConfigBufferPrefixContent(p_LnxWrpFmPortDev->h_Dev,
117792 + (t_FmBufferPrefixContent *)param))
117793 + {
117794 + XX_Free(param);
117795 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117796 + }
117797 +
117798 + XX_Free(param);
117799 + break;
117800 + }
117801 +
117802 +#if (DPAA_VERSION >= 11)
117803 +#if defined(CONFIG_COMPAT)
117804 + case FM_PORT_IOC_VSP_ALLOC_COMPAT:
117805 +#endif
117806 + case FM_PORT_IOC_VSP_ALLOC:
117807 + {
117808 + ioc_fm_port_vsp_alloc_params_t *param;
117809 + t_LnxWrpFmDev *p_LnxWrpFmDev;
117810 + t_LnxWrpFmPortDev *p_LnxWrpFmTxPortDev;
117811 +
117812 + param = (ioc_fm_port_vsp_alloc_params_t *) XX_Malloc(
117813 + sizeof(ioc_fm_port_vsp_alloc_params_t));
117814 + if (!param)
117815 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117816 +
117817 + memset(param, 0, sizeof(ioc_fm_port_vsp_alloc_params_t));
117818 +
117819 +#if defined(CONFIG_COMPAT)
117820 + if (compat)
117821 + {
117822 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param;
117823 +
117824 + compat_param = (ioc_compat_fm_port_vsp_alloc_params_t *) XX_Malloc(
117825 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
117826 + if (!compat_param)
117827 + {
117828 + XX_Free(param);
117829 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("IOCTL FM PORT"));
117830 + }
117831 +
117832 + memset(compat_param, 0, sizeof(ioc_compat_fm_port_vsp_alloc_params_t));
117833 + if (copy_from_user(compat_param,
117834 + (ioc_compat_fm_port_vsp_alloc_params_t *) compat_ptr(arg),
117835 + sizeof(ioc_compat_fm_port_vsp_alloc_params_t)))
117836 + {
117837 + XX_Free(compat_param);
117838 + XX_Free(param);
117839 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117840 + }
117841 +
117842 + compat_copy_fm_port_vsp_alloc_params(compat_param, param, COMPAT_US_TO_K);
117843 +
117844 + XX_Free(compat_param);
117845 + }
117846 + else
117847 +#endif
117848 + {
117849 + if (copy_from_user(param, (ioc_fm_port_vsp_alloc_params_t *)arg,
117850 + sizeof(ioc_fm_port_vsp_alloc_params_t)))
117851 + {
117852 + XX_Free(param);
117853 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117854 + }
117855 + }
117856 +
117857 + /* Userspace may not have the Tx port t_handle when issuing the IOCTL */
117858 + if (p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX ||
117859 + p_LnxWrpFmPortDev->settings.param.portType == e_FM_PORT_TYPE_RX_10G)
117860 + {
117861 + /* Determine the Tx port t_Handle from the Rx port id */
117862 + p_LnxWrpFmDev = p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117863 + p_LnxWrpFmTxPortDev = &p_LnxWrpFmDev->txPorts[p_LnxWrpFmPortDev->id];
117864 + param->p_fm_tx_port = p_LnxWrpFmTxPortDev->h_Dev;
117865 + }
117866 +
117867 + if (FM_PORT_VSPAlloc(p_LnxWrpFmPortDev->h_Dev, (t_FmPortVSPAllocParams *)param))
117868 + {
117869 + XX_Free(param);
117870 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117871 + }
117872 +
117873 + XX_Free(param);
117874 + break;
117875 + }
117876 +#endif /* (DPAA_VERSION >= 11) */
117877 +
117878 + case FM_PORT_IOC_GET_MAC_STATISTICS:
117879 + {
117880 + t_LnxWrpFmDev *p_LnxWrpFmDev =
117881 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117882 + ioc_fm_port_mac_statistics_t param;
117883 + int mac_id = p_LnxWrpFmPortDev->id;
117884 +
117885 + if (!p_LnxWrpFmDev)
117886 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117887 +
117888 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
117889 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
117890 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
117891 +
117892 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
117893 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117894 +
117895 + if (FM_MAC_GetStatistics(p_LnxWrpFmDev->macs[mac_id].h_Dev,
117896 + (t_FmMacStatistics *)&param))
117897 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117898 +
117899 + if (copy_to_user((ioc_fm_port_mac_statistics_t *)arg, &param,
117900 + sizeof(ioc_fm_port_mac_statistics_t)))
117901 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117902 +
117903 + break;
117904 + }
117905 +
117906 + case FM_PORT_IOC_GET_MAC_FRAME_SIZE_COUNTERS:
117907 + {
117908 + t_LnxWrpFmDev *p_LnxWrpFmDev =
117909 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117910 + ioc_fm_port_mac_frame_size_counters_t param;
117911 + t_FmMacFrameSizeCounters frameSizeCounters;
117912 + int mac_id = p_LnxWrpFmPortDev->id;
117913 +
117914 + if (!p_LnxWrpFmDev)
117915 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117916 +
117917 + if (&p_LnxWrpFmDev->txPorts[mac_id] != p_LnxWrpFmPortDev &&
117918 + &p_LnxWrpFmDev->rxPorts[mac_id] != p_LnxWrpFmPortDev)
117919 + mac_id += FM_MAX_NUM_OF_1G_MACS; /* 10G port */
117920 +
117921 + if (!p_LnxWrpFmDev->macs[mac_id].h_Dev)
117922 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117923 +
117924 + if (copy_from_user(&param, (ioc_fm_port_mac_frame_size_counters_t *)arg,
117925 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
117926 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117927 +
117928 + if (FM_MAC_GetFrameSizeCounters(p_LnxWrpFmDev->macs[mac_id].h_Dev,
117929 + &frameSizeCounters, param.type))
117930 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117931 +
117932 + param.count_pkts_64 = frameSizeCounters.count_pkts_64;
117933 + param.count_pkts_65_to_127 = frameSizeCounters.count_pkts_65_to_127;
117934 + param.count_pkts_128_to_255 = frameSizeCounters.count_pkts_128_to_255;
117935 + param.count_pkts_256_to_511 = frameSizeCounters.count_pkts_256_to_511;
117936 + param.count_pkts_512_to_1023 = frameSizeCounters.count_pkts_512_to_1023;
117937 + param.count_pkts_1024_to_1518 = frameSizeCounters.count_pkts_1024_to_1518;
117938 + param.count_pkts_1519_to_1522 = frameSizeCounters.count_pkts_1519_to_1522;
117939 +
117940 + if (copy_to_user((ioc_fm_port_mac_frame_size_counters_t *)arg, &param,
117941 + sizeof(ioc_fm_port_mac_frame_size_counters_t)))
117942 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117943 +
117944 + break;
117945 + }
117946 +
117947 + case FM_PORT_IOC_GET_BMI_COUNTERS:
117948 + {
117949 + t_LnxWrpFmDev *p_LnxWrpFmDev =
117950 + (t_LnxWrpFmDev *)p_LnxWrpFmPortDev->h_LnxWrpFmDev;
117951 + ioc_fm_port_bmi_stats_t param;
117952 +
117953 + if (!p_LnxWrpFmDev)
117954 + RETURN_ERROR(MINOR, E_NOT_AVAILABLE, ("Port not initialized or other error!"));
117955 +
117956 + if (FM_PORT_GetBmiCounters(p_LnxWrpFmPortDev->h_Dev,
117957 + (t_FmPortBmiStats *)&param))
117958 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117959 +
117960 + if (copy_to_user((ioc_fm_port_bmi_stats_t *)arg, &param,
117961 + sizeof(ioc_fm_port_bmi_stats_t)))
117962 + RETURN_ERROR(MINOR, E_WRITE_FAILED, NO_MSG);
117963 +
117964 + break;
117965 + }
117966 +
117967 + default:
117968 + RETURN_ERROR(MINOR, E_INVALID_SELECTION,
117969 + ("invalid ioctl: cmd:0x%08x(type:0x%02x, nr:0x%02x.\n",
117970 + cmd, _IOC_TYPE(cmd), _IOC_NR(cmd)));
117971 + }
117972 +
117973 + if (err)
117974 + RETURN_ERROR(MINOR, E_INVALID_OPERATION, ("IOCTL FM PORT"));
117975 +
117976 + return E_OK;
117977 +}
117978 +
117979 +/*****************************************************************************/
117980 +/* API routines for the FM Linux Device */
117981 +/*****************************************************************************/
117982 +
117983 +static int fm_open(struct inode *inode, struct file *file)
117984 +{
117985 + t_LnxWrpFmDev *p_LnxWrpFmDev = NULL;
117986 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
117987 + unsigned int major = imajor(inode);
117988 + unsigned int minor = iminor(inode);
117989 + struct device_node *fm_node;
117990 + static struct of_device_id fm_node_of_match[] = {
117991 + { .compatible = "fsl,fman", },
117992 + { /* end of list */ },
117993 + };
117994 +
117995 + DBG(TRACE, ("Opening minor - %d - ", minor));
117996 +
117997 + if (file->private_data != NULL)
117998 + return 0;
117999 +
118000 + /* Get all the FM nodes */
118001 + for_each_matching_node(fm_node, fm_node_of_match) {
118002 + struct platform_device *of_dev;
118003 +
118004 + of_dev = of_find_device_by_node(fm_node);
118005 + if (unlikely(of_dev == NULL)) {
118006 + REPORT_ERROR(MAJOR, E_INVALID_VALUE, ("fm id!"));
118007 + return -ENXIO;
118008 + }
118009 +
118010 + p_LnxWrpFmDev = (t_LnxWrpFmDev *)fm_bind(&of_dev->dev);
118011 + if (p_LnxWrpFmDev->major == major)
118012 + break;
118013 + fm_unbind((struct fm *)p_LnxWrpFmDev);
118014 + p_LnxWrpFmDev = NULL;
118015 + }
118016 +
118017 + if (!p_LnxWrpFmDev)
118018 + return -ENODEV;
118019 +
118020 + if (minor == DEV_FM_MINOR_BASE)
118021 + file->private_data = p_LnxWrpFmDev;
118022 + else if (minor == DEV_FM_PCD_MINOR_BASE)
118023 + file->private_data = p_LnxWrpFmDev;
118024 + else {
118025 + if (minor == DEV_FM_OH_PORTS_MINOR_BASE)
118026 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->hcPort;
118027 + else if ((minor > DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE))
118028 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->opPorts[minor-DEV_FM_OH_PORTS_MINOR_BASE-1];
118029 + else if ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE))
118030 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->rxPorts[minor-DEV_FM_RX_PORTS_MINOR_BASE];
118031 + else if ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS))
118032 + p_LnxWrpFmPortDev = &p_LnxWrpFmDev->txPorts[minor-DEV_FM_TX_PORTS_MINOR_BASE];
118033 + else
118034 + return -EINVAL;
118035 +
118036 + /* if trying to open port, check if it initialized */
118037 + if (!p_LnxWrpFmPortDev->h_Dev)
118038 + return -ENODEV;
118039 +
118040 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *)fm_port_bind(p_LnxWrpFmPortDev->dev);
118041 + file->private_data = p_LnxWrpFmPortDev;
118042 + fm_unbind((struct fm *)p_LnxWrpFmDev);
118043 + }
118044 +
118045 + if (file->private_data == NULL)
118046 + return -ENXIO;
118047 +
118048 + return 0;
118049 +}
118050 +
118051 +static int fm_close(struct inode *inode, struct file *file)
118052 +{
118053 + t_LnxWrpFmDev *p_LnxWrpFmDev;
118054 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
118055 + unsigned int minor = iminor(inode);
118056 + int err = 0;
118057 +
118058 + DBG(TRACE, ("Closing minor - %d - ", minor));
118059 +
118060 + if ((minor == DEV_FM_MINOR_BASE) ||
118061 + (minor == DEV_FM_PCD_MINOR_BASE))
118062 + {
118063 + p_LnxWrpFmDev = (t_LnxWrpFmDev*)file->private_data;
118064 + if (!p_LnxWrpFmDev)
118065 + return -ENODEV;
118066 + fm_unbind((struct fm *)p_LnxWrpFmDev);
118067 + }
118068 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
118069 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
118070 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
118071 + {
118072 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev*)file->private_data;
118073 + if (!p_LnxWrpFmPortDev)
118074 + return -ENODEV;
118075 + fm_port_unbind((struct fm_port *)p_LnxWrpFmPortDev);
118076 + }
118077 +
118078 + return err;
118079 +}
118080 +
118081 +static int fm_ioctls(unsigned int minor, struct file *file, unsigned int cmd, unsigned long arg, bool compat)
118082 +{
118083 + DBG(TRACE, ("IOCTL minor - %u, cmd - 0x%08x, arg - 0x%08lx \n", minor, cmd, arg));
118084 +
118085 + if ((minor == DEV_FM_MINOR_BASE) ||
118086 + (minor == DEV_FM_PCD_MINOR_BASE))
118087 + {
118088 + t_LnxWrpFmDev *p_LnxWrpFmDev = ((t_LnxWrpFmDev*)file->private_data);
118089 + if (!p_LnxWrpFmDev)
118090 + return -ENODEV;
118091 + if (LnxwrpFmIOCTL(p_LnxWrpFmDev, cmd, arg, compat))
118092 + return -EFAULT;
118093 + }
118094 + else if (((minor >= DEV_FM_OH_PORTS_MINOR_BASE) && (minor < DEV_FM_RX_PORTS_MINOR_BASE)) ||
118095 + ((minor >= DEV_FM_RX_PORTS_MINOR_BASE) && (minor < DEV_FM_TX_PORTS_MINOR_BASE)) ||
118096 + ((minor >= DEV_FM_TX_PORTS_MINOR_BASE) && (minor < DEV_FM_MAX_MINORS)))
118097 + {
118098 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = ((t_LnxWrpFmPortDev*)file->private_data);
118099 + if (!p_LnxWrpFmPortDev)
118100 + return -ENODEV;
118101 + if (LnxwrpFmPortIOCTL(p_LnxWrpFmPortDev, cmd, arg, compat))
118102 + return -EFAULT;
118103 + }
118104 + else
118105 + {
118106 + REPORT_ERROR(MINOR, E_INVALID_VALUE, ("minor"));
118107 + return -ENODEV;
118108 + }
118109 +
118110 + return 0;
118111 +}
118112 +
118113 +#ifdef CONFIG_COMPAT
118114 +static long fm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
118115 +{
118116 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
118117 + long res;
118118 +
118119 + fm_mutex_lock();
118120 + res = fm_ioctls(minor, file, cmd, arg, true);
118121 + fm_mutex_unlock();
118122 +
118123 + return res;
118124 +}
118125 +#endif
118126 +
118127 +static long fm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
118128 +{
118129 + unsigned int minor = iminor(file->f_path.dentry->d_inode);
118130 + long res;
118131 +
118132 + fm_mutex_lock();
118133 + res = fm_ioctls(minor, file, cmd, arg, false);
118134 + fm_mutex_unlock();
118135 +
118136 + return res;
118137 +}
118138 +
118139 +/* Globals for FM character device */
118140 +struct file_operations fm_fops =
118141 +{
118142 + .owner = THIS_MODULE,
118143 + .unlocked_ioctl = fm_ioctl,
118144 +#ifdef CONFIG_COMPAT
118145 + .compat_ioctl = fm_compat_ioctl,
118146 +#endif
118147 + .open = fm_open,
118148 + .release = fm_close,
118149 +};
118150 --- /dev/null
118151 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.c
118152 @@ -0,0 +1,1297 @@
118153 +/*
118154 + * Copyright 2008-2012 Freescale Semiconductor Inc.
118155 + *
118156 + * Redistribution and use in source and binary forms, with or without
118157 + * modification, are permitted provided that the following conditions are met:
118158 + * * Redistributions of source code must retain the above copyright
118159 + * notice, this list of conditions and the following disclaimer.
118160 + * * Redistributions in binary form must reproduce the above copyright
118161 + * notice, this list of conditions and the following disclaimer in the
118162 + * documentation and/or other materials provided with the distribution.
118163 + * * Neither the name of Freescale Semiconductor nor the
118164 + * names of its contributors may be used to endorse or promote products
118165 + * derived from this software without specific prior written permission.
118166 + *
118167 + *
118168 + * ALTERNATIVELY, this software may be distributed under the terms of the
118169 + * GNU General Public License ("GPL") as published by the Free Software
118170 + * Foundation, either version 2 of that License or (at your option) any
118171 + * later version.
118172 + *
118173 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
118174 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
118175 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
118176 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
118177 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
118178 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
118179 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
118180 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
118181 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
118182 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
118183 + */
118184 +
118185 +/*
118186 + @File lnxwrp_fm_compat_ioctls.c
118187 +
118188 + @Description FM PCD compat functions
118189 +
118190 +*/
118191 +
118192 +#if !defined(CONFIG_COMPAT)
118193 +#error "missing COMPAT layer..."
118194 +#endif
118195 +
118196 +
118197 +#include <linux/kernel.h>
118198 +#include <linux/module.h>
118199 +#include <linux/fs.h>
118200 +#include <linux/cdev.h>
118201 +#include <linux/device.h>
118202 +#include <linux/irq.h>
118203 +#include <linux/interrupt.h>
118204 +#include <linux/io.h>
118205 +#include <linux/ioport.h>
118206 +#include <asm/uaccess.h>
118207 +#include <asm/errno.h>
118208 +#ifndef CONFIG_FMAN_ARM
118209 +#include <sysdev/fsl_soc.h>
118210 +#endif
118211 +
118212 +#include "part_ext.h"
118213 +#include "fm_ioctls.h"
118214 +#include "fm_pcd_ioctls.h"
118215 +#include "fm_port_ioctls.h"
118216 +#include "lnxwrp_ioctls_fm_compat.h"
118217 +
118218 +#if defined(FM_COMPAT_DBG)
118219 +static void hex_dump(void * p_addr, unsigned int size)
118220 +{
118221 + int i;
118222 +
118223 + for(i=0; i<size; i+=16)
118224 + {
118225 + printk("%p: 0x%08x 0x%08x 0x%08x 0x%08x\n", p_addr + i,
118226 + *(unsigned int *)(p_addr + i),
118227 + *(unsigned int *)(p_addr + i + 4),
118228 + *(unsigned int *)(p_addr + i + 8),
118229 + *(unsigned int *)(p_addr + i +12)
118230 + );
118231 + }
118232 +}
118233 +#endif
118234 +
118235 +/* maping kernel pointers w/ UserSpace id's { */
118236 +struct map_node {
118237 + void *ptr;
118238 + u8 node_type;
118239 +};
118240 +
118241 +static struct map_node compat_ptr2id_array[COMPAT_PTR2ID_ARRAY_MAX] = {{NULL},{FM_MAP_TYPE_UNSPEC}};
118242 +
118243 +void compat_del_ptr2id(void *p, enum fm_map_node_type node_type)
118244 +{
118245 + compat_uptr_t k;
118246 +
118247 + _fm_cpt_dbg(COMPAT_GENERIC, "delete (%p)\n", p);
118248 +
118249 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
118250 + if(compat_ptr2id_array[k].ptr == p){
118251 + compat_ptr2id_array[k].ptr = NULL;
118252 + compat_ptr2id_array[k].node_type = FM_MAP_TYPE_UNSPEC;
118253 + }
118254 +}
118255 +EXPORT_SYMBOL(compat_del_ptr2id);
118256 +
118257 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type node_type)
118258 +{
118259 + compat_uptr_t k;
118260 +
118261 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) do ->\n", p);
118262 +
118263 + if(!p)
118264 + return 0;
118265 +
118266 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
118267 + if(compat_ptr2id_array[k].ptr == NULL)
118268 + {
118269 + compat_ptr2id_array[k].ptr = p;
118270 + compat_ptr2id_array[k].node_type = node_type;
118271 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x \n", k | COMPAT_PTR2ID_WATERMARK);
118272 + return k | COMPAT_PTR2ID_WATERMARK;
118273 + }
118274 +
118275 + printk(KERN_WARNING "FMan map list full! No more PCD space on kernel!\n");
118276 + return 0;
118277 +}
118278 +EXPORT_SYMBOL(compat_add_ptr2id);
118279 +
118280 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type node_type)
118281 +{
118282 + compat_uptr_t k;
118283 +
118284 + _fm_cpt_dbg(COMPAT_GENERIC, " (%p) get -> \n", p);
118285 +
118286 + for(k=1; k < COMPAT_PTR2ID_ARRAY_MAX; k++)
118287 + if(compat_ptr2id_array[k].ptr == p &&
118288 + compat_ptr2id_array[k].node_type == node_type) {
118289 +
118290 + _fm_cpt_dbg(COMPAT_GENERIC, "0x%08x\n", k | COMPAT_PTR2ID_WATERMARK);
118291 + return k | COMPAT_PTR2ID_WATERMARK;
118292 + }
118293 +
118294 + return 0;
118295 +}
118296 +EXPORT_SYMBOL(compat_get_ptr2id);
118297 +
118298 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type node_type)
118299 +{
118300 +
118301 + _fm_cpt_dbg(COMPAT_GENERIC, " (0x%08x) get -> \n", comp);
118302 +
118303 + if((COMPAT_PTR2ID_WM_MASK & comp) != COMPAT_PTR2ID_WATERMARK) {
118304 + _fm_cpt_dbg(COMPAT_GENERIC, "Error, invalid watermark (0x%08x)!\n\n", comp);
118305 + dump_stack();
118306 + return compat_ptr(comp);
118307 + }
118308 +
118309 + comp &= ~COMPAT_PTR2ID_WM_MASK;
118310 +
118311 + if(((0 < comp) && (comp < COMPAT_PTR2ID_ARRAY_MAX) && (compat_ptr2id_array[comp].ptr != NULL)
118312 + && compat_ptr2id_array[comp].node_type == node_type)) {
118313 + _fm_cpt_dbg(COMPAT_GENERIC, "%p\n", compat_ptr2id_array[comp].ptr);
118314 + return compat_ptr2id_array[comp].ptr;
118315 + }
118316 + return NULL;
118317 +}
118318 +EXPORT_SYMBOL(compat_get_id2ptr);
118319 +/* } maping kernel pointers w/ UserSpace id's */
118320 +
118321 +void compat_obj_delete(
118322 + ioc_compat_fm_obj_t *compat_id,
118323 + ioc_fm_obj_t *id)
118324 +{
118325 + id->obj = compat_pcd_id2ptr(compat_id->obj);
118326 + compat_del_ptr2id(id->obj, FM_MAP_TYPE_PCD_NODE);
118327 +}
118328 +
118329 +static inline void compat_copy_fm_pcd_plcr_next_engine(
118330 + ioc_compat_fm_pcd_plcr_next_engine_params_u *compat_param,
118331 + ioc_fm_pcd_plcr_next_engine_params_u *param,
118332 + ioc_fm_pcd_engine next_engine,
118333 + uint8_t compat)
118334 +{
118335 + _fm_cpt_dbg (compat, " {->...\n");
118336 +
118337 + switch (next_engine)
118338 + {
118339 + case e_IOC_FM_PCD_PLCR:
118340 + if (compat == COMPAT_US_TO_K)
118341 + param->p_profile = compat_pcd_id2ptr(compat_param->p_profile);
118342 + else
118343 + compat_param->p_profile = compat_pcd_ptr2id(param->p_profile);
118344 + break;
118345 + case e_IOC_FM_PCD_KG:
118346 + if (compat == COMPAT_US_TO_K)
118347 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
118348 + else
118349 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
118350 + break;
118351 + default:
118352 + if (compat == COMPAT_US_TO_K)
118353 + param->action = compat_param->action;
118354 + else
118355 + compat_param->action = param->action;
118356 + break;
118357 + }
118358 +
118359 + _fm_cpt_dbg (compat, " ...->}\n");
118360 +}
118361 +
118362 +void compat_copy_fm_pcd_plcr_profile(
118363 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
118364 + ioc_fm_pcd_plcr_profile_params_t *param,
118365 + uint8_t compat)
118366 +{
118367 + _fm_cpt_dbg (compat, " {->...\n");
118368 +
118369 + if (compat == COMPAT_US_TO_K)
118370 + {
118371 + param->modify = compat_param->modify;
118372 +
118373 + /* profile_select */
118374 + if (!compat_param->modify)
118375 + {
118376 + param->profile_select.new_params.profile_type =
118377 + compat_param->profile_select.new_params.profile_type;
118378 + param->profile_select.new_params.p_fm_port =
118379 + compat_ptr(compat_param->profile_select.new_params.p_fm_port);
118380 + param->profile_select.new_params.relative_profile_id =
118381 + compat_param->profile_select.new_params.relative_profile_id;
118382 + }
118383 + else
118384 + param->profile_select.p_profile =
118385 + compat_pcd_id2ptr(compat_param->profile_select.p_profile);
118386 +
118387 + param->alg_selection = compat_param->alg_selection;
118388 + param->color_mode = compat_param->color_mode;
118389 +
118390 + /* both parameters in the union has the same size, so memcpy works */
118391 + memcpy(&param->color, &compat_param->color, sizeof(param->color));
118392 +
118393 + memcpy(&param->non_passthrough_alg_param,
118394 + &compat_param->non_passthrough_alg_param,
118395 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
118396 +
118397 + param->next_engine_on_green = compat_param->next_engine_on_green;
118398 + param->next_engine_on_yellow = compat_param->next_engine_on_yellow;
118399 + param->next_engine_on_red = compat_param->next_engine_on_red;
118400 +
118401 + param->trap_profile_on_flow_A = compat_param->trap_profile_on_flow_A;
118402 + param->trap_profile_on_flow_B = compat_param->trap_profile_on_flow_B;
118403 + param->trap_profile_on_flow_C = compat_param->trap_profile_on_flow_C;
118404 + }
118405 + else
118406 + {
118407 + compat_param->modify = param->modify;
118408 +
118409 + /* profile_select */
118410 + if (!param->modify)
118411 + {
118412 + compat_param->profile_select.new_params.profile_type =
118413 + param->profile_select.new_params.profile_type;
118414 + compat_param->profile_select.new_params.p_fm_port =
118415 + ptr_to_compat(param->profile_select.new_params.p_fm_port);
118416 + compat_param->profile_select.new_params.relative_profile_id =
118417 + param->profile_select.new_params.relative_profile_id;
118418 + }
118419 + else
118420 + compat_param->profile_select.p_profile =
118421 + compat_pcd_ptr2id(param->profile_select.p_profile);
118422 +
118423 + compat_param->alg_selection = param->alg_selection;
118424 + compat_param->color_mode = param->color_mode;
118425 +
118426 + /* both parameters in the union has the same size, so memcpy works */
118427 + memcpy(&compat_param->color, &param->color, sizeof(compat_param->color));
118428 +
118429 + memcpy(&compat_param->non_passthrough_alg_param,
118430 + &param->non_passthrough_alg_param,
118431 + sizeof(ioc_fm_pcd_plcr_non_passthrough_alg_param_t));
118432 +
118433 + compat_param->next_engine_on_green = param->next_engine_on_green;
118434 + compat_param->next_engine_on_yellow = param->next_engine_on_yellow;
118435 + compat_param->next_engine_on_red = param->next_engine_on_red;
118436 +
118437 + compat_param->trap_profile_on_flow_A = param->trap_profile_on_flow_A;
118438 + compat_param->trap_profile_on_flow_B = param->trap_profile_on_flow_B;
118439 + compat_param->trap_profile_on_flow_C = param->trap_profile_on_flow_C;
118440 +
118441 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118442 + }
118443 +
118444 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_green,
118445 + &param->params_on_green, param->next_engine_on_green, compat);
118446 +
118447 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_yellow,
118448 + &param->params_on_yellow, param->next_engine_on_yellow, compat);
118449 +
118450 + compat_copy_fm_pcd_plcr_next_engine(&compat_param->params_on_red,
118451 + &param->params_on_red, param->next_engine_on_red, compat);
118452 +
118453 + _fm_cpt_dbg (compat, " ...->}\n");
118454 +}
118455 +
118456 +static inline void compat_copy_fm_pcd_cc_next_kg(
118457 + ioc_compat_fm_pcd_cc_next_kg_params_t *compat_param,
118458 + ioc_fm_pcd_cc_next_kg_params_t *param,
118459 + uint8_t compat)
118460 +{
118461 + _fm_cpt_dbg (compat, " {->...\n");
118462 +
118463 + if (compat == COMPAT_US_TO_K)
118464 + {
118465 + param->new_fqid = compat_param->new_fqid;
118466 + param->override_fqid = compat_param->override_fqid;
118467 +#if DPAA_VERSION >= 11
118468 + param->new_relative_storage_profile_id = compat_param->new_relative_storage_profile_id;
118469 +#endif
118470 + param->p_direct_scheme = compat_pcd_id2ptr(compat_param->p_direct_scheme);
118471 + }
118472 + else
118473 + {
118474 + compat_param->new_fqid = param->new_fqid;
118475 + compat_param->override_fqid = param->override_fqid;
118476 +#if DPAA_VERSION >= 11
118477 + compat_param->new_relative_storage_profile_id = param->new_relative_storage_profile_id;
118478 +#endif
118479 + compat_param->p_direct_scheme = compat_pcd_ptr2id(param->p_direct_scheme);
118480 + }
118481 +
118482 + _fm_cpt_dbg (compat, " ...->}\n");
118483 +}
118484 +
118485 +static inline void compat_copy_fm_pcd_cc_next_cc(
118486 + ioc_compat_fm_pcd_cc_next_cc_params_t *compat_param,
118487 + ioc_fm_pcd_cc_next_cc_params_t *param,
118488 + uint8_t compat)
118489 +{
118490 + _fm_cpt_dbg (compat, " {->...\n");
118491 +
118492 + if (compat == COMPAT_US_TO_K)
118493 + param->cc_node_id = compat_pcd_id2ptr(compat_param->cc_node_id);
118494 + else
118495 + compat_param->cc_node_id = compat_pcd_ptr2id(param->cc_node_id);
118496 +
118497 + _fm_cpt_dbg (compat, " ...->}\n");
118498 +}
118499 +
118500 +static inline void compat_copy_fm_pcd_cc_next_engine(
118501 + ioc_compat_fm_pcd_cc_next_engine_params_t *compat_param,
118502 + ioc_fm_pcd_cc_next_engine_params_t *param,
118503 + uint8_t compat)
118504 +{
118505 + _fm_cpt_dbg (compat, " {->...\n");
118506 +
118507 + if (compat == COMPAT_US_TO_K)
118508 + {
118509 + param->next_engine = compat_param->next_engine;
118510 + if (param->next_engine != e_IOC_FM_PCD_INVALID )
118511 + _fm_cpt_dbg(compat, " param->next_engine = %i \n", param->next_engine);
118512 +
118513 + switch (param->next_engine)
118514 + {
118515 +#if DPAA_VERSION >= 11
118516 + case e_IOC_FM_PCD_FR:
118517 + param->params.fr_params.frm_replic_id = compat_pcd_id2ptr(compat_param->params.fr_params.frm_replic_id);
118518 + break;
118519 +#endif /* DPAA_VERSION >= 11 */
118520 + case e_IOC_FM_PCD_CC:
118521 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
118522 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
118523 + break;
118524 + case e_IOC_FM_PCD_KG:
118525 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
118526 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
118527 + break;
118528 + case e_IOC_FM_PCD_DONE:
118529 + case e_IOC_FM_PCD_PLCR:
118530 + param->manip_id = compat_pcd_id2ptr(compat_param->manip_id);
118531 + default:
118532 + memcpy(&param->params, &compat_param->params, sizeof(param->params));
118533 + }
118534 + param->statistics_en = compat_param->statistics_en;
118535 + }
118536 + else
118537 + {
118538 + compat_param->next_engine = param->next_engine;
118539 +
118540 + switch (compat_param->next_engine)
118541 + {
118542 +#if DPAA_VERSION >= 11
118543 + case e_IOC_FM_PCD_FR:
118544 + compat_param->params.fr_params.frm_replic_id = compat_pcd_ptr2id(param->params.fr_params.frm_replic_id);
118545 + break;
118546 +#endif /* DPAA_VERSION >= 11 */
118547 + case e_IOC_FM_PCD_CC:
118548 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
118549 + compat_copy_fm_pcd_cc_next_cc(&compat_param->params.cc_params, &param->params.cc_params, compat);
118550 + break;
118551 + case e_IOC_FM_PCD_KG:
118552 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
118553 + compat_copy_fm_pcd_cc_next_kg(&compat_param->params.kg_params, &param->params.kg_params, compat);
118554 + break;
118555 + case e_IOC_FM_PCD_DONE:
118556 + case e_IOC_FM_PCD_PLCR:
118557 + compat_param->manip_id = compat_pcd_ptr2id(param->manip_id);
118558 + default:
118559 + memcpy(&compat_param->params, &param->params, sizeof(compat_param->params));
118560 + }
118561 + compat_param->statistics_en = param->statistics_en;
118562 + }
118563 +
118564 + _fm_cpt_dbg (compat, " ...->}\n");
118565 +}
118566 +
118567 +void compat_copy_fm_pcd_cc_key(
118568 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
118569 + ioc_fm_pcd_cc_key_params_t *param,
118570 + uint8_t compat)
118571 +{
118572 + if (compat == COMPAT_US_TO_K)
118573 + {
118574 + param->p_key = compat_ptr(compat_param->p_key);
118575 + param->p_mask = compat_ptr(compat_param->p_mask);
118576 + }
118577 + else
118578 + {
118579 + compat_param->p_key = ptr_to_compat(param->p_key);
118580 + compat_param->p_mask = ptr_to_compat(param->p_mask);
118581 + }
118582 +
118583 + compat_copy_fm_pcd_cc_next_engine(
118584 + &compat_param->cc_next_engine_params,
118585 + &param->cc_next_engine_params,
118586 + compat);
118587 +}
118588 +
118589 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
118590 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
118591 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
118592 + uint8_t compat)
118593 +{
118594 + if (compat == COMPAT_US_TO_K)
118595 + {
118596 + param->id = compat_pcd_id2ptr(compat_param->id);
118597 + param->key_indx = compat_param->key_indx;
118598 + param->key_size = compat_param->key_size;
118599 + compat_copy_fm_pcd_cc_key(
118600 + &compat_param->key_params,
118601 + &param->key_params,
118602 + compat);
118603 + }
118604 + else
118605 + {
118606 + compat_param->id = compat_pcd_ptr2id(param->id);
118607 + compat_param->key_indx = param->key_indx;
118608 + compat_param->key_size = param->key_size;
118609 + compat_copy_fm_pcd_cc_key(
118610 + &compat_param->key_params,
118611 + &param->key_params,
118612 + compat);
118613 + }
118614 +}
118615 +
118616 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
118617 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
118618 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
118619 + uint8_t compat)
118620 +{
118621 + if (compat == COMPAT_US_TO_K)
118622 + {
118623 + param->id = compat_pcd_id2ptr(compat_param->id);
118624 + param->key_indx = compat_param->key_indx;
118625 + param->key_size = compat_param->key_size;
118626 + }
118627 + else
118628 + {
118629 + compat_param->id = compat_pcd_ptr2id(param->id);
118630 + compat_param->key_indx = param->key_indx;
118631 + compat_param->key_size = param->key_size;
118632 + }
118633 +
118634 + compat_copy_fm_pcd_cc_next_engine(
118635 + &compat_param->cc_next_engine_params,
118636 + &param->cc_next_engine_params,
118637 + compat);
118638 +}
118639 +
118640 +void compat_fm_pcd_cc_tree_modify_next_engine(
118641 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
118642 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
118643 + uint8_t compat)
118644 +{
118645 + if (compat == COMPAT_US_TO_K)
118646 + {
118647 + param->id = compat_pcd_id2ptr(compat_param->id);
118648 + param->grp_indx = compat_param->grp_indx;
118649 + param->indx = compat_param->indx;
118650 + }
118651 + else
118652 + {
118653 + compat_param->id = compat_pcd_ptr2id(param->id);
118654 + compat_param->grp_indx = param->grp_indx;
118655 + compat_param->indx = param->indx;
118656 + }
118657 +
118658 + compat_copy_fm_pcd_cc_next_engine(
118659 + &compat_param->cc_next_engine_params,
118660 + &param->cc_next_engine_params,
118661 + compat);
118662 +}
118663 +
118664 +void compat_copy_fm_pcd_hash_table(
118665 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
118666 + ioc_fm_pcd_hash_table_params_t *param,
118667 + uint8_t compat)
118668 +{
118669 + if (compat == COMPAT_US_TO_K)
118670 + {
118671 + param->max_num_of_keys = compat_param->max_num_of_keys;
118672 + param->statistics_mode = compat_param->statistics_mode;
118673 + param->kg_hash_shift = compat_param->kg_hash_shift;
118674 + param->hash_res_mask = compat_param->hash_res_mask;
118675 + param->hash_shift = compat_param->hash_shift;
118676 + param->match_key_size = compat_param->match_key_size;
118677 + param->id = compat_pcd_id2ptr(compat_param->id);
118678 + }
118679 + else
118680 + {
118681 + compat_param->max_num_of_keys = param->max_num_of_keys;
118682 + compat_param->statistics_mode = param->statistics_mode;
118683 + compat_param->kg_hash_shift = param->kg_hash_shift;
118684 + compat_param->hash_res_mask = param->hash_res_mask;
118685 + compat_param->hash_shift = param->hash_shift;
118686 + compat_param->match_key_size = param->match_key_size;
118687 +
118688 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118689 + }
118690 +
118691 + compat_copy_fm_pcd_cc_next_engine(
118692 + &compat_param->cc_next_engine_params_for_miss,
118693 + &param->cc_next_engine_params_for_miss,
118694 + compat);
118695 +}
118696 +
118697 +void compat_copy_fm_pcd_cc_grp(
118698 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
118699 + ioc_fm_pcd_cc_grp_params_t *param,
118700 + uint8_t compat)
118701 +{
118702 + int k;
118703 +
118704 + _fm_cpt_dbg (compat, " {->...\n");
118705 +
118706 + if (compat == COMPAT_US_TO_K)
118707 + {
118708 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
118709 + memcpy(param->unit_ids, compat_param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
118710 + }
118711 + else
118712 + {
118713 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
118714 + memcpy(compat_param->unit_ids, param->unit_ids, IOC_FM_PCD_MAX_NUM_OF_CC_UNITS);
118715 + }
118716 +
118717 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP; k++)
118718 + compat_copy_fm_pcd_cc_next_engine(
118719 + &compat_param->next_engine_per_entries_in_grp[k],
118720 + &param->next_engine_per_entries_in_grp[k],
118721 + compat);
118722 +
118723 + _fm_cpt_dbg (compat, " ...->}\n");
118724 +}
118725 +
118726 +void compat_copy_fm_pcd_cc_tree(
118727 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
118728 + ioc_fm_pcd_cc_tree_params_t *param,
118729 + uint8_t compat)
118730 +{
118731 + int k;
118732 + _fm_cpt_dbg (compat, " {->...\n");
118733 +
118734 + if (compat == COMPAT_US_TO_K)
118735 + {
118736 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
118737 + param->num_of_groups = compat_param->num_of_groups;
118738 + }
118739 + else
118740 + {
118741 + compat_param->net_env_id = compat_pcd_ptr2id(param->net_env_id);
118742 + compat_param->num_of_groups = param->num_of_groups;
118743 +
118744 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118745 + }
118746 +
118747 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS; k++)
118748 + compat_copy_fm_pcd_cc_grp(
118749 + &compat_param->fm_pcd_cc_group_params[k],
118750 + &param->fm_pcd_cc_group_params[k],
118751 + compat);
118752 +
118753 + _fm_cpt_dbg (compat, " ...->}\n");
118754 +}
118755 +
118756 +void compat_fm_pcd_prs_sw(
118757 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
118758 + ioc_fm_pcd_prs_sw_params_t *param,
118759 + uint8_t compat)
118760 +{
118761 + if (compat == COMPAT_US_TO_K)
118762 + {
118763 + param->override = compat_param->override;
118764 + param->size = compat_param->size;
118765 + param->base = compat_param->base;
118766 + param->p_code = compat_ptr(compat_param->p_code);
118767 + memcpy(param->sw_prs_data_params,compat_param->sw_prs_data_params,IOC_FM_PCD_PRS_NUM_OF_HDRS*sizeof(uint32_t));
118768 + param->num_of_labels = compat_param->num_of_labels;
118769 + memcpy(param->labels_table,compat_param->labels_table,IOC_FM_PCD_PRS_NUM_OF_LABELS*sizeof(ioc_fm_pcd_prs_label_params_t));
118770 + }
118771 +}
118772 +
118773 +void compat_copy_fm_pcd_kg_scheme(
118774 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
118775 + ioc_fm_pcd_kg_scheme_params_t *param,
118776 + uint8_t compat)
118777 +{
118778 + _fm_cpt_dbg(compat," {->...\n");
118779 +
118780 + if (compat == COMPAT_US_TO_K)
118781 + {
118782 + param->modify = compat_param->modify;
118783 +
118784 + /* scm_id */
118785 + if (compat_param->modify)
118786 + {
118787 + param->scm_id.scheme_id = compat_pcd_id2ptr(compat_param->scm_id.scheme_id);
118788 + _fm_cpt_dbg(compat," param->scm_id.scheme_id = %p \n", param->scm_id.scheme_id);
118789 + }
118790 + else
118791 + param->scm_id.relative_scheme_id = compat_param->scm_id.relative_scheme_id;
118792 +
118793 + param->always_direct = compat_param->always_direct;
118794 + /* net_env_params */
118795 + param->net_env_params.net_env_id = compat_pcd_id2ptr(compat_param->net_env_params.net_env_id);
118796 + param->net_env_params.num_of_distinction_units = compat_param->net_env_params.num_of_distinction_units;
118797 + memcpy(param->net_env_params.unit_ids,
118798 + compat_param->net_env_params.unit_ids,
118799 + IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
118800 +
118801 + param->use_hash = compat_param->use_hash;
118802 + memcpy(&param->key_extract_and_hash_params,
118803 + &compat_param->key_extract_and_hash_params,
118804 + sizeof(ioc_fm_pcd_kg_key_extract_and_hash_params_t));
118805 + param->bypass_fqid_generation = compat_param->bypass_fqid_generation;
118806 + param->base_fqid = compat_param->base_fqid;
118807 +#if DPAA_VERSION >= 11
118808 + param->override_storage_profile =
118809 + compat_param->override_storage_profile;
118810 + param->storage_profile = compat_param->storage_profile;
118811 +#endif
118812 + param->num_of_used_extracted_ors = compat_param->num_of_used_extracted_ors;
118813 + memcpy(param->extracted_ors,
118814 + compat_param->extracted_ors,
118815 + IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS * sizeof(ioc_fm_pcd_kg_extracted_or_params_t));
118816 + param->next_engine = compat_param->next_engine;
118817 +
118818 + /* kg_next_engine_params */
118819 + if (param->next_engine == e_IOC_FM_PCD_CC)
118820 + {
118821 + param->kg_next_engine_params.cc.tree_id = compat_pcd_id2ptr(compat_param->kg_next_engine_params.cc.tree_id);
118822 + param->kg_next_engine_params.cc.grp_id = compat_param->kg_next_engine_params.cc.grp_id;
118823 + param->kg_next_engine_params.cc.plcr_next = compat_param->kg_next_engine_params.cc.plcr_next;
118824 + param->kg_next_engine_params.cc.bypass_plcr_profile_generation
118825 + = compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
118826 + memcpy(&param->kg_next_engine_params.cc.plcr_profile,
118827 + &compat_param->kg_next_engine_params.cc.plcr_profile,
118828 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
118829 + }
118830 + else
118831 + memcpy(&param->kg_next_engine_params,
118832 + &compat_param->kg_next_engine_params,
118833 + sizeof(param->kg_next_engine_params));
118834 +
118835 + memcpy(&param->scheme_counter,
118836 + &compat_param->scheme_counter,
118837 + sizeof(ioc_fm_pcd_kg_scheme_counter_t));
118838 + }
118839 + else
118840 + {
118841 + compat_param->modify = param->modify;
118842 +
118843 + /* scm_id */
118844 + if (param->modify)
118845 + compat_param->scm_id.scheme_id = compat_pcd_ptr2id(param->scm_id.scheme_id);
118846 + else
118847 + compat_param->scm_id.relative_scheme_id = param->scm_id.relative_scheme_id;
118848 +
118849 + compat_param->always_direct = param->always_direct;
118850 +
118851 + /* net_env_params */
118852 + compat_param->net_env_params.net_env_id = compat_pcd_ptr2id(param->net_env_params.net_env_id);
118853 + compat_param->net_env_params.num_of_distinction_units = param->net_env_params.num_of_distinction_units;
118854 + memcpy(compat_param->net_env_params.unit_ids, param->net_env_params.unit_ids, IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
118855 +
118856 + compat_param->use_hash = param->use_hash;
118857 + 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));
118858 + compat_param->bypass_fqid_generation = param->bypass_fqid_generation;
118859 + compat_param->base_fqid = param->base_fqid;
118860 +#if DPAA_VERSION >= 11
118861 + compat_param->override_storage_profile =
118862 + param->override_storage_profile;
118863 + compat_param->storage_profile = param->storage_profile;
118864 +#endif
118865 + compat_param->num_of_used_extracted_ors = param->num_of_used_extracted_ors;
118866 + 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));
118867 + compat_param->next_engine = param->next_engine;
118868 +
118869 + /* kg_next_engine_params */
118870 + if (compat_param->next_engine == e_IOC_FM_PCD_CC)
118871 + {
118872 + compat_param->kg_next_engine_params.cc.tree_id = compat_pcd_ptr2id(param->kg_next_engine_params.cc.tree_id);
118873 + compat_param->kg_next_engine_params.cc.grp_id = param->kg_next_engine_params.cc.grp_id;
118874 + compat_param->kg_next_engine_params.cc.plcr_next = param->kg_next_engine_params.cc.plcr_next;
118875 + compat_param->kg_next_engine_params.cc.bypass_plcr_profile_generation
118876 + = param->kg_next_engine_params.cc.bypass_plcr_profile_generation;
118877 + memcpy(&compat_param->kg_next_engine_params.cc.plcr_profile,
118878 + &param->kg_next_engine_params.cc.plcr_profile,
118879 + sizeof(ioc_fm_pcd_kg_plcr_profile_t));
118880 + }
118881 + else
118882 + memcpy(&param->kg_next_engine_params, &compat_param->kg_next_engine_params, sizeof(compat_param->kg_next_engine_params));
118883 +
118884 + memcpy(&compat_param->scheme_counter, &param->scheme_counter, sizeof(ioc_fm_pcd_kg_scheme_counter_t));
118885 +
118886 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
118887 + }
118888 +
118889 + _fm_cpt_dbg(compat," ...->}\n");
118890 +}
118891 +
118892 +void compat_copy_fm_pcd_kg_scheme_spc(
118893 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
118894 + ioc_fm_pcd_kg_scheme_spc_t *param,
118895 + uint8_t compat)
118896 +{
118897 + if (compat == COMPAT_US_TO_K)
118898 + {
118899 + param->id = compat_pcd_id2ptr(compat_param->id);
118900 + param->val = compat_param->val;
118901 + } else {
118902 + compat_param->id = compat_pcd_ptr2id(param->id);
118903 + compat_param->val = param->val;
118904 + }
118905 +}
118906 +
118907 +
118908 +void compat_copy_fm_pcd_kg_scheme_select(
118909 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
118910 + ioc_fm_pcd_kg_scheme_select_t *param,
118911 + uint8_t compat)
118912 +{
118913 + if (compat == COMPAT_US_TO_K)
118914 + {
118915 + param->direct = compat_param->direct;
118916 + if (param->direct)
118917 + param->scheme_id = compat_pcd_id2ptr(compat_param->scheme_id);
118918 + }
118919 +}
118920 +
118921 +void compat_copy_fm_pcd_kg_schemes_params(
118922 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
118923 + ioc_fm_pcd_port_schemes_params_t *param,
118924 + uint8_t compat)
118925 +{
118926 + int k;
118927 +
118928 + if (compat == COMPAT_US_TO_K) {
118929 + param->num_of_schemes = compat_param->num_of_schemes;
118930 + for(k=0; k < compat_param->num_of_schemes; k++)
118931 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
118932 + }
118933 +}
118934 +
118935 +void compat_copy_fm_port_pcd_cc(
118936 + ioc_compat_fm_port_pcd_cc_params_t *compat_cc_params ,
118937 + ioc_fm_port_pcd_cc_params_t *p_cc_params,
118938 + uint8_t compat)
118939 +{
118940 + if (compat == COMPAT_US_TO_K){
118941 + p_cc_params->cc_tree_id = compat_pcd_id2ptr(compat_cc_params->cc_tree_id);
118942 + }
118943 +}
118944 +
118945 +void compat_copy_fm_port_pcd_kg(
118946 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
118947 + ioc_fm_port_pcd_kg_params_t *param,
118948 + uint8_t compat)
118949 +{
118950 + if (compat == COMPAT_US_TO_K){
118951 + uint8_t k;
118952 +
118953 + param->num_of_schemes = compat_param->num_of_schemes;
118954 + for(k=0; k<compat_param->num_of_schemes; k++)
118955 + param->scheme_ids[k] = compat_pcd_id2ptr(compat_param->scheme_ids[k]);
118956 +
118957 + param->direct_scheme = compat_param->direct_scheme;
118958 + if (param->direct_scheme)
118959 + param->direct_scheme_id = compat_pcd_id2ptr(compat_param->direct_scheme_id);
118960 + }
118961 +}
118962 +
118963 +void compat_copy_fm_port_pcd(
118964 + ioc_compat_fm_port_pcd_params_t *compat_param,
118965 + ioc_fm_port_pcd_params_t *param,
118966 + uint8_t compat)
118967 +{
118968 + if (compat == COMPAT_US_TO_K)
118969 + {
118970 + ioc_fm_port_pcd_prs_params_t *same_port_pcd_prs_params;
118971 + ioc_compat_fm_port_pcd_cc_params_t *compat_port_pcd_cc_params;
118972 + ioc_compat_fm_port_pcd_kg_params_t *compat_port_pcd_kg_params;
118973 + ioc_compat_fm_port_pcd_plcr_params_t *compat_port_pcd_plcr_params;
118974 +
118975 + same_port_pcd_prs_params = (ioc_fm_port_pcd_prs_params_t *) (compat_param + 1);
118976 + compat_port_pcd_cc_params = (ioc_compat_fm_port_pcd_cc_params_t *) (same_port_pcd_prs_params + 1);
118977 + compat_port_pcd_kg_params = (ioc_compat_fm_port_pcd_kg_params_t *) (compat_port_pcd_cc_params + 1);
118978 + compat_port_pcd_plcr_params = (ioc_compat_fm_port_pcd_plcr_params_t *) (compat_port_pcd_kg_params + 1);
118979 +
118980 + _fm_cpt_dbg(compat,"\n param->p_prs_params=%p \n", param->p_prs_params);
118981 + _fm_cpt_dbg(compat," param->p_cc_params=%p \n", param->p_cc_params);
118982 + _fm_cpt_dbg(compat," param->p_kg_params=%p \n", param->p_kg_params);
118983 + _fm_cpt_dbg(compat," param->p_plcr_params=%p \n", param->p_plcr_params);
118984 + _fm_cpt_dbg(compat," param->p_ip_reassembly_manip=%p \n", param->p_ip_reassembly_manip);
118985 +#if (DPAA_VERSION >= 11)
118986 + _fm_cpt_dbg(compat," param->p_capwap_reassembly_manip=%p \n", param->p_capwap_reassembly_manip);
118987 +#endif
118988 + param->pcd_support = compat_param->pcd_support;
118989 + param->net_env_id = compat_pcd_id2ptr(compat_param->net_env_id);
118990 +
118991 + if (param->p_cc_params)
118992 + compat_copy_fm_port_pcd_cc(compat_port_pcd_cc_params, param->p_cc_params, COMPAT_US_TO_K);
118993 + if (param->p_kg_params)
118994 + compat_copy_fm_port_pcd_kg(compat_port_pcd_kg_params, param->p_kg_params, COMPAT_US_TO_K);
118995 + if (param->p_plcr_params)
118996 + param->p_plcr_params->plcr_profile_id = compat_pcd_id2ptr(compat_port_pcd_plcr_params->plcr_profile_id);
118997 + param->p_ip_reassembly_manip = compat_pcd_id2ptr(compat_param->p_ip_reassembly_manip);
118998 +#if (DPAA_VERSION >= 11)
118999 + param->p_capwap_reassembly_manip = compat_pcd_id2ptr(compat_param->p_capwap_reassembly_manip);
119000 +#endif
119001 + }
119002 +}
119003 +
119004 +void compat_copy_fm_port_pcd_modify_tree(
119005 + ioc_compat_fm_obj_t *compat_id,
119006 + ioc_fm_obj_t *id,
119007 + uint8_t compat)
119008 +{
119009 + if (compat == COMPAT_US_TO_K)
119010 + id->obj = compat_pcd_id2ptr(compat_id->obj);
119011 +}
119012 +
119013 +#if (DPAA_VERSION >= 11)
119014 +void compat_copy_fm_port_vsp_alloc_params(
119015 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
119016 + ioc_fm_port_vsp_alloc_params_t *param,
119017 + uint8_t compat)
119018 +{
119019 + if (compat == COMPAT_US_TO_K)
119020 + {
119021 + _fm_cpt_dbg(compat," param->p_fm_tx_port=%p \n", param->p_fm_tx_port);
119022 +
119023 + param->dflt_relative_id = compat_param->dflt_relative_id;
119024 + param->num_of_profiles = compat_param->num_of_profiles;
119025 + param->p_fm_tx_port = compat_pcd_id2ptr(compat_param->p_fm_tx_port);
119026 + }
119027 +}
119028 +#endif /* (DPAA_VERSION >= 11) */
119029 +
119030 +void compat_copy_fm_pcd_cc_tbl_get_stats(
119031 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
119032 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
119033 + uint8_t compat)
119034 +{
119035 + if (compat == COMPAT_US_TO_K)
119036 + {
119037 + param->id = compat_pcd_id2ptr(compat_param->id);
119038 + param->key_index = compat_param->key_index;
119039 + memcpy(&param->statistics, &compat_param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
119040 + } else {
119041 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
119042 + compat_param->key_index = param->key_index;
119043 + memcpy(&compat_param->statistics, &param->statistics, sizeof(ioc_fm_pcd_cc_key_statistics_t));
119044 + }
119045 +}
119046 +
119047 +
119048 +void compat_copy_fm_pcd_net_env(
119049 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
119050 + ioc_fm_pcd_net_env_params_t *param,
119051 + uint8_t compat)
119052 +{
119053 + if (compat == COMPAT_US_TO_K)
119054 + {
119055 + param->num_of_distinction_units = compat_param->num_of_distinction_units;
119056 + memcpy(param->units, compat_param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
119057 + param->id = NULL; /* to avoid passing garbage to the kernel */
119058 + }
119059 + else
119060 + {
119061 + compat_param->num_of_distinction_units = param->num_of_distinction_units;
119062 + memcpy(compat_param->units, param->units, sizeof(ioc_fm_pcd_distinction_unit_t)*IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS);
119063 +
119064 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
119065 + }
119066 +}
119067 +
119068 +void compat_copy_fm_pcd_cc_node_modify_key(
119069 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
119070 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
119071 + uint8_t compat)
119072 +{
119073 + if (compat == COMPAT_US_TO_K)
119074 + {
119075 + param->key_indx = compat_param->key_indx;
119076 + param->key_size = compat_param->key_size;
119077 + param->p_key = (uint8_t *)compat_ptr(compat_param->p_key);
119078 + _fm_cpt_dbg(compat," param->p_key = %p \n", param->p_key);
119079 + param->p_mask = (uint8_t *)compat_ptr(compat_param->p_mask);
119080 + _fm_cpt_dbg(compat," param->p_mask = %p\n", param->p_mask);
119081 + param->id = compat_pcd_id2ptr(compat_param->id);
119082 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
119083 + }
119084 + else
119085 + {
119086 + compat_param->key_indx = param->key_indx;
119087 + compat_param->key_size = param->key_size;
119088 + compat_param->p_key = ptr_to_compat((void *)param->p_key);
119089 + compat_param->p_mask = ptr_to_compat((void *)param->p_mask);
119090 +
119091 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
119092 + }
119093 +}
119094 +
119095 +void compat_copy_keys(
119096 + ioc_compat_keys_params_t *compat_param,
119097 + ioc_keys_params_t *param,
119098 + uint8_t compat)
119099 +{
119100 + int k = 0;
119101 +
119102 + _fm_cpt_dbg(compat," {->...\n");
119103 +
119104 + if (compat == COMPAT_US_TO_K) {
119105 + param->max_num_of_keys = compat_param->max_num_of_keys;
119106 + param->mask_support = compat_param->mask_support;
119107 + param->statistics_mode = compat_param->statistics_mode;
119108 + param->num_of_keys = compat_param->num_of_keys;
119109 + param->key_size = compat_param->key_size;
119110 +#if (DPAA_VERSION >= 11)
119111 + memcpy(&param->frame_length_ranges,
119112 + &compat_param->frame_length_ranges,
119113 + sizeof(param->frame_length_ranges[0]) *
119114 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
119115 +#endif /* (DPAA_VERSION >= 11) */
119116 + }
119117 + else {
119118 + compat_param->max_num_of_keys = param->max_num_of_keys;
119119 + compat_param->mask_support = param->mask_support;
119120 + compat_param->statistics_mode = param->statistics_mode;
119121 + compat_param->num_of_keys = param->num_of_keys;
119122 + compat_param->key_size = param->key_size;
119123 +#if (DPAA_VERSION >= 11)
119124 + memcpy(&compat_param->frame_length_ranges,
119125 + &param->frame_length_ranges,
119126 + sizeof(compat_param->frame_length_ranges[0]) *
119127 + IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR);
119128 +#endif /* (DPAA_VERSION >= 11) */
119129 + }
119130 +
119131 + for (k=0; k < IOC_FM_PCD_MAX_NUM_OF_KEYS; k++)
119132 + compat_copy_fm_pcd_cc_key(
119133 + &compat_param->key_params[k],
119134 + &param->key_params[k],
119135 + compat);
119136 +
119137 + compat_copy_fm_pcd_cc_next_engine(
119138 + &compat_param->cc_next_engine_params_for_miss,
119139 + &param->cc_next_engine_params_for_miss,
119140 + compat);
119141 +
119142 + _fm_cpt_dbg(compat," ...->}\n");
119143 +}
119144 +
119145 +void compat_copy_fm_pcd_cc_node(
119146 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
119147 + ioc_fm_pcd_cc_node_params_t *param,
119148 + uint8_t compat)
119149 +{
119150 + _fm_cpt_dbg(compat," {->...\n");
119151 +
119152 + if (compat == COMPAT_US_TO_K)
119153 + memcpy(&param->extract_cc_params, &compat_param->extract_cc_params, sizeof(ioc_fm_pcd_extract_entry_t));
119154 +
119155 + else
119156 + {
119157 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
119158 +
119159 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
119160 + _fm_cpt_dbg(compat," param->id = %p \n", param->id);
119161 + }
119162 +
119163 + compat_copy_keys(&compat_param->keys_params, &param->keys_params, compat);
119164 +
119165 + _fm_cpt_dbg(compat," ...->}\n");
119166 +}
119167 +
119168 +void compat_fm_pcd_manip_set_node(
119169 + ioc_compat_fm_pcd_manip_params_t *compat_param,
119170 + ioc_fm_pcd_manip_params_t *param,
119171 + uint8_t compat)
119172 +{
119173 + if (compat == COMPAT_US_TO_K) {
119174 + param->type = compat_param->type;
119175 + switch (param->type) {
119176 + case e_IOC_FM_PCD_MANIP_HDR:
119177 + param->u.hdr.rmv = compat_param->u.hdr.rmv;
119178 + memcpy(&param->u.hdr.rmv_params,
119179 + &compat_param->u.hdr.rmv_params,
119180 + sizeof(param->u.hdr.rmv_params));
119181 +
119182 + param->u.hdr.insrt = compat_param->u.hdr.insrt;
119183 + param->u.hdr.insrt_params.type =
119184 + compat_param->u.hdr.insrt_params.type;
119185 + switch (compat_param->u.hdr.insrt_params.type)
119186 + {
119187 + case e_IOC_FM_PCD_MANIP_INSRT_GENERIC:
119188 + param->u.hdr.insrt_params.u.generic.offset =
119189 + compat_param->u.hdr.insrt_params.u.generic.offset;
119190 + param->u.hdr.insrt_params.u.generic.size =
119191 + compat_param->u.hdr.insrt_params.u.generic.size;
119192 + param->u.hdr.insrt_params.u.generic.replace =
119193 + compat_param->u.hdr.insrt_params.u.generic.replace;
119194 + param->u.hdr.insrt_params.u.generic.p_data =
119195 + compat_ptr(compat_param->u.hdr.insrt_params.u.generic.p_data);
119196 + break;
119197 + case e_IOC_FM_PCD_MANIP_INSRT_BY_HDR:
119198 + param->u.hdr.insrt_params.u.by_hdr.type =
119199 + compat_param->u.hdr.insrt_params.u.by_hdr.type;
119200 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2 =
119201 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.specific_l2;
119202 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update =
119203 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.update;
119204 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size =
119205 + compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.size;
119206 + param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data =
119207 + compat_ptr(compat_param->u.hdr.insrt_params.u.by_hdr.u.specific_l2_params.p_data);
119208 + break;
119209 + default:
119210 + _fm_cpt_err("Unsupported type: %d", compat_param->u.hdr.insrt_params.type);
119211 + }
119212 +
119213 + param->u.hdr.field_update = compat_param->u.hdr.field_update;
119214 + memcpy(&param->u.hdr.field_update_params,
119215 + &compat_param->u.hdr.field_update_params,
119216 + sizeof(param->u.hdr.field_update_params));
119217 +
119218 + param->u.hdr.custom = compat_param->u.hdr.custom;
119219 + memcpy(&param->u.hdr.custom_params,
119220 + &compat_param->u.hdr.custom_params,
119221 + sizeof(param->u.hdr.custom_params));
119222 +
119223 + param->u.hdr.dont_parse_after_manip =
119224 + compat_param->u.hdr.dont_parse_after_manip;
119225 + break;
119226 + case e_IOC_FM_PCD_MANIP_REASSEM:
119227 + memcpy(&param->u.reassem, &compat_param->u.reassem, sizeof(param->u.reassem));
119228 + break;
119229 + case e_IOC_FM_PCD_MANIP_FRAG:
119230 + memcpy(&param->u.frag, &compat_param->u.frag, sizeof(param->u.frag));
119231 + break;
119232 + case e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD:
119233 + memcpy(&param->u.special_offload,
119234 + &compat_param->u.special_offload,
119235 + sizeof(param->u.special_offload));
119236 + break;
119237 + }
119238 +
119239 + param->p_next_manip = compat_pcd_id2ptr(compat_param->p_next_manip);
119240 + param->id = compat_pcd_id2ptr(compat_param->id);
119241 + }
119242 + else {
119243 + compat_param->type = param->type;
119244 + memcpy(&compat_param->u, &param->u, sizeof(compat_param->u));
119245 +
119246 + if (param->type == e_IOC_FM_PCD_MANIP_HDR &&
119247 + param->u.hdr.insrt_params.type == e_IOC_FM_PCD_MANIP_INSRT_GENERIC)
119248 + compat_param->u.hdr.insrt_params.u.generic.p_data =
119249 + ptr_to_compat(param->u.hdr.insrt_params.u.generic.p_data);
119250 +
119251 + compat_param->p_next_manip = compat_pcd_ptr2id(param->id);
119252 + /* ... should be one that was added previously by the very call to
119253 + compat_add_ptr2id() below: */
119254 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
119255 + }
119256 +}
119257 +
119258 +void compat_copy_fm_pcd_manip_get_stats(
119259 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
119260 + ioc_fm_pcd_manip_get_stats_t *param,
119261 + uint8_t compat)
119262 +{
119263 + _fm_cpt_dbg (compat, " {->...\n");
119264 +
119265 + if (compat == COMPAT_US_TO_K)
119266 + {
119267 + param->id = compat_pcd_id2ptr(compat_param->id);
119268 + memcpy(&param->stats, &compat_param->stats,
119269 + sizeof(ioc_fm_pcd_manip_stats_t));
119270 + }
119271 + else
119272 + {
119273 + compat_param->id = compat_add_ptr2id(param->id,
119274 + FM_MAP_TYPE_PCD_NODE);
119275 + memcpy(&compat_param->stats, &param->stats,
119276 + sizeof(ioc_fm_pcd_manip_stats_t));
119277 + }
119278 +
119279 + _fm_cpt_dbg (compat, " ...->}\n");
119280 +}
119281 +
119282 +#if (DPAA_VERSION >= 11)
119283 +void compat_copy_fm_pcd_frm_replic_group_params(
119284 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
119285 + ioc_fm_pcd_frm_replic_group_params_t *param,
119286 + uint8_t compat)
119287 +{
119288 + int k;
119289 +
119290 + _fm_cpt_dbg (compat, " {->...\n");
119291 +
119292 + if (compat == COMPAT_US_TO_K)
119293 + {
119294 + param->max_num_of_entries = compat_param->max_num_of_entries;
119295 + param->num_of_entries = compat_param->num_of_entries;
119296 + param->id = compat_pcd_id2ptr(compat_param->id);
119297 + }
119298 + else
119299 + {
119300 + compat_param->max_num_of_entries = param->max_num_of_entries;
119301 + compat_param->num_of_entries = param->num_of_entries;
119302 + compat_param->id = compat_add_ptr2id(param->id,
119303 + FM_MAP_TYPE_PCD_NODE);
119304 + }
119305 +
119306 + for (k=0; k < IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES; k++)
119307 + compat_copy_fm_pcd_cc_next_engine(
119308 + &compat_param->next_engine_params[k],
119309 + &param->next_engine_params[k],
119310 + compat);
119311 +
119312 + _fm_cpt_dbg (compat, " ...->}\n");
119313 +}
119314 +
119315 +void compat_copy_fm_pcd_frm_replic_member(
119316 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
119317 + ioc_fm_pcd_frm_replic_member_t *param,
119318 + uint8_t compat)
119319 +{
119320 + _fm_cpt_dbg (compat, " {->...\n");
119321 +
119322 + if (compat == COMPAT_US_TO_K)
119323 + {
119324 + param->h_replic_group = compat_pcd_id2ptr(compat_param->h_replic_group);
119325 + param->member_index = compat_param->member_index;
119326 + }
119327 +
119328 + _fm_cpt_dbg (compat, " ...->}\n");
119329 +}
119330 +
119331 +void compat_copy_fm_pcd_frm_replic_member_params(
119332 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
119333 + ioc_fm_pcd_frm_replic_member_params_t *param,
119334 + uint8_t compat)
119335 +{
119336 + _fm_cpt_dbg (compat, " {->...\n");
119337 +
119338 + compat_copy_fm_pcd_frm_replic_member(&compat_param->member,
119339 + &param->member, compat);
119340 +
119341 + compat_copy_fm_pcd_cc_next_engine(&compat_param->next_engine_params,
119342 + &param->next_engine_params, compat);
119343 +
119344 + _fm_cpt_dbg (compat, " ...->}\n");
119345 +}
119346 +
119347 +void compat_copy_fm_vsp_params(
119348 + ioc_compat_fm_vsp_params_t *compat_param,
119349 + ioc_fm_vsp_params_t *param,
119350 + uint8_t compat)
119351 +{
119352 + _fm_cpt_dbg (compat, " {->...\n");
119353 +
119354 + if (compat == COMPAT_US_TO_K)
119355 + {
119356 + memcpy(&param->ext_buf_pools, &compat_param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
119357 + param->liodn_offset = compat_param->liodn_offset;
119358 + param->port_params.port_id = compat_param->port_params.port_id;
119359 + param->port_params.port_type = compat_param->port_params.port_type;
119360 + param->relative_profile_id = compat_param->relative_profile_id;
119361 + }
119362 + else
119363 + {
119364 + memcpy(&compat_param->ext_buf_pools, &param->ext_buf_pools, sizeof(ioc_fm_ext_pools));
119365 + compat_param->liodn_offset = param->liodn_offset;
119366 + compat_param->port_params.port_id = param->port_params.port_id;
119367 + compat_param->port_params.port_type = param->port_params.port_type;
119368 + compat_param->relative_profile_id = param->relative_profile_id;
119369 + compat_param->id = compat_add_ptr2id(param->id, FM_MAP_TYPE_PCD_NODE);
119370 + }
119371 +
119372 + _fm_cpt_dbg (compat, " ...->}\n");
119373 +}
119374 +
119375 +void compat_copy_fm_buf_pool_depletion_params(
119376 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
119377 + ioc_fm_buf_pool_depletion_params_t *param,
119378 + uint8_t compat)
119379 +{
119380 + _fm_cpt_dbg (compat, " {->...\n");
119381 +
119382 + if (compat == COMPAT_US_TO_K)
119383 + {
119384 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
119385 + memcpy(&param->fm_buf_pool_depletion,
119386 + &compat_param->fm_buf_pool_depletion,
119387 + sizeof(ioc_fm_buf_pool_depletion_t));
119388 + }
119389 +
119390 + _fm_cpt_dbg (compat, " ...->}\n");
119391 +}
119392 +
119393 +void compat_copy_fm_buffer_prefix_content_params(
119394 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
119395 + ioc_fm_buffer_prefix_content_params_t *param,
119396 + uint8_t compat)
119397 +{
119398 + _fm_cpt_dbg (compat, " {->...\n");
119399 +
119400 + if (compat == COMPAT_US_TO_K)
119401 + {
119402 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
119403 + memcpy(&param->fm_buffer_prefix_content,
119404 + &compat_param->fm_buffer_prefix_content,
119405 + sizeof(ioc_fm_buffer_prefix_content_t));
119406 + }
119407 +
119408 + _fm_cpt_dbg (compat, " ...->}\n");
119409 +}
119410 +
119411 +void compat_copy_fm_vsp_config_no_sg_params(
119412 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
119413 + ioc_fm_vsp_config_no_sg_params_t *param,
119414 + uint8_t compat)
119415 +{
119416 + _fm_cpt_dbg (compat, " {->...\n");
119417 +
119418 + if (compat == COMPAT_US_TO_K)
119419 + {
119420 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
119421 + param->no_sg = compat_param->no_sg;
119422 + }
119423 +
119424 + _fm_cpt_dbg (compat, " ...->}\n");
119425 +}
119426 +
119427 +void compat_copy_fm_vsp_prs_result_params(
119428 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
119429 + ioc_fm_vsp_prs_result_params_t *param,
119430 + uint8_t compat)
119431 +{
119432 + _fm_cpt_dbg (compat, " {->...\n");
119433 +
119434 + if (compat == COMPAT_US_TO_K)
119435 + {
119436 + param->p_fm_vsp = compat_pcd_id2ptr(compat_param->p_fm_vsp);
119437 + /* p_data is an user-space pointer that needs to remain unmodified */
119438 + param->p_data = (void *)(unsigned long long)compat_param->p_data;
119439 + }
119440 + else
119441 + {
119442 + compat_param->p_fm_vsp = compat_pcd_ptr2id(param->p_fm_vsp);
119443 + /* p_data is an user-space pointer that needs to remain unmodified */
119444 + compat_param->p_data = (compat_uptr_t)((unsigned long long)param->p_data & 0xFFFFFFFF);
119445 + }
119446 +
119447 + _fm_cpt_dbg (compat, " ...->}\n");
119448 +}
119449 +#endif /* (DPAA_VERSION >= 11) */
119450 --- /dev/null
119451 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_ioctls_fm_compat.h
119452 @@ -0,0 +1,755 @@
119453 +/*
119454 + * Copyright 2008-2012 Freescale Semiconductor Inc.
119455 + *
119456 + * Redistribution and use in source and binary forms, with or without
119457 + * modification, are permitted provided that the following conditions are met:
119458 + * * Redistributions of source code must retain the above copyright
119459 + * notice, this list of conditions and the following disclaimer.
119460 + * * Redistributions in binary form must reproduce the above copyright
119461 + * notice, this list of conditions and the following disclaimer in the
119462 + * documentation and/or other materials provided with the distribution.
119463 + * * Neither the name of Freescale Semiconductor nor the
119464 + * names of its contributors may be used to endorse or promote products
119465 + * derived from this software without specific prior written permission.
119466 + *
119467 + *
119468 + * ALTERNATIVELY, this software may be distributed under the terms of the
119469 + * GNU General Public License ("GPL") as published by the Free Software
119470 + * Foundation, either version 2 of that License or (at your option) any
119471 + * later version.
119472 + *
119473 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
119474 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
119475 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
119476 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
119477 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
119478 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
119479 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
119480 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
119481 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
119482 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
119483 + */
119484 +
119485 +/*
119486 + @File lnxwrp_ioctls_fm_compat.h
119487 +
119488 + @Description FM PCD compat structures definition.
119489 +
119490 +*/
119491 +
119492 +#ifndef __FM_COMPAT_IOCTLS_H
119493 +#define __FM_COMPAT_IOCTLS_H
119494 +
119495 +#include <linux/compat.h>
119496 +
119497 +#define COMPAT_K_TO_US 0 /* copy from Kernel to User */
119498 +#define COMPAT_US_TO_K 1 /* copy from User to Kernel */
119499 +#define COMPAT_GENERIC 2
119500 +
119501 +#define COMPAT_COPY_K2US(dest, src, type) compat_copy_##type(src, dest, 0)
119502 +#define COMPAT_COPY_US2K(dest, src, type) compat_copy_##type(dest, src, 1)
119503 +
119504 +/* mapping kernel pointers w/ UserSpace id's { */
119505 +/* Because compat_ptr(ptr_to_compat(X)) != X, this way we cannot exchange pointers
119506 + back and forth (US - KS). compat_ptr is a cast and pointers are broken. */
119507 +#define COMPAT_PTR2ID_ARRAY_MAX (512+1) /* first location is not used */
119508 +#define COMPAT_PTR2ID_WATERMARK 0xface0000
119509 +#define COMPAT_PTR2ID_WM_MASK 0xffff0000
119510 +
119511 +/* define it for debug trace */
119512 +/*#define FM_COMPAT_DBG*/
119513 +
119514 +#define _fm_cpt_prk(stage, format, arg...) \
119515 + printk(stage "fm_cpt (cpu:%u): " format, raw_smp_processor_id(), ##arg)
119516 +
119517 +#define _fm_cpt_inf(format, arg...) _fm_cpt_prk(KERN_INFO, format, ##arg)
119518 +#define _fm_cpt_wrn(format, arg...) _fm_cpt_prk(KERN_WARNING, format, ##arg)
119519 +#define _fm_cpt_err(format, arg...) _fm_cpt_prk(KERN_ERR, format, ##arg)
119520 +
119521 +/* used for compat IOCTL debugging */
119522 +#if defined(FM_COMPAT_DBG)
119523 + #define _fm_cpt_dbg(from, format, arg...) \
119524 + do{ \
119525 + if (from == COMPAT_US_TO_K) \
119526 + printk("fm_cpt to KS [%s:%u](cpu:%u) - " format, \
119527 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
119528 + else if (from == COMPAT_K_TO_US) \
119529 + printk("fm_cpt to US [%s:%u](cpu:%u) - " format, \
119530 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
119531 + else \
119532 + printk("fm_cpt [%s:%u](cpu:%u) - " format, \
119533 + __func__, __LINE__, raw_smp_processor_id(), ##arg); \
119534 + }while(0)
119535 +#else
119536 +# define _fm_cpt_dbg(arg...)
119537 +#endif
119538 +
119539 +/*TODO: per FMan module:
119540 + *
119541 + * Parser: FM_MAP_TYPE_PARSER_NODE,
119542 + * Kg: FM_MAP_TYPE_KG_NODE,
119543 + * Policer: FM_MAP_TYPE_POLICER_NODE
119544 + * Manip: FM_MAP_TYPE_MANIP_NODE
119545 + **/
119546 +enum fm_map_node_type {
119547 + FM_MAP_TYPE_UNSPEC = 0,
119548 + FM_MAP_TYPE_PCD_NODE,
119549 +
119550 + /* add types here, update the policy */
119551 +
119552 + __FM_MAP_TYPE_AFTER_LAST,
119553 + FM_MAP_TYPE_MAX = __FM_MAP_TYPE_AFTER_LAST - 1
119554 +};
119555 +
119556 +void compat_del_ptr2id(void *p, enum fm_map_node_type);
119557 +compat_uptr_t compat_add_ptr2id(void *p, enum fm_map_node_type);
119558 +compat_uptr_t compat_get_ptr2id(void *p, enum fm_map_node_type);
119559 +void *compat_get_id2ptr(compat_uptr_t comp, enum fm_map_node_type);
119560 +
119561 +static inline compat_uptr_t compat_pcd_ptr2id(void *ptr) {
119562 + return (ptr)? compat_get_ptr2id(ptr, FM_MAP_TYPE_PCD_NODE)
119563 + : (compat_uptr_t) 0;
119564 +}
119565 +
119566 +static inline void *compat_pcd_id2ptr(compat_uptr_t id) {
119567 + return (id) ? compat_get_id2ptr(id, FM_MAP_TYPE_PCD_NODE)
119568 + : NULL;
119569 +}
119570 +
119571 +/* other similar inlines may be added as new nodes are added
119572 + to enum fm_map_node_type above... */
119573 +/* } mapping kernel pointers w/ UserSpace id's */
119574 +
119575 +/* pcd compat structures { */
119576 +typedef struct ioc_compat_fm_pcd_cc_node_remove_key_params_t {
119577 + compat_uptr_t id;
119578 + uint16_t key_indx;
119579 +} ioc_compat_fm_pcd_cc_node_remove_key_params_t;
119580 +
119581 +typedef union ioc_compat_fm_pcd_plcr_next_engine_params_u {
119582 + ioc_fm_pcd_done_action action;
119583 + compat_uptr_t p_profile;
119584 + compat_uptr_t p_direct_scheme;
119585 +} ioc_compat_fm_pcd_plcr_next_engine_params_u;
119586 +
119587 +typedef struct ioc_compat_fm_pcd_plcr_profile_params_t {
119588 + bool modify;
119589 + union {
119590 + struct {
119591 + ioc_fm_pcd_profile_type_selection profile_type;
119592 + compat_uptr_t p_fm_port;
119593 + uint16_t relative_profile_id;
119594 + } new_params;
119595 + compat_uptr_t p_profile;
119596 + } profile_select;
119597 + ioc_fm_pcd_plcr_algorithm_selection alg_selection;
119598 + ioc_fm_pcd_plcr_color_mode color_mode;
119599 +
119600 + union {
119601 + ioc_fm_pcd_plcr_color dflt_color;
119602 + ioc_fm_pcd_plcr_color override;
119603 + } color;
119604 +
119605 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param;
119606 +
119607 + ioc_fm_pcd_engine next_engine_on_green;
119608 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_green;
119609 +
119610 + ioc_fm_pcd_engine next_engine_on_yellow;
119611 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_yellow;
119612 +
119613 + ioc_fm_pcd_engine next_engine_on_red;
119614 + ioc_compat_fm_pcd_plcr_next_engine_params_u params_on_red;
119615 +
119616 + bool trap_profile_on_flow_A;
119617 + bool trap_profile_on_flow_B;
119618 + bool trap_profile_on_flow_C;
119619 + compat_uptr_t id;
119620 +} ioc_compat_fm_pcd_plcr_profile_params_t;
119621 +
119622 +typedef struct ioc_compat_fm_obj_t {
119623 + compat_uptr_t obj;
119624 +} ioc_compat_fm_obj_t;
119625 +
119626 +typedef struct ioc_compat_fm_pcd_kg_scheme_select_t {
119627 + bool direct;
119628 + compat_uptr_t scheme_id;
119629 +} ioc_compat_fm_pcd_kg_scheme_select_t;
119630 +
119631 +typedef struct ioc_compat_fm_pcd_port_schemes_params_t {
119632 + uint8_t num_of_schemes;
119633 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
119634 +} ioc_compat_fm_pcd_port_schemes_params_t;
119635 +
119636 +#if (DPAA_VERSION >= 11)
119637 +typedef struct ioc_compat_fm_port_vsp_alloc_params_t {
119638 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
119639 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
119640 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
119641 + if relevant function called for Rx port */
119642 + compat_uptr_t p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
119643 +}ioc_compat_fm_port_vsp_alloc_params_t;
119644 +#endif /* (DPAA_VERSION >= 11) */
119645 +
119646 +typedef struct ioc_compat_fm_pcd_net_env_params_t {
119647 + uint8_t num_of_distinction_units;
119648 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS]; /* same structure*/
119649 + compat_uptr_t id;
119650 +} ioc_compat_fm_pcd_net_env_params_t;
119651 +
119652 +typedef struct ioc_compat_fm_pcd_prs_sw_params_t {
119653 + bool override;
119654 + uint32_t size;
119655 + uint16_t base;
119656 + compat_uptr_t p_code;
119657 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
119658 + uint8_t num_of_labels;
119659 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
119660 +} ioc_compat_fm_pcd_prs_sw_params_t;
119661 +
119662 +typedef struct ioc_compat_fm_pcd_cc_next_kg_params_t {
119663 + bool override_fqid;
119664 + uint32_t new_fqid;
119665 +#if DPAA_VERSION >= 11
119666 + uint8_t new_relative_storage_profile_id;
119667 +#endif
119668 + compat_uptr_t p_direct_scheme;
119669 +} ioc_compat_fm_pcd_cc_next_kg_params_t;
119670 +
119671 +typedef struct ioc_compat_fm_pcd_cc_next_cc_params_t {
119672 + compat_uptr_t cc_node_id;
119673 +} ioc_compat_fm_pcd_cc_next_cc_params_t;
119674 +
119675 +#if DPAA_VERSION >= 11
119676 +typedef struct ioc_compat_fm_pcd_cc_next_fr_params_t {
119677 + compat_uptr_t frm_replic_id;
119678 +} ioc_compat_fm_pcd_cc_next_fr_params_t;
119679 +#endif /* DPAA_VERSION >= 11 */
119680 +
119681 +typedef struct ioc_compat_fm_pcd_cc_next_engine_params_t {
119682 + ioc_fm_pcd_engine next_engine;
119683 + union {
119684 + ioc_compat_fm_pcd_cc_next_cc_params_t cc_params; /**< compat structure*/
119685 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< same structure*/
119686 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< same structure*/
119687 + ioc_compat_fm_pcd_cc_next_kg_params_t kg_params; /**< compat structure*/
119688 +#if DPAA_VERSION >= 11
119689 + ioc_compat_fm_pcd_cc_next_fr_params_t fr_params; /**< compat structure*/
119690 +#endif /* DPAA_VERSION >= 11 */
119691 + } params;
119692 + compat_uptr_t manip_id;
119693 + bool statistics_en;
119694 +} ioc_compat_fm_pcd_cc_next_engine_params_t;
119695 +
119696 +typedef struct ioc_compat_fm_pcd_cc_grp_params_t {
119697 + uint8_t num_of_distinction_units;
119698 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
119699 + 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];
119700 +} ioc_compat_fm_pcd_cc_grp_params_t;
119701 +
119702 +typedef struct ioc_compat_fm_pcd_cc_tree_params_t {
119703 + compat_uptr_t net_env_id;
119704 + uint8_t num_of_groups;
119705 + ioc_compat_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
119706 + compat_uptr_t id;
119707 +} ioc_compat_fm_pcd_cc_tree_params_t;
119708 +
119709 +typedef struct ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t {
119710 + compat_uptr_t id;
119711 + uint8_t grp_indx;
119712 + uint8_t indx;
119713 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
119714 +} ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t;
119715 +
119716 +typedef struct ioc_compat_fm_pcd_cc_key_params_t {
119717 + compat_uptr_t p_key;
119718 + compat_uptr_t p_mask;
119719 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params; /**< compat structure*/
119720 +} ioc_compat_fm_pcd_cc_key_params_t;
119721 +
119722 +typedef struct ioc_compat_keys_params_t {
119723 + uint16_t max_num_of_keys;
119724 + bool mask_support;
119725 + ioc_fm_pcd_cc_stats_mode statistics_mode;
119726 +#if (DPAA_VERSION >= 11)
119727 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
119728 +#endif /* (DPAA_VERSION >= 11) */
119729 + uint16_t num_of_keys;
119730 + uint8_t key_size;
119731 + ioc_compat_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS]; /**< compat structure*/
119732 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss; /**< compat structure*/
119733 +} ioc_compat_keys_params_t;
119734 +
119735 +typedef struct ioc_compat_fm_pcd_cc_node_params_t {
119736 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< same structure*/
119737 + ioc_compat_keys_params_t keys_params; /**< compat structure*/
119738 + compat_uptr_t id;
119739 +} ioc_compat_fm_pcd_cc_node_params_t;
119740 +
119741 +/**************************************************************************//**
119742 + @Description Parameters for defining a hash table
119743 +*//***************************************************************************/
119744 +typedef struct ioc_compat_fm_pcd_hash_table_params_t {
119745 + uint16_t max_num_of_keys;
119746 + ioc_fm_pcd_cc_stats_mode statistics_mode;
119747 + uint8_t kg_hash_shift;
119748 + uint16_t hash_res_mask;
119749 + uint8_t hash_shift;
119750 + uint8_t match_key_size;
119751 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
119752 + compat_uptr_t id;
119753 +} ioc_compat_fm_pcd_hash_table_params_t;
119754 +
119755 +typedef struct ioc_compat_fm_pcd_hash_table_add_key_params_t {
119756 + compat_uptr_t p_hash_tbl;
119757 + uint8_t key_size;
119758 + ioc_compat_fm_pcd_cc_key_params_t key_params;
119759 +} ioc_compat_fm_pcd_hash_table_add_key_params_t;
119760 +
119761 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_params_t {
119762 + compat_uptr_t id;
119763 + uint16_t key_indx;
119764 + uint8_t key_size;
119765 + compat_uptr_t p_key;
119766 + compat_uptr_t p_mask;
119767 +} ioc_compat_fm_pcd_cc_node_modify_key_params_t;
119768 +
119769 +typedef struct ioc_compat_fm_pcd_hash_table_remove_key_params_t {
119770 + compat_uptr_t p_hash_tbl;
119771 + uint8_t key_size;
119772 + compat_uptr_t p_key;
119773 +} ioc_compat_fm_pcd_hash_table_remove_key_params_t;
119774 +
119775 +typedef struct ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
119776 + compat_uptr_t id;
119777 + uint16_t key_indx;
119778 + uint8_t key_size;
119779 + ioc_compat_fm_pcd_cc_key_params_t key_params;
119780 +} ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
119781 +
119782 +typedef struct ioc_compat_fm_port_pcd_plcr_params_t {
119783 + compat_uptr_t plcr_profile_id;
119784 +} ioc_compat_fm_port_pcd_plcr_params_t;
119785 +
119786 +typedef struct ioc_compat_fm_port_pcd_cc_params_t {
119787 + compat_uptr_t cc_tree_id;
119788 +} ioc_compat_fm_port_pcd_cc_params_t;
119789 +
119790 +typedef struct ioc_compat_fm_port_pcd_kg_params_t {
119791 + uint8_t num_of_schemes;
119792 + compat_uptr_t scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
119793 + bool direct_scheme;
119794 + compat_uptr_t direct_scheme_id;
119795 +} ioc_compat_fm_port_pcd_kg_params_t;
119796 +
119797 +typedef struct ioc_compat_fm_port_pcd_params_t {
119798 + ioc_fm_port_pcd_support pcd_support;
119799 + compat_uptr_t net_env_id;
119800 + compat_uptr_t p_prs_params;
119801 + compat_uptr_t p_cc_params;
119802 + compat_uptr_t p_kg_params;
119803 + compat_uptr_t p_plcr_params;
119804 + compat_uptr_t p_ip_reassembly_manip;
119805 +#if DPAA_VERSION >= 11
119806 + compat_uptr_t p_capwap_reassembly_manip;
119807 +#endif
119808 +} ioc_compat_fm_port_pcd_params_t;
119809 +
119810 +typedef struct ioc_compat_fm_pcd_kg_cc_t {
119811 + compat_uptr_t tree_id;
119812 + uint8_t grp_id;
119813 + bool plcr_next;
119814 + bool bypass_plcr_profile_generation;
119815 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
119816 +} ioc_compat_fm_pcd_kg_cc_t;
119817 +
119818 +typedef struct ioc_compat_fm_pcd_kg_scheme_params_t {
119819 + bool modify;
119820 + union {
119821 + uint8_t relative_scheme_id;
119822 + compat_uptr_t scheme_id;
119823 + } scm_id;
119824 + bool always_direct;
119825 + struct {
119826 + compat_uptr_t net_env_id;
119827 + uint8_t num_of_distinction_units;
119828 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
119829 + } net_env_params;
119830 + bool use_hash;
119831 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
119832 + bool bypass_fqid_generation;
119833 + uint32_t base_fqid;
119834 + uint8_t num_of_used_extracted_ors;
119835 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
119836 +#if DPAA_VERSION >= 11
119837 + bool override_storage_profile;
119838 + ioc_fm_pcd_kg_storage_profile_t storage_profile;
119839 +#endif /* DPAA_VERSION >= 11 */
119840 + ioc_fm_pcd_engine next_engine;
119841 + union{
119842 + ioc_fm_pcd_done_action done_action;
119843 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile;
119844 + ioc_compat_fm_pcd_kg_cc_t cc;
119845 + } kg_next_engine_params;
119846 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter;
119847 + compat_uptr_t id;
119848 +} ioc_compat_fm_pcd_kg_scheme_params_t;
119849 +
119850 +typedef struct ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t {
119851 + compat_uptr_t id;
119852 + uint16_t key_indx;
119853 + uint8_t key_size;
119854 + ioc_compat_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
119855 +} ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t;
119856 +
119857 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t {
119858 + uint8_t offset;
119859 + uint8_t size;
119860 + bool replace;
119861 + compat_uptr_t p_data;
119862 +} ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t;
119863 +
119864 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
119865 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2;
119866 + bool update;
119867 + uint8_t size;
119868 + compat_uptr_t p_data;
119869 +} ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
119870 +
119871 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_t {
119872 + uint8_t size; /**< size of inserted section */
119873 + compat_uptr_t p_data; /**< data to be inserted */
119874 +} ioc_compat_fm_pcd_manip_hdr_insrt_t;
119875 +
119876 +#if (DPAA_VERSION >= 11)
119877 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t {
119878 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
119879 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
119880 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
119881 + the inserted header */
119882 + uint16_t id; /**< 16 bit New IP ID */
119883 + bool dont_frag_overwrite;
119884 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
119885 + * This byte is configured to be overwritten when RPD is set. */
119886 + uint8_t last_dst_offset;
119887 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
119888 + * in order to calculate UDP checksum pseudo header;
119889 + * Otherwise set it to '0'. */
119890 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
119891 +} ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t;
119892 +#endif /* (DPAA_VERSION >= 11) */
119893 +
119894 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
119895 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type;
119896 + union {
119897 + ioc_compat_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
119898 +#if (DPAA_VERSION >= 11)
119899 + ioc_compat_fm_pcd_manip_hdr_insrt_ip_params_t ip_params;
119900 + ioc_compat_fm_pcd_manip_hdr_insrt_t insrt;
119901 +#endif /* (DPAA_VERSION >= 11) */
119902 + } u;
119903 +} ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
119904 +
119905 +typedef struct ioc_compat_fm_pcd_manip_hdr_insrt_params_t {
119906 + ioc_fm_pcd_manip_hdr_insrt_type type;
119907 + union {
119908 + ioc_compat_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr;
119909 + ioc_compat_fm_pcd_manip_hdr_insrt_generic_params_t generic;
119910 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
119911 +#error "FM_CAPWAP_SUPPORT feature not supported!"
119912 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
119913 +#endif /* FM_CAPWAP_SUPPORT */
119914 + } u;
119915 +} ioc_compat_fm_pcd_manip_hdr_insrt_params_t;
119916 +
119917 +typedef struct ioc_compat_fm_pcd_manip_hdr_params_t {
119918 + bool rmv;
119919 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params;
119920 + bool insrt;
119921 + ioc_compat_fm_pcd_manip_hdr_insrt_params_t insrt_params;
119922 + bool field_update;
119923 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params;
119924 + bool custom;
119925 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params;
119926 + bool dont_parse_after_manip;
119927 +} ioc_compat_fm_pcd_manip_hdr_params_t;
119928 +
119929 +typedef struct ioc_compat_fm_pcd_manip_special_offload_params_t {
119930 + bool decryption;
119931 + bool ecn_copy;
119932 + bool dscp_copy;
119933 + bool variable_ip_hdr_len;
119934 + bool variable_ip_version;
119935 + uint8_t outer_ip_hdr_len;
119936 + uint16_t arw_size;
119937 + compat_uptr_t arw_addr;
119938 +} ioc_compat_fm_pcd_manip_special_offload_params_t;
119939 +
119940 +typedef struct ioc_compat_fm_pcd_manip_params_t {
119941 + ioc_fm_pcd_manip_type type;
119942 + union {
119943 + ioc_compat_fm_pcd_manip_hdr_params_t hdr;
119944 + ioc_fm_pcd_manip_reassem_params_t reassem;
119945 + ioc_fm_pcd_manip_frag_params_t frag;
119946 + ioc_compat_fm_pcd_manip_special_offload_params_t special_offload;
119947 + } u;
119948 + compat_uptr_t p_next_manip;
119949 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
119950 +#error "FM_CAPWAP_SUPPORT feature not supported!"
119951 + bool frag_or_reasm;
119952 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;
119953 +#endif /* FM_CAPWAP_SUPPORT */
119954 + compat_uptr_t id;
119955 +} ioc_compat_fm_pcd_manip_params_t;
119956 +
119957 +typedef struct ioc_compat_fm_pcd_manip_get_stats_t {
119958 + compat_uptr_t id;
119959 + ioc_fm_pcd_manip_stats_t stats;
119960 +} ioc_compat_fm_pcd_manip_get_stats_t;
119961 +
119962 +#if (DPAA_VERSION >= 11)
119963 +typedef struct ioc_compat_fm_pcd_frm_replic_group_params_t {
119964 + uint8_t max_num_of_entries;
119965 + uint8_t num_of_entries;
119966 + ioc_compat_fm_pcd_cc_next_engine_params_t
119967 + next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
119968 + compat_uptr_t id;
119969 +} ioc_compat_fm_pcd_frm_replic_group_params_t;
119970 +
119971 +typedef struct ioc_compat_fm_pcd_frm_replic_member_t {
119972 + compat_uptr_t h_replic_group;
119973 + uint16_t member_index;
119974 +} ioc_compat_fm_pcd_frm_replic_member_t;
119975 +
119976 +typedef struct ioc_compat_fm_pcd_frm_replic_member_params_t {
119977 + ioc_compat_fm_pcd_frm_replic_member_t member;
119978 + ioc_compat_fm_pcd_cc_next_engine_params_t next_engine_params;
119979 +} ioc_compat_fm_pcd_frm_replic_member_params_t;
119980 +
119981 +typedef struct ioc_compat_fm_vsp_params_t {
119982 + compat_uptr_t p_fm; /**< A handle to the FM object this VSP related to */
119983 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
119984 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
119985 + parameter associated with Rx / OP port */
119986 + uint16_t liodn_offset; /**< VSP's LIODN offset */
119987 + struct {
119988 + ioc_fm_port_type port_type; /**< Port type */
119989 + uint8_t port_id; /**< Port Id - relative to type */
119990 + } port_params;
119991 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
119992 + defined in relevant FM object */
119993 + compat_uptr_t id; /**< return value */
119994 +} ioc_compat_fm_vsp_params_t;
119995 +
119996 +typedef struct ioc_compat_fm_buf_pool_depletion_params_t {
119997 + compat_uptr_t p_fm_vsp;
119998 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
119999 +} ioc_compat_fm_buf_pool_depletion_params_t;
120000 +
120001 +typedef struct ioc_compat_fm_buffer_prefix_content_params_t {
120002 + compat_uptr_t p_fm_vsp;
120003 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
120004 +} ioc_compat_fm_buffer_prefix_content_params_t;
120005 +
120006 +typedef struct ioc_compat_fm_vsp_config_no_sg_params_t {
120007 + compat_uptr_t p_fm_vsp;
120008 + bool no_sg;
120009 +} ioc_compat_fm_vsp_config_no_sg_params_t;
120010 +
120011 +typedef struct ioc_compat_fm_vsp_prs_result_params_t {
120012 + compat_uptr_t p_fm_vsp;
120013 + compat_uptr_t p_data;
120014 +} ioc_compat_fm_vsp_prs_result_params_t;
120015 +
120016 +#endif /* (DPAA_VERSION >= 11) */
120017 +typedef struct ioc_compat_fm_pcd_kg_scheme_spc_t {
120018 + uint32_t val;
120019 + compat_uptr_t id;
120020 +} ioc_compat_fm_pcd_kg_scheme_spc_t;
120021 +
120022 +typedef struct ioc_compat_fm_ctrl_mon_counters_params_t {
120023 + uint8_t fm_ctrl_index;
120024 + compat_uptr_t p_mon;
120025 +} ioc_compat_fm_ctrl_mon_counters_params_t;
120026 +
120027 +typedef struct ioc_compat_fm_pcd_cc_tbl_get_stats_t {
120028 + compat_uptr_t id;
120029 + uint16_t key_index;
120030 + ioc_fm_pcd_cc_key_statistics_t statistics;
120031 +} ioc_compat_fm_pcd_cc_tbl_get_stats_t;
120032 +
120033 +
120034 +/* } pcd compat structures */
120035 +
120036 +void compat_obj_delete(
120037 + ioc_compat_fm_obj_t *compat_id,
120038 + ioc_fm_obj_t *id);
120039 +
120040 +/* pcd compat functions { */
120041 +void compat_copy_fm_pcd_plcr_profile(
120042 + ioc_compat_fm_pcd_plcr_profile_params_t *compat_param,
120043 + ioc_fm_pcd_plcr_profile_params_t *param,
120044 + uint8_t compat);
120045 +
120046 +void compat_copy_fm_pcd_cc_key(
120047 + ioc_compat_fm_pcd_cc_key_params_t *compat_param,
120048 + ioc_fm_pcd_cc_key_params_t *param,
120049 + uint8_t compat);
120050 +
120051 +void compat_copy_fm_pcd_cc_node_modify_key_and_next_engine(
120052 + ioc_compat_fm_pcd_cc_node_modify_key_and_next_engine_params_t *compat_param,
120053 + ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t *param,
120054 + uint8_t compat);
120055 +
120056 +void compat_copy_fm_pcd_cc_node_modify_next_engine(
120057 + ioc_compat_fm_pcd_cc_node_modify_next_engine_params_t *compat_param,
120058 + ioc_fm_pcd_cc_node_modify_next_engine_params_t *param,
120059 + uint8_t compat);
120060 +
120061 +void compat_fm_pcd_cc_tree_modify_next_engine(
120062 + ioc_compat_fm_pcd_cc_tree_modify_next_engine_params_t *compat_param,
120063 + ioc_fm_pcd_cc_tree_modify_next_engine_params_t *param,
120064 + uint8_t compat);
120065 +
120066 +void compat_copy_fm_pcd_hash_table(
120067 + ioc_compat_fm_pcd_hash_table_params_t *compat_param,
120068 + ioc_fm_pcd_hash_table_params_t *param,
120069 + uint8_t compat);
120070 +
120071 +void compat_copy_fm_pcd_cc_grp(
120072 + ioc_compat_fm_pcd_cc_grp_params_t *compat_param,
120073 + ioc_fm_pcd_cc_grp_params_t *param,
120074 + uint8_t compat);
120075 +
120076 +void compat_copy_fm_pcd_cc_tree(
120077 + ioc_compat_fm_pcd_cc_tree_params_t *compat_param,
120078 + ioc_fm_pcd_cc_tree_params_t *param,
120079 + uint8_t compat);
120080 +
120081 +void compat_copy_fm_pcd_cc_tbl_get_stats(
120082 + ioc_compat_fm_pcd_cc_tbl_get_stats_t *compat_param,
120083 + ioc_fm_pcd_cc_tbl_get_stats_t *param,
120084 + uint8_t compat);
120085 +
120086 +void compat_fm_pcd_prs_sw(
120087 + ioc_compat_fm_pcd_prs_sw_params_t *compat_param,
120088 + ioc_fm_pcd_prs_sw_params_t *param,
120089 + uint8_t compat);
120090 +
120091 +void compat_copy_fm_pcd_kg_scheme(
120092 + ioc_compat_fm_pcd_kg_scheme_params_t *compat_param,
120093 + ioc_fm_pcd_kg_scheme_params_t *param,
120094 + uint8_t compat);
120095 +
120096 +void compat_copy_fm_pcd_kg_scheme_select(
120097 + ioc_compat_fm_pcd_kg_scheme_select_t *compat_param,
120098 + ioc_fm_pcd_kg_scheme_select_t *param,
120099 + uint8_t compat);
120100 +
120101 +void compat_copy_fm_pcd_kg_schemes_params(
120102 + ioc_compat_fm_pcd_port_schemes_params_t *compat_param,
120103 + ioc_fm_pcd_port_schemes_params_t *param,
120104 + uint8_t compat);
120105 +
120106 +void compat_copy_fm_port_pcd_kg(
120107 + ioc_compat_fm_port_pcd_kg_params_t *compat_param,
120108 + ioc_fm_port_pcd_kg_params_t *param,
120109 + uint8_t compat);
120110 +
120111 +void compat_copy_fm_port_pcd(
120112 + ioc_compat_fm_port_pcd_params_t *compat_param,
120113 + ioc_fm_port_pcd_params_t *param,
120114 + uint8_t compat);
120115 +
120116 +#if (DPAA_VERSION >= 11)
120117 +void compat_copy_fm_port_vsp_alloc_params(
120118 + ioc_compat_fm_port_vsp_alloc_params_t *compat_param,
120119 + ioc_fm_port_vsp_alloc_params_t *param,
120120 + uint8_t compat);
120121 +#endif /* (DPAA_VERSION >= 11) */
120122 +
120123 +void compat_copy_fm_pcd_net_env(
120124 + ioc_compat_fm_pcd_net_env_params_t *compat_param,
120125 + ioc_fm_pcd_net_env_params_t *param,
120126 + uint8_t compat);
120127 +
120128 +void compat_copy_fm_pcd_cc_node_modify_key(
120129 + ioc_compat_fm_pcd_cc_node_modify_key_params_t *compat_param,
120130 + ioc_fm_pcd_cc_node_modify_key_params_t *param,
120131 + uint8_t compat);
120132 +
120133 +void compat_copy_keys(
120134 + ioc_compat_keys_params_t *compat_param,
120135 + ioc_keys_params_t *param,
120136 + uint8_t compat);
120137 +
120138 +void compat_copy_fm_pcd_cc_node(
120139 + ioc_compat_fm_pcd_cc_node_params_t *compat_param,
120140 + ioc_fm_pcd_cc_node_params_t *param,
120141 + uint8_t compat);
120142 +
120143 +void compat_fm_pcd_manip_set_node(
120144 + ioc_compat_fm_pcd_manip_params_t *compat_param,
120145 + ioc_fm_pcd_manip_params_t *param,
120146 + uint8_t compat);
120147 +
120148 +void compat_copy_fm_pcd_manip_get_stats(
120149 + ioc_compat_fm_pcd_manip_get_stats_t *compat_param,
120150 + ioc_fm_pcd_manip_get_stats_t *param,
120151 + uint8_t compat);
120152 +
120153 +void compat_copy_fm_port_pcd_modify_tree(
120154 + ioc_compat_fm_obj_t *compat_id,
120155 + ioc_fm_obj_t *id,
120156 + uint8_t compat);
120157 +
120158 +#if (DPAA_VERSION >= 11)
120159 +void compat_copy_fm_pcd_frm_replic_group_params(
120160 + ioc_compat_fm_pcd_frm_replic_group_params_t *compat_param,
120161 + ioc_fm_pcd_frm_replic_group_params_t *param,
120162 + uint8_t compat);
120163 +
120164 +void compat_copy_fm_pcd_frm_replic_member(
120165 + ioc_compat_fm_pcd_frm_replic_member_t *compat_param,
120166 + ioc_fm_pcd_frm_replic_member_t *param,
120167 + uint8_t compat);
120168 +
120169 +void compat_copy_fm_pcd_frm_replic_member_params(
120170 + ioc_compat_fm_pcd_frm_replic_member_params_t *compat_param,
120171 + ioc_fm_pcd_frm_replic_member_params_t *param,
120172 + uint8_t compat);
120173 +
120174 +void compat_copy_fm_vsp_params(
120175 + ioc_compat_fm_vsp_params_t *compat_param,
120176 + ioc_fm_vsp_params_t *param,
120177 + uint8_t compat);
120178 +
120179 +void compat_copy_fm_buf_pool_depletion_params(
120180 + ioc_compat_fm_buf_pool_depletion_params_t *compat_param,
120181 + ioc_fm_buf_pool_depletion_params_t *param,
120182 + uint8_t compat);
120183 +
120184 +void compat_copy_fm_buffer_prefix_content_params(
120185 + ioc_compat_fm_buffer_prefix_content_params_t *compat_param,
120186 + ioc_fm_buffer_prefix_content_params_t *param,
120187 + uint8_t compat);
120188 +
120189 +void compat_copy_fm_vsp_config_no_sg_params(
120190 + ioc_compat_fm_vsp_config_no_sg_params_t *compat_param,
120191 + ioc_fm_vsp_config_no_sg_params_t *param,
120192 + uint8_t compat);
120193 +
120194 +void compat_copy_fm_vsp_prs_result_params(
120195 + ioc_compat_fm_vsp_prs_result_params_t *compat_param,
120196 + ioc_fm_vsp_prs_result_params_t *param,
120197 + uint8_t compat);
120198 +
120199 +#endif /* (DPAA_VERSION >= 11) */
120200 +
120201 +void compat_copy_fm_pcd_kg_scheme_spc(
120202 + ioc_compat_fm_pcd_kg_scheme_spc_t *compat_param,
120203 + ioc_fm_pcd_kg_scheme_spc_t *param,
120204 + uint8_t compat);
120205 +
120206 +/* } pcd compat functions */
120207 +#endif
120208 --- /dev/null
120209 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources.h
120210 @@ -0,0 +1,121 @@
120211 +/*
120212 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120213 + *
120214 + * Redistribution and use in source and binary forms, with or without
120215 + * modification, are permitted provided that the following conditions are met:
120216 + * * Redistributions of source code must retain the above copyright
120217 + * notice, this list of conditions and the following disclaimer.
120218 + * * Redistributions in binary form must reproduce the above copyright
120219 + * notice, this list of conditions and the following disclaimer in the
120220 + * documentation and/or other materials provided with the distribution.
120221 + * * Neither the name of Freescale Semiconductor nor the
120222 + * names of its contributors may be used to endorse or promote products
120223 + * derived from this software without specific prior written permission.
120224 + *
120225 + *
120226 + * ALTERNATIVELY, this software may be distributed under the terms of the
120227 + * GNU General Public License ("GPL") as published by the Free Software
120228 + * Foundation, either version 2 of that License or (at your option) any
120229 + * later version.
120230 + *
120231 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120232 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120233 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120234 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120235 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120236 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120237 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120238 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120239 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120240 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120241 + */
120242 +
120243 +/*
120244 + @File lnxwrp_resources.h
120245 +
120246 + @Description FMD wrapper resource allocation functions.
120247 +
120248 +*/
120249 +
120250 +#ifndef LNXWRP_RESOURCES_H_
120251 +#define LNXWRP_RESOURCES_H_
120252 +
120253 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
120254 +#include "lnxwrp_fm.h"
120255 +#else
120256 +#include "lnxwrp_resources_ut.h"
120257 +#endif
120258 +
120259 +#define ROUND(X) ((2*(X)+1)/2)
120260 +#define CEIL(X) ((X)+1)
120261 +/* #define ROUND_DIV(X, Y) (((X)+(Y)/2)/(Y)) */
120262 +#define ROUND_DIV(X, Y) ((2*(X)+(Y))/(2*(Y)))
120263 +#define CEIL_DIV(X, Y) (((X)+(Y)-1)/(Y))
120264 +
120265 +/* used for resource calculus */
120266 +#define DPDE_1G 2 /* DQDP 1g - from LLD:
120267 + DEFAULT_PORT_txFifoDeqPipelineDepth_1G */
120268 +#define DPDE_10G 8 /* DQDP 10g - from LLD:
120269 + DEFAULT_PORT_txFifoDeqPipelineDepth_10G */
120270 +
120271 +int fm_set_active_fman_ports(struct platform_device *of_dev,
120272 + t_LnxWrpFmDev *p_LnxWrpFmDev);
120273 +
120274 +/* Calculate the fifosize based on MURAM allocation, number of ports, dpde
120275 + * value and s/g software support (! Kernel does not suport s/g).
120276 + *
120277 + * Algorithm summary:
120278 + * - Calculate the the minimum fifosize required for every type of port
120279 + * (TX,RX for 1G, 2.5G and 10G).
120280 + * - Set TX the minimum fifosize required.
120281 + * - Distribute the remaining buffers (after all TX were set) to RX ports
120282 + * based on:
120283 + * 1G RX = Remaining_buffers * 1/(1+2.5+10)
120284 + * 2.5G RX = Remaining_buffers * 2.5/(1+2.5+10)
120285 + * 10G RX = Remaining_buffers * 10/(1+2.5+10)
120286 + * - if the RX is smaller than the minimum required, then set the minimum
120287 + * required
120288 + * - In the end distribuite the leftovers if there are any (due to
120289 + * unprecise calculus) or if over allocation cat some buffers from all RX
120290 + * ports w/o pass over minimum required treshold, but if there must be
120291 + * pass the treshold in order to cat the over allocation ,then this
120292 + * configuration can not be set - KERN_ALERT.
120293 +*/
120294 +int fm_precalculate_fifosizes(t_LnxWrpFmDev *p_LnxWrpFmDev,
120295 + int muram_fifo_size);
120296 +
120297 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
120298 +int fm_config_precalculate_fifosize(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
120299 +#endif
120300 +
120301 +/* Compute FMan open DMA based on total number of open DMAs and
120302 + * number of available fman ports.
120303 + *
120304 + * By default 10g ports are set to input parameters. The other ports
120305 + * tries to keep the proportion rx=2tx open dmas or tresholds.
120306 + *
120307 + * If leftovers, then those will be set as shared.
120308 + *
120309 + * If after computing overflow appears, then it decrements open dma
120310 + * for all ports w/o cross the tresholds. If the tresholds are meet
120311 + * and is still overflow, then it returns error.
120312 +*/
120313 +int fm_precalculate_open_dma(t_LnxWrpFmDev *p_LnxWrpFmDev,
120314 + int max_fm_open_dma,
120315 + int default_tx_10g_dmas,
120316 + int default_rx_10g_dmas,
120317 + int min_tx_10g_treshold, int min_rx_10g_treshold);
120318 +
120319 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
120320 +int fm_config_precalculate_open_dma(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
120321 +#endif
120322 +
120323 +/* Compute FMan tnums based on available tnums and number of ports.
120324 + * Set defaults (minim tresholds) and then distribute leftovers.*/
120325 +int fm_precalculate_tnums(t_LnxWrpFmDev *p_LnxWrpFmDev, int max_fm_tnums);
120326 +
120327 +#if !defined(FMAN_RESOURCES_UNIT_TEST)
120328 +int fm_config_precalculate_tnums(t_LnxWrpFmPortDev *p_LnxWrpFmPortDev);
120329 +#endif
120330 +
120331 +#endif /* LNXWRP_RESOURCES_H_ */
120332 --- /dev/null
120333 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.c
120334 @@ -0,0 +1,191 @@
120335 +/* Copyright (c) 2012 Freescale Semiconductor, Inc.
120336 + * All rights reserved.
120337 + *
120338 + * Redistribution and use in source and binary forms, with or without
120339 + * modification, are permitted provided that the following conditions are met:
120340 + * * Redistributions of source code must retain the above copyright
120341 + * notice, this list of conditions and the following disclaimer.
120342 + * * Redistributions in binary form must reproduce the above copyright
120343 + * notice, this list of conditions and the following disclaimer in the
120344 + * documentation and/or other materials provided with the distribution.
120345 + * * Neither the name of Freescale Semiconductor nor the
120346 + * names of its contributors may be used to endorse or promote products
120347 + * derived from this software without specific prior written permission.
120348 + *
120349 + *
120350 + * ALTERNATIVELY, this software may be distributed under the terms of the
120351 + * GNU General Public License ("GPL") as published by the Free Software
120352 + * Foundation, either version 2 of that License or (at your option) any
120353 + * later version.
120354 + *
120355 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120356 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120357 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120358 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120359 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120360 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120361 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120362 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120363 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120364 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120365 + */
120366 +
120367 +#include "lnxwrp_resources.h"
120368 +#include "lnxwrp_resources_ut.h"
120369 +
120370 +#define KILOBYTE 0x400 /* 1024 */
120371 +
120372 +typedef enum e_board_type {
120373 + e_p3041,
120374 + e_p4080,
120375 + e_p5020,
120376 + e_p1023
120377 +} e_board_type;
120378 +
120379 +uint8_t board_type;
120380 +uint32_t muram_size = 0;
120381 +uint32_t dmas_num = 0;
120382 +uint32_t task_num = 0;
120383 +uint32_t frame_size = 0;
120384 +uint32_t oh_num = 0;
120385 +uint32_t num_ports_1g = 0;
120386 +uint32_t num_ports_10g = 0;
120387 +uint32_t num_ports_2g5 = 0;
120388 +uint32_t fsl_fman_phy_maxfrm = 0;
120389 +uint32_t dpa_rx_extra_headroom = 0;
120390 +
120391 +void show_help(void){
120392 + printf(" help: \n");
120393 + printf(" -b <board_type> -f <max_fram_size(mtu)> -o <num_oh_ports> -g1"
120394 + " <num_1g_ports> -g10 <num_10g_ports> -g25 <num_2g5_ports>\n");
120395 + printf(" Maxim num of DMAS availbale: P3/P4/P5:32 , P1023:16 \n");
120396 + printf(" Maxim num of TNUMs availbale: P3/P4/P5:128, P1023:32 \n");
120397 + printf(" Muram size: P3/P4/P5:160K, P1023:64K \n");
120398 + printf(" Number of ports:\n");
120399 + printf(" P3/P5: 5p 1g, 1p 10g, 7p oh \n");
120400 + printf(" P4 : 4p 1g, 1p 10g, 7p oh \n");
120401 + printf(" P1 : 2p 1g, 0p 10g, 4p oh \n");
120402 + printf(" MTU: Default:1522, Jumbo:9600 \n");
120403 +}
120404 +
120405 +int fm_set_param(t_LnxWrpFmDev *p_LnxWrpFmDev) {
120406 + struct fm_active_ports *fm_active_ports_info = NULL;
120407 + fm_active_ports_info = &p_LnxWrpFmDev->fm_active_ports_info;
120408 +
120409 + switch(board_type){
120410 + case e_p3041:
120411 + case e_p5020:
120412 + muram_size = 160*KILOBYTE;
120413 + dmas_num = 32;
120414 + task_num = 128;
120415 + if ((num_ports_1g+num_ports_2g5) > 5 || num_ports_10g > 1 || oh_num > 7)
120416 + goto err_fm_set_param;
120417 + break;
120418 + case e_p4080:
120419 + muram_size = 160*KILOBYTE;
120420 + dmas_num = 32;
120421 + task_num = 128;
120422 + if ((num_ports_1g+num_ports_2g5) > 4 || num_ports_10g > 1 || oh_num > 7)
120423 + goto err_fm_set_param;
120424 + break;
120425 + case e_p1023:
120426 + muram_size = 64*KILOBYTE;
120427 + dmas_num = 16;
120428 + task_num = 128;
120429 + if ((num_ports_1g+num_ports_2g5) > 2 || oh_num > 4)
120430 + goto err_fm_set_param;
120431 + break;
120432 + default:
120433 + goto err_fm_set_param;
120434 + break;
120435 + }
120436 +
120437 + p_LnxWrpFmDev->id = 0;
120438 + fsl_fman_phy_maxfrm = frame_size;
120439 + dpa_rx_extra_headroom = 0; /* ATTENTION: can be != 0 */
120440 + fm_active_ports_info->num_oh_ports = oh_num;
120441 + fm_active_ports_info->num_tx_ports = num_ports_1g;
120442 + fm_active_ports_info->num_rx_ports = num_ports_1g;
120443 + fm_active_ports_info->num_tx25_ports = num_ports_2g5;
120444 + fm_active_ports_info->num_rx25_ports = num_ports_2g5;
120445 + fm_active_ports_info->num_tx10_ports = num_ports_10g;
120446 + fm_active_ports_info->num_rx10_ports = num_ports_10g;
120447 +
120448 + return 0;
120449 +
120450 +err_fm_set_param:
120451 + printf(" ERR: To many ports!!! \n");
120452 + return -1;
120453 +}
120454 +
120455 +int main (int argc, char *argv[]){
120456 + t_LnxWrpFmDev LnxWrpFmDev;
120457 + t_LnxWrpFmDev *p_LnxWrpFmDev = &LnxWrpFmDev;
120458 + int tokens_cnt = 1;
120459 +
120460 + char *token = NULL;
120461 +
120462 + while(tokens_cnt < argc)
120463 + {
120464 + token = argv[tokens_cnt++];
120465 + if (strcmp(token, "-b") == 0){
120466 + if(strcmp(argv[tokens_cnt],"p3") == 0)
120467 + board_type = e_p3041;
120468 + else if(strcmp(argv[tokens_cnt],"p4") == 0)
120469 + board_type = e_p4080;
120470 + else if(strcmp(argv[tokens_cnt],"p5") == 0)
120471 + board_type = e_p5020;
120472 + else if(strcmp(argv[tokens_cnt],"p1") == 0)
120473 + board_type = e_p1023;
120474 + else
120475 + show_help();
120476 + tokens_cnt++;
120477 + }
120478 + else if(strcmp(token, "-d") == 0){
120479 + dmas_num = atoi(argv[tokens_cnt++]);
120480 + }
120481 + else if(strcmp(token, "-t") == 0)
120482 + task_num = atoi(argv[tokens_cnt++]);
120483 + else if(strcmp(token, "-f") == 0)
120484 + frame_size = atoi(argv[tokens_cnt++]);
120485 + else if(strcmp(token, "-o") == 0)
120486 + oh_num = atoi(argv[tokens_cnt++]);
120487 + else if(strcmp(token, "-g1") == 0)
120488 + num_ports_1g = atoi(argv[tokens_cnt++]);
120489 + else if(strcmp(token, "-g10") == 0)
120490 + num_ports_10g = atoi(argv[tokens_cnt++]);
120491 + else if(strcmp(token, "-g25") == 0)
120492 + num_ports_2g5 = atoi(argv[tokens_cnt++]);
120493 + else {
120494 + show_help();
120495 + return -1;
120496 + }
120497 + }
120498 +
120499 + if(fm_set_param(p_LnxWrpFmDev) < 0){
120500 + show_help();
120501 + return -1;
120502 + }
120503 +
120504 + if(fm_precalculate_fifosizes(
120505 + p_LnxWrpFmDev,
120506 + 128*KILOBYTE)
120507 + != 0)
120508 + return -1;
120509 + if(fm_precalculate_open_dma(
120510 + p_LnxWrpFmDev,
120511 + dmas_num, /* max open dmas:dpaa_integration_ext.h */
120512 + FM_DEFAULT_TX10G_OPENDMA, /* default TX 10g open dmas */
120513 + FM_DEFAULT_RX10G_OPENDMA, /* default RX 10g open dmas */
120514 + FM_10G_OPENDMA_MIN_TRESHOLD,/* TX 10g minimum treshold */
120515 + FM_10G_OPENDMA_MIN_TRESHOLD)/* RX 10g minimum treshold */
120516 + != 0)
120517 + return -1;
120518 + if(fm_precalculate_tnums(
120519 + p_LnxWrpFmDev,
120520 + task_num) /* max TNUMS: dpa integration file. */
120521 + != 0)
120522 + return -1;
120523 +
120524 + return 0;
120525 +}
120526 --- /dev/null
120527 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.h
120528 @@ -0,0 +1,144 @@
120529 +/* Copyright (c) 2012 Freescale Semiconductor, Inc
120530 + * All rights reserved.
120531 + *
120532 + * Redistribution and use in source and binary forms, with or without
120533 + * modification, are permitted provided that the following conditions are met:
120534 + * * Redistributions of source code must retain the above copyright
120535 + * notice, this list of conditions and the following disclaimer.
120536 + * * Redistributions in binary form must reproduce the above copyright
120537 + * notice, this list of conditions and the following disclaimer in the
120538 + * documentation and/or other materials provided with the distribution.
120539 + * * Neither the name of Freescale Semiconductor nor the
120540 + * names of its contributors may be used to endorse or promote products
120541 + * derived from this software without specific prior written permission.
120542 + *
120543 + *
120544 + * ALTERNATIVELY, this software may be distributed under the terms of the
120545 + * GNU General Public License ("GPL") as published by the Free Software
120546 + * Foundation, either version 2 of that License or (at your option) any
120547 + * later version.
120548 + *
120549 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120550 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120551 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120552 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120553 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120554 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120555 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120556 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120557 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120558 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120559 + */
120560 +
120561 +#ifndef FM_RESS_TEST_H_
120562 +#define FM_RESS_TEST_H_
120563 +
120564 +#include <stdint.h>
120565 +#include <stdbool.h>
120566 +#include <stdio.h>
120567 +#include <assert.h>
120568 +#include <string.h>
120569 +#include <stdlib.h>
120570 +
120571 +#define _Packed
120572 +#define _PackedType __attribute__ ((packed))
120573 +#define MAX(x, y) (((x) > (y)) ? (x) : (y))
120574 +#define MIN(x, y) (((x) < (y)) ? (x) : (y))
120575 +#define KERN_ALERT ""
120576 +#define KERN_INFO ""
120577 +#define ASSERT_COND assert
120578 +#define printk printf
120579 +#define NET_IP_ALIGN 0
120580 +#define FM_FIFO_ALLOCATION_OLD_ALG
120581 +
120582 +#if defined(CONFIG_FMAN_DISABLE_OH_AND_DISTRIBUTE_RESOURCES)
120583 +#define FM_10G_OPENDMA_MIN_TRESHOLD 8 /* 10g minimum treshold if only HC is enabled and no OH port enabled */
120584 +#define FM_OPENDMA_RX_TX_RAPORT 2 /* RX = 2*TX */
120585 +#else
120586 +#define FM_10G_OPENDMA_MIN_TRESHOLD 7 /* 10g minimum treshold if 7 OH ports are enabled */
120587 +#define FM_OPENDMA_RX_TX_RAPORT 1 /* RX = TX */
120588 +#endif
120589 +#define FM_DEFAULT_TX10G_OPENDMA 8 /* default TX 10g open dmas */
120590 +#define FM_DEFAULT_RX10G_OPENDMA 8 /* default RX 10g open dmas */
120591 +
120592 +/* information about all active ports for an FMan.
120593 + * !Some ports may be disabled by u-boot, thus will not be available */
120594 +struct fm_active_ports {
120595 + uint32_t num_oh_ports;
120596 + uint32_t num_tx_ports;
120597 + uint32_t num_rx_ports;
120598 + uint32_t num_tx25_ports;
120599 + uint32_t num_rx25_ports;
120600 + uint32_t num_tx10_ports;
120601 + uint32_t num_rx10_ports;
120602 +};
120603 +
120604 +/* FMan resources precalculated at fm probe based
120605 + * on available FMan port. */
120606 +struct fm_resource_settings {
120607 + /* buffers - fifo sizes */
120608 + uint32_t tx1g_num_buffers;
120609 + uint32_t rx1g_num_buffers;
120610 + uint32_t tx2g5_num_buffers; /* Not supported yet by LLD */
120611 + uint32_t rx2g5_num_buffers; /* Not supported yet by LLD */
120612 + uint32_t tx10g_num_buffers;
120613 + uint32_t rx10g_num_buffers;
120614 + uint32_t oh_num_buffers;
120615 + uint32_t shared_ext_buffers;
120616 +
120617 +
120618 + /* open DMAs */
120619 + uint32_t tx_1g_dmas;
120620 + uint32_t rx_1g_dmas;
120621 + uint32_t tx_2g5_dmas; /* Not supported yet by LLD */
120622 + uint32_t rx_2g5_dmas; /* Not supported yet by LLD */
120623 + uint32_t tx_10g_dmas;
120624 + uint32_t rx_10g_dmas;
120625 + uint32_t oh_dmas;
120626 + uint32_t shared_ext_open_dma;
120627 +
120628 + /* Tnums */
120629 + uint32_t tx_1g_tnums;
120630 + uint32_t rx_1g_tnums;
120631 + uint32_t tx_2g5_tnums; /* Not supported yet by LLD */
120632 + uint32_t rx_2g5_tnums; /* Not supported yet by LLD */
120633 + uint32_t tx_10g_tnums;
120634 + uint32_t rx_10g_tnums;
120635 + uint32_t oh_tnums;
120636 + uint32_t shared_ext_tnums;
120637 +};
120638 +
120639 +typedef struct {
120640 + uint8_t id;
120641 + struct fm_active_ports fm_active_ports_info;
120642 + struct fm_resource_settings fm_resource_settings_info;
120643 +} t_LnxWrpFmDev;
120644 +
120645 +typedef struct {
120646 + uint8_t id;
120647 +} t_LnxWrpFmPortDev;
120648 +
120649 +typedef _Packed struct t_FmPrsResult {
120650 + volatile uint8_t lpid; /**< Logical port id */
120651 + volatile uint8_t shimr; /**< Shim header result */
120652 + volatile uint16_t l2r; /**< Layer 2 result */
120653 + volatile uint16_t l3r; /**< Layer 3 result */
120654 + volatile uint8_t l4r; /**< Layer 4 result */
120655 + volatile uint8_t cplan; /**< Classification plan id */
120656 + volatile uint16_t nxthdr; /**< Next Header */
120657 + volatile uint16_t cksum; /**< Checksum */
120658 + volatile uint32_t lcv; /**< LCV */
120659 + volatile uint8_t shim_off[3]; /**< Shim offset */
120660 + volatile uint8_t eth_off; /**< ETH offset */
120661 + volatile uint8_t llc_snap_off; /**< LLC_SNAP offset */
120662 + volatile uint8_t vlan_off[2]; /**< VLAN offset */
120663 + volatile uint8_t etype_off; /**< ETYPE offset */
120664 + volatile uint8_t pppoe_off; /**< PPP offset */
120665 + volatile uint8_t mpls_off[2]; /**< MPLS offset */
120666 + volatile uint8_t ip_off[2]; /**< IP offset */
120667 + volatile uint8_t gre_off; /**< GRE offset */
120668 + volatile uint8_t l4_off; /**< Layer 4 offset */
120669 + volatile uint8_t nxthdr_off; /**< Parser end point */
120670 +} _PackedType t_FmPrsResult;
120671 +
120672 +#endif
120673 --- /dev/null
120674 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_resources_ut.make
120675 @@ -0,0 +1,28 @@
120676 +CC=gcc
120677 +
120678 +LNXWRP_RESS_UT=lnxwrp_resources_ut
120679 +OBJ=lnxwrp_resources
120680 +
120681 +INC_PATH=
120682 +LIB_PATH=
120683 +
120684 +INC=$(addprefix -I,$(INC_PATH))
120685 +LIB=$(addprefix -L,$(LIB_PATH))
120686 +
120687 +CFLAGS= -gdwarf-2 -g -O0 -Wall
120688 +XFLAGS= -DFMAN_RESOURCES_UNIT_TEST
120689 +
120690 +all: $(LNXWRP_RESS_UT)
120691 +
120692 +$(LNXWRP_RESS_UT):$(addsuffix .o,$(OBJ)) $(LNXWRP_RESS_UT).o
120693 + $(CC) -o $(LNXWRP_RESS_UT) $(LNXWRP_RESS_UT).o $(addsuffix .o,$(OBJ))
120694 +
120695 +%.o: %.c
120696 + @(echo " (CC) $@")
120697 + @($(CC) $(INC) $(CFLAGS) $(XFLAGS) -o $(@) -c $<)
120698 +
120699 +.PHONY: clean
120700 +
120701 +clean:
120702 + rm -f *.o
120703 + rm -f $(LNXWRP_RESS_UT)
120704 --- /dev/null
120705 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.c
120706 @@ -0,0 +1,60 @@
120707 +/*
120708 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120709 + *
120710 + * Redistribution and use in source and binary forms, with or without
120711 + * modification, are permitted provided that the following conditions are met:
120712 + * * Redistributions of source code must retain the above copyright
120713 + * notice, this list of conditions and the following disclaimer.
120714 + * * Redistributions in binary form must reproduce the above copyright
120715 + * notice, this list of conditions and the following disclaimer in the
120716 + * documentation and/or other materials provided with the distribution.
120717 + * * Neither the name of Freescale Semiconductor nor the
120718 + * names of its contributors may be used to endorse or promote products
120719 + * derived from this software without specific prior written permission.
120720 + *
120721 + *
120722 + * ALTERNATIVELY, this software may be distributed under the terms of the
120723 + * GNU General Public License ("GPL") as published by the Free Software
120724 + * Foundation, either version 2 of that License or (at your option) any
120725 + * later version.
120726 + *
120727 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120728 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120729 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120730 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120731 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120732 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120733 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120734 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120735 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120736 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120737 + */
120738 +
120739 +/*
120740 + @File lnxwrp_sysfs.c
120741 +
120742 + @Description FM wrapper sysfs related functions.
120743 +
120744 +*/
120745 +
120746 +#include <linux/types.h>
120747 +#include "lnxwrp_sysfs.h"
120748 +
120749 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
120750 + const struct sysfs_stats_t *sysfs_stats,
120751 + uint8_t *offset)
120752 +{
120753 + int i = 0;
120754 +
120755 + while (sysfs_stats[i].stat_name != NULL) {
120756 + if (strcmp(sysfs_stats[i].stat_name, attr_name) == 0) {
120757 + if (offset != NULL)
120758 + *offset = i;
120759 + return sysfs_stats[i].stat_counter;
120760 + }
120761 +
120762 + i++;
120763 + }
120764 + WARN(1, "FMD: Should never get here!");
120765 + return 0;
120766 +}
120767 --- /dev/null
120768 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs.h
120769 @@ -0,0 +1,60 @@
120770 +/*
120771 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120772 + *
120773 + * Redistribution and use in source and binary forms, with or without
120774 + * modification, are permitted provided that the following conditions are met:
120775 + * * Redistributions of source code must retain the above copyright
120776 + * notice, this list of conditions and the following disclaimer.
120777 + * * Redistributions in binary form must reproduce the above copyright
120778 + * notice, this list of conditions and the following disclaimer in the
120779 + * documentation and/or other materials provided with the distribution.
120780 + * * Neither the name of Freescale Semiconductor nor the
120781 + * names of its contributors may be used to endorse or promote products
120782 + * derived from this software without specific prior written permission.
120783 + *
120784 + *
120785 + * ALTERNATIVELY, this software may be distributed under the terms of the
120786 + * GNU General Public License ("GPL") as published by the Free Software
120787 + * Foundation, either version 2 of that License or (at your option) any
120788 + * later version.
120789 + *
120790 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120791 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120792 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120793 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120794 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120795 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120796 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120797 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120798 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120799 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120800 + */
120801 +
120802 +#ifndef LNXWRP_SYSFS_H_
120803 +#define LNXWRP_SYSFS_H_
120804 +
120805 +/* Linux Headers ------------------- */
120806 +#include <linux/version.h>
120807 +
120808 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
120809 +#define MODVERSIONS
120810 +#endif
120811 +#ifdef MODVERSIONS
120812 +#include <config/modversions.h>
120813 +#endif /* MODVERSIONS */
120814 +
120815 +#include <linux/kernel.h>
120816 +#include <linux/module.h>
120817 +#include <linux/device.h>
120818 +#include <linux/sysfs.h>
120819 +
120820 +struct sysfs_stats_t {
120821 + const char *stat_name;
120822 + uint8_t stat_counter;
120823 +};
120824 +
120825 +uint8_t fm_find_statistic_counter_by_name(const char *attr_name,
120826 + const struct sysfs_stats_t *sysfs_stats,
120827 + uint8_t *offset);
120828 +
120829 +#endif /* LNXWRP_SYSFS_H_ */
120830 --- /dev/null
120831 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.c
120832 @@ -0,0 +1,1855 @@
120833 +/*
120834 + * Copyright 2008-2012 Freescale Semiconductor Inc.
120835 + *
120836 + * Redistribution and use in source and binary forms, with or without
120837 + * modification, are permitted provided that the following conditions are met:
120838 + * * Redistributions of source code must retain the above copyright
120839 + * notice, this list of conditions and the following disclaimer.
120840 + * * Redistributions in binary form must reproduce the above copyright
120841 + * notice, this list of conditions and the following disclaimer in the
120842 + * documentation and/or other materials provided with the distribution.
120843 + * * Neither the name of Freescale Semiconductor nor the
120844 + * names of its contributors may be used to endorse or promote products
120845 + * derived from this software without specific prior written permission.
120846 + *
120847 + *
120848 + * ALTERNATIVELY, this software may be distributed under the terms of the
120849 + * GNU General Public License ("GPL") as published by the Free Software
120850 + * Foundation, either version 2 of that License or (at your option) any
120851 + * later version.
120852 + *
120853 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
120854 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
120855 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
120856 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
120857 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
120858 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
120859 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
120860 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
120861 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
120862 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
120863 + */
120864 +
120865 +#include "lnxwrp_sysfs.h"
120866 +#include "lnxwrp_sysfs_fm.h"
120867 +#include "lnxwrp_fm.h"
120868 +
120869 +#include "../../sdk_fman/Peripherals/FM/inc/fm_common.h"
120870 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_pcd.h"
120871 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_kg.h"
120872 +#include "../../sdk_fman/Peripherals/FM/Pcd/fm_plcr.h"
120873 +
120874 +#if defined(__ERR_MODULE__)
120875 +#undef __ERR_MODULE__
120876 +#endif
120877 +
120878 +#include "../../sdk_fman/Peripherals/FM/fm.h"
120879 +#include <linux/delay.h>
120880 +
120881 +
120882 +static int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val);
120883 +
120884 +enum fm_dma_match_stats {
120885 + FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
120886 + FM_DMA_COUNTERS_BUS_ERROR,
120887 + FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
120888 + FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
120889 + FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR
120890 +};
120891 +
120892 +static const struct sysfs_stats_t fm_sysfs_stats[] = {
120893 + /* FM statistics */
120894 + {
120895 + .stat_name = "enq_total_frame",
120896 + .stat_counter = e_FM_COUNTERS_ENQ_TOTAL_FRAME,
120897 + },
120898 + {
120899 + .stat_name = "deq_total_frame",
120900 + .stat_counter = e_FM_COUNTERS_DEQ_TOTAL_FRAME,
120901 + },
120902 + {
120903 + .stat_name = "deq_0",
120904 + .stat_counter = e_FM_COUNTERS_DEQ_0,
120905 + },
120906 + {
120907 + .stat_name = "deq_1",
120908 + .stat_counter = e_FM_COUNTERS_DEQ_1,
120909 + },
120910 + {
120911 + .stat_name = "deq_2",
120912 + .stat_counter = e_FM_COUNTERS_DEQ_2,
120913 + },
120914 + {
120915 + .stat_name = "deq_3",
120916 + .stat_counter = e_FM_COUNTERS_DEQ_3,
120917 + },
120918 + {
120919 + .stat_name = "deq_from_default",
120920 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_DEFAULT,
120921 + },
120922 + {
120923 + .stat_name = "deq_from_context",
120924 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_CONTEXT,
120925 + },
120926 + {
120927 + .stat_name = "deq_from_fd",
120928 + .stat_counter = e_FM_COUNTERS_DEQ_FROM_FD,
120929 + },
120930 + {
120931 + .stat_name = "deq_confirm",
120932 + .stat_counter = e_FM_COUNTERS_DEQ_CONFIRM,
120933 + },
120934 + /* FM:DMA statistics */
120935 + {
120936 + .stat_name = "cmq_not_empty",
120937 + .stat_counter = FM_DMA_COUNTERS_CMQ_NOT_EMPTY,
120938 + },
120939 + {
120940 + .stat_name = "bus_error",
120941 + .stat_counter = FM_DMA_COUNTERS_BUS_ERROR,
120942 + },
120943 + {
120944 + .stat_name = "read_buf_ecc_error",
120945 + .stat_counter = FM_DMA_COUNTERS_READ_BUF_ECC_ERROR,
120946 + },
120947 + {
120948 + .stat_name = "write_buf_ecc_sys_error",
120949 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR,
120950 + },
120951 + {
120952 + .stat_name = "write_buf_ecc_fm_error",
120953 + .stat_counter = FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR,
120954 + },
120955 + /* FM:PCD statistics */
120956 + {
120957 + .stat_name = "pcd_kg_total",
120958 + .stat_counter = e_FM_PCD_KG_COUNTERS_TOTAL,
120959 + },
120960 + {
120961 + .stat_name = "pcd_plcr_yellow",
120962 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_YELLOW,
120963 + },
120964 + {
120965 + .stat_name = "pcd_plcr_red",
120966 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RED,
120967 + },
120968 + {
120969 + .stat_name = "pcd_plcr_recolored_to_red",
120970 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED,
120971 + },
120972 + {
120973 + .stat_name = "pcd_plcr_recolored_to_yellow",
120974 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW,
120975 + },
120976 + {
120977 + .stat_name = "pcd_plcr_total",
120978 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_TOTAL,
120979 + },
120980 + {
120981 + .stat_name = "pcd_plcr_length_mismatch",
120982 + .stat_counter = e_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH,
120983 + },
120984 + {
120985 + .stat_name = "pcd_prs_parse_dispatch",
120986 + .stat_counter = e_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH,
120987 + },
120988 + {
120989 + .stat_name = "pcd_prs_l2_parse_result_returned",
120990 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED,
120991 + },
120992 + {
120993 + .stat_name = "pcd_prs_l3_parse_result_returned",
120994 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED,
120995 + },
120996 + {
120997 + .stat_name = "pcd_prs_l4_parse_result_returned",
120998 + .stat_counter = e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED,
120999 + },
121000 + {
121001 + .stat_name = "pcd_prs_shim_parse_result_returned",
121002 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED,
121003 + },
121004 + {
121005 + .stat_name = "pcd_prs_l2_parse_result_returned_with_err",
121006 + .stat_counter =
121007 + e_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED_WITH_ERR,
121008 + },
121009 + {
121010 + .stat_name = "pcd_prs_l3_parse_result_returned_with_err",
121011 + .stat_counter =
121012 + e_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED_WITH_ERR,
121013 + },
121014 + {
121015 + .stat_name = "pcd_prs_l4_parse_result_returned_with_err",
121016 + .stat_counter =
121017 + e_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED_WITH_ERR,
121018 + },
121019 + {
121020 + .stat_name = "pcd_prs_shim_parse_result_returned_with_err",
121021 + .stat_counter =
121022 + e_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED_WITH_ERR,
121023 + },
121024 + {
121025 + .stat_name = "pcd_prs_soft_prs_cycles",
121026 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES,
121027 + },
121028 + {
121029 + .stat_name = "pcd_prs_soft_prs_stall_cycles",
121030 + .stat_counter = e_FM_PCD_PRS_COUNTERS_SOFT_PRS_STALL_CYCLES,
121031 + },
121032 + {
121033 + .stat_name = "pcd_prs_hard_prs_cycle_incl_stall_cycles",
121034 + .stat_counter =
121035 + e_FM_PCD_PRS_COUNTERS_HARD_PRS_CYCLE_INCL_STALL_CYCLES,
121036 + },
121037 + {
121038 + .stat_name = "pcd_prs_muram_read_cycles",
121039 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES,
121040 + },
121041 + {
121042 + .stat_name = "pcd_prs_muram_read_stall_cycles",
121043 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES,
121044 + },
121045 + {
121046 + .stat_name = "pcd_prs_muram_write_cycles",
121047 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES,
121048 + },
121049 + {
121050 + .stat_name = "pcd_prs_muram_write_stall_cycles",
121051 + .stat_counter = e_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES,
121052 + },
121053 + {
121054 + .stat_name = "pcd_prs_fpm_command_stall_cycles",
121055 + .stat_counter = e_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES,
121056 + },
121057 + {}
121058 +};
121059 +
121060 +
121061 +static ssize_t show_fm_risc_load(struct device *dev,
121062 + struct device_attribute *attr, char *buf)
121063 +{
121064 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121065 + unsigned long flags;
121066 + int m =0;
121067 + int err =0;
121068 + unsigned n = 0;
121069 + t_FmCtrlMon util;
121070 + uint8_t i =0 ;
121071 +
121072 + if (attr == NULL || buf == NULL || dev == NULL)
121073 + return -EINVAL;
121074 +
121075 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121076 + if (WARN_ON(p_wrp_fm_dev == NULL))
121077 + return -EINVAL;
121078 +
121079 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121080 + return -EIO;
121081 +
121082 + local_irq_save(flags);
121083 +
121084 + /* Calculate risc load */
121085 + FM_CtrlMonStart(p_wrp_fm_dev->h_Dev);
121086 + msleep(1000);
121087 + FM_CtrlMonStop(p_wrp_fm_dev->h_Dev);
121088 +
121089 + for (i = 0; i < FM_NUM_OF_CTRL; i++) {
121090 + err |= FM_CtrlMonGetCounters(p_wrp_fm_dev->h_Dev, i, &util);
121091 + m = snprintf(&buf[n],PAGE_SIZE,"\tRisc%u: util-%u%%, efficiency-%u%%\n",
121092 + i, util.percentCnt[0], util.percentCnt[1]);
121093 + n=m+n;
121094 + }
121095 +
121096 + local_irq_restore(flags);
121097 +
121098 + return n;
121099 +}
121100 +
121101 +/* Fm stats and regs dumps via sysfs */
121102 +static ssize_t show_fm_dma_stats(struct device *dev,
121103 + struct device_attribute *attr, char *buf)
121104 +{
121105 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121106 + t_FmDmaStatus dma_status;
121107 + unsigned long flags = 0;
121108 + unsigned n = 0;
121109 + uint8_t counter_value = 0, counter = 0;
121110 +
121111 + if (attr == NULL || buf == NULL || dev == NULL)
121112 + return -EINVAL;
121113 +
121114 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121115 + if (WARN_ON(p_wrp_fm_dev == NULL))
121116 + return -EINVAL;
121117 +
121118 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121119 + return -EIO;
121120 +
121121 + counter = fm_find_statistic_counter_by_name(
121122 + attr->attr.name,
121123 + fm_sysfs_stats, NULL);
121124 +
121125 + local_irq_save(flags);
121126 +
121127 + memset(&dma_status, 0, sizeof(dma_status));
121128 + FM_GetDmaStatus(p_wrp_fm_dev->h_Dev, &dma_status);
121129 +
121130 + switch (counter) {
121131 + case FM_DMA_COUNTERS_CMQ_NOT_EMPTY:
121132 + counter_value = dma_status.cmqNotEmpty;
121133 + break;
121134 + case FM_DMA_COUNTERS_BUS_ERROR:
121135 + counter_value = dma_status.busError;
121136 + break;
121137 + case FM_DMA_COUNTERS_READ_BUF_ECC_ERROR:
121138 + counter_value = dma_status.readBufEccError;
121139 + break;
121140 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_SYS_ERROR:
121141 + counter_value = dma_status.writeBufEccSysError;
121142 + break;
121143 + case FM_DMA_COUNTERS_WRITE_BUF_ECC_FM_ERROR:
121144 + counter_value = dma_status.writeBufEccFmError;
121145 + break;
121146 + default:
121147 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
121148 + __func__);
121149 + break;
121150 + };
121151 +
121152 + n = snprintf(buf, PAGE_SIZE, "\tFM %u counter: %c\n",
121153 + p_wrp_fm_dev->id, counter_value ? 'T' : 'F');
121154 +
121155 + local_irq_restore(flags);
121156 +
121157 + return n;
121158 +}
121159 +
121160 +static ssize_t show_fm_stats(struct device *dev,
121161 + struct device_attribute *attr, char *buf)
121162 +{
121163 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121164 + unsigned long flags = 0;
121165 + unsigned n = 0, cnt_e = 0;
121166 + uint32_t cnt_val;
121167 + int err;
121168 +
121169 + if (attr == NULL || buf == NULL || dev == NULL)
121170 + return -EINVAL;
121171 +
121172 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121173 + if (WARN_ON(p_wrp_fm_dev == NULL))
121174 + return -EINVAL;
121175 +
121176 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121177 + return -EIO;
121178 +
121179 + cnt_e = fm_find_statistic_counter_by_name(
121180 + attr->attr.name,
121181 + fm_sysfs_stats, NULL);
121182 +
121183 + err = fm_get_counter(p_wrp_fm_dev->h_Dev,
121184 + (e_FmCounters) cnt_e, &cnt_val);
121185 +
121186 + if (err)
121187 + return err;
121188 +
121189 + local_irq_save(flags);
121190 +
121191 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
121192 + p_wrp_fm_dev->id, cnt_val);
121193 +
121194 + local_irq_restore(flags);
121195 +
121196 + return n;
121197 +}
121198 +
121199 +static ssize_t show_fm_muram_free_sz(struct device *dev,
121200 + struct device_attribute *attr, char *buf)
121201 +{
121202 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121203 + unsigned long flags = 0;
121204 + unsigned n = 0;
121205 + uint64_t muram_free_size = 0;
121206 +
121207 + if (attr == NULL || buf == NULL || dev == NULL)
121208 + return -EINVAL;
121209 +
121210 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121211 + if (WARN_ON(p_wrp_fm_dev == NULL))
121212 + return -EINVAL;
121213 +
121214 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121215 + return -EIO;
121216 +
121217 + muram_free_size = FM_MURAM_GetFreeMemSize(p_wrp_fm_dev->h_MuramDev);
121218 +
121219 + local_irq_save(flags);
121220 +
121221 + n = snprintf(buf, PAGE_SIZE, "\tFM %d muram_free_size: %lld\n",
121222 + p_wrp_fm_dev->id, muram_free_size);
121223 +
121224 + local_irq_restore(flags);
121225 +
121226 + return n;
121227 +}
121228 +
121229 +static ssize_t show_fm_ctrl_code_ver(struct device *dev,
121230 + struct device_attribute *attr, char *buf)
121231 +{
121232 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121233 + unsigned long flags = 0;
121234 + unsigned n = 0;
121235 + t_FmCtrlCodeRevisionInfo rv_info;
121236 +
121237 + if (attr == NULL || buf == NULL || dev == NULL)
121238 + return -EINVAL;
121239 +
121240 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121241 + if (WARN_ON(p_wrp_fm_dev == NULL))
121242 + return -EINVAL;
121243 +
121244 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121245 + return -EIO;
121246 +
121247 + FM_GetFmanCtrlCodeRevision((t_Fm *)p_wrp_fm_dev->h_Dev, &rv_info);
121248 +
121249 + local_irq_save(flags);
121250 +
121251 + FM_DMP_LN(buf, n, "- FM %d ctrl code pkg info:\n", p_wrp_fm_dev->id);
121252 + FM_DMP_LN(buf, n, "Package rev: %d\n", rv_info.packageRev);
121253 + FM_DMP_LN(buf, n, "major rev: %d\n", rv_info.majorRev);
121254 + FM_DMP_LN(buf, n, "minor rev: %d\n", rv_info.minorRev);
121255 +
121256 + local_irq_restore(flags);
121257 +
121258 + return n;
121259 +}
121260 +
121261 +static ssize_t show_fm_pcd_stats(struct device *dev,
121262 + struct device_attribute *attr, char *buf)
121263 +{
121264 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121265 + unsigned long flags = 0;
121266 + unsigned n = 0, counter = 0;
121267 +
121268 + if (attr == NULL || buf == NULL || dev == NULL)
121269 + return -EINVAL;
121270 +
121271 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121272 + if (WARN_ON(p_wrp_fm_dev == NULL))
121273 + return -EINVAL;
121274 +
121275 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev ||
121276 + !p_wrp_fm_dev->h_PcdDev)
121277 + return -EIO;
121278 +
121279 + counter = fm_find_statistic_counter_by_name(
121280 + attr->attr.name,
121281 + fm_sysfs_stats, NULL);
121282 +
121283 + local_irq_save(flags);
121284 +
121285 + n = snprintf(buf, PAGE_SIZE, "\tFM %d counter: %d\n",
121286 + p_wrp_fm_dev->id,
121287 + FM_PCD_GetCounter(p_wrp_fm_dev->h_PcdDev,
121288 + (e_FmPcdCounters) counter));
121289 +
121290 + local_irq_restore(flags);
121291 +
121292 + return n;
121293 +}
121294 +
121295 +static ssize_t show_fm_tnum_dbg(struct device *dev,
121296 + struct device_attribute *attr,
121297 + char *buf)
121298 +{
121299 + unsigned long flags;
121300 + unsigned n = 0;
121301 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121302 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121303 +#endif
121304 +
121305 + if (attr == NULL || buf == NULL || dev == NULL)
121306 + return -EINVAL;
121307 +
121308 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121309 +
121310 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121311 + if (WARN_ON(p_wrp_fm_dev == NULL))
121312 + return -EINVAL;
121313 +
121314 + local_irq_save(flags);
121315 +
121316 + if (!p_wrp_fm_dev->active)
121317 + return -EIO;
121318 + else {
121319 + int tn_s;
121320 +
121321 + if (!sscanf(attr->attr.name, "tnum_dbg_%d", &tn_s))
121322 + return -EINVAL;
121323 +
121324 + n = fm_dump_tnum_dbg(p_wrp_fm_dev->h_Dev,
121325 + tn_s, tn_s + 15, buf, n);
121326 + }
121327 + local_irq_restore(flags);
121328 +#else
121329 +
121330 + local_irq_save(flags);
121331 + n = snprintf(buf, PAGE_SIZE,
121332 + "Debug level is too low to dump registers!!!\n");
121333 + local_irq_restore(flags);
121334 +#endif /* (defined(DEBUG_ERRORS) && ... */
121335 +
121336 + return n;
121337 +}
121338 +
121339 +static ssize_t show_fm_cls_plan(struct device *dev,
121340 + struct device_attribute *attr,
121341 + char *buf)
121342 +{
121343 + unsigned long flags;
121344 + unsigned n = 0;
121345 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121346 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121347 +#endif
121348 +
121349 + if (attr == NULL || buf == NULL || dev == NULL)
121350 + return -EINVAL;
121351 +
121352 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121353 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121354 + if (WARN_ON(p_wrp_fm_dev == NULL))
121355 + return -EINVAL;
121356 +
121357 + local_irq_save(flags);
121358 +
121359 + n = snprintf(buf, PAGE_SIZE, "\n FM-KG classification plan dump.\n");
121360 +
121361 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121362 + return -EIO;
121363 + else {
121364 + int cpn;
121365 +
121366 + if (!sscanf(attr->attr.name, "cls_plan_%d", &cpn))
121367 + return -EINVAL;
121368 +
121369 + n = fm_dump_cls_plan(p_wrp_fm_dev->h_PcdDev, cpn, buf, n);
121370 + }
121371 + local_irq_restore(flags);
121372 +#else
121373 + local_irq_save(flags);
121374 + n = snprintf(buf, PAGE_SIZE,
121375 + "Debug level is too low to dump registers!!!\n");
121376 + local_irq_restore(flags);
121377 +#endif /* (defined(DEBUG_ERRORS) && ... */
121378 +
121379 + return n;
121380 +}
121381 +
121382 +static ssize_t show_fm_profiles(struct device *dev,
121383 + struct device_attribute *attr,
121384 + char *buf)
121385 +{
121386 + unsigned long flags;
121387 + unsigned n = 0;
121388 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121389 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121390 +#endif
121391 +
121392 + if (attr == NULL || buf == NULL || dev == NULL)
121393 + return -EINVAL;
121394 +
121395 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121396 +
121397 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121398 + if (WARN_ON(p_wrp_fm_dev == NULL))
121399 + return -EINVAL;
121400 +
121401 + local_irq_save(flags);
121402 +
121403 + n = snprintf(buf, PAGE_SIZE, "FM policer profile dump.\n");
121404 +
121405 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121406 + return -EIO;
121407 + else {
121408 + int pn;
121409 +
121410 + if (!sscanf(attr->attr.name, "profile_%d", &pn))
121411 + return -EINVAL;
121412 +
121413 + n = fm_profile_dump_regs(p_wrp_fm_dev->h_PcdDev, pn, buf, n);
121414 + }
121415 + local_irq_restore(flags);
121416 +#else
121417 + local_irq_save(flags);
121418 + n = snprintf(buf, PAGE_SIZE,
121419 + "Debug level is too low to dump registers!!!\n");
121420 + local_irq_restore(flags);
121421 +#endif /* (defined(DEBUG_ERRORS) && ... */
121422 +
121423 + return n;
121424 +}
121425 +
121426 +static ssize_t show_fm_schemes(struct device *dev,
121427 + struct device_attribute *attr,
121428 + char *buf)
121429 +{
121430 + unsigned long flags;
121431 + unsigned n = 0;
121432 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121433 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121434 +#endif
121435 +
121436 + if (attr == NULL || buf == NULL || dev == NULL)
121437 + return -EINVAL;
121438 +
121439 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121440 +
121441 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121442 + if (WARN_ON(p_wrp_fm_dev == NULL))
121443 + return -EINVAL;
121444 +
121445 + local_irq_save(flags);
121446 +
121447 + n = snprintf(buf, PAGE_SIZE, "FM-KG driver schemes dump.\n");
121448 +
121449 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121450 + return -EIO;
121451 + else {
121452 + int sn;
121453 +
121454 + if (!sscanf(attr->attr.name, "scheme_%d", &sn))
121455 + return -EINVAL;
121456 +
121457 + n = fm_dump_scheme(p_wrp_fm_dev->h_PcdDev, sn, buf, n);
121458 + }
121459 + local_irq_restore(flags);
121460 +#else
121461 +
121462 + local_irq_save(flags);
121463 + n = snprintf(buf, PAGE_SIZE,
121464 + "Debug level is too low to dump registers!!!\n");
121465 + local_irq_restore(flags);
121466 +#endif /* (defined(DEBUG_ERRORS) && ... */
121467 +
121468 + return n;
121469 +}
121470 +
121471 +/* FM */
121472 +static DEVICE_ATTR(enq_total_frame, S_IRUGO, show_fm_stats, NULL);
121473 +static DEVICE_ATTR(deq_total_frame, S_IRUGO, show_fm_stats, NULL);
121474 +static DEVICE_ATTR(fm_risc_load_val, S_IRUGO, show_fm_risc_load, NULL);
121475 +static DEVICE_ATTR(deq_0, S_IRUGO, show_fm_stats, NULL);
121476 +static DEVICE_ATTR(deq_1, S_IRUGO, show_fm_stats, NULL);
121477 +static DEVICE_ATTR(deq_2, S_IRUGO, show_fm_stats, NULL);
121478 +static DEVICE_ATTR(deq_3, S_IRUGO, show_fm_stats, NULL);
121479 +static DEVICE_ATTR(deq_from_default, S_IRUGO, show_fm_stats, NULL);
121480 +static DEVICE_ATTR(deq_from_context, S_IRUGO, show_fm_stats, NULL);
121481 +static DEVICE_ATTR(deq_from_fd, S_IRUGO, show_fm_stats, NULL);
121482 +static DEVICE_ATTR(deq_confirm, S_IRUGO, show_fm_stats, NULL);
121483 +/* FM:DMA */
121484 +static DEVICE_ATTR(cmq_not_empty, S_IRUGO, show_fm_dma_stats, NULL);
121485 +static DEVICE_ATTR(bus_error, S_IRUGO, show_fm_dma_stats, NULL);
121486 +static DEVICE_ATTR(read_buf_ecc_error, S_IRUGO, show_fm_dma_stats, NULL);
121487 +static DEVICE_ATTR(write_buf_ecc_sys_error, S_IRUGO, show_fm_dma_stats, NULL);
121488 +static DEVICE_ATTR(write_buf_ecc_fm_error, S_IRUGO, show_fm_dma_stats, NULL);
121489 +/* FM:PCD */
121490 +static DEVICE_ATTR(pcd_kg_total, S_IRUGO, show_fm_pcd_stats, NULL);
121491 +static DEVICE_ATTR(pcd_plcr_yellow, S_IRUGO, show_fm_pcd_stats, NULL);
121492 +static DEVICE_ATTR(pcd_plcr_red, S_IRUGO, show_fm_pcd_stats, NULL);
121493 +static DEVICE_ATTR(pcd_plcr_recolored_to_red, S_IRUGO, show_fm_pcd_stats,
121494 + NULL);
121495 +static DEVICE_ATTR(pcd_plcr_recolored_to_yellow, S_IRUGO, show_fm_pcd_stats,
121496 + NULL);
121497 +static DEVICE_ATTR(pcd_plcr_total, S_IRUGO, show_fm_pcd_stats, NULL);
121498 +static DEVICE_ATTR(pcd_plcr_length_mismatch, S_IRUGO, show_fm_pcd_stats,
121499 + NULL);
121500 +static DEVICE_ATTR(pcd_prs_parse_dispatch, S_IRUGO, show_fm_pcd_stats, NULL);
121501 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned, S_IRUGO,
121502 + show_fm_pcd_stats, NULL);
121503 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned, S_IRUGO,
121504 + show_fm_pcd_stats, NULL);
121505 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned, S_IRUGO,
121506 + show_fm_pcd_stats, NULL);
121507 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned, S_IRUGO,
121508 + show_fm_pcd_stats, NULL);
121509 +static DEVICE_ATTR(pcd_prs_l2_parse_result_returned_with_err, S_IRUGO,
121510 + show_fm_pcd_stats, NULL);
121511 +static DEVICE_ATTR(pcd_prs_l3_parse_result_returned_with_err, S_IRUGO,
121512 + show_fm_pcd_stats, NULL);
121513 +static DEVICE_ATTR(pcd_prs_l4_parse_result_returned_with_err, S_IRUGO,
121514 + show_fm_pcd_stats, NULL);
121515 +static DEVICE_ATTR(pcd_prs_shim_parse_result_returned_with_err, S_IRUGO,
121516 + show_fm_pcd_stats, NULL);
121517 +static DEVICE_ATTR(pcd_prs_soft_prs_cycles, S_IRUGO, show_fm_pcd_stats, NULL);
121518 +static DEVICE_ATTR(pcd_prs_soft_prs_stall_cycles, S_IRUGO, show_fm_pcd_stats,
121519 + NULL);
121520 +static DEVICE_ATTR(pcd_prs_hard_prs_cycle_incl_stall_cycles, S_IRUGO,
121521 + show_fm_pcd_stats, NULL);
121522 +static DEVICE_ATTR(pcd_prs_muram_read_cycles, S_IRUGO, show_fm_pcd_stats,
121523 + NULL);
121524 +static DEVICE_ATTR(pcd_prs_muram_read_stall_cycles, S_IRUGO,
121525 + show_fm_pcd_stats, NULL);
121526 +static DEVICE_ATTR(pcd_prs_muram_write_cycles, S_IRUGO, show_fm_pcd_stats,
121527 + NULL);
121528 +static DEVICE_ATTR(pcd_prs_muram_write_stall_cycles, S_IRUGO,
121529 + show_fm_pcd_stats, NULL);
121530 +static DEVICE_ATTR(pcd_prs_fpm_command_stall_cycles, S_IRUGO,
121531 + show_fm_pcd_stats, NULL);
121532 +
121533 +static DEVICE_ATTR(tnum_dbg_0, S_IRUGO, show_fm_tnum_dbg, NULL);
121534 +static DEVICE_ATTR(tnum_dbg_16, S_IRUGO, show_fm_tnum_dbg, NULL);
121535 +static DEVICE_ATTR(tnum_dbg_32, S_IRUGO, show_fm_tnum_dbg, NULL);
121536 +static DEVICE_ATTR(tnum_dbg_48, S_IRUGO, show_fm_tnum_dbg, NULL);
121537 +static DEVICE_ATTR(tnum_dbg_64, S_IRUGO, show_fm_tnum_dbg, NULL);
121538 +static DEVICE_ATTR(tnum_dbg_80, S_IRUGO, show_fm_tnum_dbg, NULL);
121539 +static DEVICE_ATTR(tnum_dbg_96, S_IRUGO, show_fm_tnum_dbg, NULL);
121540 +static DEVICE_ATTR(tnum_dbg_112, S_IRUGO, show_fm_tnum_dbg, NULL);
121541 +
121542 +static DEVICE_ATTR(cls_plan_0, S_IRUGO, show_fm_cls_plan, NULL);
121543 +static DEVICE_ATTR(cls_plan_1, S_IRUGO, show_fm_cls_plan, NULL);
121544 +static DEVICE_ATTR(cls_plan_2, S_IRUGO, show_fm_cls_plan, NULL);
121545 +static DEVICE_ATTR(cls_plan_3, S_IRUGO, show_fm_cls_plan, NULL);
121546 +static DEVICE_ATTR(cls_plan_4, S_IRUGO, show_fm_cls_plan, NULL);
121547 +static DEVICE_ATTR(cls_plan_5, S_IRUGO, show_fm_cls_plan, NULL);
121548 +static DEVICE_ATTR(cls_plan_6, S_IRUGO, show_fm_cls_plan, NULL);
121549 +static DEVICE_ATTR(cls_plan_7, S_IRUGO, show_fm_cls_plan, NULL);
121550 +static DEVICE_ATTR(cls_plan_8, S_IRUGO, show_fm_cls_plan, NULL);
121551 +static DEVICE_ATTR(cls_plan_9, S_IRUGO, show_fm_cls_plan, NULL);
121552 +static DEVICE_ATTR(cls_plan_10, S_IRUGO, show_fm_cls_plan, NULL);
121553 +static DEVICE_ATTR(cls_plan_11, S_IRUGO, show_fm_cls_plan, NULL);
121554 +static DEVICE_ATTR(cls_plan_12, S_IRUGO, show_fm_cls_plan, NULL);
121555 +static DEVICE_ATTR(cls_plan_13, S_IRUGO, show_fm_cls_plan, NULL);
121556 +static DEVICE_ATTR(cls_plan_14, S_IRUGO, show_fm_cls_plan, NULL);
121557 +static DEVICE_ATTR(cls_plan_15, S_IRUGO, show_fm_cls_plan, NULL);
121558 +static DEVICE_ATTR(cls_plan_16, S_IRUGO, show_fm_cls_plan, NULL);
121559 +static DEVICE_ATTR(cls_plan_17, S_IRUGO, show_fm_cls_plan, NULL);
121560 +static DEVICE_ATTR(cls_plan_18, S_IRUGO, show_fm_cls_plan, NULL);
121561 +static DEVICE_ATTR(cls_plan_19, S_IRUGO, show_fm_cls_plan, NULL);
121562 +static DEVICE_ATTR(cls_plan_20, S_IRUGO, show_fm_cls_plan, NULL);
121563 +static DEVICE_ATTR(cls_plan_21, S_IRUGO, show_fm_cls_plan, NULL);
121564 +static DEVICE_ATTR(cls_plan_22, S_IRUGO, show_fm_cls_plan, NULL);
121565 +static DEVICE_ATTR(cls_plan_23, S_IRUGO, show_fm_cls_plan, NULL);
121566 +static DEVICE_ATTR(cls_plan_24, S_IRUGO, show_fm_cls_plan, NULL);
121567 +static DEVICE_ATTR(cls_plan_25, S_IRUGO, show_fm_cls_plan, NULL);
121568 +static DEVICE_ATTR(cls_plan_26, S_IRUGO, show_fm_cls_plan, NULL);
121569 +static DEVICE_ATTR(cls_plan_27, S_IRUGO, show_fm_cls_plan, NULL);
121570 +static DEVICE_ATTR(cls_plan_28, S_IRUGO, show_fm_cls_plan, NULL);
121571 +static DEVICE_ATTR(cls_plan_29, S_IRUGO, show_fm_cls_plan, NULL);
121572 +static DEVICE_ATTR(cls_plan_30, S_IRUGO, show_fm_cls_plan, NULL);
121573 +static DEVICE_ATTR(cls_plan_31, S_IRUGO, show_fm_cls_plan, NULL);
121574 +
121575 +static DEVICE_ATTR(profile_0, S_IRUGO, show_fm_profiles, NULL);
121576 +static DEVICE_ATTR(profile_1, S_IRUGO, show_fm_profiles, NULL);
121577 +static DEVICE_ATTR(profile_2, S_IRUGO, show_fm_profiles, NULL);
121578 +static DEVICE_ATTR(profile_3, S_IRUGO, show_fm_profiles, NULL);
121579 +static DEVICE_ATTR(profile_4, S_IRUGO, show_fm_profiles, NULL);
121580 +static DEVICE_ATTR(profile_5, S_IRUGO, show_fm_profiles, NULL);
121581 +static DEVICE_ATTR(profile_6, S_IRUGO, show_fm_profiles, NULL);
121582 +static DEVICE_ATTR(profile_7, S_IRUGO, show_fm_profiles, NULL);
121583 +static DEVICE_ATTR(profile_8, S_IRUGO, show_fm_profiles, NULL);
121584 +static DEVICE_ATTR(profile_9, S_IRUGO, show_fm_profiles, NULL);
121585 +static DEVICE_ATTR(profile_10, S_IRUGO, show_fm_profiles, NULL);
121586 +static DEVICE_ATTR(profile_11, S_IRUGO, show_fm_profiles, NULL);
121587 +static DEVICE_ATTR(profile_12, S_IRUGO, show_fm_profiles, NULL);
121588 +static DEVICE_ATTR(profile_13, S_IRUGO, show_fm_profiles, NULL);
121589 +static DEVICE_ATTR(profile_14, S_IRUGO, show_fm_profiles, NULL);
121590 +static DEVICE_ATTR(profile_15, S_IRUGO, show_fm_profiles, NULL);
121591 +static DEVICE_ATTR(profile_16, S_IRUGO, show_fm_profiles, NULL);
121592 +static DEVICE_ATTR(profile_17, S_IRUGO, show_fm_profiles, NULL);
121593 +static DEVICE_ATTR(profile_18, S_IRUGO, show_fm_profiles, NULL);
121594 +static DEVICE_ATTR(profile_19, S_IRUGO, show_fm_profiles, NULL);
121595 +static DEVICE_ATTR(profile_20, S_IRUGO, show_fm_profiles, NULL);
121596 +static DEVICE_ATTR(profile_21, S_IRUGO, show_fm_profiles, NULL);
121597 +static DEVICE_ATTR(profile_22, S_IRUGO, show_fm_profiles, NULL);
121598 +static DEVICE_ATTR(profile_23, S_IRUGO, show_fm_profiles, NULL);
121599 +static DEVICE_ATTR(profile_24, S_IRUGO, show_fm_profiles, NULL);
121600 +static DEVICE_ATTR(profile_25, S_IRUGO, show_fm_profiles, NULL);
121601 +static DEVICE_ATTR(profile_26, S_IRUGO, show_fm_profiles, NULL);
121602 +static DEVICE_ATTR(profile_27, S_IRUGO, show_fm_profiles, NULL);
121603 +static DEVICE_ATTR(profile_28, S_IRUGO, show_fm_profiles, NULL);
121604 +static DEVICE_ATTR(profile_29, S_IRUGO, show_fm_profiles, NULL);
121605 +static DEVICE_ATTR(profile_30, S_IRUGO, show_fm_profiles, NULL);
121606 +static DEVICE_ATTR(profile_31, S_IRUGO, show_fm_profiles, NULL);
121607 +
121608 +static DEVICE_ATTR(scheme_0, S_IRUGO, show_fm_schemes, NULL);
121609 +static DEVICE_ATTR(scheme_1, S_IRUGO, show_fm_schemes, NULL);
121610 +static DEVICE_ATTR(scheme_2, S_IRUGO, show_fm_schemes, NULL);
121611 +static DEVICE_ATTR(scheme_3, S_IRUGO, show_fm_schemes, NULL);
121612 +static DEVICE_ATTR(scheme_4, S_IRUGO, show_fm_schemes, NULL);
121613 +static DEVICE_ATTR(scheme_5, S_IRUGO, show_fm_schemes, NULL);
121614 +static DEVICE_ATTR(scheme_6, S_IRUGO, show_fm_schemes, NULL);
121615 +static DEVICE_ATTR(scheme_7, S_IRUGO, show_fm_schemes, NULL);
121616 +static DEVICE_ATTR(scheme_8, S_IRUGO, show_fm_schemes, NULL);
121617 +static DEVICE_ATTR(scheme_9, S_IRUGO, show_fm_schemes, NULL);
121618 +static DEVICE_ATTR(scheme_10, S_IRUGO, show_fm_schemes, NULL);
121619 +static DEVICE_ATTR(scheme_11, S_IRUGO, show_fm_schemes, NULL);
121620 +static DEVICE_ATTR(scheme_12, S_IRUGO, show_fm_schemes, NULL);
121621 +static DEVICE_ATTR(scheme_13, S_IRUGO, show_fm_schemes, NULL);
121622 +static DEVICE_ATTR(scheme_14, S_IRUGO, show_fm_schemes, NULL);
121623 +static DEVICE_ATTR(scheme_15, S_IRUGO, show_fm_schemes, NULL);
121624 +static DEVICE_ATTR(scheme_16, S_IRUGO, show_fm_schemes, NULL);
121625 +static DEVICE_ATTR(scheme_17, S_IRUGO, show_fm_schemes, NULL);
121626 +static DEVICE_ATTR(scheme_18, S_IRUGO, show_fm_schemes, NULL);
121627 +static DEVICE_ATTR(scheme_19, S_IRUGO, show_fm_schemes, NULL);
121628 +static DEVICE_ATTR(scheme_20, S_IRUGO, show_fm_schemes, NULL);
121629 +static DEVICE_ATTR(scheme_21, S_IRUGO, show_fm_schemes, NULL);
121630 +static DEVICE_ATTR(scheme_22, S_IRUGO, show_fm_schemes, NULL);
121631 +static DEVICE_ATTR(scheme_23, S_IRUGO, show_fm_schemes, NULL);
121632 +static DEVICE_ATTR(scheme_24, S_IRUGO, show_fm_schemes, NULL);
121633 +static DEVICE_ATTR(scheme_25, S_IRUGO, show_fm_schemes, NULL);
121634 +static DEVICE_ATTR(scheme_26, S_IRUGO, show_fm_schemes, NULL);
121635 +static DEVICE_ATTR(scheme_27, S_IRUGO, show_fm_schemes, NULL);
121636 +static DEVICE_ATTR(scheme_28, S_IRUGO, show_fm_schemes, NULL);
121637 +static DEVICE_ATTR(scheme_29, S_IRUGO, show_fm_schemes, NULL);
121638 +static DEVICE_ATTR(scheme_30, S_IRUGO, show_fm_schemes, NULL);
121639 +static DEVICE_ATTR(scheme_31, S_IRUGO, show_fm_schemes, NULL);
121640 +
121641 +
121642 +static struct attribute *fm_dev_stats_attributes[] = {
121643 + &dev_attr_enq_total_frame.attr,
121644 + &dev_attr_deq_total_frame.attr,
121645 + &dev_attr_deq_0.attr,
121646 + &dev_attr_deq_1.attr,
121647 + &dev_attr_deq_2.attr,
121648 + &dev_attr_deq_3.attr,
121649 + &dev_attr_deq_from_default.attr,
121650 + &dev_attr_deq_from_context.attr,
121651 + &dev_attr_deq_from_fd.attr,
121652 + &dev_attr_deq_confirm.attr,
121653 + &dev_attr_cmq_not_empty.attr,
121654 + &dev_attr_bus_error.attr,
121655 + &dev_attr_read_buf_ecc_error.attr,
121656 + &dev_attr_write_buf_ecc_sys_error.attr,
121657 + &dev_attr_write_buf_ecc_fm_error.attr,
121658 + &dev_attr_pcd_kg_total.attr,
121659 + &dev_attr_pcd_plcr_yellow.attr,
121660 + &dev_attr_pcd_plcr_red.attr,
121661 + &dev_attr_pcd_plcr_recolored_to_red.attr,
121662 + &dev_attr_pcd_plcr_recolored_to_yellow.attr,
121663 + &dev_attr_pcd_plcr_total.attr,
121664 + &dev_attr_pcd_plcr_length_mismatch.attr,
121665 + &dev_attr_pcd_prs_parse_dispatch.attr,
121666 + &dev_attr_pcd_prs_l2_parse_result_returned.attr,
121667 + &dev_attr_pcd_prs_l3_parse_result_returned.attr,
121668 + &dev_attr_pcd_prs_l4_parse_result_returned.attr,
121669 + &dev_attr_pcd_prs_shim_parse_result_returned.attr,
121670 + &dev_attr_pcd_prs_l2_parse_result_returned_with_err.attr,
121671 + &dev_attr_pcd_prs_l3_parse_result_returned_with_err.attr,
121672 + &dev_attr_pcd_prs_l4_parse_result_returned_with_err.attr,
121673 + &dev_attr_pcd_prs_shim_parse_result_returned_with_err.attr,
121674 + &dev_attr_pcd_prs_soft_prs_cycles.attr,
121675 + &dev_attr_pcd_prs_soft_prs_stall_cycles.attr,
121676 + &dev_attr_pcd_prs_hard_prs_cycle_incl_stall_cycles.attr,
121677 + &dev_attr_pcd_prs_muram_read_cycles.attr,
121678 + &dev_attr_pcd_prs_muram_read_stall_cycles.attr,
121679 + &dev_attr_pcd_prs_muram_write_cycles.attr,
121680 + &dev_attr_pcd_prs_muram_write_stall_cycles.attr,
121681 + &dev_attr_pcd_prs_fpm_command_stall_cycles.attr,
121682 + NULL
121683 +};
121684 +
121685 +static struct attribute *fm_dev_tnums_dbg_attributes[] = {
121686 + &dev_attr_tnum_dbg_0.attr,
121687 + &dev_attr_tnum_dbg_16.attr,
121688 + &dev_attr_tnum_dbg_32.attr,
121689 + &dev_attr_tnum_dbg_48.attr,
121690 + &dev_attr_tnum_dbg_64.attr,
121691 + &dev_attr_tnum_dbg_80.attr,
121692 + &dev_attr_tnum_dbg_96.attr,
121693 + &dev_attr_tnum_dbg_112.attr,
121694 + NULL
121695 +};
121696 +
121697 +static struct attribute *fm_dev_cls_plans_attributes[] = {
121698 + &dev_attr_cls_plan_0.attr,
121699 + &dev_attr_cls_plan_1.attr,
121700 + &dev_attr_cls_plan_2.attr,
121701 + &dev_attr_cls_plan_3.attr,
121702 + &dev_attr_cls_plan_4.attr,
121703 + &dev_attr_cls_plan_5.attr,
121704 + &dev_attr_cls_plan_6.attr,
121705 + &dev_attr_cls_plan_7.attr,
121706 + &dev_attr_cls_plan_8.attr,
121707 + &dev_attr_cls_plan_9.attr,
121708 + &dev_attr_cls_plan_10.attr,
121709 + &dev_attr_cls_plan_11.attr,
121710 + &dev_attr_cls_plan_12.attr,
121711 + &dev_attr_cls_plan_13.attr,
121712 + &dev_attr_cls_plan_14.attr,
121713 + &dev_attr_cls_plan_15.attr,
121714 + &dev_attr_cls_plan_16.attr,
121715 + &dev_attr_cls_plan_17.attr,
121716 + &dev_attr_cls_plan_18.attr,
121717 + &dev_attr_cls_plan_19.attr,
121718 + &dev_attr_cls_plan_20.attr,
121719 + &dev_attr_cls_plan_21.attr,
121720 + &dev_attr_cls_plan_22.attr,
121721 + &dev_attr_cls_plan_23.attr,
121722 + &dev_attr_cls_plan_24.attr,
121723 + &dev_attr_cls_plan_25.attr,
121724 + &dev_attr_cls_plan_26.attr,
121725 + &dev_attr_cls_plan_27.attr,
121726 + &dev_attr_cls_plan_28.attr,
121727 + &dev_attr_cls_plan_29.attr,
121728 + &dev_attr_cls_plan_30.attr,
121729 + &dev_attr_cls_plan_31.attr,
121730 + NULL
121731 +};
121732 +
121733 +static struct attribute *fm_dev_profiles_attributes[] = {
121734 + &dev_attr_profile_0.attr,
121735 + &dev_attr_profile_1.attr,
121736 + &dev_attr_profile_2.attr,
121737 + &dev_attr_profile_3.attr,
121738 + &dev_attr_profile_4.attr,
121739 + &dev_attr_profile_5.attr,
121740 + &dev_attr_profile_6.attr,
121741 + &dev_attr_profile_7.attr,
121742 + &dev_attr_profile_8.attr,
121743 + &dev_attr_profile_9.attr,
121744 + &dev_attr_profile_10.attr,
121745 + &dev_attr_profile_11.attr,
121746 + &dev_attr_profile_12.attr,
121747 + &dev_attr_profile_13.attr,
121748 + &dev_attr_profile_14.attr,
121749 + &dev_attr_profile_15.attr,
121750 + &dev_attr_profile_16.attr,
121751 + &dev_attr_profile_17.attr,
121752 + &dev_attr_profile_18.attr,
121753 + &dev_attr_profile_19.attr,
121754 + &dev_attr_profile_20.attr,
121755 + &dev_attr_profile_21.attr,
121756 + &dev_attr_profile_22.attr,
121757 + &dev_attr_profile_23.attr,
121758 + &dev_attr_profile_24.attr,
121759 + &dev_attr_profile_25.attr,
121760 + &dev_attr_profile_26.attr,
121761 + &dev_attr_profile_27.attr,
121762 + &dev_attr_profile_28.attr,
121763 + &dev_attr_profile_29.attr,
121764 + &dev_attr_profile_30.attr,
121765 + &dev_attr_profile_31.attr,
121766 + NULL
121767 +};
121768 +
121769 +static struct attribute *fm_dev_schemes_attributes[] = {
121770 + &dev_attr_scheme_0.attr,
121771 + &dev_attr_scheme_1.attr,
121772 + &dev_attr_scheme_2.attr,
121773 + &dev_attr_scheme_3.attr,
121774 + &dev_attr_scheme_4.attr,
121775 + &dev_attr_scheme_5.attr,
121776 + &dev_attr_scheme_6.attr,
121777 + &dev_attr_scheme_7.attr,
121778 + &dev_attr_scheme_8.attr,
121779 + &dev_attr_scheme_9.attr,
121780 + &dev_attr_scheme_10.attr,
121781 + &dev_attr_scheme_11.attr,
121782 + &dev_attr_scheme_12.attr,
121783 + &dev_attr_scheme_13.attr,
121784 + &dev_attr_scheme_14.attr,
121785 + &dev_attr_scheme_15.attr,
121786 + &dev_attr_scheme_16.attr,
121787 + &dev_attr_scheme_17.attr,
121788 + &dev_attr_scheme_18.attr,
121789 + &dev_attr_scheme_19.attr,
121790 + &dev_attr_scheme_20.attr,
121791 + &dev_attr_scheme_21.attr,
121792 + &dev_attr_scheme_22.attr,
121793 + &dev_attr_scheme_23.attr,
121794 + &dev_attr_scheme_24.attr,
121795 + &dev_attr_scheme_25.attr,
121796 + &dev_attr_scheme_26.attr,
121797 + &dev_attr_scheme_27.attr,
121798 + &dev_attr_scheme_28.attr,
121799 + &dev_attr_scheme_29.attr,
121800 + &dev_attr_scheme_30.attr,
121801 + &dev_attr_scheme_31.attr,
121802 + NULL
121803 +};
121804 +
121805 +static const struct attribute_group fm_dev_stats_attr_grp = {
121806 + .name = "statistics",
121807 + .attrs = fm_dev_stats_attributes
121808 +};
121809 +
121810 +static const struct attribute_group fm_dev_tnums_dbg_attr_grp = {
121811 + .name = "tnums_dbg",
121812 + .attrs = fm_dev_tnums_dbg_attributes
121813 +};
121814 +
121815 +static const struct attribute_group fm_dev_cls_plans_attr_grp = {
121816 + .name = "cls_plans",
121817 + .attrs = fm_dev_cls_plans_attributes
121818 +};
121819 +
121820 +static const struct attribute_group fm_dev_schemes_attr_grp = {
121821 + .name = "schemes",
121822 + .attrs = fm_dev_schemes_attributes
121823 +};
121824 +
121825 +static const struct attribute_group fm_dev_profiles_attr_grp = {
121826 + .name = "profiles",
121827 + .attrs = fm_dev_profiles_attributes
121828 +};
121829 +
121830 +static ssize_t show_fm_regs(struct device *dev,
121831 + struct device_attribute *attr,
121832 + char *buf)
121833 +{
121834 + unsigned long flags;
121835 + unsigned n = 0;
121836 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121837 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121838 +#endif
121839 + if (attr == NULL || buf == NULL || dev == NULL)
121840 + return -EINVAL;
121841 +
121842 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121843 +
121844 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121845 + if (WARN_ON(p_wrp_fm_dev == NULL))
121846 + return -EINVAL;
121847 +
121848 + local_irq_save(flags);
121849 +
121850 + n = snprintf(buf, PAGE_SIZE, "FM driver registers dump.\n");
121851 +
121852 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121853 + return -EIO;
121854 + else
121855 + n = fm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
121856 +
121857 + local_irq_restore(flags);
121858 +#else
121859 +
121860 + local_irq_save(flags);
121861 + n = snprintf(buf, PAGE_SIZE,
121862 + "Debug level is too low to dump registers!!!\n");
121863 + local_irq_restore(flags);
121864 +#endif /* (defined(DEBUG_ERRORS) && ... */
121865 +
121866 + return n;
121867 +}
121868 +
121869 +static ssize_t show_fm_kg_pe_regs(struct device *dev,
121870 + struct device_attribute *attr,
121871 + char *buf)
121872 +{
121873 + unsigned long flags;
121874 + unsigned n = 0;
121875 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121876 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121877 +#endif
121878 +
121879 + if (attr == NULL || buf == NULL || dev == NULL)
121880 + return -EINVAL;
121881 +
121882 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121883 +
121884 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121885 + if (WARN_ON(p_wrp_fm_dev == NULL))
121886 + return -EINVAL;
121887 +
121888 + local_irq_save(flags);
121889 +
121890 + n = snprintf(buf, PAGE_SIZE,
121891 + "\n FM-KG Port Partition Config registers dump.\n");
121892 +
121893 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121894 + return -EIO;
121895 + else
121896 + n = fm_kg_pe_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
121897 +
121898 + local_irq_restore(flags);
121899 +#else
121900 +
121901 + local_irq_save(flags);
121902 + n = snprintf(buf, PAGE_SIZE,
121903 + "Debug level is too low to dump registers!!!\n");
121904 + local_irq_restore(flags);
121905 +#endif /* (defined(DEBUG_ERRORS) && ... */
121906 +
121907 + return n;
121908 +}
121909 +
121910 +static ssize_t show_fm_kg_regs(struct device *dev,
121911 + struct device_attribute *attr,
121912 + char *buf)
121913 +{
121914 + unsigned long flags;
121915 + unsigned n = 0;
121916 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121917 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121918 +#endif
121919 +
121920 + if (attr == NULL || buf == NULL || dev == NULL)
121921 + return -EINVAL;
121922 +
121923 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121924 +
121925 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121926 + if (WARN_ON(p_wrp_fm_dev == NULL))
121927 + return -EINVAL;
121928 +
121929 + local_irq_save(flags);
121930 +
121931 + n = snprintf(buf, PAGE_SIZE, "FM-KG registers dump.\n");
121932 +
121933 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
121934 + return -EIO;
121935 + else
121936 + n = fm_kg_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
121937 +
121938 + local_irq_restore(flags);
121939 +#else
121940 +
121941 + local_irq_save(flags);
121942 + n = snprintf(buf, PAGE_SIZE,
121943 + "Debug level is too low to dump registers!!!\n");
121944 + local_irq_restore(flags);
121945 +#endif /* (defined(DEBUG_ERRORS) && ... */
121946 +
121947 + return n;
121948 +}
121949 +
121950 +
121951 +static ssize_t show_fm_fpm_regs(struct device *dev,
121952 + struct device_attribute *attr,
121953 + char *buf)
121954 +{
121955 + unsigned long flags;
121956 + unsigned n = 0;
121957 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121958 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121959 +#endif
121960 +
121961 + if (attr == NULL || buf == NULL || dev == NULL)
121962 + return -EINVAL;
121963 +
121964 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121965 +
121966 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
121967 + if (WARN_ON(p_wrp_fm_dev == NULL))
121968 + return -EINVAL;
121969 +
121970 + local_irq_save(flags);
121971 +
121972 + n = snprintf(buf, PAGE_SIZE, "FM-FPM registers dump.\n");
121973 +
121974 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_Dev)
121975 + return -EIO;
121976 + else
121977 + n = fm_fpm_dump_regs(p_wrp_fm_dev->h_Dev, buf, n);
121978 +
121979 + local_irq_restore(flags);
121980 +#else
121981 +
121982 + local_irq_save(flags);
121983 + n = snprintf(buf, PAGE_SIZE,
121984 + "Debug level is too low to dump registers!!!\n");
121985 + local_irq_restore(flags);
121986 +#endif /* (defined(DEBUG_ERRORS) && ... */
121987 +
121988 + return n;
121989 +}
121990 +
121991 +static ssize_t show_prs_regs(struct device *dev,
121992 + struct device_attribute *attr, char *buf)
121993 +{
121994 + unsigned long flags;
121995 + unsigned n = 0;
121996 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
121997 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
121998 +#endif
121999 +
122000 + if (attr == NULL || buf == NULL || dev == NULL)
122001 + return -EINVAL;
122002 +
122003 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122004 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
122005 + if (WARN_ON(p_wrp_fm_dev == NULL))
122006 + return -EINVAL;
122007 +
122008 + local_irq_save(flags);
122009 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
122010 +
122011 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
122012 + return -EIO;
122013 + else
122014 + n = fm_prs_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
122015 +
122016 + local_irq_restore(flags);
122017 +#else
122018 +
122019 + local_irq_save(flags);
122020 + n = snprintf(buf, PAGE_SIZE,
122021 + "Debug level is too low to dump registers!!!\n");
122022 + local_irq_restore(flags);
122023 +
122024 +#endif /* (defined(DEBUG_ERRORS) && ... */
122025 +
122026 + return n;
122027 +}
122028 +
122029 +static ssize_t show_plcr_regs(struct device *dev,
122030 + struct device_attribute *attr,
122031 + char *buf)
122032 +{
122033 + unsigned long flags;
122034 + unsigned n = 0;
122035 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122036 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
122037 +#endif
122038 +
122039 + if (attr == NULL || buf == NULL || dev == NULL)
122040 + return -EINVAL;
122041 +
122042 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
122043 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
122044 + if (WARN_ON(p_wrp_fm_dev == NULL))
122045 + return -EINVAL;
122046 +
122047 + local_irq_save(flags);
122048 + n = snprintf(buf, PAGE_SIZE, "FM Policer registers dump.\n");
122049 +
122050 + if (!p_wrp_fm_dev->active || !p_wrp_fm_dev->h_PcdDev)
122051 + return -EIO;
122052 + else
122053 + n = fm_plcr_dump_regs(p_wrp_fm_dev->h_PcdDev, buf, n);
122054 +
122055 + local_irq_restore(flags);
122056 +#else
122057 +
122058 + local_irq_save(flags);
122059 + n = snprintf(buf, PAGE_SIZE,
122060 + "Debug level is too low to dump registers!!!\n");
122061 + local_irq_restore(flags);
122062 +
122063 +#endif /* (defined(DEBUG_ERRORS) && ... */
122064 +
122065 + return n;
122066 +}
122067 +
122068 +static DEVICE_ATTR(fm_regs, S_IRUGO, show_fm_regs, NULL);
122069 +static DEVICE_ATTR(fm_fpm_regs, S_IRUGO, show_fm_fpm_regs, NULL);
122070 +static DEVICE_ATTR(fm_kg_regs, S_IRUGO, show_fm_kg_regs, NULL);
122071 +static DEVICE_ATTR(fm_kg_pe_regs, S_IRUGO, show_fm_kg_pe_regs, NULL);
122072 +static DEVICE_ATTR(fm_plcr_regs, S_IRUGO, show_plcr_regs, NULL);
122073 +static DEVICE_ATTR(fm_prs_regs, S_IRUGO, show_prs_regs, NULL);
122074 +static DEVICE_ATTR(fm_muram_free_size, S_IRUGO, show_fm_muram_free_sz, NULL);
122075 +static DEVICE_ATTR(fm_ctrl_code_ver, S_IRUGO, show_fm_ctrl_code_ver, NULL);
122076 +
122077 +int fm_sysfs_create(struct device *dev)
122078 +{
122079 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
122080 +
122081 + if (dev == NULL)
122082 + return -EIO;
122083 +
122084 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
122085 +
122086 + /* store to remove them when module is disabled */
122087 + p_wrp_fm_dev->dev_attr_regs = &dev_attr_fm_regs;
122088 + p_wrp_fm_dev->dev_attr_risc_load = &dev_attr_fm_risc_load_val;
122089 + p_wrp_fm_dev->dev_fm_fpm_attr_regs = &dev_attr_fm_fpm_regs;
122090 + p_wrp_fm_dev->dev_fm_kg_attr_regs = &dev_attr_fm_kg_regs;
122091 + p_wrp_fm_dev->dev_fm_kg_pe_attr_regs = &dev_attr_fm_kg_pe_regs;
122092 + p_wrp_fm_dev->dev_plcr_attr_regs = &dev_attr_fm_plcr_regs;
122093 + p_wrp_fm_dev->dev_prs_attr_regs = &dev_attr_fm_prs_regs;
122094 + p_wrp_fm_dev->dev_attr_muram_free_size = &dev_attr_fm_muram_free_size;
122095 + p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver = &dev_attr_fm_ctrl_code_ver;
122096 +
122097 + /* Create sysfs statistics group for FM module */
122098 + if (sysfs_create_group(&dev->kobj, &fm_dev_stats_attr_grp) != 0)
122099 + return -EIO;
122100 +
122101 + if (sysfs_create_group(&dev->kobj, &fm_dev_schemes_attr_grp) != 0)
122102 + return -EIO;
122103 +
122104 + if (sysfs_create_group(&dev->kobj, &fm_dev_profiles_attr_grp) != 0)
122105 + return -EIO;
122106 +
122107 + if (sysfs_create_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp) != 0)
122108 + return -EIO;
122109 +
122110 + if (sysfs_create_group(&dev->kobj, &fm_dev_cls_plans_attr_grp) != 0)
122111 + return -EIO;
122112 +
122113 + /* Registers dump entry - in future will be moved to debugfs */
122114 + if (device_create_file(dev, &dev_attr_fm_regs) != 0)
122115 + return -EIO;
122116 +
122117 + if (device_create_file(dev, &dev_attr_fm_risc_load_val) != 0)
122118 + return -EIO;
122119 +
122120 + if (device_create_file(dev, &dev_attr_fm_fpm_regs) != 0)
122121 + return -EIO;
122122 +
122123 + if (device_create_file(dev, &dev_attr_fm_kg_regs) != 0)
122124 + return -EIO;
122125 +
122126 + if (device_create_file(dev, &dev_attr_fm_kg_pe_regs) != 0)
122127 + return -EIO;
122128 +
122129 + if (device_create_file(dev, &dev_attr_fm_plcr_regs) != 0)
122130 + return -EIO;
122131 +
122132 + if (device_create_file(dev, &dev_attr_fm_prs_regs) != 0)
122133 + return -EIO;
122134 +
122135 + /* muram free size */
122136 + if (device_create_file(dev, &dev_attr_fm_muram_free_size) != 0)
122137 + return -EIO;
122138 +
122139 + /* fm ctrl code version */
122140 + if (device_create_file(dev, &dev_attr_fm_ctrl_code_ver) != 0)
122141 + return -EIO;
122142 +
122143 + return 0;
122144 +}
122145 +
122146 +void fm_sysfs_destroy(struct device *dev)
122147 +{
122148 + t_LnxWrpFmDev *p_wrp_fm_dev = NULL;
122149 +
122150 + if (WARN_ON(dev == NULL))
122151 + return;
122152 +
122153 + p_wrp_fm_dev = (t_LnxWrpFmDev *) dev_get_drvdata(dev);
122154 + if (WARN_ON(p_wrp_fm_dev == NULL))
122155 + return;
122156 +
122157 + sysfs_remove_group(&dev->kobj, &fm_dev_stats_attr_grp);
122158 + sysfs_remove_group(&dev->kobj, &fm_dev_schemes_attr_grp);
122159 + sysfs_remove_group(&dev->kobj, &fm_dev_profiles_attr_grp);
122160 + sysfs_remove_group(&dev->kobj, &fm_dev_cls_plans_attr_grp);
122161 + sysfs_remove_group(&dev->kobj, &fm_dev_tnums_dbg_attr_grp);
122162 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_regs);
122163 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_fpm_attr_regs);
122164 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_attr_regs);
122165 + device_remove_file(dev, p_wrp_fm_dev->dev_fm_kg_pe_attr_regs);
122166 + device_remove_file(dev, p_wrp_fm_dev->dev_plcr_attr_regs);
122167 + device_remove_file(dev, p_wrp_fm_dev->dev_prs_attr_regs);
122168 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_muram_free_size);
122169 + device_remove_file(dev, p_wrp_fm_dev->dev_attr_fm_ctrl_code_ver);
122170 +}
122171 +
122172 +int fm_dump_regs(void *h_fm, char *buf, int nn)
122173 +{
122174 + t_Fm *p_Fm = (t_Fm *)h_fm;
122175 + uint8_t i = 0;
122176 + int n = nn;
122177 +
122178 + FM_DMP_SUBTITLE(buf, n, "\n");
122179 +
122180 + FM_DMP_TITLE(buf, n, p_Fm->p_FmDmaRegs, "FM-DMA Regs");
122181 +
122182 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsr);
122183 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmemsr);
122184 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmmr);
122185 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtr);
122186 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmhy);
122187 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmsetr);
122188 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtah);
122189 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtal);
122190 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmtcid);
122191 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmra);
122192 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmrd);
122193 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmwcr);
122194 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmebcr);
122195 + FM_DMP_V32(buf, n, p_Fm->p_FmDmaRegs, fmdmdcr);
122196 +
122197 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr, "fmdmplr");
122198 +
122199 + for (i = 0; i < FM_MAX_NUM_OF_HW_PORT_IDS / 2 ; ++i)
122200 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[i]);
122201 +
122202 + FM_DMP_TITLE(buf, n, p_Fm->p_FmBmiRegs, "FM-BMI COMMON Regs");
122203 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_init);
122204 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg1);
122205 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_cfg2);
122206 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ievr);
122207 + FM_DMP_V32(buf, n, p_Fm->p_FmBmiRegs, fmbm_ier);
122208 +
122209 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb, "fmbm_arb");
122210 + for (i = 0; i < 8 ; ++i)
122211 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmBmiRegs->fmbm_arb[i]);
122212 +
122213 + FM_DMP_TITLE(buf, n, p_Fm->p_FmQmiRegs, "FM-QMI COMMON Regs");
122214 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gc);
122215 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eie);
122216 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eien);
122217 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_eif);
122218 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ie);
122219 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_ien);
122220 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_if);
122221 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_gs);
122222 + FM_DMP_V32(buf, n, p_Fm->p_FmQmiRegs, fmqm_etfc);
122223 +
122224 + return n;
122225 +}
122226 +
122227 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn)
122228 +{
122229 + t_Fm *p_Fm = (t_Fm *)h_fm;
122230 + uint8_t i, j = 0;
122231 + int n = nn;
122232 +
122233 + FM_DMP_TITLE(buf, n, NULL, "Tnums and Tnum dbg regs %d - %d",
122234 + tn_s, tn_e);
122235 +
122236 + iowrite32be(tn_s << 24, &p_Fm->p_FmFpmRegs->fmfp_dra);
122237 +
122238 + mb();
122239 +
122240 + for (j = tn_s; j <= tn_e; j++) {
122241 + FM_DMP_LN(buf, n, "> fmfp_ts[%d]\n", j);
122242 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ts[j]);
122243 + FM_DMP_V32(buf, n, p_Fm->p_FmFpmRegs, fmfp_dra);
122244 + FM_DMP_LN(buf, n, "> fmfp_drd[0-3]\n");
122245 +
122246 + for (i = 0; i < 4 ; ++i)
122247 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_drd[i]);
122248 +
122249 + FM_DMP_LN(buf, n, "\n");
122250 +
122251 + }
122252 +
122253 + return n;
122254 +}
122255 +
122256 +int fm_dump_cls_plan(void *h_fm_pcd, int cpn, char *buf, int nn)
122257 +{
122258 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122259 + int i = 0;
122260 + uint32_t tmp;
122261 + unsigned long i_flg;
122262 + int n = nn;
122263 + u_FmPcdKgIndirectAccessRegs *idac;
122264 + spinlock_t *p_lk;
122265 +
122266 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
122267 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
122268 +
122269 + spin_lock_irqsave(p_lk, i_flg);
122270 +
122271 + /* Read ClsPlan Block Action Regs */
122272 + tmp = (uint32_t)(FM_KG_KGAR_GO |
122273 + FM_KG_KGAR_READ |
122274 + FM_PCD_KG_KGAR_SEL_CLS_PLAN_ENTRY |
122275 + DUMMY_PORT_ID |
122276 + ((uint32_t)cpn << FM_PCD_KG_KGAR_NUM_SHIFT) |
122277 + FM_PCD_KG_KGAR_WSEL_MASK);
122278 +
122279 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp)) {
122280 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
122281 + spin_unlock_irqrestore(p_lk, i_flg);
122282 + return nn;
122283 + }
122284 + FM_DMP_TITLE(buf, n, &idac->clsPlanRegs,
122285 + "ClsPlan %d Indirect Access Regs", cpn);
122286 +
122287 + for (i = 0; i < 8; i++)
122288 + FM_DMP_MEM_32(buf, n, &idac->clsPlanRegs.kgcpe[i]);
122289 +
122290 + spin_unlock_irqrestore(p_lk, i_flg);
122291 +
122292 + return n;
122293 +}
122294 +
122295 +int fm_profile_dump_regs(void *h_fm_pcd, int ppn, char *buf, int nn)
122296 +{
122297 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122298 + t_FmPcdPlcrProfileRegs *p_prof_regs;
122299 + t_FmPcdPlcrRegs *p_plcr_regs;
122300 + t_FmPcdPlcr *p_plcr;
122301 + uint32_t tmp;
122302 + unsigned long i_flg;
122303 + int n = nn;
122304 + int toc = 10;
122305 + spinlock_t *p_lk;
122306 +
122307 + p_plcr = p_pcd->p_FmPcdPlcr;
122308 + p_prof_regs = &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->profileRegs;
122309 + p_plcr_regs = p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs;
122310 +
122311 + p_lk = (spinlock_t *)((t_FmPcdPlcr *)p_plcr)->h_HwSpinlock;
122312 +
122313 + FM_DMP_SUBTITLE(buf, n, "\n");
122314 + FM_DMP_TITLE(buf, n, p_plcr_regs, "FM-PCD policer-profile regs");
122315 +
122316 + tmp = (uint32_t)(FM_PCD_PLCR_PAR_GO |
122317 + FM_PCD_PLCR_PAR_R |
122318 + ((uint32_t)ppn << FM_PCD_PLCR_PAR_PNUM_SHIFT) |
122319 + FM_PCD_PLCR_PAR_PWSEL_MASK);
122320 +
122321 + spin_lock_irqsave(p_lk, i_flg);
122322 +
122323 + iowrite32be(tmp, &p_plcr_regs->fmpl_par);
122324 +
122325 + mb();
122326 +
122327 + /* wait for the porfile regs to be present */
122328 + do {
122329 + --toc;
122330 + udelay(10);
122331 + if (!toc) {
122332 + /* looks like PLCR_PAR_GO refuses to clear */
122333 + spin_unlock_irqrestore(p_lk, i_flg);
122334 + FM_DMP_LN(buf, n, "Profile regs not accessible -");
122335 + FM_DMP_LN(buf, n, " check profile init process\n");
122336 + return n;
122337 + }
122338 + } while ((ioread32be(&p_plcr_regs->fmpl_par) & FM_PCD_PLCR_PAR_GO));
122339 +
122340 + FM_DMP_TITLE(buf, n, p_prof_regs, "Profile %d regs", ppn);
122341 +
122342 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pemode);
122343 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegnia);
122344 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peynia);
122345 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pernia);
122346 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecir);
122347 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pecbs);
122348 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepepir_eir);
122349 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepbs_ebs);
122350 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pelts);
122351 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pects);
122352 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pepts_ets);
122353 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_pegpc);
122354 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_peypc);
122355 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perpc);
122356 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perypc);
122357 + FM_DMP_V32(buf, n, p_prof_regs, fmpl_perrpc);
122358 +
122359 + spin_unlock_irqrestore(p_lk, i_flg);
122360 +
122361 + return n;
122362 +}
122363 +
122364 +int fm_dump_scheme(void *h_fm_pcd, int scnum, char *buf, int nn)
122365 +{
122366 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122367 + uint32_t tmp_ar;
122368 + unsigned long i_flg;
122369 + int i, n = nn;
122370 + spinlock_t *p_lk;
122371 + u_FmPcdKgIndirectAccessRegs *idac;
122372 +
122373 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
122374 + p_lk = (spinlock_t *)p_pcd->p_FmPcdKg->h_HwSpinlock;
122375 +
122376 + spin_lock_irqsave(p_lk, i_flg);
122377 +
122378 + tmp_ar = FmPcdKgBuildReadSchemeActionReg((uint8_t)scnum);
122379 + if (fman_kg_write_ar_wait(p_pcd->p_FmPcdKg->p_FmPcdKgRegs, tmp_ar)) {
122380 + FM_DMP_LN(buf, nn,
122381 + "Keygen scheme access violation or no such scheme");
122382 + spin_unlock_irqrestore(p_lk, i_flg);
122383 + return nn;
122384 + }
122385 +
122386 + FM_DMP_TITLE(buf, n, &idac->schemeRegs,
122387 + "Scheme %d Indirect Access Regs", scnum);
122388 +
122389 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mode);
122390 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekfc);
122391 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ekdv);
122392 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmch);
122393 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_bmcl);
122394 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_fqb);
122395 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_hc);
122396 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ppc);
122397 +
122398 + FM_DMP_TITLE(buf, n, &idac->schemeRegs.kgse_gec, "kgse_gec");
122399 +
122400 + for (i = 0; i < FM_KG_NUM_OF_GENERIC_REGS; i++)
122401 + FM_DMP_MEM_32(buf, n, &idac->schemeRegs.kgse_gec[i]);
122402 +
122403 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_spc);
122404 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv0);
122405 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_dv1);
122406 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_ccbs);
122407 + FM_DMP_V32(buf, n, &idac->schemeRegs, kgse_mv);
122408 +
122409 + FM_DMP_SUBTITLE(buf, n, "\n");
122410 +
122411 + spin_unlock_irqrestore(p_lk, i_flg);
122412 +
122413 + return n;
122414 +}
122415 +
122416 +int fm_kg_pe_dump_regs(void *h_fm_pcd, char *buf, int nn)
122417 +{
122418 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122419 + int i = 0;
122420 + uint8_t prt_id = 0;
122421 + uint32_t tmp_ar;
122422 + unsigned long i_flg;
122423 + int n = nn;
122424 + u_FmPcdKgIndirectAccessRegs *idac;
122425 + t_FmPcdKg *p_kg;
122426 + spinlock_t *p_lk;
122427 +
122428 + p_kg = p_pcd->p_FmPcdKg;
122429 + idac = p_pcd->p_FmPcdKg->p_IndirectAccessRegs;
122430 + p_lk = (spinlock_t *)p_kg->h_HwSpinlock;
122431 +
122432 + spin_lock_irqsave(p_lk, i_flg);
122433 +
122434 + FM_DMP_SUBTITLE(buf, n, "\n");
122435 +
122436 + for (i = 0; i < FM_MAX_NUM_OF_PORTS; i++) {
122437 + SW_PORT_INDX_TO_HW_PORT_ID(prt_id, i);
122438 +
122439 + tmp_ar = FmPcdKgBuildReadPortSchemeBindActionReg(prt_id);
122440 +
122441 + if (fman_kg_write_ar_wait(p_kg->p_FmPcdKgRegs, tmp_ar)) {
122442 + FM_DMP_LN(buf, nn, "Keygen scheme access violation");
122443 + spin_unlock_irqrestore(p_lk, i_flg);
122444 + return nn;
122445 + }
122446 + FM_DMP_TITLE(buf, n, &idac->portRegs, "Port %d regs", prt_id);
122447 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_sp);
122448 + FM_DMP_V32(buf, n, &idac->portRegs, fmkg_pe_cpp);
122449 + }
122450 +
122451 + FM_DMP_SUBTITLE(buf, n, "\n");
122452 +
122453 + spin_unlock_irqrestore(p_lk, i_flg);
122454 +
122455 + return n;
122456 +}
122457 +
122458 +int fm_kg_dump_regs(void *h_fm_pcd, char *buf, int nn)
122459 +{
122460 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122461 + int n = nn;
122462 +
122463 + FM_DMP_SUBTITLE(buf, n, "\n");
122464 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs,
122465 + "FmPcdKgRegs Regs");
122466 +
122467 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gcr);
122468 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eer);
122469 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_eeer);
122470 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seer);
122471 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_seeer);
122472 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gsr);
122473 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_tpc);
122474 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_serc);
122475 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_fdor);
122476 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv0r);
122477 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_gdv1r);
122478 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_feer);
122479 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdKg->p_FmPcdKgRegs, fmkg_ar);
122480 +
122481 + FM_DMP_SUBTITLE(buf, n, "\n");
122482 +
122483 + return n;
122484 +}
122485 +
122486 +
122487 +int fm_fpm_dump_regs(void *h_fm, char *buf, int nn)
122488 +{
122489 + t_Fm *p_fm = (t_Fm *)h_fm;
122490 + uint8_t i;
122491 + int n = nn;
122492 +
122493 + FM_DMP_SUBTITLE(buf, n, "\n");
122494 +
122495 + FM_DMP_TITLE(buf, n, p_fm->p_FmFpmRegs, "FM-FPM Regs");
122496 +
122497 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tnc);
122498 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_prc);
122499 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_brkc);
122500 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_mxd);
122501 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist1);
122502 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_dist2);
122503 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_epi);
122504 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rie);
122505 +
122506 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev, "fmfp_fcev");
122507 + for (i = 0; i < 4; ++i)
122508 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_fcev[i]);
122509 +
122510 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee, "fmfp_cee");
122511 + for (i = 0; i < 4; ++i)
122512 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cee[i]);
122513 +
122514 + FM_DMP_SUBTITLE(buf, n, "\n");
122515 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc1);
122516 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsc2);
122517 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsp);
122518 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_tsf);
122519 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rcr);
122520 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_extc);
122521 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext1);
122522 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ext2);
122523 +
122524 + FM_DMP_SUBTITLE(buf, n, "\n");
122525 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_1);
122526 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_ip_rev_2);
122527 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_rstc);
122528 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_cld);
122529 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fm_npi);
122530 + FM_DMP_V32(buf, n, p_fm->p_FmFpmRegs, fmfp_ee);
122531 +
122532 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev, "fmfp_cev");
122533 + for (i = 0; i < 4; ++i)
122534 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_cev[i]);
122535 +
122536 + FM_DMP_TITLE(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps, "fmfp_ps");
122537 + for (i = 0; i < 64; ++i)
122538 + FM_DMP_MEM_32(buf, n, &p_fm->p_FmFpmRegs->fmfp_ps[i]);
122539 +
122540 + return n;
122541 +}
122542 +
122543 +int fm_prs_dump_regs(void *h_fm_pcd, char *buf, int nn)
122544 +{
122545 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122546 + int n = nn;
122547 +
122548 + FM_DMP_SUBTITLE(buf, n, "\n");
122549 +
122550 + FM_DMP_TITLE(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs,
122551 + "FM-PCD parser regs");
122552 +
122553 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpclim);
122554 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_rpimac);
122555 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, pmeec);
122556 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pevr);
122557 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pever);
122558 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perr);
122559 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_perer);
122560 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_ppsc);
122561 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_pds);
122562 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rrs);
122563 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rrs);
122564 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rrs);
122565 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srrs);
122566 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l2rres);
122567 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l3rres);
122568 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_l4rres);
122569 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_srres);
122570 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spcs);
122571 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_spscs);
122572 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_hxscs);
122573 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrcs);
122574 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwcs);
122575 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mrscs);
122576 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_mwscs);
122577 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPrs->p_FmPcdPrsRegs, fmpr_fcscs);
122578 +
122579 + return n;
122580 +}
122581 +
122582 +int fm_plcr_dump_regs(void *h_fm_pcd, char *buf, int nn)
122583 +{
122584 + t_FmPcd *p_pcd = (t_FmPcd *)h_fm_pcd;
122585 + int i = 0;
122586 + int n = nn;
122587 +
122588 + FM_DMP_SUBTITLE(buf, n, "\n");
122589 +
122590 + FM_DMP_TITLE(buf, n,
122591 + p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs,
122592 + "FM policer regs");
122593 +
122594 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gcr);
122595 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_gsr);
122596 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_evr);
122597 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ier);
122598 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ifr);
122599 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eevr);
122600 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eier);
122601 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_eifr);
122602 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rpcnt);
122603 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_ypcnt);
122604 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rrpcnt);
122605 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_rypcnt);
122606 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_tpcnt);
122607 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_flmcnt);
122608 +
122609 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_serc);
122610 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_upcr);
122611 + FM_DMP_V32(buf, n, p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs, fmpl_dpmr);
122612 +
122613 + FM_DMP_TITLE(buf, n,
122614 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr,
122615 + "fmpl_pmr");
122616 +
122617 + for (i = 0; i < 63; ++i)
122618 + FM_DMP_MEM_32(buf, n,
122619 + &p_pcd->p_FmPcdPlcr->p_FmPcdPlcrRegs->fmpl_pmr[i]);
122620 +
122621 + return n;
122622 +}
122623 +
122624 +int fm_get_counter(void *h_fm, e_FmCounters cnt_e, uint32_t *cnt_val)
122625 +{
122626 + t_Fm *p_fm = (t_Fm *)h_fm;
122627 +
122628 + /* When applicable (when there is an "enable counters" bit),
122629 + check that counters are enabled */
122630 +
122631 + switch (cnt_e) {
122632 + case (e_FM_COUNTERS_DEQ_1):
122633 + case (e_FM_COUNTERS_DEQ_2):
122634 + case (e_FM_COUNTERS_DEQ_3):
122635 + if (p_fm->p_FmStateStruct->revInfo.majorRev >= 6)
122636 + return -EINVAL; /* counter not available */
122637 +
122638 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
122639 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
122640 + case (e_FM_COUNTERS_DEQ_0):
122641 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
122642 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
122643 + case (e_FM_COUNTERS_DEQ_FROM_FD):
122644 + case (e_FM_COUNTERS_DEQ_CONFIRM):
122645 + if (!(ioread32be(&p_fm->p_FmQmiRegs->fmqm_gc) &
122646 + QMI_CFG_EN_COUNTERS))
122647 + return -EINVAL; /* Requested counter not available */
122648 + break;
122649 + default:
122650 + break;
122651 + }
122652 +
122653 + switch (cnt_e) {
122654 + case (e_FM_COUNTERS_ENQ_TOTAL_FRAME):
122655 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_etfc);
122656 + return 0;
122657 + case (e_FM_COUNTERS_DEQ_TOTAL_FRAME):
122658 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dtfc);
122659 + return 0;
122660 + case (e_FM_COUNTERS_DEQ_0):
122661 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc0);
122662 + return 0;
122663 + case (e_FM_COUNTERS_DEQ_1):
122664 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc1);
122665 + return 0;
122666 + case (e_FM_COUNTERS_DEQ_2):
122667 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc2);
122668 + return 0;
122669 + case (e_FM_COUNTERS_DEQ_3):
122670 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dc3);
122671 + return 0;
122672 + case (e_FM_COUNTERS_DEQ_FROM_DEFAULT):
122673 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfdc);
122674 + return 0;
122675 + case (e_FM_COUNTERS_DEQ_FROM_CONTEXT):
122676 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dfcc);
122677 + return 0;
122678 + case (e_FM_COUNTERS_DEQ_FROM_FD):
122679 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dffc);
122680 + return 0;
122681 + case (e_FM_COUNTERS_DEQ_CONFIRM):
122682 + *cnt_val = ioread32be(&p_fm->p_FmQmiRegs->fmqm_dcc);
122683 + return 0;
122684 + }
122685 + /* should never get here */
122686 + return -EINVAL; /* counter not available */
122687 +}
122688 --- /dev/null
122689 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm.h
122690 @@ -0,0 +1,136 @@
122691 +/*
122692 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122693 + *
122694 + * Redistribution and use in source and binary forms, with or without
122695 + * modification, are permitted provided that the following conditions are met:
122696 + * * Redistributions of source code must retain the above copyright
122697 + * notice, this list of conditions and the following disclaimer.
122698 + * * Redistributions in binary form must reproduce the above copyright
122699 + * notice, this list of conditions and the following disclaimer in the
122700 + * documentation and/or other materials provided with the distribution.
122701 + * * Neither the name of Freescale Semiconductor nor the
122702 + * names of its contributors may be used to endorse or promote products
122703 + * derived from this software without specific prior written permission.
122704 + *
122705 + *
122706 + * ALTERNATIVELY, this software may be distributed under the terms of the
122707 + * GNU General Public License ("GPL") as published by the Free Software
122708 + * Foundation, either version 2 of that License or (at your option) any
122709 + * later version.
122710 + *
122711 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122712 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122713 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122714 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122715 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122716 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122717 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122718 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122719 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122720 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122721 + */
122722 +
122723 +
122724 +#ifndef LNXWRP_SYSFS_FM_H_
122725 +#define LNXWRP_SYSFS_FM_H_
122726 +
122727 +#include "lnxwrp_sysfs.h"
122728 +
122729 +int fm_sysfs_create(struct device *dev);
122730 +void fm_sysfs_destroy(struct device *dev);
122731 +int fm_dump_regs(void *h_dev, char *buf, int nn);
122732 +int fm_fpm_dump_regs(void *h_dev, char *buf, int nn);
122733 +int fm_kg_dump_regs(void *h_pcd, char *buf, int nn);
122734 +int fm_kg_pe_dump_regs(void *h_pcd, char *buf, int nn);
122735 +int fm_dump_scheme(void *h_pcd, int scnum, char *buf, int nn);
122736 +int fm_dump_tnum_dbg(void *h_fm, int tn_s, int tn_e, char *buf, int nn);
122737 +int fm_dump_cls_plan(void *h_pcd, int cpn, char *buf, int nn);
122738 +int fm_plcr_dump_regs(void *h_pcd, char *buf, int nn);
122739 +int fm_prs_dump_regs(void *h_pcd, char *buf, int nn);
122740 +int fm_profile_dump_regs(void *h_pcd, int ppnum, char *buf, int nn);
122741 +
122742 +#define FM_DMP_PGSZ_ERR { \
122743 + snprintf(&buf[PAGE_SIZE - 80], 70, \
122744 + "\n Err: current sysfs buffer reached PAGE_SIZE\n");\
122745 + n = PAGE_SIZE - 2; \
122746 + }
122747 +
122748 +#define FM_DMP_LN(buf, n, ...) \
122749 + do { \
122750 + int k, m = n; \
122751 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
122752 + if (k < 0 || m > PAGE_SIZE - 90) \
122753 + FM_DMP_PGSZ_ERR \
122754 + n = m; \
122755 + } while (0)
122756 +
122757 +#define FM_DMP_TITLE(buf, n, addr, ...) \
122758 + do { \
122759 + int k, m = n; \
122760 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
122761 + if (k < 0 || m > PAGE_SIZE - 90) \
122762 + FM_DMP_PGSZ_ERR \
122763 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
122764 + if (k < 0 || m > PAGE_SIZE - 90) \
122765 + FM_DMP_PGSZ_ERR \
122766 + if (addr) { \
122767 + phys_addr_t pa; \
122768 + pa = virt_to_phys(addr); \
122769 + m += k = \
122770 + snprintf(&buf[m], PAGE_SIZE - m, " (0x%lX)", \
122771 + (long unsigned int)(pa)); \
122772 + if (k < 0 || m > PAGE_SIZE - 90) \
122773 + FM_DMP_PGSZ_ERR \
122774 + } \
122775 + m += k = snprintf(&buf[m], PAGE_SIZE - m, \
122776 + "\n----------------------------------------\n\n"); \
122777 + if (k < 0 || m > PAGE_SIZE - 90) \
122778 + FM_DMP_PGSZ_ERR \
122779 + n = m; \
122780 + } while (0)
122781 +
122782 +#define FM_DMP_SUBTITLE(buf, n, ...) \
122783 + do { \
122784 + int k, m = n; \
122785 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "------- "); \
122786 + if (k < 0 || m > PAGE_SIZE - 90) \
122787 + FM_DMP_PGSZ_ERR \
122788 + m += k = snprintf(&buf[m], PAGE_SIZE - m, __VA_ARGS__); \
122789 + if (k < 0 || m > PAGE_SIZE - 90) \
122790 + FM_DMP_PGSZ_ERR \
122791 + m += k = snprintf(&buf[m], PAGE_SIZE - m, "\n"); \
122792 + if (k < 0 || m > PAGE_SIZE - 90) \
122793 + FM_DMP_PGSZ_ERR \
122794 + n = m; \
122795 + } while (0)
122796 +
122797 +#define FM_DMP_MEM_32(buf, n, addr) \
122798 + { \
122799 + uint32_t val; \
122800 + phys_addr_t pa; \
122801 + int k, m = n; \
122802 + pa = virt_to_phys(addr); \
122803 + val = ioread32be((addr)); \
122804 + do { \
122805 + m += k = snprintf(&buf[m], \
122806 + PAGE_SIZE - m, "0x%010llX: 0x%08x\n", \
122807 + pa, val); \
122808 + if (k < 0 || m > PAGE_SIZE - 90) \
122809 + FM_DMP_PGSZ_ERR \
122810 + n += k; \
122811 + } while (0) ;\
122812 + }
122813 +
122814 +#define FM_DMP_V32(buf, n, st, phrase) \
122815 + do { \
122816 + int k, m = n; \
122817 + phys_addr_t pa = virt_to_phys(&((st)->phrase)); \
122818 + k = snprintf(&buf[m], PAGE_SIZE - m, \
122819 + "0x%010llX: 0x%08x%8s\t%s\n", (unsigned long long) pa, \
122820 + ioread32be((uint32_t *)&((st)->phrase)), "", #phrase); \
122821 + if (k < 0 || m > PAGE_SIZE - 90) \
122822 + FM_DMP_PGSZ_ERR \
122823 + n += k; \
122824 + } while (0)
122825 +
122826 +#endif /* LNXWRP_SYSFS_FM_H_ */
122827 --- /dev/null
122828 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.c
122829 @@ -0,0 +1,1268 @@
122830 +/*
122831 + * Copyright 2008-2012 Freescale Semiconductor Inc.
122832 + *
122833 + * Redistribution and use in source and binary forms, with or without
122834 + * modification, are permitted provided that the following conditions are met:
122835 + * * Redistributions of source code must retain the above copyright
122836 + * notice, this list of conditions and the following disclaimer.
122837 + * * Redistributions in binary form must reproduce the above copyright
122838 + * notice, this list of conditions and the following disclaimer in the
122839 + * documentation and/or other materials provided with the distribution.
122840 + * * Neither the name of Freescale Semiconductor nor the
122841 + * names of its contributors may be used to endorse or promote products
122842 + * derived from this software without specific prior written permission.
122843 + *
122844 + *
122845 + * ALTERNATIVELY, this software may be distributed under the terms of the
122846 + * GNU General Public License ("GPL") as published by the Free Software
122847 + * Foundation, either version 2 of that License or (at your option) any
122848 + * later version.
122849 + *
122850 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
122851 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
122852 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
122853 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
122854 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
122855 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
122856 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
122857 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
122858 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
122859 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
122860 + */
122861 +
122862 +#include "lnxwrp_sysfs.h"
122863 +#include "lnxwrp_fm.h"
122864 +#include "debug_ext.h"
122865 +#include "lnxwrp_sysfs_fm_port.h"
122866 +#include "lnxwrp_sysfs_fm.h"
122867 +
122868 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port.h"
122869 +#include "../../sdk_fman/Peripherals/FM/Port/fm_port_dsar.h"
122870 +
122871 +#if defined(__ERR_MODULE__)
122872 +#undef __ERR_MODULE__
122873 +#endif
122874 +
122875 +#include "../../sdk_fman/Peripherals/FM/fm.h"
122876 +
122877 +static const struct sysfs_stats_t portSysfsStats[] = {
122878 + /* RX/TX/OH common statistics */
122879 + {
122880 + .stat_name = "port_frame",
122881 + .stat_counter = e_FM_PORT_COUNTERS_FRAME,
122882 + },
122883 + {
122884 + .stat_name = "port_discard_frame",
122885 + .stat_counter = e_FM_PORT_COUNTERS_DISCARD_FRAME,
122886 + },
122887 + {
122888 + .stat_name = "port_dealloc_buf",
122889 + .stat_counter = e_FM_PORT_COUNTERS_DEALLOC_BUF,
122890 + },
122891 + {
122892 + .stat_name = "port_enq_total",
122893 + .stat_counter = e_FM_PORT_COUNTERS_ENQ_TOTAL,
122894 + },
122895 + /* TX/OH */
122896 + {
122897 + .stat_name = "port_length_err",
122898 + .stat_counter = e_FM_PORT_COUNTERS_LENGTH_ERR,
122899 + },
122900 + {
122901 + .stat_name = "port_unsupprted_format",
122902 + .stat_counter = e_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT,
122903 + },
122904 + {
122905 + .stat_name = "port_deq_total",
122906 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_TOTAL,
122907 + },
122908 + {
122909 + .stat_name = "port_deq_from_default",
122910 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT,
122911 + },
122912 + {
122913 + .stat_name = "port_deq_confirm",
122914 + .stat_counter = e_FM_PORT_COUNTERS_DEQ_CONFIRM,
122915 + },
122916 + /* RX/OH */
122917 + {
122918 + .stat_name = "port_rx_bad_frame",
122919 + .stat_counter = e_FM_PORT_COUNTERS_RX_BAD_FRAME,
122920 + },
122921 + {
122922 + .stat_name = "port_rx_large_frame",
122923 + .stat_counter = e_FM_PORT_COUNTERS_RX_LARGE_FRAME,
122924 + },
122925 + {
122926 + .stat_name = "port_rx_out_of_buffers_discard",
122927 + .stat_counter = e_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD,
122928 + },
122929 + {
122930 + .stat_name = "port_rx_filter_frame",
122931 + .stat_counter = e_FM_PORT_COUNTERS_RX_FILTER_FRAME,
122932 + },
122933 + /* TODO: Particular statistics for OH ports */
122934 + {}
122935 +};
122936 +
122937 +static ssize_t show_fm_port_stats(struct device *dev,
122938 + struct device_attribute *attr, char *buf)
122939 +{
122940 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
122941 + t_LnxWrpFmDev *p_LnxWrpFmDev;
122942 + unsigned long flags;
122943 + int n = 0;
122944 + uint8_t counter = 0;
122945 +
122946 + if (attr == NULL || buf == NULL || dev == NULL)
122947 + return -EINVAL;
122948 +
122949 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
122950 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
122951 + return -EINVAL;
122952 +
122953 + p_LnxWrpFmDev = (t_LnxWrpFmDev *) p_LnxWrpFmPortDev->h_LnxWrpFmDev;
122954 + if (WARN_ON(p_LnxWrpFmDev == NULL))
122955 + return -EINVAL;
122956 +
122957 + if (!p_LnxWrpFmDev->active || !p_LnxWrpFmDev->h_Dev)
122958 + return -EIO;
122959 +
122960 + if (!p_LnxWrpFmPortDev->h_Dev) {
122961 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
122962 + return n;
122963 + }
122964 +
122965 + counter = fm_find_statistic_counter_by_name(
122966 + attr->attr.name,
122967 + portSysfsStats, NULL);
122968 +
122969 + if (counter == e_FM_PORT_COUNTERS_RX_LIST_DMA_ERR) {
122970 + uint32_t fmRev = 0;
122971 + fmRev = 0xffff &
122972 + ioread32(UINT_TO_PTR(p_LnxWrpFmDev->fmBaseAddr +
122973 + 0x000c30c4));
122974 +
122975 + if (fmRev == 0x0100) {
122976 + local_irq_save(flags);
122977 + n = snprintf(buf, PAGE_SIZE,
122978 + "counter not available for revision 1\n");
122979 + local_irq_restore(flags);
122980 + }
122981 + return n;
122982 + }
122983 +
122984 + local_irq_save(flags);
122985 + n = snprintf(buf, PAGE_SIZE, "\t%s counter: %u\n",
122986 + p_LnxWrpFmPortDev->name,
122987 + FM_PORT_GetCounter(p_LnxWrpFmPortDev->h_Dev,
122988 + (e_FmPortCounters) counter));
122989 + local_irq_restore(flags);
122990 +
122991 + return n;
122992 +}
122993 +
122994 +/* FM PORT RX/TX/OH statistics */
122995 +static DEVICE_ATTR(port_frame, S_IRUGO, show_fm_port_stats, NULL);
122996 +static DEVICE_ATTR(port_discard_frame, S_IRUGO, show_fm_port_stats, NULL);
122997 +static DEVICE_ATTR(port_dealloc_buf, S_IRUGO, show_fm_port_stats, NULL);
122998 +static DEVICE_ATTR(port_enq_total, S_IRUGO, show_fm_port_stats, NULL);
122999 +/* FM PORT TX/OH statistics */
123000 +static DEVICE_ATTR(port_length_err, S_IRUGO, show_fm_port_stats, NULL);
123001 +static DEVICE_ATTR(port_unsupprted_format, S_IRUGO, show_fm_port_stats, NULL);
123002 +static DEVICE_ATTR(port_deq_total, S_IRUGO, show_fm_port_stats, NULL);
123003 +static DEVICE_ATTR(port_deq_from_default, S_IRUGO, show_fm_port_stats, NULL);
123004 +static DEVICE_ATTR(port_deq_confirm, S_IRUGO, show_fm_port_stats, NULL);
123005 +/* FM PORT RX/OH statistics */
123006 +static DEVICE_ATTR(port_rx_bad_frame, S_IRUGO, show_fm_port_stats, NULL);
123007 +static DEVICE_ATTR(port_rx_large_frame, S_IRUGO, show_fm_port_stats, NULL);
123008 +static DEVICE_ATTR(port_rx_out_of_buffers_discard, S_IRUGO,
123009 + show_fm_port_stats, NULL);
123010 +static DEVICE_ATTR(port_rx_filter_frame, S_IRUGO, show_fm_port_stats, NULL);
123011 +
123012 +/* FM PORT TX statistics */
123013 +static struct attribute *fm_tx_port_dev_stats_attributes[] = {
123014 + &dev_attr_port_frame.attr,
123015 + &dev_attr_port_discard_frame.attr,
123016 + &dev_attr_port_dealloc_buf.attr,
123017 + &dev_attr_port_enq_total.attr,
123018 + &dev_attr_port_length_err.attr,
123019 + &dev_attr_port_unsupprted_format.attr,
123020 + &dev_attr_port_deq_total.attr,
123021 + &dev_attr_port_deq_from_default.attr,
123022 + &dev_attr_port_deq_confirm.attr,
123023 + NULL
123024 +};
123025 +
123026 +static const struct attribute_group fm_tx_port_dev_stats_attr_grp = {
123027 + .name = "statistics",
123028 + .attrs = fm_tx_port_dev_stats_attributes
123029 +};
123030 +
123031 +/* FM PORT RX statistics */
123032 +static struct attribute *fm_rx_port_dev_stats_attributes[] = {
123033 + &dev_attr_port_frame.attr,
123034 + &dev_attr_port_discard_frame.attr,
123035 + &dev_attr_port_dealloc_buf.attr,
123036 + &dev_attr_port_enq_total.attr,
123037 + &dev_attr_port_rx_bad_frame.attr,
123038 + &dev_attr_port_rx_large_frame.attr,
123039 + &dev_attr_port_rx_out_of_buffers_discard.attr,
123040 + &dev_attr_port_rx_filter_frame.attr,
123041 + NULL
123042 +};
123043 +
123044 +static const struct attribute_group fm_rx_port_dev_stats_attr_grp = {
123045 + .name = "statistics",
123046 + .attrs = fm_rx_port_dev_stats_attributes
123047 +};
123048 +
123049 +/* TODO: add particular OH ports statistics */
123050 +static struct attribute *fm_oh_port_dev_stats_attributes[] = {
123051 + &dev_attr_port_frame.attr,
123052 + &dev_attr_port_discard_frame.attr,
123053 + &dev_attr_port_dealloc_buf.attr,
123054 + &dev_attr_port_enq_total.attr,
123055 + /*TX*/ &dev_attr_port_length_err.attr,
123056 + &dev_attr_port_unsupprted_format.attr,
123057 + &dev_attr_port_deq_total.attr,
123058 + &dev_attr_port_deq_from_default.attr,
123059 + &dev_attr_port_deq_confirm.attr,
123060 + /* &dev_attr_port_rx_bad_frame.attr, */
123061 + /* &dev_attr_port_rx_large_frame.attr, */
123062 + &dev_attr_port_rx_out_of_buffers_discard.attr,
123063 + /*&dev_attr_port_rx_filter_frame.attr, */
123064 + NULL
123065 +};
123066 +
123067 +static const struct attribute_group fm_oh_port_dev_stats_attr_grp = {
123068 + .name = "statistics",
123069 + .attrs = fm_oh_port_dev_stats_attributes
123070 +};
123071 +
123072 +static ssize_t show_fm_port_regs(struct device *dev,
123073 + struct device_attribute *attr, char *buf)
123074 +{
123075 + unsigned long flags;
123076 + unsigned n = 0;
123077 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123078 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123079 +#endif
123080 + if (attr == NULL || buf == NULL || dev == NULL)
123081 + return -EINVAL;
123082 +
123083 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123084 + p_LnxWrpFmPortDev =
123085 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123086 +
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_dump_regs(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 +static int fm_port_dsar_dump_mem(void *h_dev, char *buf, int nn)
123113 +{
123114 + t_FmPort *p_FmPort;
123115 + t_Fm *p_Fm;
123116 + uint8_t hardwarePortId;
123117 + uint32_t *param_page;
123118 + t_ArCommonDesc *ArCommonDescPtr;
123119 + uint32_t *mem;
123120 + int i, n = nn;
123121 +
123122 + p_FmPort = (t_FmPort *)h_dev;
123123 + hardwarePortId = p_FmPort->hardwarePortId;
123124 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
123125 +
123126 + if (!FM_PORT_IsInDsar(p_FmPort))
123127 + {
123128 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
123129 + hardwarePortId);
123130 + return n;
123131 + }
123132 + FM_DMP_LN(buf, n, "port %u DSAR mem\n", hardwarePortId);
123133 + FM_DMP_LN(buf, n, "========================\n");
123134 +
123135 + /* do I need request_mem_region here? */
123136 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
123137 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), 300*4)); /* this should be changed*/
123138 + mem = (uint32_t*)ArCommonDescPtr;
123139 + for (i = 0; i < 300; i+=4)
123140 + FM_DMP_LN(buf, n, "%08x: %08x %08x %08x %08x\n", i*4, mem[i], mem[i + 1], mem[i + 2], mem[i + 3]);
123141 + iounmap(ArCommonDescPtr);
123142 + iounmap(param_page);
123143 + return n;
123144 +}
123145 +
123146 +static int fm_port_dsar_dump_regs(void *h_dev, char *buf, int nn)
123147 +{
123148 + t_FmPort *p_FmPort;
123149 + t_Fm *p_Fm;
123150 + uint8_t hardwarePortId;
123151 + uint32_t *param_page;
123152 + t_ArCommonDesc *ArCommonDescPtr;
123153 + int i, n = nn;
123154 +
123155 + p_FmPort = (t_FmPort *)h_dev;
123156 + hardwarePortId = p_FmPort->hardwarePortId;
123157 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
123158 +
123159 + if (!FM_PORT_IsInDsar(p_FmPort))
123160 + {
123161 + FM_DMP_LN(buf, n, "port %u is not a DSAR port\n",
123162 + hardwarePortId);
123163 + return n;
123164 + }
123165 + FM_DMP_LN(buf, n, "port %u DSAR information\n", hardwarePortId);
123166 + FM_DMP_LN(buf, n, "========================\n");
123167 +
123168 + /* do I need request_mem_region here? */
123169 + param_page = ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(&p_FmPort->p_FmPortBmiRegs->rxPortBmiRegs.fmbm_rgpr), 4);
123170 + ArCommonDescPtr = (t_ArCommonDesc*)(ioremap(p_FmPort->fmMuramPhysBaseAddr + ioread32be(param_page), sizeof(t_ArCommonDesc))); /* this should be changed*/
123171 + FM_DMP_LN(buf, n, "Tx port: 0x%x\n", ArCommonDescPtr->arTxPort);
123172 + FM_DMP_LN(buf, n, "Active HPNIA: 0x%08x\n", ArCommonDescPtr->activeHPNIA);
123173 + FM_DMP_LN(buf, n, "Snmp port: 0x%x\n", ArCommonDescPtr->snmpPort);
123174 + FM_DMP_LN(buf, n, "MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ArCommonDescPtr->macStationAddr[0],
123175 + ArCommonDescPtr->macStationAddr[1], ArCommonDescPtr->macStationAddr[2],
123176 + ArCommonDescPtr->macStationAddr[3], ArCommonDescPtr->macStationAddr[4],
123177 + ArCommonDescPtr->macStationAddr[5]);
123178 + FM_DMP_LN(buf, n, "filterControl: 0x%02x\n", ArCommonDescPtr->filterControl);
123179 + FM_DMP_LN(buf, n, "tcpControlPass: 0x%04x\n", ArCommonDescPtr->tcpControlPass);
123180 + FM_DMP_LN(buf, n, "ipProtocolTblSize: 0x%x\n", ArCommonDescPtr->ipProtocolTblSize);
123181 + FM_DMP_LN(buf, n, "udpPortTblSize: 0x%x\n", ArCommonDescPtr->udpPortTblSize);
123182 + FM_DMP_LN(buf, n, "tcpPortTblSize: 0x%x\n", ArCommonDescPtr->tcpPortTblSize);
123183 + if (ArCommonDescPtr->p_ArStats)
123184 + {
123185 + t_ArStatistics *arStatistics = (t_ArStatistics*)
123186 + ioremap(ioread32be(&ArCommonDescPtr->p_ArStats) +
123187 + p_FmPort->fmMuramPhysBaseAddr,
123188 + sizeof (t_ArStatistics));
123189 + FM_DMP_LN(buf, n, "\nDSAR statistics\n");
123190 + FM_DMP_LN(buf, n, "DSAR_Discarded: 0x%x\n", arStatistics->dsarDiscarded);
123191 + FM_DMP_LN(buf, n, "DSAR_Err_Discarded: 0x%x\n", arStatistics->dsarErrDiscarded);
123192 + FM_DMP_LN(buf, n, "DSAR_Frag_Discarded: 0x%x\n", arStatistics->dsarFragDiscarded);
123193 + FM_DMP_LN(buf, n, "DSAR_Tunnel_Discarded: 0x%x\n", arStatistics->dsarTunnelDiscarded);
123194 + FM_DMP_LN(buf, n, "DSAR_ARP_Discarded: 0x%x\n", arStatistics->dsarArpDiscarded);
123195 + FM_DMP_LN(buf, n, "DSAR_IP_Discarded: 0x%x\n", arStatistics->dsarIpDiscarded);
123196 + FM_DMP_LN(buf, n, "DSAR_TCP_Discarded: 0x%x\n", arStatistics->dsarTcpDiscarded);
123197 + FM_DMP_LN(buf, n, "DSAR_UDP_Discarded: 0x%x\n", arStatistics->dsarUdpDiscarded);
123198 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Checksum_Err: 0x%x\n", arStatistics->dsarIcmpV6ChecksumErr);
123199 + FM_DMP_LN(buf, n, "DSAR_ICMPv6_Other_Type: 0x%x\n", arStatistics->dsarIcmpV6OtherType);
123200 + FM_DMP_LN(buf, n, "DSAR_ICMPv4_Other_Type: 0x%x\n", arStatistics->dsarIcmpV4OtherType);
123201 +
123202 + iounmap(arStatistics);
123203 + }
123204 + if (ArCommonDescPtr->p_ArpDescriptor)
123205 + {
123206 + t_DsarArpDescriptor* ArpDescriptor = (t_DsarArpDescriptor*)
123207 + ioremap(ioread32be(&ArCommonDescPtr->p_ArpDescriptor) +
123208 + p_FmPort->fmMuramPhysBaseAddr,
123209 + sizeof (t_DsarArpDescriptor));
123210 + FM_DMP_LN(buf, n, "\nARP\n");
123211 + FM_DMP_LN(buf, n, "===\n");
123212 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ArpDescriptor->control);
123213 + if (ArpDescriptor->numOfBindings)
123214 + {
123215 + char ip_str[100];
123216 + t_DsarArpBindingEntry* bindings = ioremap(
123217 + ioread32be(&ArpDescriptor->p_Bindings) +
123218 + p_FmPort->fmMuramPhysBaseAddr,
123219 + ArpDescriptor->numOfBindings *
123220 + sizeof(t_DsarArpBindingEntry));
123221 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
123222 + FM_DMP_LN(buf, n, " ip vlan id\n");
123223 + for (i = 0; i < ArpDescriptor->numOfBindings; i++)
123224 + {
123225 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
123226 + ip_addr[0], ip_addr[1],
123227 + ip_addr[2], ip_addr[3]);
123228 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
123229 + ip_str, bindings->vlanId);
123230 + }
123231 + iounmap(bindings);
123232 + }
123233 + if (ArpDescriptor->p_Statistics)
123234 + {
123235 + t_DsarArpStatistics* arpStats = ioremap(
123236 + ioread32be(&ArpDescriptor->p_Statistics) +
123237 + p_FmPort->fmMuramPhysBaseAddr,
123238 + sizeof(t_DsarArpStatistics));
123239 + FM_DMP_LN(buf, n, "statistics\n");
123240 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", arpStats->invalCnt);
123241 + FM_DMP_LN(buf, n, "ECHO_CNT: 0x%x\n", arpStats->echoCnt);
123242 + FM_DMP_LN(buf, n, "CD_CNT: 0x%x\n", arpStats->cdCnt);
123243 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", arpStats->arCnt);
123244 + FM_DMP_LN(buf, n, "RATM_CNT: 0x%x\n", arpStats->ratmCnt);
123245 + FM_DMP_LN(buf, n, "UKOP_CNT: 0x%x\n", arpStats->ukopCnt);
123246 + FM_DMP_LN(buf, n, "NMTP_CNT: 0x%x\n", arpStats->nmtpCnt);
123247 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", arpStats->nmVlanCnt);
123248 + iounmap(arpStats);
123249 + }
123250 +
123251 + iounmap(ArpDescriptor);
123252 + }
123253 + if (ArCommonDescPtr->p_IcmpV4Descriptor)
123254 + {
123255 + t_DsarIcmpV4Descriptor* ICMPV4Descriptor =
123256 + (t_DsarIcmpV4Descriptor*)ioremap(ioread32be(
123257 + &ArCommonDescPtr->p_IcmpV4Descriptor) +
123258 + p_FmPort->fmMuramPhysBaseAddr,
123259 + sizeof (t_DsarIcmpV4Descriptor));
123260 + FM_DMP_LN(buf, n, "\nEcho ICMPv4\n");
123261 + FM_DMP_LN(buf, n, "===========\n");
123262 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV4Descriptor->control);
123263 + if (ICMPV4Descriptor->numOfBindings)
123264 + {
123265 + char ip_str[100];
123266 + t_DsarArpBindingEntry* bindings = ioremap(
123267 + ioread32be(&ICMPV4Descriptor->p_Bindings) +
123268 + p_FmPort->fmMuramPhysBaseAddr,
123269 + ICMPV4Descriptor->numOfBindings *
123270 + sizeof(t_DsarArpBindingEntry));
123271 + uint8_t* ip_addr = (uint8_t*)&bindings->ipv4Addr;
123272 + FM_DMP_LN(buf, n, " ip vlan id\n");
123273 + for (i = 0; i < ICMPV4Descriptor->numOfBindings; i++)
123274 + {
123275 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
123276 + ip_addr[0], ip_addr[1],
123277 + ip_addr[2], ip_addr[3]);
123278 + FM_DMP_LN(buf, n, "%-15s 0x%x\n",
123279 + ip_str, bindings->vlanId);
123280 + }
123281 + iounmap(bindings);
123282 + }
123283 + if (ICMPV4Descriptor->p_Statistics)
123284 + {
123285 + t_DsarIcmpV4Statistics* icmpv4Stats = ioremap(
123286 + ioread32be(&ICMPV4Descriptor->p_Statistics) +
123287 + p_FmPort->fmMuramPhysBaseAddr,
123288 + sizeof(t_DsarIcmpV4Statistics));
123289 + FM_DMP_LN(buf, n, "statistics\n");
123290 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv4Stats->invalCnt);
123291 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv4Stats->nmVlanCnt);
123292 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv4Stats->nmIpCnt);
123293 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv4Stats->arCnt);
123294 + FM_DMP_LN(buf, n, "CSERR_CNT: 0x%x\n", icmpv4Stats->cserrCnt);
123295 + iounmap(icmpv4Stats);
123296 + }
123297 + iounmap(ICMPV4Descriptor);
123298 + }
123299 + if (ArCommonDescPtr->p_NdDescriptor)
123300 + {
123301 + t_DsarNdDescriptor *NDDescriptor =
123302 + (t_DsarNdDescriptor*)ioremap(ioread32be(
123303 + &ArCommonDescPtr->p_NdDescriptor) + p_FmPort->
123304 + fmMuramPhysBaseAddr, sizeof (t_DsarNdDescriptor));
123305 + FM_DMP_LN(buf, n, "\nNDP\n");
123306 + FM_DMP_LN(buf, n, "===\n");
123307 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", NDDescriptor->control);
123308 + FM_DMP_LN(buf, n, "solicited address 0x%08x\n", NDDescriptor->solicitedAddr);
123309 + if (NDDescriptor->numOfBindings)
123310 + {
123311 + char ip_str[100];
123312 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
123313 + ioread32be(&NDDescriptor->p_Bindings) +
123314 + p_FmPort->fmMuramPhysBaseAddr,
123315 + NDDescriptor->numOfBindings *
123316 + sizeof(t_DsarIcmpV6BindingEntry));
123317 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
123318 + FM_DMP_LN(buf, n, " ip vlan id\n");
123319 + for (i = 0; i < NDDescriptor->numOfBindings; i++)
123320 + {
123321 + n += snprintf(ip_str, 100,
123322 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
123323 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
123324 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
123325 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
123326 + }
123327 + iounmap(bindings);
123328 + }
123329 + if (NDDescriptor->p_Statistics)
123330 + {
123331 + t_NdStatistics* ndStats = ioremap(
123332 + ioread32be(&NDDescriptor->p_Statistics) +
123333 + p_FmPort->fmMuramPhysBaseAddr,
123334 + sizeof(t_NdStatistics));
123335 + FM_DMP_LN(buf, n, "statistics\n");
123336 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", ndStats->invalCnt);
123337 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", ndStats->nmVlanCnt);
123338 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", ndStats->nmIpCnt);
123339 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", ndStats->arCnt);
123340 + FM_DMP_LN(buf, n, "USADVERT_CNT: 0x%x\n", ndStats->usadvertCnt);
123341 + FM_DMP_LN(buf, n, "NMMCAST_CNT: 0x%x\n", ndStats->nmmcastCnt);
123342 + FM_DMP_LN(buf, n, "NSLLA_CNT: 0x%x\n", ndStats->nsllaCnt);
123343 + iounmap(ndStats);
123344 + }
123345 + iounmap(NDDescriptor);
123346 + }
123347 + if (ArCommonDescPtr->p_IcmpV6Descriptor)
123348 + {
123349 + t_DsarIcmpV6Descriptor *ICMPV6Descriptor =
123350 + (t_DsarIcmpV6Descriptor*)ioremap(ioread32be(
123351 + &ArCommonDescPtr->p_IcmpV6Descriptor) + p_FmPort->
123352 + fmMuramPhysBaseAddr, sizeof (t_DsarIcmpV6Descriptor));
123353 + FM_DMP_LN(buf, n, "\nEcho ICMPv6\n");
123354 + FM_DMP_LN(buf, n, "===========\n");
123355 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", ICMPV6Descriptor->control);
123356 + if (ICMPV6Descriptor->numOfBindings)
123357 + {
123358 + char ip_str[100];
123359 + t_DsarIcmpV6BindingEntry* bindings = ioremap(
123360 + ioread32be(&ICMPV6Descriptor->p_Bindings) +
123361 + p_FmPort->fmMuramPhysBaseAddr,
123362 + ICMPV6Descriptor->numOfBindings *
123363 + sizeof(t_DsarIcmpV6BindingEntry));
123364 + uint16_t* ip_addr = (uint16_t*)&bindings->ipv6Addr;
123365 + FM_DMP_LN(buf, n, " ip vlan id\n");
123366 + for (i = 0; i < ICMPV6Descriptor->numOfBindings; i++)
123367 + {
123368 + n += snprintf(ip_str, 100,
123369 + "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x",
123370 + ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
123371 + ip_addr[4], ip_addr[5], ip_addr[6], ip_addr[7]);
123372 + FM_DMP_LN(buf, n, "%s 0x%x\n", ip_str, bindings->vlanId);
123373 + }
123374 + iounmap(bindings);
123375 + }
123376 + if (ICMPV6Descriptor->p_Statistics)
123377 + {
123378 + t_DsarIcmpV6Statistics* icmpv6Stats = ioremap(
123379 + ioread32be(&ICMPV6Descriptor->p_Statistics) +
123380 + p_FmPort->fmMuramPhysBaseAddr,
123381 + sizeof(t_DsarIcmpV6Statistics));
123382 + FM_DMP_LN(buf, n, "statistics\n");
123383 + FM_DMP_LN(buf, n, "INVAL_CNT: 0x%x\n", icmpv6Stats->invalCnt);
123384 + FM_DMP_LN(buf, n, "NMVLAN_CNT: 0x%x\n", icmpv6Stats->nmVlanCnt);
123385 + FM_DMP_LN(buf, n, "NMIP_CNT: 0x%x\n", icmpv6Stats->nmIpCnt);
123386 + FM_DMP_LN(buf, n, "AR_CNT: 0x%x\n", icmpv6Stats->arCnt);
123387 + iounmap(icmpv6Stats);
123388 + }
123389 + iounmap(ICMPV6Descriptor);
123390 + }
123391 + if (ArCommonDescPtr->p_SnmpDescriptor)
123392 + {
123393 + t_DsarSnmpDescriptor *SnmpDescriptor =
123394 + (t_DsarSnmpDescriptor*)ioremap(ioread32be(
123395 + &ArCommonDescPtr->p_SnmpDescriptor) + p_FmPort->
123396 + fmMuramPhysBaseAddr, sizeof (t_DsarSnmpDescriptor));
123397 + FM_DMP_LN(buf, n, "\nSNMP\n");
123398 + FM_DMP_LN(buf, n, "===========\n");
123399 + FM_DMP_LN(buf, n, "control bits 0x%04x\n", SnmpDescriptor->control);
123400 + FM_DMP_LN(buf, n, "max message length 0x%04x\n", SnmpDescriptor->maxSnmpMsgLength);
123401 + if (SnmpDescriptor->numOfIpv4Addresses)
123402 + {
123403 + char ip_str[100];
123404 + t_DsarSnmpIpv4AddrTblEntry* addrs = ioremap(
123405 + ioread32be(&SnmpDescriptor->p_Ipv4AddrTbl) +
123406 + p_FmPort->fmMuramPhysBaseAddr,
123407 + SnmpDescriptor->numOfIpv4Addresses *
123408 + sizeof(t_DsarSnmpIpv4AddrTblEntry));
123409 + uint8_t* ip_addr = (uint8_t*)&addrs->ipv4Addr;
123410 + FM_DMP_LN(buf, n, " ip vlan id\n");
123411 + for (i = 0; i < SnmpDescriptor->numOfIpv4Addresses; i++)
123412 + {
123413 + n += snprintf(ip_str, 100, "%d.%d.%d.%d",
123414 + ip_addr[0], ip_addr[1],
123415 + ip_addr[2], ip_addr[3]);
123416 + FM_DMP_LN(buf, n, "%-15s 0x%x\n", ip_str, addrs->vlanId);
123417 + }
123418 + iounmap(addrs);
123419 + }
123420 + if (SnmpDescriptor->p_Statistics)
123421 + {
123422 + t_DsarSnmpStatistics* snmpStats = ioremap(
123423 + ioread32be(&SnmpDescriptor->p_Statistics) +
123424 + p_FmPort->fmMuramPhysBaseAddr,
123425 + sizeof(t_DsarSnmpStatistics));
123426 + FM_DMP_LN(buf, n, "statistics\n");
123427 + FM_DMP_LN(buf, n, "snmpErrCnt: 0x%x\n", snmpStats->snmpErrCnt);
123428 + FM_DMP_LN(buf, n, "snmpCommunityErrCnt: 0x%x\n", snmpStats->snmpCommunityErrCnt);
123429 + FM_DMP_LN(buf, n, "snmpTotalDiscardCnt: 0x%x\n", snmpStats->snmpTotalDiscardCnt);
123430 + FM_DMP_LN(buf, n, "snmpGetReqCnt: 0x%x\n", snmpStats->snmpGetReqCnt);
123431 + FM_DMP_LN(buf, n, "snmpGetNextReqCnt: 0x%x\n", snmpStats->snmpGetNextReqCnt);
123432 + iounmap(snmpStats);
123433 + }
123434 + iounmap(SnmpDescriptor);
123435 + }
123436 + iounmap(ArCommonDescPtr);
123437 + iounmap(param_page);
123438 + return n;
123439 +}
123440 +
123441 +static ssize_t show_fm_port_dsar_mem(struct device *dev,
123442 + struct device_attribute *attr, char *buf)
123443 +{
123444 + unsigned long flags;
123445 + unsigned n = 0;
123446 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123447 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123448 +#endif
123449 + if (attr == NULL || buf == NULL || dev == NULL)
123450 + return -EINVAL;
123451 +
123452 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123453 + p_LnxWrpFmPortDev =
123454 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123455 +
123456 + local_irq_save(flags);
123457 +
123458 + if (!p_LnxWrpFmPortDev->h_Dev) {
123459 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123460 + return n;
123461 + } else {
123462 + n = snprintf(buf, PAGE_SIZE,
123463 + "FM port driver registers dump.\n");
123464 + n = fm_port_dsar_dump_mem(p_LnxWrpFmPortDev->h_Dev, buf, n);
123465 + }
123466 +
123467 + local_irq_restore(flags);
123468 +
123469 + return n;
123470 +#else
123471 +
123472 + local_irq_save(flags);
123473 + n = snprintf(buf, PAGE_SIZE,
123474 + "Debug level is too low to dump registers!!!\n");
123475 + local_irq_restore(flags);
123476 +
123477 + return n;
123478 +#endif
123479 +}
123480 +
123481 +static ssize_t show_fm_port_dsar_regs(struct device *dev,
123482 + struct device_attribute *attr, char *buf)
123483 +{
123484 + unsigned long flags;
123485 + unsigned n = 0;
123486 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123487 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123488 +#endif
123489 + if (attr == NULL || buf == NULL || dev == NULL)
123490 + return -EINVAL;
123491 +
123492 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123493 + p_LnxWrpFmPortDev =
123494 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123495 +
123496 + local_irq_save(flags);
123497 +
123498 + if (!p_LnxWrpFmPortDev->h_Dev) {
123499 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123500 + return n;
123501 + } else {
123502 + n = snprintf(buf, PAGE_SIZE,
123503 + "FM port driver registers dump.\n");
123504 + n = fm_port_dsar_dump_regs(p_LnxWrpFmPortDev->h_Dev, buf, n);
123505 + }
123506 +
123507 + local_irq_restore(flags);
123508 +
123509 + return n;
123510 +#else
123511 +
123512 + local_irq_save(flags);
123513 + n = snprintf(buf, PAGE_SIZE,
123514 + "Debug level is too low to dump registers!!!\n");
123515 + local_irq_restore(flags);
123516 +
123517 + return n;
123518 +#endif
123519 +}
123520 +
123521 +#if (DPAA_VERSION >= 11)
123522 +static ssize_t show_fm_port_ipv4_options(struct device *dev,
123523 + struct device_attribute *attr, char *buf)
123524 +{
123525 + unsigned long flags;
123526 + unsigned n = 0;
123527 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123528 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123529 +#endif
123530 +
123531 + if (attr == NULL || buf == NULL || dev == NULL)
123532 + return -EINVAL;
123533 +
123534 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123535 + p_LnxWrpFmPortDev =
123536 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123537 +
123538 + local_irq_save(flags);
123539 +
123540 + if (!p_LnxWrpFmPortDev->h_Dev) {
123541 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123542 + return n;
123543 + } else if (((t_FmPort *)p_LnxWrpFmPortDev->h_Dev)->p_ParamsPage
123544 + == NULL) {
123545 + n = snprintf(buf, PAGE_SIZE,
123546 + "\tPort: FMan-controller params page not set\n");
123547 + return n;
123548 + } else {
123549 + n = snprintf(buf, PAGE_SIZE,
123550 + "Counter for fragmented pkt with IP header options\n");
123551 + n = fm_port_dump_ipv4_opt(p_LnxWrpFmPortDev->h_Dev, buf, n);
123552 + }
123553 +
123554 + local_irq_restore(flags);
123555 +
123556 + return n;
123557 +#else
123558 +
123559 + local_irq_save(flags);
123560 + n = snprintf(buf, PAGE_SIZE,
123561 + "Debug level is too low to dump registers!!!\n");
123562 + local_irq_restore(flags);
123563 +
123564 + return n;
123565 +#endif
123566 +}
123567 +
123568 +#endif
123569 +
123570 +static ssize_t show_fm_port_bmi_regs(struct device *dev,
123571 + struct device_attribute *attr, char *buf)
123572 +{
123573 + unsigned long flags;
123574 + unsigned n = 0;
123575 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123576 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123577 +#endif
123578 +
123579 + if (attr == NULL || buf == NULL || dev == NULL)
123580 + return -EINVAL;
123581 +
123582 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123583 + p_LnxWrpFmPortDev =
123584 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123585 +
123586 + local_irq_save(flags);
123587 +
123588 + if (!p_LnxWrpFmPortDev->h_Dev) {
123589 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123590 + return n;
123591 + } else {
123592 + n = snprintf(buf, PAGE_SIZE,
123593 + "FM port driver registers dump.\n");
123594 + n = fm_port_dump_regs_bmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
123595 + }
123596 +
123597 + local_irq_restore(flags);
123598 +
123599 + return n;
123600 +#else
123601 +
123602 + local_irq_save(flags);
123603 + n = snprintf(buf, PAGE_SIZE,
123604 + "Debug level is too low to dump registers!!!\n");
123605 + local_irq_restore(flags);
123606 +
123607 + return n;
123608 +#endif
123609 +}
123610 +
123611 +static ssize_t show_fm_port_qmi_regs(struct device *dev,
123612 + struct device_attribute *attr, char *buf)
123613 +{
123614 + unsigned long flags;
123615 + unsigned n = 0;
123616 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123617 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123618 +#endif
123619 +
123620 + if (attr == NULL || buf == NULL || dev == NULL)
123621 + return -EINVAL;
123622 +
123623 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
123624 + p_LnxWrpFmPortDev =
123625 + (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123626 +
123627 + local_irq_save(flags);
123628 +
123629 + if (!p_LnxWrpFmPortDev->h_Dev) {
123630 + n = snprintf(buf, PAGE_SIZE, "\tFM Port not configured...\n");
123631 + return n;
123632 + } else {
123633 + n = snprintf(buf, PAGE_SIZE,
123634 + "FM port driver registers dump.\n");
123635 + n = fm_port_dump_regs_qmi(p_LnxWrpFmPortDev->h_Dev, buf, n);
123636 + }
123637 +
123638 + local_irq_restore(flags);
123639 +
123640 + return n;
123641 +#else
123642 +
123643 + local_irq_save(flags);
123644 + n = snprintf(buf, PAGE_SIZE,
123645 + "Debug level is too low to dump registers!!!\n");
123646 + local_irq_restore(flags);
123647 +
123648 + return n;
123649 +#endif
123650 +}
123651 +
123652 +static DEVICE_ATTR(fm_port_regs, S_IRUGO | S_IRUSR, show_fm_port_regs, NULL);
123653 +static DEVICE_ATTR(fm_port_qmi_regs, S_IRUGO | S_IRUSR, show_fm_port_qmi_regs, NULL);
123654 +static DEVICE_ATTR(fm_port_bmi_regs, S_IRUGO | S_IRUSR, show_fm_port_bmi_regs, NULL);
123655 +#if (DPAA_VERSION >= 11)
123656 +static DEVICE_ATTR(fm_port_ipv4_opt, S_IRUGO | S_IRUSR, show_fm_port_ipv4_options, NULL);
123657 +#endif
123658 +static DEVICE_ATTR(fm_port_dsar_regs, S_IRUGO | S_IRUSR, show_fm_port_dsar_regs, NULL);
123659 +static DEVICE_ATTR(fm_port_dsar_mem, S_IRUGO | S_IRUSR, show_fm_port_dsar_mem, NULL);
123660 +
123661 +int fm_port_sysfs_create(struct device *dev)
123662 +{
123663 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev;
123664 +
123665 + if (dev == NULL)
123666 + return -EINVAL;
123667 +
123668 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123669 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
123670 + return -EINVAL;
123671 +
123672 + /* store to remove them when module is disabled */
123673 + p_LnxWrpFmPortDev->dev_attr_regs = &dev_attr_fm_port_regs;
123674 + p_LnxWrpFmPortDev->dev_attr_qmi_regs = &dev_attr_fm_port_qmi_regs;
123675 + p_LnxWrpFmPortDev->dev_attr_bmi_regs = &dev_attr_fm_port_bmi_regs;
123676 +#if (DPAA_VERSION >= 11)
123677 + p_LnxWrpFmPortDev->dev_attr_ipv4_opt = &dev_attr_fm_port_ipv4_opt;
123678 +#endif
123679 + p_LnxWrpFmPortDev->dev_attr_dsar_regs = &dev_attr_fm_port_dsar_regs;
123680 + p_LnxWrpFmPortDev->dev_attr_dsar_mem = &dev_attr_fm_port_dsar_mem;
123681 + /* Registers dump entry - in future will be moved to debugfs */
123682 + if (device_create_file(dev, &dev_attr_fm_port_regs) != 0)
123683 + return -EIO;
123684 + if (device_create_file(dev, &dev_attr_fm_port_qmi_regs) != 0)
123685 + return -EIO;
123686 + if (device_create_file(dev, &dev_attr_fm_port_bmi_regs) != 0)
123687 + return -EIO;
123688 +#if (DPAA_VERSION >= 11)
123689 + if (device_create_file(dev, &dev_attr_fm_port_ipv4_opt) != 0)
123690 + return -EIO;
123691 +#endif
123692 + if (device_create_file(dev, &dev_attr_fm_port_dsar_regs) != 0)
123693 + return -EIO;
123694 + if (device_create_file(dev, &dev_attr_fm_port_dsar_mem) != 0)
123695 + return -EIO;
123696 +
123697 + /* FM Ports statistics */
123698 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
123699 + case e_FM_PORT_TYPE_TX:
123700 + case e_FM_PORT_TYPE_TX_10G:
123701 + if (sysfs_create_group
123702 + (&dev->kobj, &fm_tx_port_dev_stats_attr_grp) != 0)
123703 + return -EIO;
123704 + break;
123705 + case e_FM_PORT_TYPE_RX:
123706 + case e_FM_PORT_TYPE_RX_10G:
123707 + if (sysfs_create_group
123708 + (&dev->kobj, &fm_rx_port_dev_stats_attr_grp) != 0)
123709 + return -EIO;
123710 + break;
123711 + case e_FM_PORT_TYPE_DUMMY:
123712 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
123713 + if (sysfs_create_group
123714 + (&dev->kobj, &fm_oh_port_dev_stats_attr_grp) != 0)
123715 + return -EIO;
123716 + break;
123717 + default:
123718 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
123719 + __func__);
123720 + return -EINVAL;
123721 + break;
123722 + };
123723 +
123724 + return 0;
123725 +}
123726 +
123727 +void fm_port_sysfs_destroy(struct device *dev)
123728 +{
123729 + t_LnxWrpFmPortDev *p_LnxWrpFmPortDev = NULL;
123730 +
123731 + /* this function has never been tested !!! */
123732 +
123733 + if (WARN_ON(dev == NULL))
123734 + return;
123735 +
123736 + p_LnxWrpFmPortDev = (t_LnxWrpFmPortDev *) dev_get_drvdata(dev);
123737 + if (WARN_ON(p_LnxWrpFmPortDev == NULL))
123738 + return;
123739 +
123740 + /* The name attribute will be freed also by these 2 functions? */
123741 + switch (p_LnxWrpFmPortDev->settings.param.portType) {
123742 + case e_FM_PORT_TYPE_TX:
123743 + case e_FM_PORT_TYPE_TX_10G:
123744 + sysfs_remove_group(&dev->kobj, &fm_tx_port_dev_stats_attr_grp);
123745 + break;
123746 + case e_FM_PORT_TYPE_RX:
123747 + case e_FM_PORT_TYPE_RX_10G:
123748 + sysfs_remove_group(&dev->kobj, &fm_rx_port_dev_stats_attr_grp);
123749 + break;
123750 + case e_FM_PORT_TYPE_DUMMY:
123751 + case e_FM_PORT_TYPE_OH_OFFLINE_PARSING:
123752 + sysfs_remove_group(&dev->kobj, &fm_oh_port_dev_stats_attr_grp);
123753 + break;
123754 + default:
123755 + WARN(1, "FMD: failure at %s:%d/%s()!\n", __FILE__, __LINE__,
123756 + __func__);
123757 + break;
123758 + };
123759 +
123760 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_regs);
123761 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_qmi_regs);
123762 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_bmi_regs);
123763 +#if (DPAA_VERSION >= 11)
123764 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_ipv4_opt);
123765 +#endif
123766 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_regs);
123767 + device_remove_file(dev, p_LnxWrpFmPortDev->dev_attr_dsar_mem);
123768 +}
123769 +
123770 +
123771 +int fm_port_dump_regs(void *h_dev, char *buf, int nn)
123772 +{
123773 + t_FmPort *p_FmPort;
123774 + t_Fm *p_Fm;
123775 + uint8_t hardwarePortId;
123776 + int n = nn;
123777 +
123778 + p_FmPort = (t_FmPort *)h_dev;
123779 + hardwarePortId = p_FmPort->hardwarePortId;
123780 + p_Fm = (t_Fm *)p_FmPort->h_Fm;
123781 +
123782 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1],
123783 + "fmbm_pp for port %u", hardwarePortId);
123784 + FM_DMP_MEM_32(buf, n,
123785 + &p_Fm->p_FmBmiRegs->fmbm_pp[hardwarePortId - 1]);
123786 +
123787 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1],
123788 + "fmbm_pfs for port %u", hardwarePortId);
123789 + FM_DMP_MEM_32(buf, n,
123790 + &p_Fm->p_FmBmiRegs->fmbm_pfs[hardwarePortId - 1]);
123791 +
123792 + FM_DMP_TITLE(buf, n,
123793 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1],
123794 + "fmbm_spliodn for port %u", hardwarePortId);
123795 + FM_DMP_MEM_32(buf, n,
123796 + &p_Fm->p_FmBmiRegs->fmbm_spliodn[hardwarePortId - 1]);
123797 +
123798 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId],
123799 + "fmfp_psfor port %u", hardwarePortId);
123800 + FM_DMP_MEM_32(buf, n, &p_Fm->p_FmFpmRegs->fmfp_ps[hardwarePortId]);
123801 +
123802 + FM_DMP_TITLE(buf, n, &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2],
123803 + "fmdmplrfor port %u", hardwarePortId);
123804 + FM_DMP_MEM_32(buf, n,
123805 + &p_Fm->p_FmDmaRegs->fmdmplr[hardwarePortId / 2]);
123806 + return n;
123807 +}
123808 +
123809 +#if (DPAA_VERSION >= 11)
123810 +
123811 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int nn)
123812 +{
123813 + t_FmPort *p_FmPort;
123814 + int n = nn;
123815 +
123816 + p_FmPort = (t_FmPort *)h_dev;
123817 +
123818 + FM_DMP_V32(buf, n, p_FmPort->p_ParamsPage, ipfOptionsCounter);
123819 +
123820 + FM_DMP_SUBTITLE(buf, n, "\n");
123821 +
123822 + return n;
123823 +}
123824 +#endif
123825 +
123826 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int nn)
123827 +{
123828 + t_FmPort *p_FmPort;
123829 + u_FmPortBmiRegs *p_bmi;
123830 +
123831 + char arr[20];
123832 + uint8_t flag;
123833 + int i = 0;
123834 + int n = nn;
123835 +
123836 + p_FmPort = (t_FmPort *)h_dev;
123837 + p_bmi = p_FmPort->p_FmPortBmiRegs;
123838 +
123839 + memset(arr, 0, sizeof(arr));
123840 + switch (p_FmPort->portType) {
123841 + case (e_FM_PORT_TYPE_OH_OFFLINE_PARSING):
123842 + strcpy(arr, "OFFLINE-PARSING");
123843 + flag = 0;
123844 + break;
123845 + case (e_FM_PORT_TYPE_OH_HOST_COMMAND):
123846 + strcpy(arr, "HOST-COMMAND");
123847 + flag = 0;
123848 + break;
123849 + case (e_FM_PORT_TYPE_RX):
123850 + strcpy(arr, "RX");
123851 + flag = 1;
123852 + break;
123853 + case (e_FM_PORT_TYPE_RX_10G):
123854 + strcpy(arr, "RX-10G");
123855 + flag = 1;
123856 + break;
123857 + case (e_FM_PORT_TYPE_TX):
123858 + strcpy(arr, "TX");
123859 + flag = 2;
123860 + break;
123861 + case (e_FM_PORT_TYPE_TX_10G):
123862 + strcpy(arr, "TX-10G");
123863 + flag = 2;
123864 + break;
123865 + default:
123866 + return -EINVAL;
123867 + }
123868 +
123869 + FM_DMP_TITLE(buf, n, NULL,
123870 + "FMan-Port (%s #%d) registers:",
123871 + arr, p_FmPort->portId);
123872 +
123873 + FM_DMP_TITLE(buf, n, p_bmi, "Bmi Port Regs");
123874 +
123875 + switch (flag) {
123876 + case (0):
123877 + FM_DMP_SUBTITLE(buf, n, "\n");
123878 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocfg);
123879 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ost);
123880 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oda);
123881 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oicp);
123882 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdne);
123883 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofne);
123884 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofca);
123885 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofpne);
123886 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opso);
123887 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opp);
123888 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occb);
123889 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oim);
123890 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofp);
123891 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofed);
123892 +
123893 + FM_DMP_TITLE(buf, n,
123894 + &(p_bmi->ohPortBmiRegs.fmbm_oprai), "fmbm_oprai");
123895 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
123896 + FM_DMP_MEM_32(buf, n,
123897 + &(p_bmi->ohPortBmiRegs.fmbm_oprai[i]));
123898 + }
123899 + FM_DMP_SUBTITLE(buf, n, "\n");
123900 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofqid);
123901 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oefqid);
123902 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsdm);
123903 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofsem);
123904 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofene);
123905 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmts);
123906 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_orlmt);
123907 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocmne);
123908 + {
123909 +#ifndef FM_NO_OP_OBSERVED_POOLS
123910 + if (p_FmPort->fmRevInfo.majorRev == 4) {
123911 + FM_DMP_TITLE(buf, n,
123912 + &p_bmi->ohPortBmiRegs.fmbm_oebmpi,
123913 + "fmbm_oebmpi");
123914 +
123915 + for (i = 0; i < FM_PORT_MAX_NUM_OF_OBSERVED_EXT_POOLS; ++i) {
123916 + FM_DMP_MEM_32(buf, n,
123917 + &(p_bmi->ohPortBmiRegs.fmbm_oebmpi[i]));
123918 + }
123919 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ocgm);
123920 + }
123921 +#endif /* !FM_NO_OP_OBSERVED_POOLS */
123922 + }
123923 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ostc);
123924 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofrc);
123925 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofdc);
123926 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofledc);
123927 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofufdc);
123928 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_offc);
123929 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofwdc);
123930 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofldec);
123931 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opc);
123932 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_opcp);
123933 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_occn);
123934 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_otuc);
123935 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_oduc);
123936 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ofuc);
123937 + FM_DMP_TITLE(buf, n, &(p_bmi->ohPortBmiRegs.fmbm_odcfg),
123938 + "fmbm_odcfg");
123939 + for (i = 0; i < 3; ++i) {
123940 + FM_DMP_MEM_32(buf, n,
123941 + &(p_bmi->ohPortBmiRegs.fmbm_odcfg[i]));
123942 + }
123943 + FM_DMP_SUBTITLE(buf, n, "\n");
123944 +
123945 + FM_DMP_V32(buf, n, &p_bmi->ohPortBmiRegs, fmbm_ogpr);
123946 + break;
123947 + case (1):
123948 + FM_DMP_SUBTITLE(buf, n, "\n");
123949 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcfg);
123950 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rst);
123951 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rda);
123952 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfp);
123953 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_reth);
123954 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfed);
123955 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_ricp);
123956 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rebm);
123957 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfne);
123958 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfca);
123959 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfpne);
123960 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpso);
123961 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpp);
123962 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rprai),
123963 + "fmbm_rprai");
123964 + for (i = 0; i < FM_PORT_PRS_RESULT_NUM_OF_WORDS; ++i) {
123965 + FM_DMP_MEM_32(buf, n,
123966 + &(p_bmi->rxPortBmiRegs.fmbm_rprai[i]));
123967 + }
123968 + FM_DMP_SUBTITLE(buf, n, "\n");
123969 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfqid);
123970 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_refqid);
123971 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsdm);
123972 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfsem);
123973 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfene);
123974 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rcmne);
123975 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_ebmpi,
123976 + "fmbm_ebmpi");
123977 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
123978 + FM_DMP_MEM_32(buf, n,
123979 + &(p_bmi->rxPortBmiRegs.fmbm_ebmpi[i]));
123980 + }
123981 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_acnt,
123982 + "fmbm_acnt");
123983 + for (i = 0; i < FM_PORT_MAX_NUM_OF_EXT_POOLS; ++i) {
123984 + FM_DMP_MEM_32(buf, n,
123985 + &(p_bmi->rxPortBmiRegs.fmbm_acnt[i]));
123986 + }
123987 + FM_DMP_TITLE(buf, n, &p_bmi->rxPortBmiRegs.fmbm_rcgm,
123988 + "fmbm_rcgm");
123989 + for (i = 0; i < FM_PORT_NUM_OF_CONGESTION_GRPS / 32; ++i) {
123990 + FM_DMP_MEM_32(buf, n,
123991 + &(p_bmi->rxPortBmiRegs.fmbm_rcgm[i]));
123992 + }
123993 +
123994 + FM_DMP_SUBTITLE(buf, n, "\n");
123995 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rmpd);
123996 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rstc);
123997 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfrc);
123998 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfbc);
123999 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rlfc);
124000 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rffc);
124001 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfcd);
124002 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfldec);
124003 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rodc);
124004 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpc);
124005 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpcp);
124006 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rccn);
124007 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rtuc);
124008 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rrquc);
124009 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rduc);
124010 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rfuc);
124011 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rpac);
124012 + FM_DMP_TITLE(buf, n, &(p_bmi->rxPortBmiRegs.fmbm_rdcfg),
124013 + "fmbm_rdcfg");
124014 + for (i = 0; i < 3; ++i) {
124015 + FM_DMP_MEM_32(buf, n,
124016 + &(p_bmi->rxPortBmiRegs.fmbm_rdcfg[i]));
124017 + }
124018 + FM_DMP_SUBTITLE(buf, n, "\n");
124019 + FM_DMP_V32(buf, n, &p_bmi->rxPortBmiRegs, fmbm_rgpr);
124020 + break;
124021 + case (2):
124022 + FM_DMP_SUBTITLE(buf, n, "\n");
124023 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfg);
124024 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tst);
124025 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tda);
124026 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfp);
124027 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfed);
124028 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ticp);
124029 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdne);
124030 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfca);
124031 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcfqid);
124032 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfeqid);
124033 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfene);
124034 +#if (DPAA_VERSION >= 11)
124035 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfne);
124036 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tcmne);
124037 +#endif /* (DPAA_VERSION >= 11) */
124038 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmts);
124039 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_trlmt);
124040 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tstc);
124041 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfrc);
124042 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfdc);
124043 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfledc);
124044 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfufdc);
124045 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpc);
124046 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tpcp);
124047 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tccn);
124048 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttuc);
124049 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_ttcquc);
124050 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tduc);
124051 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tfuc);
124052 + FM_DMP_TITLE(buf, n, &(p_bmi->txPortBmiRegs.fmbm_tdcfg),
124053 + "fmbm_tdcfg");
124054 + for (i = 0; i < 3 ; ++i) {
124055 + FM_DMP_MEM_32(buf, n,
124056 + &(p_bmi->txPortBmiRegs.fmbm_tdcfg[i]));
124057 + }
124058 + FM_DMP_SUBTITLE(buf, n, "\n");
124059 + FM_DMP_V32(buf, n, &p_bmi->txPortBmiRegs, fmbm_tgpr);
124060 + break;
124061 + }
124062 +
124063 + FM_DMP_SUBTITLE(buf, n, "\n");
124064 +
124065 + return n;
124066 +}
124067 +
124068 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int nn)
124069 +{
124070 + t_FmPort *p_FmPort;
124071 + int n = nn;
124072 +
124073 + p_FmPort = (t_FmPort *)h_dev;
124074 +
124075 + FM_DMP_TITLE(buf, n, p_FmPort->p_FmPortQmiRegs, "Qmi Port Regs");
124076 +
124077 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnc);
124078 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pns);
124079 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnts);
124080 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnen);
124081 + FM_DMP_V32(buf, n, p_FmPort->p_FmPortQmiRegs, fmqm_pnetfc);
124082 + FM_DMP_V32(buf, n,
124083 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndn);
124084 + FM_DMP_V32(buf, n,
124085 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndc);
124086 + FM_DMP_V32(buf, n,
124087 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndtfc);
124088 + FM_DMP_V32(buf, n,
124089 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndfdc);
124090 + FM_DMP_V32(buf, n,
124091 + &p_FmPort->p_FmPortQmiRegs->nonRxQmiRegs, fmqm_pndcc);
124092 +
124093 + FM_DMP_SUBTITLE(buf, n, "\n");
124094 +
124095 + return n;
124096 +}
124097 +
124098 --- /dev/null
124099 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/wrapper/lnxwrp_sysfs_fm_port.h
124100 @@ -0,0 +1,56 @@
124101 +/*
124102 + * Copyright 2008-2012 Freescale Semiconductor Inc.
124103 + *
124104 + * Redistribution and use in source and binary forms, with or without
124105 + * modification, are permitted provided that the following conditions are met:
124106 + * * Redistributions of source code must retain the above copyright
124107 + * notice, this list of conditions and the following disclaimer.
124108 + * * Redistributions in binary form must reproduce the above copyright
124109 + * notice, this list of conditions and the following disclaimer in the
124110 + * documentation and/or other materials provided with the distribution.
124111 + * * Neither the name of Freescale Semiconductor nor the
124112 + * names of its contributors may be used to endorse or promote products
124113 + * derived from this software without specific prior written permission.
124114 + *
124115 + *
124116 + * ALTERNATIVELY, this software may be distributed under the terms of the
124117 + * GNU General Public License ("GPL") as published by the Free Software
124118 + * Foundation, either version 2 of that License or (at your option) any
124119 + * later version.
124120 + *
124121 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124122 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124123 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124124 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124125 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124126 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124127 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124128 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124129 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124130 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124131 + */
124132 +
124133 +/*
124134 + @File lnxwrp_sysfs_fm_port.h
124135 +
124136 + @Description FM port sysfs functions.
124137 +
124138 +*/
124139 +
124140 +#ifndef LNXWRP_SYSFS_FM_PORT_H_
124141 +#define LNXWRP_SYSFS_FM_PORT_H_
124142 +
124143 +#include "lnxwrp_sysfs.h"
124144 +
124145 +int fm_port_sysfs_create(struct device *dev);
124146 +void fm_port_sysfs_destroy(struct device *dev);
124147 +
124148 +int fm_port_dump_regs(void *h_dev, char *buf, int n);
124149 +int fm_port_dump_regs_bmi(void *h_dev, char *buf, int n);
124150 +int fm_port_dump_regs_qmi(void *h_dev, char *buf, int n);
124151 +
124152 +#if (DPAA_VERSION >= 11)
124153 +int fm_port_dump_ipv4_opt(void *h_dev, char *buf, int n);
124154 +#endif
124155 +
124156 +#endif /* LNXWRP_SYSFS_FM_PORT_H_ */
124157 --- /dev/null
124158 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/Makefile
124159 @@ -0,0 +1,18 @@
124160 +#
124161 +# Makefile for the Freescale Ethernet controllers
124162 +#
124163 +ccflags-y += -DVERSION=\"\"
124164 +#
124165 +#Include netcomm SW specific definitions
124166 +include $(srctree)/drivers/net/ethernet/freescale/sdk_fman/ncsw_config.mk
124167 +
124168 +obj-y += fsl-ncsw-xx.o
124169 +
124170 +ifneq ($(CONFIG_FMAN_ARM),y)
124171 +fsl-ncsw-xx-objs := xx_linux.o \
124172 + module_strings.o
124173 +else
124174 +fsl-ncsw-xx-objs := xx_arm_linux.o \
124175 + module_strings.o
124176 +endif
124177 +
124178 --- /dev/null
124179 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/module_strings.c
124180 @@ -0,0 +1,46 @@
124181 +/*
124182 + * Copyright 2012 Freescale Semiconductor Inc.
124183 + *
124184 + * Redistribution and use in source and binary forms, with or without
124185 + * modification, are permitted provided that the following conditions are met:
124186 + * * Redistributions of source code must retain the above copyright
124187 + * notice, this list of conditions and the following disclaimer.
124188 + * * Redistributions in binary form must reproduce the above copyright
124189 + * notice, this list of conditions and the following disclaimer in the
124190 + * documentation and/or other materials provided with the distribution.
124191 + * * Neither the name of Freescale Semiconductor nor the
124192 + * names of its contributors may be used to endorse or promote products
124193 + * derived from this software without specific prior written permission.
124194 + *
124195 + *
124196 + * ALTERNATIVELY, this software may be distributed under the terms of the
124197 + * GNU General Public License ("GPL") as published by the Free Software
124198 + * Foundation, either version 2 of that License or (at your option) any
124199 + * later version.
124200 + *
124201 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124202 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124203 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124204 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124205 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124206 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124207 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124208 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124209 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124210 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124211 + */
124212 +
124213 +/* Module names for debug messages */
124214 +const char *moduleStrings[] =
124215 +{
124216 + "", /* MODULE_UNKNOWN */
124217 + "FM", /* MODULE_FM */
124218 + "FM-MURAM", /* MODULE_FM_MURAM */
124219 + "FM-PCD", /* MODULE_FM_PCD */
124220 + "FM-RTC", /* MODULE_FM_RTC */
124221 + "FM-MAC", /* MODULE_FM_MAC */
124222 + "FM-Port", /* MODULE_FM_PORT */
124223 + "MM", /* MODULE_MM */
124224 + "FM-SP", /* MODULE_FM_SP */
124225 + "FM-MACSEC" /* MODULE_FM_MACSEC */
124226 +};
124227 --- /dev/null
124228 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_arm_linux.c
124229 @@ -0,0 +1,905 @@
124230 +/*
124231 + * Copyright 2008-2012 Freescale Semiconductor Inc.
124232 + *
124233 + * Redistribution and use in source and binary forms, with or without
124234 + * modification, are permitted provided that the following conditions are met:
124235 + * * Redistributions of source code must retain the above copyright
124236 + * notice, this list of conditions and the following disclaimer.
124237 + * * Redistributions in binary form must reproduce the above copyright
124238 + * notice, this list of conditions and the following disclaimer in the
124239 + * documentation and/or other materials provided with the distribution.
124240 + * * Neither the name of Freescale Semiconductor nor the
124241 + * names of its contributors may be used to endorse or promote products
124242 + * derived from this software without specific prior written permission.
124243 + *
124244 + *
124245 + * ALTERNATIVELY, this software may be distributed under the terms of the
124246 + * GNU General Public License ("GPL") as published by the Free Software
124247 + * Foundation, either version 2 of that License or (at your option) any
124248 + * later version.
124249 + *
124250 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
124251 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
124252 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
124253 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
124254 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
124255 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
124256 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
124257 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
124258 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
124259 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
124260 + */
124261 +
124262 +/**************************************************************************//**
124263 + @File xx_arm_linux.c
124264 +
124265 + @Description XX routines implementation for Linux.
124266 +*//***************************************************************************/
124267 +#include <linux/version.h>
124268 +
124269 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
124270 +#define MODVERSIONS
124271 +#endif
124272 +#ifdef MODVERSIONS
124273 +#include <config/modversions.h>
124274 +#endif /* MODVERSIONS */
124275 +
124276 +#include <linux/module.h>
124277 +#include <linux/kernel.h>
124278 +#include <linux/sched.h>
124279 +#include <linux/string.h>
124280 +#include <linux/ptrace.h>
124281 +#include <linux/errno.h>
124282 +#include <linux/ioport.h>
124283 +#include <linux/slab.h>
124284 +#include <linux/interrupt.h>
124285 +#include <linux/fs.h>
124286 +#include <linux/vmalloc.h>
124287 +#include <linux/init.h>
124288 +#include <linux/timer.h>
124289 +#include <linux/spinlock.h>
124290 +#include <linux/delay.h>
124291 +#include <linux/proc_fs.h>
124292 +#include <linux/smp.h>
124293 +#include <linux/of.h>
124294 +#include <linux/irqdomain.h>
124295 +
124296 +#include <linux/workqueue.h>
124297 +
124298 +#ifdef BIGPHYSAREA_ENABLE
124299 +#include <linux/bigphysarea.h>
124300 +#endif /* BIGPHYSAREA_ENABLE */
124301 +
124302 +//#include <sysdev/fsl_soc.h>
124303 +#include <asm/pgtable.h>
124304 +#include <asm/irq.h>
124305 +#include <asm/bitops.h>
124306 +#include <asm/uaccess.h>
124307 +#include <asm/io.h>
124308 +#include <asm/atomic.h>
124309 +#include <asm/string.h>
124310 +#include <asm/byteorder.h>
124311 +#include <asm/page.h>
124312 +
124313 +#include "error_ext.h"
124314 +#include "std_ext.h"
124315 +#include "list_ext.h"
124316 +#include "mm_ext.h"
124317 +#include "sys_io_ext.h"
124318 +#include "xx.h"
124319 +
124320 +
124321 +#define __ERR_MODULE__ MODULE_UNKNOWN
124322 +
124323 +#ifdef BIGPHYSAREA_ENABLE
124324 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
124325 +
124326 +
124327 +/* TODO: large allocations => use big phys area */
124328 +/******************************************************************************
124329 + * routine: get_nr_pages
124330 + *
124331 + * description:
124332 + * calculates the number of memory pages for a given size (in bytes)
124333 + *
124334 + * arguments:
124335 + * size - the number of bytes
124336 + *
124337 + * return code:
124338 + * The number of pages
124339 + *
124340 + *****************************************************************************/
124341 +static __inline__ uint32_t get_nr_pages (uint32_t size)
124342 +{
124343 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
124344 +}
124345 +
124346 +static bool in_big_phys_area (uint32_t addr)
124347 +{
124348 + uint32_t base, size;
124349 +
124350 + bigphysarea_get_details (&base, &size);
124351 + return ((addr >= base) && (addr < base + size));
124352 +}
124353 +#endif /* BIGPHYSAREA_ENABLE */
124354 +
124355 +void * xx_Malloc(uint32_t n)
124356 +{
124357 + void *a;
124358 + uint32_t flags;
124359 +
124360 + flags = XX_DisableAllIntr();
124361 +#ifdef BIGPHYSAREA_ENABLE
124362 + if (n >= MAX_ALLOCATION_SIZE)
124363 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
124364 + else
124365 +#endif /* BIGPHYSAREA_ENABLE */
124366 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
124367 + if (!a)
124368 + XX_Print("No memory for XX_Malloc\n");
124369 + XX_RestoreAllIntr(flags);
124370 +
124371 + return a;
124372 +}
124373 +
124374 +void xx_Free(void *p)
124375 +{
124376 +#ifdef BIGPHYSAREA_ENABLE
124377 + if (in_big_phys_area ((uint32_t)p))
124378 + bigphysarea_free_pages(p);
124379 + else
124380 +#endif /* BIGPHYSAREA_ENABLE */
124381 + kfree(p);
124382 +}
124383 +
124384 +void XX_Exit(int status)
124385 +{
124386 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
124387 +}
124388 +
124389 +#define BUF_SIZE 512
124390 +void XX_Print(char *str, ...)
124391 +{
124392 + va_list args;
124393 +#ifdef CONFIG_SMP
124394 + char buf[BUF_SIZE];
124395 +#endif /* CONFIG_SMP */
124396 +
124397 + va_start(args, str);
124398 +#ifdef CONFIG_SMP
124399 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
124400 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
124401 + printk(KERN_CRIT "cpu %d: %s", raw_smp_processor_id(), buf);
124402 +#else
124403 + vprintk(str, args);
124404 +#endif /* CONFIG_SMP */
124405 + va_end(args);
124406 +}
124407 +
124408 +void XX_Fprint(void *file, char *str, ...)
124409 +{
124410 + va_list args;
124411 +#ifdef CONFIG_SMP
124412 + char buf[BUF_SIZE];
124413 +#endif /* CONFIG_SMP */
124414 +
124415 + va_start(args, str);
124416 +#ifdef CONFIG_SMP
124417 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
124418 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
124419 + printk (KERN_CRIT "cpu %d: %s", smp_processor_id(), buf);
124420 +
124421 +#else
124422 + vprintk(str, args);
124423 +#endif /* CONFIG_SMP */
124424 + va_end(args);
124425 +}
124426 +
124427 +#ifdef DEBUG_XX_MALLOC
124428 +typedef void (*t_ffn)(void *);
124429 +typedef struct {
124430 + t_ffn f_free;
124431 + void *mem;
124432 + char *fname;
124433 + int fline;
124434 + uint32_t size;
124435 + t_List node;
124436 +} t_MemDebug;
124437 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
124438 +
124439 +LIST(memDbgLst);
124440 +
124441 +
124442 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
124443 +{
124444 + void *mem;
124445 + t_MemDebug *p_MemDbg;
124446 +
124447 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
124448 + if (p_MemDbg == NULL)
124449 + return NULL;
124450 +
124451 + mem = xx_Malloc(size);
124452 + if (mem == NULL)
124453 + {
124454 + XX_Free(p_MemDbg);
124455 + return NULL;
124456 + }
124457 +
124458 + INIT_LIST(&p_MemDbg->node);
124459 + p_MemDbg->f_free = xx_Free;
124460 + p_MemDbg->mem = mem;
124461 + p_MemDbg->fname = fname;
124462 + p_MemDbg->fline = line;
124463 + p_MemDbg->size = size+sizeof(t_MemDebug);
124464 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
124465 +
124466 + return mem;
124467 +}
124468 +
124469 +void * XX_MallocSmartDebug(uint32_t size,
124470 + int memPartitionId,
124471 + uint32_t align,
124472 + char *fname,
124473 + int line)
124474 +{
124475 + void *mem;
124476 + t_MemDebug *p_MemDbg;
124477 +
124478 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
124479 + if (p_MemDbg == NULL)
124480 + return NULL;
124481 +
124482 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
124483 + if (mem == NULL)
124484 + {
124485 + XX_Free(p_MemDbg);
124486 + return NULL;
124487 + }
124488 +
124489 + INIT_LIST(&p_MemDbg->node);
124490 + p_MemDbg->f_free = xx_FreeSmart;
124491 + p_MemDbg->mem = mem;
124492 + p_MemDbg->fname = fname;
124493 + p_MemDbg->fline = line;
124494 + p_MemDbg->size = size+sizeof(t_MemDebug);
124495 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
124496 +
124497 + return mem;
124498 +}
124499 +
124500 +static void debug_free(void *mem)
124501 +{
124502 + t_List *p_MemDbgLh = NULL;
124503 + t_MemDebug *p_MemDbg;
124504 + bool found = FALSE;
124505 +
124506 + if (LIST_IsEmpty(&memDbgLst))
124507 + {
124508 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
124509 + return;
124510 + }
124511 +
124512 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
124513 + {
124514 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
124515 + if (p_MemDbg->mem == mem)
124516 + {
124517 + found = TRUE;
124518 + break;
124519 + }
124520 + }
124521 +
124522 + if (!found)
124523 + {
124524 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
124525 + ("Attempt to free unallocated address (0x%08x)",mem));
124526 + dump_stack();
124527 + return;
124528 + }
124529 +
124530 + LIST_Del(p_MemDbgLh);
124531 + p_MemDbg->f_free(mem);
124532 + p_MemDbg->f_free(p_MemDbg);
124533 +}
124534 +
124535 +void XX_FreeSmart(void *p)
124536 +{
124537 + debug_free(p);
124538 +}
124539 +
124540 +
124541 +void XX_Free(void *p)
124542 +{
124543 + debug_free(p);
124544 +}
124545 +
124546 +#else /* not DEBUG_XX_MALLOC */
124547 +void * XX_Malloc(uint32_t size)
124548 +{
124549 + return xx_Malloc(size);
124550 +}
124551 +
124552 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
124553 +{
124554 + return xx_MallocSmart(size,memPartitionId, alignment);
124555 +}
124556 +
124557 +void XX_FreeSmart(void *p)
124558 +{
124559 + xx_FreeSmart(p);
124560 +}
124561 +
124562 +
124563 +void XX_Free(void *p)
124564 +{
124565 + xx_Free(p);
124566 +}
124567 +#endif /* not DEBUG_XX_MALLOC */
124568 +
124569 +
124570 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
124571 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
124572 +{
124573 + e_Event eventCode = (e_Event)event;
124574 +
124575 + UNUSED(eventCode);
124576 + UNUSED(appId);
124577 + UNUSED(flags);
124578 + UNUSED(msg);
124579 +}
124580 +#endif /* (defined(REPORT_EVENTS) && ... */
124581 +
124582 +
124583 +uint32_t XX_DisableAllIntr(void)
124584 +{
124585 + unsigned long flags;
124586 +
124587 +#ifdef local_irq_save_nort
124588 + local_irq_save_nort(flags);
124589 +#else
124590 + local_irq_save(flags);
124591 +#endif
124592 +
124593 + return (uint32_t)flags;
124594 +}
124595 +
124596 +void XX_RestoreAllIntr(uint32_t flags)
124597 +{
124598 +#ifdef local_irq_restore_nort
124599 + local_irq_restore_nort((unsigned long)flags);
124600 +#else
124601 + local_irq_restore((unsigned long)flags);
124602 +#endif
124603 +}
124604 +
124605 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
124606 +{
124607 + UNUSED(qid);
124608 + UNUSED(appId);
124609 + UNUSED(flags);
124610 +
124611 + return f(id);
124612 +}
124613 +
124614 +int XX_IsICacheEnable(void)
124615 +{
124616 + return TRUE;
124617 +}
124618 +
124619 +int XX_IsDCacheEnable(void)
124620 +{
124621 + return TRUE;
124622 +}
124623 +
124624 +
124625 +typedef struct {
124626 + t_Isr *f_Isr;
124627 + t_Handle handle;
124628 +} t_InterruptHandler;
124629 +
124630 +
124631 +t_Handle interruptHandlers[0x00010000];
124632 +
124633 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
124634 +{
124635 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
124636 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
124637 + return IRQ_HANDLED;
124638 +}
124639 +
124640 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
124641 +{
124642 + const char *device;
124643 + t_InterruptHandler *p_IntrHndl;
124644 +
124645 + device = GetDeviceName(irq);
124646 + if (device == NULL)
124647 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
124648 +
124649 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
124650 + if (p_IntrHndl == NULL)
124651 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
124652 + p_IntrHndl->f_Isr = f_Isr;
124653 + p_IntrHndl->handle = handle;
124654 + interruptHandlers[irq] = p_IntrHndl;
124655 +
124656 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
124657 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
124658 + disable_irq(GetDeviceIrqNum(irq));
124659 +
124660 + return E_OK;
124661 +}
124662 +
124663 +t_Error XX_FreeIntr(int irq)
124664 +{
124665 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
124666 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
124667 + XX_Free(p_IntrHndl);
124668 + interruptHandlers[irq] = 0;
124669 + return E_OK;
124670 +}
124671 +
124672 +t_Error XX_EnableIntr(int irq)
124673 +{
124674 + enable_irq(GetDeviceIrqNum(irq));
124675 + return E_OK;
124676 +}
124677 +
124678 +t_Error XX_DisableIntr(int irq)
124679 +{
124680 + disable_irq(GetDeviceIrqNum(irq));
124681 + return E_OK;
124682 +}
124683 +
124684 +
124685 +/*****************************************************************************/
124686 +/* Tasklet Service Routines */
124687 +/*****************************************************************************/
124688 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
124689 +typedef struct
124690 +{
124691 + t_Handle h_Data;
124692 + void (*f_Callback) (void *);
124693 + struct delayed_work dwork;
124694 +} t_Tasklet;
124695 +
124696 +static void GenericTaskletCallback(struct work_struct *p_Work)
124697 +{
124698 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
124699 +
124700 + p_Task->f_Callback(p_Task->h_Data);
124701 +}
124702 +#endif /* LINUX_VERSION_CODE */
124703 +
124704 +
124705 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
124706 +{
124707 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124708 + struct work_struct *p_Task;
124709 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
124710 + INIT_WORK(p_Task, routine, data);
124711 +#else
124712 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
124713 + p_Task->h_Data = data;
124714 + p_Task->f_Callback = routine;
124715 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
124716 +#endif /* LINUX_VERSION_CODE */
124717 +
124718 + return (t_TaskletHandle)p_Task;
124719 +}
124720 +
124721 +
124722 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
124723 +{
124724 + if (h_Tasklet)
124725 + XX_Free(h_Tasklet);
124726 +}
124727 +
124728 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
124729 +{
124730 + int ans;
124731 +
124732 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124733 + if (immediate)
124734 + ans = schedule_work(h_Tasklet);
124735 + else
124736 + ans = schedule_delayed_work(h_Tasklet, 1);
124737 +#else
124738 + if (immediate)
124739 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
124740 + else
124741 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
124742 +#endif /* LINUX_VERSION_CODE */
124743 +
124744 + return ans;
124745 +}
124746 +
124747 +void XX_FlushScheduledTasks(void)
124748 +{
124749 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124750 + flush_scheduled_tasks();
124751 +#else
124752 + flush_scheduled_work();
124753 +#endif /* LINUX_VERSION_CODE */
124754 +}
124755 +
124756 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
124757 +{
124758 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124759 + return (int)(((struct work_struct *)h_Tasklet)->pending);
124760 +#else
124761 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
124762 +#endif /* LINUX_VERSION_CODE */
124763 +}
124764 +
124765 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
124766 +{
124767 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
124768 + ((struct tq_struct *)h_Tasklet)->data = data;
124769 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124770 + ((struct work_struct *)h_Tasklet)->data = data;
124771 +#else
124772 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
124773 +#endif /* LINUX_VERSION_CODE */
124774 +}
124775 +
124776 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
124777 +{
124778 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
124779 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
124780 +#else
124781 + return ((t_Tasklet *)h_Tasklet)->h_Data;
124782 +#endif /* LINUX_VERSION_CODE */
124783 +}
124784 +
124785 +
124786 +/*****************************************************************************/
124787 +/* Spinlock Service Routines */
124788 +/*****************************************************************************/
124789 +
124790 +t_Handle XX_InitSpinlock(void)
124791 +{
124792 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
124793 + if (!p_Spinlock)
124794 + return NULL;
124795 +
124796 + spin_lock_init(p_Spinlock);
124797 +
124798 + return (t_Handle)p_Spinlock;
124799 +}
124800 +
124801 +void XX_FreeSpinlock(t_Handle h_Spinlock)
124802 +{
124803 + if (h_Spinlock)
124804 + XX_Free(h_Spinlock);
124805 +}
124806 +
124807 +void XX_LockSpinlock(t_Handle h_Spinlock)
124808 +{
124809 + spin_lock((spinlock_t *)h_Spinlock);
124810 +}
124811 +
124812 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
124813 +{
124814 + spin_unlock((spinlock_t *)h_Spinlock);
124815 +}
124816 +
124817 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
124818 +{
124819 + unsigned long intrFlags;
124820 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
124821 + return intrFlags;
124822 +}
124823 +
124824 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
124825 +{
124826 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
124827 +}
124828 +
124829 +
124830 +/*****************************************************************************/
124831 +/* Timers Service Routines */
124832 +/*****************************************************************************/
124833 +/* The time now is in mili sec. resolution */
124834 +uint32_t XX_CurrentTime(void)
124835 +{
124836 + return (jiffies*1000)/HZ;
124837 +}
124838 +
124839 +
124840 +t_Handle XX_CreateTimer(void)
124841 +{
124842 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
124843 + if (p_Timer)
124844 + {
124845 + memset(p_Timer, 0, sizeof(struct timer_list));
124846 + init_timer(p_Timer);
124847 + }
124848 + return (t_Handle)p_Timer;
124849 +}
124850 +
124851 +void XX_FreeTimer(t_Handle h_Timer)
124852 +{
124853 + if (h_Timer)
124854 + XX_Free(h_Timer);
124855 +}
124856 +
124857 +void XX_StartTimer(t_Handle h_Timer,
124858 + uint32_t msecs,
124859 + bool periodic,
124860 + void (*f_TimerExpired)(t_Handle),
124861 + t_Handle h_Arg)
124862 +{
124863 + int tmp_jiffies = (msecs*HZ)/1000;
124864 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124865 +
124866 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
124867 +
124868 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
124869 + p_Timer->data = (unsigned long)h_Arg;
124870 + if ((msecs*HZ)%1000)
124871 + tmp_jiffies++;
124872 + p_Timer->expires = (jiffies + tmp_jiffies);
124873 +
124874 + add_timer((struct timer_list *)h_Timer);
124875 +}
124876 +
124877 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
124878 +{
124879 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124880 +
124881 + p_Timer->data = (unsigned long)data;
124882 +}
124883 +
124884 +t_Handle XX_GetTimerData(t_Handle h_Timer)
124885 +{
124886 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124887 +
124888 + return (t_Handle)p_Timer->data;
124889 +}
124890 +
124891 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
124892 +{
124893 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
124894 +
124895 + return (uint32_t)p_Timer->expires;
124896 +}
124897 +
124898 +void XX_StopTimer(t_Handle h_Timer)
124899 +{
124900 + del_timer((struct timer_list *)h_Timer);
124901 +}
124902 +
124903 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
124904 +{
124905 + int tmp_jiffies = (msecs*HZ)/1000;
124906 +
124907 + if ((msecs*HZ)%1000)
124908 + tmp_jiffies++;
124909 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
124910 +}
124911 +
124912 +int XX_TimerIsActive(t_Handle h_Timer)
124913 +{
124914 + return timer_pending((struct timer_list *)h_Timer);
124915 +}
124916 +
124917 +uint32_t XX_Sleep(uint32_t msecs)
124918 +{
124919 + int tmp_jiffies = (msecs*HZ)/1000;
124920 +
124921 + if ((msecs*HZ)%1000)
124922 + tmp_jiffies++;
124923 + return schedule_timeout(tmp_jiffies);
124924 +}
124925 +
124926 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
124927 +void XX_UDelay(uint32_t usecs)
124928 +{
124929 + udelay(usecs);
124930 +}
124931 +
124932 +/* TODO: verify that these are correct */
124933 +#define MSG_BODY_SIZE 512
124934 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
124935 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
124936 +t_Error XX_SendMessage(char *p_DestAddr,
124937 + uint32_t msgId,
124938 + uint8_t msgBody[MSG_BODY_SIZE],
124939 + t_MsgCompletionCB *f_CompletionCB,
124940 + t_Handle h_CBArg);
124941 +
124942 +typedef struct {
124943 + char *p_Addr;
124944 + t_MsgHandler *f_MsgHandlerCB;
124945 + t_Handle h_Mod;
124946 + t_List node;
124947 +} t_MsgHndlr;
124948 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
124949 +
124950 +LIST(msgHndlrList);
124951 +
124952 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
124953 +{
124954 + uint32_t intFlags;
124955 +
124956 + intFlags = XX_DisableAllIntr();
124957 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
124958 + XX_RestoreAllIntr(intFlags);
124959 +}
124960 +/* TODO: add this for multi-platform support
124961 +static t_MsgHndlr * DequeueMsgHndlr(void)
124962 +{
124963 + t_MsgHndlr *p_MsgHndlr = NULL;
124964 + uint32_t intFlags;
124965 +
124966 + intFlags = XX_DisableAllIntr();
124967 + if (!LIST_IsEmpty(&msgHndlrList))
124968 + {
124969 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
124970 + LIST_DelAndInit(&p_MsgHndlr->node);
124971 + }
124972 + XX_RestoreAllIntr(intFlags);
124973 +
124974 + return p_MsgHndlr;
124975 +}
124976 +*/
124977 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
124978 +{
124979 + t_MsgHndlr *p_MsgHndlr;
124980 + t_List *p_Pos;
124981 +
124982 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
124983 + {
124984 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
124985 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
124986 + return p_MsgHndlr;
124987 + }
124988 +
124989 + return NULL;
124990 +}
124991 +
124992 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
124993 +{
124994 + t_MsgHndlr *p_MsgHndlr;
124995 + uint32_t len;
124996 +
124997 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
124998 + if (!p_MsgHndlr)
124999 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
125000 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
125001 +
125002 + len = strlen(p_Addr);
125003 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
125004 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
125005 +
125006 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
125007 + p_MsgHndlr->h_Mod = h_Mod;
125008 + INIT_LIST(&p_MsgHndlr->node);
125009 + EnqueueMsgHndlr(p_MsgHndlr);
125010 +
125011 + return E_OK;
125012 +}
125013 +
125014 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
125015 +{
125016 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
125017 + if (!p_MsgHndlr)
125018 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
125019 +
125020 + LIST_Del(&p_MsgHndlr->node);
125021 + XX_Free(p_MsgHndlr->p_Addr);
125022 + XX_Free(p_MsgHndlr);
125023 +
125024 + return E_OK;
125025 +}
125026 +
125027 +t_Error XX_SendMessage(char *p_DestAddr,
125028 + uint32_t msgId,
125029 + uint8_t msgBody[MSG_BODY_SIZE],
125030 + t_MsgCompletionCB *f_CompletionCB,
125031 + t_Handle h_CBArg)
125032 +{
125033 + t_Error ans;
125034 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
125035 + if (!p_MsgHndlr)
125036 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
125037 +
125038 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
125039 +
125040 + if (f_CompletionCB)
125041 + f_CompletionCB(h_CBArg, msgBody);
125042 +
125043 + return ans;
125044 +}
125045 +
125046 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
125047 + t_IpcMsgHandler *f_MsgHandler,
125048 + t_Handle h_Module,
125049 + uint32_t replyLength)
125050 +{
125051 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
125052 + return E_OK;
125053 +}
125054 +
125055 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
125056 +{
125057 + UNUSED(addr);
125058 + return E_OK;
125059 +}
125060 +
125061 +
125062 +t_Error XX_IpcSendMessage(t_Handle h_Session,
125063 + uint8_t *p_Msg,
125064 + uint32_t msgLength,
125065 + uint8_t *p_Reply,
125066 + uint32_t *p_ReplyLength,
125067 + t_IpcMsgCompletion *f_Completion,
125068 + t_Handle h_Arg)
125069 +{
125070 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
125071 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
125072 + return E_OK;
125073 +}
125074 +
125075 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
125076 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
125077 +{
125078 + UNUSED(destAddr); UNUSED(srcAddr);
125079 + return E_OK;
125080 +}
125081 +
125082 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
125083 +int GetDeviceIrqNum(int irq)
125084 +{
125085 + struct device_node *iPar;
125086 + struct irq_domain *irqHost;
125087 + uint32_t hwIrq;
125088 +
125089 + /* Get the interrupt controller */
125090 + iPar = of_find_node_by_name(NULL, "mpic");
125091 + hwIrq = 0;
125092 +
125093 + ASSERT_COND(iPar != NULL);
125094 + /* Get the irq host */
125095 + irqHost = irq_find_host(iPar);
125096 + of_node_put(iPar);
125097 +
125098 + /* Create irq mapping */
125099 + return irq_create_mapping(irqHost, hwIrq);
125100 +}
125101 +#else
125102 +#error "kernel not supported!!!"
125103 +#endif /* LINUX_VERSION_CODE */
125104 +
125105 +void * XX_PhysToVirt(physAddress_t addr)
125106 +{
125107 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
125108 +}
125109 +
125110 +physAddress_t XX_VirtToPhys(void * addr)
125111 +{
125112 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
125113 +}
125114 +
125115 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
125116 +{
125117 + uintptr_t *returnCode, tmp;
125118 +
125119 + if (alignment < sizeof(uintptr_t))
125120 + alignment = sizeof(uintptr_t);
125121 + size += alignment + sizeof(returnCode);
125122 + tmp = (uintptr_t)xx_Malloc(size);
125123 + if (tmp == 0)
125124 + return NULL;
125125 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
125126 + *(returnCode - 1) = tmp;
125127 +
125128 + return (void*)returnCode;
125129 +}
125130 +
125131 +void xx_FreeSmart(void *p)
125132 +{
125133 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
125134 +}
125135 --- /dev/null
125136 +++ b/drivers/net/ethernet/freescale/sdk_fman/src/xx/xx_linux.c
125137 @@ -0,0 +1,918 @@
125138 +/*
125139 + * Copyright 2008-2012 Freescale Semiconductor Inc.
125140 + *
125141 + * Redistribution and use in source and binary forms, with or without
125142 + * modification, are permitted provided that the following conditions are met:
125143 + * * Redistributions of source code must retain the above copyright
125144 + * notice, this list of conditions and the following disclaimer.
125145 + * * Redistributions in binary form must reproduce the above copyright
125146 + * notice, this list of conditions and the following disclaimer in the
125147 + * documentation and/or other materials provided with the distribution.
125148 + * * Neither the name of Freescale Semiconductor nor the
125149 + * names of its contributors may be used to endorse or promote products
125150 + * derived from this software without specific prior written permission.
125151 + *
125152 + *
125153 + * ALTERNATIVELY, this software may be distributed under the terms of the
125154 + * GNU General Public License ("GPL") as published by the Free Software
125155 + * Foundation, either version 2 of that License or (at your option) any
125156 + * later version.
125157 + *
125158 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
125159 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
125160 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
125161 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
125162 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
125163 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
125164 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
125165 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
125166 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
125167 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125168 + */
125169 +
125170 +/**************************************************************************//**
125171 + @File xx_linux.c
125172 +
125173 + @Description XX routines implementation for Linux.
125174 +*//***************************************************************************/
125175 +#include <linux/version.h>
125176 +
125177 +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS)
125178 +#define MODVERSIONS
125179 +#endif
125180 +#ifdef MODVERSIONS
125181 +#include <config/modversions.h>
125182 +#endif /* MODVERSIONS */
125183 +
125184 +#include <linux/module.h>
125185 +#include <linux/kernel.h>
125186 +#include <linux/sched.h>
125187 +#include <linux/string.h>
125188 +#include <linux/ptrace.h>
125189 +#include <linux/errno.h>
125190 +#include <linux/ioport.h>
125191 +#include <linux/slab.h>
125192 +#include <linux/interrupt.h>
125193 +#include <linux/fs.h>
125194 +#include <linux/vmalloc.h>
125195 +#include <linux/init.h>
125196 +#include <linux/timer.h>
125197 +#include <linux/spinlock.h>
125198 +#include <linux/delay.h>
125199 +#include <linux/proc_fs.h>
125200 +#include <linux/smp.h>
125201 +#include <linux/of.h>
125202 +#ifdef CONFIG_FMAN_ARM
125203 +#include <linux/irqdomain.h>
125204 +#endif
125205 +
125206 +#include <linux/workqueue.h>
125207 +
125208 +#ifdef BIGPHYSAREA_ENABLE
125209 +#include <linux/bigphysarea.h>
125210 +#endif /* BIGPHYSAREA_ENABLE */
125211 +
125212 +#ifndef CONFIG_FMAN_ARM
125213 +#include <sysdev/fsl_soc.h>
125214 +#endif
125215 +#include <asm/pgtable.h>
125216 +#include <asm/irq.h>
125217 +#include <asm/bitops.h>
125218 +#include <asm/uaccess.h>
125219 +#include <asm/io.h>
125220 +#include <asm/atomic.h>
125221 +#include <asm/string.h>
125222 +#include <asm/byteorder.h>
125223 +#include <asm/page.h>
125224 +
125225 +#include "error_ext.h"
125226 +#include "std_ext.h"
125227 +#include "list_ext.h"
125228 +#include "mm_ext.h"
125229 +#include "sys_io_ext.h"
125230 +#include "xx.h"
125231 +
125232 +
125233 +#define __ERR_MODULE__ MODULE_UNKNOWN
125234 +
125235 +#ifdef BIGPHYSAREA_ENABLE
125236 +#define MAX_ALLOCATION_SIZE 128 * 1024 /* Maximum size allocated with kmalloc is 128K */
125237 +
125238 +
125239 +/* TODO: large allocations => use big phys area */
125240 +/******************************************************************************
125241 + * routine: get_nr_pages
125242 + *
125243 + * description:
125244 + * calculates the number of memory pages for a given size (in bytes)
125245 + *
125246 + * arguments:
125247 + * size - the number of bytes
125248 + *
125249 + * return code:
125250 + * The number of pages
125251 + *
125252 + *****************************************************************************/
125253 +static __inline__ uint32_t get_nr_pages (uint32_t size)
125254 +{
125255 + return (uint32_t)((size >> PAGE_SHIFT) + (size & PAGE_SHIFT ? 1 : 0));
125256 +}
125257 +
125258 +static bool in_big_phys_area (uint32_t addr)
125259 +{
125260 + uint32_t base, size;
125261 +
125262 + bigphysarea_get_details (&base, &size);
125263 + return ((addr >= base) && (addr < base + size));
125264 +}
125265 +#endif /* BIGPHYSAREA_ENABLE */
125266 +
125267 +void * xx_Malloc(uint32_t n)
125268 +{
125269 + void *a;
125270 + uint32_t flags;
125271 +
125272 + flags = XX_DisableAllIntr();
125273 +#ifdef BIGPHYSAREA_ENABLE
125274 + if (n >= MAX_ALLOCATION_SIZE)
125275 + a = (void*)bigphysarea_alloc_pages(get_nr_pages(n), 0, GFP_ATOMIC);
125276 + else
125277 +#endif /* BIGPHYSAREA_ENABLE */
125278 + a = (void *)kmalloc((uint32_t)n, GFP_ATOMIC);
125279 + if (!a)
125280 + XX_Print("No memory for XX_Malloc\n");
125281 + XX_RestoreAllIntr(flags);
125282 +
125283 + return a;
125284 +}
125285 +
125286 +void xx_Free(void *p)
125287 +{
125288 +#ifdef BIGPHYSAREA_ENABLE
125289 + if (in_big_phys_area ((uint32_t)p))
125290 + bigphysarea_free_pages(p);
125291 + else
125292 +#endif /* BIGPHYSAREA_ENABLE */
125293 + kfree(p);
125294 +}
125295 +
125296 +void XX_Exit(int status)
125297 +{
125298 + WARN(1, "\n\nFMD: fatal error, driver can't go on!!!\n\n");
125299 +}
125300 +
125301 +#define BUF_SIZE 512
125302 +void XX_Print(char *str, ...)
125303 +{
125304 + va_list args;
125305 +#ifdef CONFIG_SMP
125306 + char buf[BUF_SIZE];
125307 +#endif /* CONFIG_SMP */
125308 +
125309 + va_start(args, str);
125310 +#ifdef CONFIG_SMP
125311 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
125312 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
125313 + printk(KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
125314 +#else
125315 + vprintk(str, args);
125316 +#endif /* CONFIG_SMP */
125317 + va_end(args);
125318 +}
125319 +
125320 +void XX_Fprint(void *file, char *str, ...)
125321 +{
125322 + va_list args;
125323 +#ifdef CONFIG_SMP
125324 + char buf[BUF_SIZE];
125325 +#endif /* CONFIG_SMP */
125326 +
125327 + va_start(args, str);
125328 +#ifdef CONFIG_SMP
125329 + if (vsnprintf (buf, BUF_SIZE, str, args) >= BUF_SIZE)
125330 + printk(KERN_WARNING "Illegal string to print!\n more than %d characters.\n\tString was not printed completelly.\n", BUF_SIZE);
125331 + printk (KERN_CRIT "cpu%d/%d: %s", raw_smp_processor_id(), NR_CPUS, buf);
125332 +
125333 +#else
125334 + vprintk(str, args);
125335 +#endif /* CONFIG_SMP */
125336 + va_end(args);
125337 +}
125338 +
125339 +#ifdef DEBUG_XX_MALLOC
125340 +typedef void (*t_ffn)(void *);
125341 +typedef struct {
125342 + t_ffn f_free;
125343 + void *mem;
125344 + char *fname;
125345 + int fline;
125346 + uint32_t size;
125347 + t_List node;
125348 +} t_MemDebug;
125349 +#define MEMDBG_OBJECT(p_List) LIST_OBJECT(p_List, t_MemDebug, node)
125350 +
125351 +LIST(memDbgLst);
125352 +
125353 +
125354 +void * XX_MallocDebug(uint32_t size, char *fname, int line)
125355 +{
125356 + void *mem;
125357 + t_MemDebug *p_MemDbg;
125358 +
125359 + p_MemDbg = (t_MemDebug *)xx_Malloc(sizeof(t_MemDebug));
125360 + if (p_MemDbg == NULL)
125361 + return NULL;
125362 +
125363 + mem = xx_Malloc(size);
125364 + if (mem == NULL)
125365 + {
125366 + XX_Free(p_MemDbg);
125367 + return NULL;
125368 + }
125369 +
125370 + INIT_LIST(&p_MemDbg->node);
125371 + p_MemDbg->f_free = xx_Free;
125372 + p_MemDbg->mem = mem;
125373 + p_MemDbg->fname = fname;
125374 + p_MemDbg->fline = line;
125375 + p_MemDbg->size = size+sizeof(t_MemDebug);
125376 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
125377 +
125378 + return mem;
125379 +}
125380 +
125381 +void * XX_MallocSmartDebug(uint32_t size,
125382 + int memPartitionId,
125383 + uint32_t align,
125384 + char *fname,
125385 + int line)
125386 +{
125387 + void *mem;
125388 + t_MemDebug *p_MemDbg;
125389 +
125390 + p_MemDbg = (t_MemDebug *)XX_Malloc(sizeof(t_MemDebug));
125391 + if (p_MemDbg == NULL)
125392 + return NULL;
125393 +
125394 + mem = xx_MallocSmart((uint32_t)size, memPartitionId, align);
125395 + if (mem == NULL)
125396 + {
125397 + XX_Free(p_MemDbg);
125398 + return NULL;
125399 + }
125400 +
125401 + INIT_LIST(&p_MemDbg->node);
125402 + p_MemDbg->f_free = xx_FreeSmart;
125403 + p_MemDbg->mem = mem;
125404 + p_MemDbg->fname = fname;
125405 + p_MemDbg->fline = line;
125406 + p_MemDbg->size = size+sizeof(t_MemDebug);
125407 + LIST_AddToTail(&p_MemDbg->node, &memDbgLst);
125408 +
125409 + return mem;
125410 +}
125411 +
125412 +static void debug_free(void *mem)
125413 +{
125414 + t_List *p_MemDbgLh = NULL;
125415 + t_MemDebug *p_MemDbg;
125416 + bool found = FALSE;
125417 +
125418 + if (LIST_IsEmpty(&memDbgLst))
125419 + {
125420 + REPORT_ERROR(MAJOR, E_ALREADY_FREE, ("Unbalanced free (0x%08x)", mem));
125421 + return;
125422 + }
125423 +
125424 + LIST_FOR_EACH(p_MemDbgLh, &memDbgLst)
125425 + {
125426 + p_MemDbg = MEMDBG_OBJECT(p_MemDbgLh);
125427 + if (p_MemDbg->mem == mem)
125428 + {
125429 + found = TRUE;
125430 + break;
125431 + }
125432 + }
125433 +
125434 + if (!found)
125435 + {
125436 + REPORT_ERROR(MAJOR, E_NOT_FOUND,
125437 + ("Attempt to free unallocated address (0x%08x)",mem));
125438 + dump_stack();
125439 + return;
125440 + }
125441 +
125442 + LIST_Del(p_MemDbgLh);
125443 + p_MemDbg->f_free(mem);
125444 + p_MemDbg->f_free(p_MemDbg);
125445 +}
125446 +
125447 +void XX_FreeSmart(void *p)
125448 +{
125449 + debug_free(p);
125450 +}
125451 +
125452 +
125453 +void XX_Free(void *p)
125454 +{
125455 + debug_free(p);
125456 +}
125457 +
125458 +#else /* not DEBUG_XX_MALLOC */
125459 +void * XX_Malloc(uint32_t size)
125460 +{
125461 + return xx_Malloc(size);
125462 +}
125463 +
125464 +void * XX_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
125465 +{
125466 + return xx_MallocSmart(size,memPartitionId, alignment);
125467 +}
125468 +
125469 +void XX_FreeSmart(void *p)
125470 +{
125471 + xx_FreeSmart(p);
125472 +}
125473 +
125474 +
125475 +void XX_Free(void *p)
125476 +{
125477 + xx_Free(p);
125478 +}
125479 +#endif /* not DEBUG_XX_MALLOC */
125480 +
125481 +
125482 +#if (defined(REPORT_EVENTS) && (REPORT_EVENTS > 0))
125483 +void XX_EventById(uint32_t event, t_Handle appId, uint16_t flags, char *msg)
125484 +{
125485 + e_Event eventCode = (e_Event)event;
125486 +
125487 + UNUSED(eventCode);
125488 + UNUSED(appId);
125489 + UNUSED(flags);
125490 + UNUSED(msg);
125491 +}
125492 +#endif /* (defined(REPORT_EVENTS) && ... */
125493 +
125494 +
125495 +uint32_t XX_DisableAllIntr(void)
125496 +{
125497 + unsigned long flags;
125498 +
125499 +#ifdef local_irq_save_nort
125500 + local_irq_save_nort(flags);
125501 +#else
125502 + local_irq_save(flags);
125503 +#endif
125504 +
125505 + return (uint32_t)flags;
125506 +}
125507 +
125508 +void XX_RestoreAllIntr(uint32_t flags)
125509 +{
125510 +#ifdef local_irq_restore_nort
125511 + local_irq_restore_nort((unsigned long)flags);
125512 +#else
125513 + local_irq_restore((unsigned long)flags);
125514 +#endif
125515 +}
125516 +
125517 +t_Error XX_Call( uint32_t qid, t_Error (* f)(t_Handle), t_Handle id, t_Handle appId, uint16_t flags )
125518 +{
125519 + UNUSED(qid);
125520 + UNUSED(appId);
125521 + UNUSED(flags);
125522 +
125523 + return f(id);
125524 +}
125525 +
125526 +int XX_IsICacheEnable(void)
125527 +{
125528 + return TRUE;
125529 +}
125530 +
125531 +int XX_IsDCacheEnable(void)
125532 +{
125533 + return TRUE;
125534 +}
125535 +
125536 +
125537 +typedef struct {
125538 + t_Isr *f_Isr;
125539 + t_Handle handle;
125540 +} t_InterruptHandler;
125541 +
125542 +
125543 +t_Handle interruptHandlers[0x00010000];
125544 +
125545 +#ifdef CONFIG_FMAN_ARM
125546 +static irqreturn_t LinuxInterruptHandler (int irq, void *dev_id)
125547 +{
125548 + t_InterruptHandler *p_IntrHndl = (t_InterruptHandler *)dev_id;
125549 + p_IntrHndl->f_Isr(p_IntrHndl->handle);
125550 + return IRQ_HANDLED;
125551 +}
125552 +#endif
125553 +
125554 +t_Error XX_SetIntr(int irq, t_Isr *f_Isr, t_Handle handle)
125555 +{
125556 +#ifdef CONFIG_FMAN_ARM
125557 + const char *device;
125558 + t_InterruptHandler *p_IntrHndl;
125559 +
125560 + device = GetDeviceName(irq);
125561 + if (device == NULL)
125562 + RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Interrupt source - %d", irq));
125563 +
125564 + p_IntrHndl = (t_InterruptHandler *)XX_Malloc(sizeof(t_InterruptHandler));
125565 + if (p_IntrHndl == NULL)
125566 + RETURN_ERROR(MAJOR, E_NO_MEMORY, NO_MSG);
125567 + p_IntrHndl->f_Isr = f_Isr;
125568 + p_IntrHndl->handle = handle;
125569 + interruptHandlers[irq] = p_IntrHndl;
125570 +
125571 + if (request_irq(GetDeviceIrqNum(irq), LinuxInterruptHandler, 0, device, p_IntrHndl) < 0)
125572 + RETURN_ERROR(MAJOR, E_BUSY, ("Can't get IRQ %s\n", device));
125573 + disable_irq(GetDeviceIrqNum(irq));
125574 +#endif
125575 + return E_OK;
125576 +}
125577 +
125578 +t_Error XX_FreeIntr(int irq)
125579 +{
125580 + t_InterruptHandler *p_IntrHndl = interruptHandlers[irq];
125581 + free_irq(GetDeviceIrqNum(irq), p_IntrHndl);
125582 + XX_Free(p_IntrHndl);
125583 + interruptHandlers[irq] = 0;
125584 + return E_OK;
125585 +}
125586 +
125587 +t_Error XX_EnableIntr(int irq)
125588 +{
125589 + enable_irq(GetDeviceIrqNum(irq));
125590 + return E_OK;
125591 +}
125592 +
125593 +t_Error XX_DisableIntr(int irq)
125594 +{
125595 + disable_irq(GetDeviceIrqNum(irq));
125596 + return E_OK;
125597 +}
125598 +
125599 +
125600 +/*****************************************************************************/
125601 +/* Tasklet Service Routines */
125602 +/*****************************************************************************/
125603 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
125604 +typedef struct
125605 +{
125606 + t_Handle h_Data;
125607 + void (*f_Callback) (void *);
125608 + struct delayed_work dwork;
125609 +} t_Tasklet;
125610 +
125611 +static void GenericTaskletCallback(struct work_struct *p_Work)
125612 +{
125613 + t_Tasklet *p_Task = container_of(p_Work, t_Tasklet, dwork.work);
125614 +
125615 + p_Task->f_Callback(p_Task->h_Data);
125616 +}
125617 +#endif /* LINUX_VERSION_CODE */
125618 +
125619 +
125620 +t_TaskletHandle XX_InitTasklet (void (*routine)(void *), void *data)
125621 +{
125622 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125623 + struct work_struct *p_Task;
125624 + p_Task = (struct work_struct *)XX_Malloc(sizeof(struct work_struct));
125625 + INIT_WORK(p_Task, routine, data);
125626 +#else
125627 + t_Tasklet *p_Task = (t_Tasklet *)XX_Malloc(sizeof(t_Tasklet));
125628 + p_Task->h_Data = data;
125629 + p_Task->f_Callback = routine;
125630 + INIT_DELAYED_WORK(&p_Task->dwork, GenericTaskletCallback);
125631 +#endif /* LINUX_VERSION_CODE */
125632 +
125633 + return (t_TaskletHandle)p_Task;
125634 +}
125635 +
125636 +
125637 +void XX_FreeTasklet (t_TaskletHandle h_Tasklet)
125638 +{
125639 + if (h_Tasklet)
125640 + XX_Free(h_Tasklet);
125641 +}
125642 +
125643 +int XX_ScheduleTask(t_TaskletHandle h_Tasklet, int immediate)
125644 +{
125645 + int ans;
125646 +
125647 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125648 + if (immediate)
125649 + ans = schedule_work(h_Tasklet);
125650 + else
125651 + ans = schedule_delayed_work(h_Tasklet, 1);
125652 +#else
125653 + if (immediate)
125654 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, 0);
125655 + else
125656 + ans = schedule_delayed_work(&((t_Tasklet *)h_Tasklet)->dwork, HZ);
125657 +#endif /* LINUX_VERSION_CODE */
125658 +
125659 + return ans;
125660 +}
125661 +
125662 +void XX_FlushScheduledTasks(void)
125663 +{
125664 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
125665 + flush_scheduled_tasks();
125666 +#else
125667 + flush_scheduled_work();
125668 +#endif /* LINUX_VERSION_CODE */
125669 +}
125670 +
125671 +int XX_TaskletIsQueued(t_TaskletHandle h_Tasklet)
125672 +{
125673 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125674 + return (int)(((struct work_struct *)h_Tasklet)->pending);
125675 +#else
125676 + return (int)delayed_work_pending(&((t_Tasklet *)h_Tasklet)->dwork);
125677 +#endif /* LINUX_VERSION_CODE */
125678 +}
125679 +
125680 +void XX_SetTaskletData(t_TaskletHandle h_Tasklet, t_Handle data)
125681 +{
125682 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
125683 + ((struct tq_struct *)h_Tasklet)->data = data;
125684 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125685 + ((struct work_struct *)h_Tasklet)->data = data;
125686 +#else
125687 + ((t_Tasklet *)h_Tasklet)->h_Data = data;
125688 +#endif /* LINUX_VERSION_CODE */
125689 +}
125690 +
125691 +t_Handle XX_GetTaskletData(t_TaskletHandle h_Tasklet)
125692 +{
125693 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
125694 + return (t_Handle)(((struct work_struct *)h_Tasklet)->data);
125695 +#else
125696 + return ((t_Tasklet *)h_Tasklet)->h_Data;
125697 +#endif /* LINUX_VERSION_CODE */
125698 +}
125699 +
125700 +
125701 +/*****************************************************************************/
125702 +/* Spinlock Service Routines */
125703 +/*****************************************************************************/
125704 +
125705 +t_Handle XX_InitSpinlock(void)
125706 +{
125707 + spinlock_t *p_Spinlock = (spinlock_t *)XX_Malloc(sizeof(spinlock_t));
125708 + if (!p_Spinlock)
125709 + return NULL;
125710 +
125711 + spin_lock_init(p_Spinlock);
125712 +
125713 + return (t_Handle)p_Spinlock;
125714 +}
125715 +
125716 +void XX_FreeSpinlock(t_Handle h_Spinlock)
125717 +{
125718 + if (h_Spinlock)
125719 + XX_Free(h_Spinlock);
125720 +}
125721 +
125722 +void XX_LockSpinlock(t_Handle h_Spinlock)
125723 +{
125724 + spin_lock((spinlock_t *)h_Spinlock);
125725 +}
125726 +
125727 +void XX_UnlockSpinlock(t_Handle h_Spinlock)
125728 +{
125729 + spin_unlock((spinlock_t *)h_Spinlock);
125730 +}
125731 +
125732 +uint32_t XX_LockIntrSpinlock(t_Handle h_Spinlock)
125733 +{
125734 + unsigned long intrFlags;
125735 + spin_lock_irqsave((spinlock_t *)h_Spinlock, intrFlags);
125736 + return intrFlags;
125737 +}
125738 +
125739 +void XX_UnlockIntrSpinlock(t_Handle h_Spinlock, uint32_t intrFlags)
125740 +{
125741 + spin_unlock_irqrestore((spinlock_t *)h_Spinlock, (unsigned long)intrFlags);
125742 +}
125743 +
125744 +
125745 +/*****************************************************************************/
125746 +/* Timers Service Routines */
125747 +/*****************************************************************************/
125748 +/* The time now is in mili sec. resolution */
125749 +uint32_t XX_CurrentTime(void)
125750 +{
125751 + return (jiffies*1000)/HZ;
125752 +}
125753 +
125754 +
125755 +t_Handle XX_CreateTimer(void)
125756 +{
125757 + struct timer_list *p_Timer = (struct timer_list *)XX_Malloc(sizeof(struct timer_list));
125758 + if (p_Timer)
125759 + {
125760 + memset(p_Timer, 0, sizeof(struct timer_list));
125761 + init_timer(p_Timer);
125762 + }
125763 + return (t_Handle)p_Timer;
125764 +}
125765 +
125766 +void XX_FreeTimer(t_Handle h_Timer)
125767 +{
125768 + if (h_Timer)
125769 + XX_Free(h_Timer);
125770 +}
125771 +
125772 +void XX_StartTimer(t_Handle h_Timer,
125773 + uint32_t msecs,
125774 + bool periodic,
125775 + void (*f_TimerExpired)(t_Handle),
125776 + t_Handle h_Arg)
125777 +{
125778 + int tmp_jiffies = (msecs*HZ)/1000;
125779 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
125780 +
125781 + SANITY_CHECK_RETURN((periodic == FALSE), E_NOT_SUPPORTED);
125782 +
125783 + p_Timer->function = (void (*)(unsigned long))f_TimerExpired;
125784 + p_Timer->data = (unsigned long)h_Arg;
125785 + if ((msecs*HZ)%1000)
125786 + tmp_jiffies++;
125787 + p_Timer->expires = (jiffies + tmp_jiffies);
125788 +
125789 + add_timer((struct timer_list *)h_Timer);
125790 +}
125791 +
125792 +void XX_SetTimerData(t_Handle h_Timer, t_Handle data)
125793 +{
125794 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
125795 +
125796 + p_Timer->data = (unsigned long)data;
125797 +}
125798 +
125799 +t_Handle XX_GetTimerData(t_Handle h_Timer)
125800 +{
125801 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
125802 +
125803 + return (t_Handle)p_Timer->data;
125804 +}
125805 +
125806 +uint32_t XX_GetExpirationTime(t_Handle h_Timer)
125807 +{
125808 + struct timer_list *p_Timer = (struct timer_list *)h_Timer;
125809 +
125810 + return (uint32_t)p_Timer->expires;
125811 +}
125812 +
125813 +void XX_StopTimer(t_Handle h_Timer)
125814 +{
125815 + del_timer((struct timer_list *)h_Timer);
125816 +}
125817 +
125818 +void XX_ModTimer(t_Handle h_Timer, uint32_t msecs)
125819 +{
125820 + int tmp_jiffies = (msecs*HZ)/1000;
125821 +
125822 + if ((msecs*HZ)%1000)
125823 + tmp_jiffies++;
125824 + mod_timer((struct timer_list *)h_Timer, jiffies + tmp_jiffies);
125825 +}
125826 +
125827 +int XX_TimerIsActive(t_Handle h_Timer)
125828 +{
125829 + return timer_pending((struct timer_list *)h_Timer);
125830 +}
125831 +
125832 +uint32_t XX_Sleep(uint32_t msecs)
125833 +{
125834 + int tmp_jiffies = (msecs*HZ)/1000;
125835 +
125836 + if ((msecs*HZ)%1000)
125837 + tmp_jiffies++;
125838 + return schedule_timeout(tmp_jiffies);
125839 +}
125840 +
125841 +/*BEWARE!!!!! UDelay routine is BUSY WAITTING!!!!!*/
125842 +void XX_UDelay(uint32_t usecs)
125843 +{
125844 + udelay(usecs);
125845 +}
125846 +
125847 +/* TODO: verify that these are correct */
125848 +#define MSG_BODY_SIZE 512
125849 +typedef t_Error (t_MsgHandler) (t_Handle h_Mod, uint32_t msgId, uint8_t msgBody[MSG_BODY_SIZE]);
125850 +typedef void (t_MsgCompletionCB) (t_Handle h_Arg, uint8_t msgBody[MSG_BODY_SIZE]);
125851 +t_Error XX_SendMessage(char *p_DestAddr,
125852 + uint32_t msgId,
125853 + uint8_t msgBody[MSG_BODY_SIZE],
125854 + t_MsgCompletionCB *f_CompletionCB,
125855 + t_Handle h_CBArg);
125856 +
125857 +typedef struct {
125858 + char *p_Addr;
125859 + t_MsgHandler *f_MsgHandlerCB;
125860 + t_Handle h_Mod;
125861 + t_List node;
125862 +} t_MsgHndlr;
125863 +#define MSG_HNDLR_OBJECT(ptr) LIST_OBJECT(ptr, t_MsgHndlr, node)
125864 +
125865 +LIST(msgHndlrList);
125866 +
125867 +static void EnqueueMsgHndlr(t_MsgHndlr *p_MsgHndlr)
125868 +{
125869 + uint32_t intFlags;
125870 +
125871 + intFlags = XX_DisableAllIntr();
125872 + LIST_AddToTail(&p_MsgHndlr->node, &msgHndlrList);
125873 + XX_RestoreAllIntr(intFlags);
125874 +}
125875 +/* TODO: add this for multi-platform support
125876 +static t_MsgHndlr * DequeueMsgHndlr(void)
125877 +{
125878 + t_MsgHndlr *p_MsgHndlr = NULL;
125879 + uint32_t intFlags;
125880 +
125881 + intFlags = XX_DisableAllIntr();
125882 + if (!LIST_IsEmpty(&msgHndlrList))
125883 + {
125884 + p_MsgHndlr = MSG_HNDLR_OBJECT(msgHndlrList.p_Next);
125885 + LIST_DelAndInit(&p_MsgHndlr->node);
125886 + }
125887 + XX_RestoreAllIntr(intFlags);
125888 +
125889 + return p_MsgHndlr;
125890 +}
125891 +*/
125892 +static t_MsgHndlr * FindMsgHndlr(char *p_Addr)
125893 +{
125894 + t_MsgHndlr *p_MsgHndlr;
125895 + t_List *p_Pos;
125896 +
125897 + LIST_FOR_EACH(p_Pos, &msgHndlrList)
125898 + {
125899 + p_MsgHndlr = MSG_HNDLR_OBJECT(p_Pos);
125900 + if (strstr(p_MsgHndlr->p_Addr, p_Addr))
125901 + return p_MsgHndlr;
125902 + }
125903 +
125904 + return NULL;
125905 +}
125906 +
125907 +t_Error XX_RegisterMessageHandler (char *p_Addr, t_MsgHandler *f_MsgHandlerCB, t_Handle h_Mod)
125908 +{
125909 + t_MsgHndlr *p_MsgHndlr;
125910 + uint32_t len;
125911 +
125912 + p_MsgHndlr = (t_MsgHndlr*)XX_Malloc(sizeof(t_MsgHndlr));
125913 + if (!p_MsgHndlr)
125914 + RETURN_ERROR(MINOR, E_NO_MEMORY, ("message handler object!!!"));
125915 + memset(p_MsgHndlr, 0, sizeof(t_MsgHndlr));
125916 +
125917 + len = strlen(p_Addr);
125918 + p_MsgHndlr->p_Addr = (char*)XX_Malloc(len+1);
125919 + strncpy(p_MsgHndlr->p_Addr,p_Addr, (uint32_t)(len+1));
125920 +
125921 + p_MsgHndlr->f_MsgHandlerCB = f_MsgHandlerCB;
125922 + p_MsgHndlr->h_Mod = h_Mod;
125923 + INIT_LIST(&p_MsgHndlr->node);
125924 + EnqueueMsgHndlr(p_MsgHndlr);
125925 +
125926 + return E_OK;
125927 +}
125928 +
125929 +t_Error XX_UnregisterMessageHandler (char *p_Addr)
125930 +{
125931 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_Addr);
125932 + if (!p_MsgHndlr)
125933 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
125934 +
125935 + LIST_Del(&p_MsgHndlr->node);
125936 + XX_Free(p_MsgHndlr->p_Addr);
125937 + XX_Free(p_MsgHndlr);
125938 +
125939 + return E_OK;
125940 +}
125941 +
125942 +t_Error XX_SendMessage(char *p_DestAddr,
125943 + uint32_t msgId,
125944 + uint8_t msgBody[MSG_BODY_SIZE],
125945 + t_MsgCompletionCB *f_CompletionCB,
125946 + t_Handle h_CBArg)
125947 +{
125948 + t_Error ans;
125949 + t_MsgHndlr *p_MsgHndlr = FindMsgHndlr(p_DestAddr);
125950 + if (!p_MsgHndlr)
125951 + RETURN_ERROR(MINOR, E_NO_DEVICE, ("message handler not found in list!!!"));
125952 +
125953 + ans = p_MsgHndlr->f_MsgHandlerCB(p_MsgHndlr->h_Mod, msgId, msgBody);
125954 +
125955 + if (f_CompletionCB)
125956 + f_CompletionCB(h_CBArg, msgBody);
125957 +
125958 + return ans;
125959 +}
125960 +
125961 +t_Error XX_IpcRegisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH],
125962 + t_IpcMsgHandler *f_MsgHandler,
125963 + t_Handle h_Module,
125964 + uint32_t replyLength)
125965 +{
125966 + UNUSED(addr);UNUSED(f_MsgHandler);UNUSED(h_Module);UNUSED(replyLength);
125967 + return E_OK;
125968 +}
125969 +
125970 +t_Error XX_IpcUnregisterMsgHandler(char addr[XX_IPC_MAX_ADDR_NAME_LENGTH])
125971 +{
125972 + UNUSED(addr);
125973 + return E_OK;
125974 +}
125975 +
125976 +
125977 +t_Error XX_IpcSendMessage(t_Handle h_Session,
125978 + uint8_t *p_Msg,
125979 + uint32_t msgLength,
125980 + uint8_t *p_Reply,
125981 + uint32_t *p_ReplyLength,
125982 + t_IpcMsgCompletion *f_Completion,
125983 + t_Handle h_Arg)
125984 +{
125985 + UNUSED(h_Session); UNUSED(p_Msg); UNUSED(msgLength); UNUSED(p_Reply);
125986 + UNUSED(p_ReplyLength); UNUSED(f_Completion); UNUSED(h_Arg);
125987 + return E_OK;
125988 +}
125989 +
125990 +t_Handle XX_IpcInitSession(char destAddr[XX_IPC_MAX_ADDR_NAME_LENGTH],
125991 + char srcAddr[XX_IPC_MAX_ADDR_NAME_LENGTH])
125992 +{
125993 + UNUSED(destAddr); UNUSED(srcAddr);
125994 + return E_OK;
125995 +}
125996 +
125997 +/*Forced to introduce due to PRINT_FMT_PARAMS define*/
125998 +uint32_t E500_GetId(void)
125999 +{
126000 + return raw_smp_processor_id();
126001 +}
126002 +
126003 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
126004 +int GetDeviceIrqNum(int irq)
126005 +{
126006 + struct device_node *iPar;
126007 + struct irq_domain *irqHost;
126008 + uint32_t hwIrq;
126009 +
126010 + /* Get the interrupt controller */
126011 + iPar = of_find_node_by_name(NULL, "mpic");
126012 + hwIrq = 0;
126013 +
126014 + ASSERT_COND(iPar != NULL);
126015 + /* Get the irq host */
126016 + irqHost = irq_find_host(iPar);
126017 + of_node_put(iPar);
126018 +
126019 + /* Create irq mapping */
126020 + return irq_create_mapping(irqHost, hwIrq);
126021 +}
126022 +#else
126023 +#error "kernel not supported!!!"
126024 +#endif /* LINUX_VERSION_CODE */
126025 +
126026 +void * XX_PhysToVirt(physAddress_t addr)
126027 +{
126028 + return UINT_TO_PTR(SYS_PhysToVirt((uint64_t)addr));
126029 +}
126030 +
126031 +physAddress_t XX_VirtToPhys(void * addr)
126032 +{
126033 + return (physAddress_t)SYS_VirtToPhys(PTR_TO_UINT(addr));
126034 +}
126035 +
126036 +void * xx_MallocSmart(uint32_t size, int memPartitionId, uint32_t alignment)
126037 +{
126038 + uintptr_t *returnCode, tmp;
126039 +
126040 + if (alignment < sizeof(uintptr_t))
126041 + alignment = sizeof(uintptr_t);
126042 + size += alignment + sizeof(returnCode);
126043 + tmp = (uintptr_t)xx_Malloc(size);
126044 + if (tmp == 0)
126045 + return NULL;
126046 + returnCode = (uintptr_t*)((tmp + alignment + sizeof(returnCode)) & ~((uintptr_t)alignment - 1));
126047 + *(returnCode - 1) = tmp;
126048 +
126049 + return (void*)returnCode;
126050 +}
126051 +
126052 +void xx_FreeSmart(void *p)
126053 +{
126054 + xx_Free((void*)(*((uintptr_t *)(p) - 1)));
126055 +}
126056 --- /dev/null
126057 +++ b/drivers/staging/fsl_qbman/Kconfig
126058 @@ -0,0 +1,228 @@
126059 +config FSL_SDK_DPA
126060 + bool "Freescale Datapath Queue and Buffer management"
126061 + depends on !FSL_DPAA
126062 + select FSL_QMAN_FQ_LOOKUP if PPC64
126063 + select FSL_QMAN_FQ_LOOKUP if ARM64
126064 +
126065 +
126066 +menu "Freescale Datapath QMan/BMan options"
126067 + depends on FSL_SDK_DPA
126068 +
126069 +config FSL_DPA_CHECKING
126070 + bool "additional driver checking"
126071 + default n
126072 + ---help---
126073 + Compiles in additional checks to sanity-check the drivers and any
126074 + use of it by other code. Not recommended for performance.
126075 +
126076 +config FSL_DPA_CAN_WAIT
126077 + bool
126078 + default y
126079 +
126080 +config FSL_DPA_CAN_WAIT_SYNC
126081 + bool
126082 + default y
126083 +
126084 +config FSL_DPA_PIRQ_FAST
126085 + bool
126086 + default y
126087 +
126088 +config FSL_DPA_PIRQ_SLOW
126089 + bool
126090 + default y
126091 +
126092 +config FSL_DPA_PORTAL_SHARE
126093 + bool
126094 + default y
126095 +
126096 +config FSL_SDK_BMAN
126097 + bool "Freescale Buffer Manager (BMan) support"
126098 + default y
126099 +
126100 +if FSL_SDK_BMAN
126101 +
126102 +config FSL_BMAN_CONFIG
126103 + bool "BMan device management"
126104 + default y
126105 + ---help---
126106 + If this linux image is running natively, you need this option. If this
126107 + linux image is running as a guest OS under the hypervisor, only one
126108 + guest OS ("the control plane") needs this option.
126109 +
126110 +config FSL_BMAN_TEST
126111 + tristate "BMan self-tests"
126112 + default n
126113 + ---help---
126114 + This option compiles self-test code for BMan.
126115 +
126116 +config FSL_BMAN_TEST_HIGH
126117 + bool "BMan high-level self-test"
126118 + depends on FSL_BMAN_TEST
126119 + default y
126120 + ---help---
126121 + This requires the presence of cpu-affine portals, and performs
126122 + high-level API testing with them (whichever portal(s) are affine to
126123 + the cpu(s) the test executes on).
126124 +
126125 +config FSL_BMAN_TEST_THRESH
126126 + bool "BMan threshold test"
126127 + depends on FSL_BMAN_TEST
126128 + default y
126129 + ---help---
126130 + Multi-threaded (SMP) test of BMan pool depletion. A pool is seeded
126131 + before multiple threads (one per cpu) create pool objects to track
126132 + depletion state changes. The pool is then drained to empty by a
126133 + "drainer" thread, and the other threads that they observe exactly
126134 + the depletion state changes that are expected.
126135 +
126136 +config FSL_BMAN_DEBUGFS
126137 + tristate "BMan debugfs interface"
126138 + depends on DEBUG_FS
126139 + default y
126140 + ---help---
126141 + This option compiles debugfs code for BMan.
126142 +
126143 +endif # FSL_SDK_BMAN
126144 +
126145 +config FSL_SDK_QMAN
126146 + bool "Freescale Queue Manager (QMan) support"
126147 + default y
126148 +
126149 +if FSL_SDK_QMAN
126150 +
126151 +config FSL_QMAN_POLL_LIMIT
126152 + int
126153 + default 32
126154 +
126155 +config FSL_QMAN_CONFIG
126156 + bool "QMan device management"
126157 + default y
126158 + ---help---
126159 + If this linux image is running natively, you need this option. If this
126160 + linux image is running as a guest OS under the hypervisor, only one
126161 + guest OS ("the control plane") needs this option.
126162 +
126163 +config FSL_QMAN_TEST
126164 + tristate "QMan self-tests"
126165 + default n
126166 + ---help---
126167 + This option compiles self-test code for QMan.
126168 +
126169 +config FSL_QMAN_TEST_STASH_POTATO
126170 + bool "QMan 'hot potato' data-stashing self-test"
126171 + depends on FSL_QMAN_TEST
126172 + default y
126173 + ---help---
126174 + This performs a "hot potato" style test enqueuing/dequeuing a frame
126175 + across a series of FQs scheduled to different portals (and cpus), with
126176 + DQRR, data and context stashing always on.
126177 +
126178 +config FSL_QMAN_TEST_HIGH
126179 + bool "QMan high-level self-test"
126180 + depends on FSL_QMAN_TEST
126181 + default y
126182 + ---help---
126183 + This requires the presence of cpu-affine portals, and performs
126184 + high-level API testing with them (whichever portal(s) are affine to
126185 + the cpu(s) the test executes on).
126186 +
126187 +config FSL_QMAN_DEBUGFS
126188 + tristate "QMan debugfs interface"
126189 + depends on DEBUG_FS
126190 + default y
126191 + ---help---
126192 + This option compiles debugfs code for QMan.
126193 +
126194 +# H/w settings that can be hard-coded for now.
126195 +config FSL_QMAN_FQD_SZ
126196 + int "size of Frame Queue Descriptor region"
126197 + default 10
126198 + ---help---
126199 + This is the size of the FQD region defined as: PAGE_SIZE * (2^value)
126200 + ex: 10 => PAGE_SIZE * (2^10)
126201 + Note: Default device-trees now require minimum Kconfig setting of 10.
126202 +
126203 +config FSL_QMAN_PFDR_SZ
126204 + int "size of the PFDR pool"
126205 + default 13
126206 + ---help---
126207 + This is the size of the PFDR pool defined as: PAGE_SIZE * (2^value)
126208 + ex: 13 => PAGE_SIZE * (2^13)
126209 +
126210 +# Corenet initiator settings. Stash request queues are 4-deep to match cores'
126211 +# ability to snart. Stash priority is 3, other priorities are 2.
126212 +config FSL_QMAN_CI_SCHED_CFG_SRCCIV
126213 + int
126214 + depends on FSL_QMAN_CONFIG
126215 + default 4
126216 +config FSL_QMAN_CI_SCHED_CFG_SRQ_W
126217 + int
126218 + depends on FSL_QMAN_CONFIG
126219 + default 3
126220 +config FSL_QMAN_CI_SCHED_CFG_RW_W
126221 + int
126222 + depends on FSL_QMAN_CONFIG
126223 + default 2
126224 +config FSL_QMAN_CI_SCHED_CFG_BMAN_W
126225 + int
126226 + depends on FSL_QMAN_CONFIG
126227 + default 2
126228 +
126229 +# portal interrupt settings
126230 +config FSL_QMAN_PIRQ_DQRR_ITHRESH
126231 + int
126232 + default 12
126233 +config FSL_QMAN_PIRQ_MR_ITHRESH
126234 + int
126235 + default 4
126236 +config FSL_QMAN_PIRQ_IPERIOD
126237 + int
126238 + default 100
126239 +
126240 +# 64 bit kernel support
126241 +config FSL_QMAN_FQ_LOOKUP
126242 + bool
126243 + default n
126244 +
126245 +config QMAN_CEETM_UPDATE_PERIOD
126246 + int "Token update period for shaping, in nanoseconds"
126247 + default 1000
126248 + ---help---
126249 + Traffic shaping works by performing token calculations (using
126250 + credits) on shaper instances periodically. This update period
126251 + sets the granularity for how often those token rate credit
126252 + updates are performed, and thus determines the accuracy and
126253 + range of traffic rates that can be configured by users. The
126254 + reference manual recommends a 1 microsecond period as providing
126255 + a good balance between granularity and range.
126256 +
126257 + Unless you know what you are doing, leave this value at its default.
126258 +
126259 +config FSL_QMAN_INIT_TIMEOUT
126260 + int "timeout for qman init stage, in seconds"
126261 + default 10
126262 + ---help---
126263 + The timeout setting to quit the initialization loop for non-control
126264 + partition in case the control partition fails to boot-up.
126265 +
126266 +endif # FSL_SDK_QMAN
126267 +
126268 +config FSL_USDPAA
126269 + bool "Freescale USDPAA process driver"
126270 + depends on FSL_SDK_DPA
126271 + default y
126272 + ---help---
126273 + This driver provides user-space access to kernel-managed
126274 + resource interfaces for USDPAA applications, on the assumption
126275 + that each process will open this device once. Specifically, this
126276 + device exposes functionality that would be awkward if exposed
126277 + via the portal devices - ie. this device exposes functionality
126278 + that is inherently process-wide rather than portal-specific.
126279 + This device is necessary for obtaining access to DMA memory and
126280 + for allocation of Qman and Bman resources. In short, if you wish
126281 + to use USDPAA applications, you need this.
126282 +
126283 + If unsure, say Y.
126284 +
126285 +
126286 +endmenu
126287 --- /dev/null
126288 +++ b/drivers/staging/fsl_qbman/Makefile
126289 @@ -0,0 +1,28 @@
126290 +subdir-ccflags-y := -Werror
126291 +
126292 +# Common
126293 +obj-$(CONFIG_FSL_SDK_DPA) += dpa_alloc.o
126294 +obj-$(CONFIG_FSL_SDK_DPA) += qbman_driver.o
126295 +
126296 +# Bman
126297 +obj-$(CONFIG_FSL_SDK_BMAN) += bman_high.o
126298 +obj-$(CONFIG_FSL_BMAN_CONFIG) += bman_config.o bman_driver.o
126299 +obj-$(CONFIG_FSL_BMAN_TEST) += bman_tester.o
126300 +obj-$(CONFIG_FSL_BMAN_DEBUGFS) += bman_debugfs_interface.o
126301 +bman_tester-y = bman_test.o
126302 +bman_tester-$(CONFIG_FSL_BMAN_TEST_HIGH) += bman_test_high.o
126303 +bman_tester-$(CONFIG_FSL_BMAN_TEST_THRESH) += bman_test_thresh.o
126304 +bman_debugfs_interface-y = bman_debugfs.o
126305 +
126306 +# Qman
126307 +obj-$(CONFIG_FSL_SDK_QMAN) += qman_high.o qman_utility.o
126308 +obj-$(CONFIG_FSL_QMAN_CONFIG) += qman_config.o qman_driver.o
126309 +obj-$(CONFIG_FSL_QMAN_TEST) += qman_tester.o
126310 +qman_tester-y = qman_test.o
126311 +qman_tester-$(CONFIG_FSL_QMAN_TEST_STASH_POTATO) += qman_test_hotpotato.o
126312 +qman_tester-$(CONFIG_FSL_QMAN_TEST_HIGH) += qman_test_high.o
126313 +obj-$(CONFIG_FSL_QMAN_DEBUGFS) += qman_debugfs_interface.o
126314 +qman_debugfs_interface-y = qman_debugfs.o
126315 +
126316 +# USDPAA
126317 +obj-$(CONFIG_FSL_USDPAA) += fsl_usdpaa.o fsl_usdpaa_irq.o
126318 --- /dev/null
126319 +++ b/drivers/staging/fsl_qbman/bman_config.c
126320 @@ -0,0 +1,720 @@
126321 +/* Copyright (c) 2009-2012 Freescale Semiconductor, Inc.
126322 + *
126323 + * Redistribution and use in source and binary forms, with or without
126324 + * modification, are permitted provided that the following conditions are met:
126325 + * * Redistributions of source code must retain the above copyright
126326 + * notice, this list of conditions and the following disclaimer.
126327 + * * Redistributions in binary form must reproduce the above copyright
126328 + * notice, this list of conditions and the following disclaimer in the
126329 + * documentation and/or other materials provided with the distribution.
126330 + * * Neither the name of Freescale Semiconductor nor the
126331 + * names of its contributors may be used to endorse or promote products
126332 + * derived from this software without specific prior written permission.
126333 + *
126334 + *
126335 + * ALTERNATIVELY, this software may be distributed under the terms of the
126336 + * GNU General Public License ("GPL") as published by the Free Software
126337 + * Foundation, either version 2 of that License or (at your option) any
126338 + * later version.
126339 + *
126340 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
126341 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
126342 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
126343 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
126344 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126345 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
126346 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
126347 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
126348 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
126349 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
126350 + */
126351 +
126352 +#include <asm/cacheflush.h>
126353 +#include "bman_private.h"
126354 +#include <linux/of_reserved_mem.h>
126355 +
126356 +/* Last updated for v00.79 of the BG */
126357 +
126358 +struct bman;
126359 +
126360 +/* Register offsets */
126361 +#define REG_POOL_SWDET(n) (0x0000 + ((n) * 0x04))
126362 +#define REG_POOL_HWDET(n) (0x0100 + ((n) * 0x04))
126363 +#define REG_POOL_SWDXT(n) (0x0200 + ((n) * 0x04))
126364 +#define REG_POOL_HWDXT(n) (0x0300 + ((n) * 0x04))
126365 +#define REG_POOL_CONTENT(n) (0x0600 + ((n) * 0x04))
126366 +#define REG_FBPR_FPC 0x0800
126367 +#define REG_STATE_IDLE 0x960
126368 +#define REG_STATE_STOP 0x964
126369 +#define REG_ECSR 0x0a00
126370 +#define REG_ECIR 0x0a04
126371 +#define REG_EADR 0x0a08
126372 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
126373 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
126374 +#define REG_IP_REV_1 0x0bf8
126375 +#define REG_IP_REV_2 0x0bfc
126376 +#define REG_FBPR_BARE 0x0c00
126377 +#define REG_FBPR_BAR 0x0c04
126378 +#define REG_FBPR_AR 0x0c10
126379 +#define REG_SRCIDR 0x0d04
126380 +#define REG_LIODNR 0x0d08
126381 +#define REG_ERR_ISR 0x0e00 /* + "enum bm_isr_reg" */
126382 +
126383 +/* Used by all error interrupt registers except 'inhibit' */
126384 +#define BM_EIRQ_IVCI 0x00000010 /* Invalid Command Verb */
126385 +#define BM_EIRQ_FLWI 0x00000008 /* FBPR Low Watermark */
126386 +#define BM_EIRQ_MBEI 0x00000004 /* Multi-bit ECC Error */
126387 +#define BM_EIRQ_SBEI 0x00000002 /* Single-bit ECC Error */
126388 +#define BM_EIRQ_BSCN 0x00000001 /* pool State Change Notification */
126389 +
126390 +/* BMAN_ECIR valid error bit */
126391 +#define PORTAL_ECSR_ERR (BM_EIRQ_IVCI)
126392 +
126393 +union bman_ecir {
126394 + u32 ecir_raw;
126395 + struct {
126396 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
126397 + u32 __reserved1:4;
126398 + u32 portal_num:4;
126399 + u32 __reserved2:12;
126400 + u32 numb:4;
126401 + u32 __reserved3:2;
126402 + u32 pid:6;
126403 +#else
126404 + u32 pid:6;
126405 + u32 __reserved3:2;
126406 + u32 numb:4;
126407 + u32 __reserved2:12;
126408 + u32 portal_num:4;
126409 + u32 __reserved1:4;
126410 +#endif
126411 + } __packed info;
126412 +};
126413 +
126414 +union bman_eadr {
126415 + u32 eadr_raw;
126416 + struct {
126417 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
126418 + u32 __reserved1:5;
126419 + u32 memid:3;
126420 + u32 __reserved2:14;
126421 + u32 eadr:10;
126422 +#else
126423 + u32 eadr:10;
126424 + u32 __reserved2:14;
126425 + u32 memid:3;
126426 + u32 __reserved1:5;
126427 +#endif
126428 + } __packed info;
126429 +};
126430 +
126431 +struct bman_hwerr_txt {
126432 + u32 mask;
126433 + const char *txt;
126434 +};
126435 +
126436 +#define BMAN_HWE_TXT(a, b) { .mask = BM_EIRQ_##a, .txt = b }
126437 +
126438 +static const struct bman_hwerr_txt bman_hwerr_txts[] = {
126439 + BMAN_HWE_TXT(IVCI, "Invalid Command Verb"),
126440 + BMAN_HWE_TXT(FLWI, "FBPR Low Watermark"),
126441 + BMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
126442 + BMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
126443 + BMAN_HWE_TXT(BSCN, "Pool State Change Notification"),
126444 +};
126445 +#define BMAN_HWE_COUNT (sizeof(bman_hwerr_txts)/sizeof(struct bman_hwerr_txt))
126446 +
126447 +struct bman_error_info_mdata {
126448 + u16 addr_mask;
126449 + u16 bits;
126450 + const char *txt;
126451 +};
126452 +
126453 +#define BMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
126454 +static const struct bman_error_info_mdata error_mdata[] = {
126455 + BMAN_ERR_MDATA(0x03FF, 192, "Stockpile memory"),
126456 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 1"),
126457 + BMAN_ERR_MDATA(0x00FF, 256, "SW portal ring memory port 2"),
126458 +};
126459 +#define BMAN_ERR_MDATA_COUNT \
126460 + (sizeof(error_mdata)/sizeof(struct bman_error_info_mdata))
126461 +
126462 +/* Add this in Kconfig */
126463 +#define BMAN_ERRS_TO_UNENABLE (BM_EIRQ_FLWI)
126464 +
126465 +/**
126466 + * bm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
126467 + * @v: for accessors that write values, this is the 32-bit value
126468 + *
126469 + * Manipulates BMAN_ERR_ISR, BMAN_ERR_IER, BMAN_ERR_ISDR, BMAN_ERR_IIR. All
126470 + * manipulations except bm_err_isr_[un]inhibit() use 32-bit masks composed of
126471 + * the BM_EIRQ_*** definitions. Note that "bm_err_isr_enable_write" means
126472 + * "write the enable register" rather than "enable the write register"!
126473 + */
126474 +#define bm_err_isr_status_read(bm) \
126475 + __bm_err_isr_read(bm, bm_isr_status)
126476 +#define bm_err_isr_status_clear(bm, m) \
126477 + __bm_err_isr_write(bm, bm_isr_status, m)
126478 +#define bm_err_isr_enable_read(bm) \
126479 + __bm_err_isr_read(bm, bm_isr_enable)
126480 +#define bm_err_isr_enable_write(bm, v) \
126481 + __bm_err_isr_write(bm, bm_isr_enable, v)
126482 +#define bm_err_isr_disable_read(bm) \
126483 + __bm_err_isr_read(bm, bm_isr_disable)
126484 +#define bm_err_isr_disable_write(bm, v) \
126485 + __bm_err_isr_write(bm, bm_isr_disable, v)
126486 +#define bm_err_isr_inhibit(bm) \
126487 + __bm_err_isr_write(bm, bm_isr_inhibit, 1)
126488 +#define bm_err_isr_uninhibit(bm) \
126489 + __bm_err_isr_write(bm, bm_isr_inhibit, 0)
126490 +
126491 +/*
126492 + * TODO: unimplemented registers
126493 + *
126494 + * BMAN_POOLk_SDCNT, BMAN_POOLk_HDCNT, BMAN_FULT,
126495 + * BMAN_VLDPL, BMAN_EECC, BMAN_SBET, BMAN_EINJ
126496 + */
126497 +
126498 +/* Encapsulate "struct bman *" as a cast of the register space address. */
126499 +
126500 +static struct bman *bm_create(void *regs)
126501 +{
126502 + return (struct bman *)regs;
126503 +}
126504 +
126505 +static inline u32 __bm_in(struct bman *bm, u32 offset)
126506 +{
126507 + return in_be32((void *)bm + offset);
126508 +}
126509 +static inline void __bm_out(struct bman *bm, u32 offset, u32 val)
126510 +{
126511 + out_be32((void *)bm + offset, val);
126512 +}
126513 +#define bm_in(reg) __bm_in(bm, REG_##reg)
126514 +#define bm_out(reg, val) __bm_out(bm, REG_##reg, val)
126515 +
126516 +static u32 __bm_err_isr_read(struct bman *bm, enum bm_isr_reg n)
126517 +{
126518 + return __bm_in(bm, REG_ERR_ISR + (n << 2));
126519 +}
126520 +
126521 +static void __bm_err_isr_write(struct bman *bm, enum bm_isr_reg n, u32 val)
126522 +{
126523 + __bm_out(bm, REG_ERR_ISR + (n << 2), val);
126524 +}
126525 +
126526 +static void bm_get_version(struct bman *bm, u16 *id, u8 *major, u8 *minor)
126527 +{
126528 + u32 v = bm_in(IP_REV_1);
126529 + *id = (v >> 16);
126530 + *major = (v >> 8) & 0xff;
126531 + *minor = v & 0xff;
126532 +}
126533 +
126534 +static u32 __generate_thresh(u32 val, int roundup)
126535 +{
126536 + u32 e = 0; /* co-efficient, exponent */
126537 + int oddbit = 0;
126538 + while (val > 0xff) {
126539 + oddbit = val & 1;
126540 + val >>= 1;
126541 + e++;
126542 + if (roundup && oddbit)
126543 + val++;
126544 + }
126545 + DPA_ASSERT(e < 0x10);
126546 + return val | (e << 8);
126547 +}
126548 +
126549 +static void bm_set_pool(struct bman *bm, u8 pool, u32 swdet, u32 swdxt,
126550 + u32 hwdet, u32 hwdxt)
126551 +{
126552 + DPA_ASSERT(pool < bman_pool_max);
126553 + bm_out(POOL_SWDET(pool), __generate_thresh(swdet, 0));
126554 + bm_out(POOL_SWDXT(pool), __generate_thresh(swdxt, 1));
126555 + bm_out(POOL_HWDET(pool), __generate_thresh(hwdet, 0));
126556 + bm_out(POOL_HWDXT(pool), __generate_thresh(hwdxt, 1));
126557 +}
126558 +
126559 +static void bm_set_memory(struct bman *bm, u64 ba, int prio, u32 size)
126560 +{
126561 + u32 exp = ilog2(size);
126562 + /* choke if size isn't within range */
126563 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
126564 + is_power_of_2(size));
126565 + /* choke if '[e]ba' has lower-alignment than 'size' */
126566 + DPA_ASSERT(!(ba & (size - 1)));
126567 + bm_out(FBPR_BARE, upper_32_bits(ba));
126568 + bm_out(FBPR_BAR, lower_32_bits(ba));
126569 + bm_out(FBPR_AR, (prio ? 0x40000000 : 0) | (exp - 1));
126570 +}
126571 +
126572 +/*****************/
126573 +/* Config driver */
126574 +/*****************/
126575 +
126576 +/* TODO: Kconfig these? */
126577 +#define DEFAULT_FBPR_SZ (PAGE_SIZE << 12)
126578 +
126579 +/* We support only one of these. */
126580 +static struct bman *bm;
126581 +static struct device_node *bm_node;
126582 +
126583 +/* And this state belongs to 'bm'. It is set during fsl_bman_init(), but used
126584 + * during bman_init_ccsr(). */
126585 +static dma_addr_t fbpr_a;
126586 +static size_t fbpr_sz = DEFAULT_FBPR_SZ;
126587 +
126588 +static int bman_fbpr(struct reserved_mem *rmem)
126589 +{
126590 + fbpr_a = rmem->base;
126591 + fbpr_sz = rmem->size;
126592 +
126593 + WARN_ON(!(fbpr_a && fbpr_sz));
126594 +
126595 + return 0;
126596 +}
126597 +RESERVEDMEM_OF_DECLARE(bman_fbpr, "fsl,bman-fbpr", bman_fbpr);
126598 +
126599 +static int __init fsl_bman_init(struct device_node *node)
126600 +{
126601 + struct resource res;
126602 + u32 __iomem *regs;
126603 + const char *s;
126604 + int ret, standby = 0;
126605 + u16 id;
126606 + u8 major, minor;
126607 +
126608 + ret = of_address_to_resource(node, 0, &res);
126609 + if (ret) {
126610 + pr_err("Can't get %s property 'reg'\n",
126611 + node->full_name);
126612 + return ret;
126613 + }
126614 + s = of_get_property(node, "fsl,hv-claimable", &ret);
126615 + if (s && !strcmp(s, "standby"))
126616 + standby = 1;
126617 + /* Global configuration */
126618 + regs = ioremap(res.start, res.end - res.start + 1);
126619 + bm = bm_create(regs);
126620 + BUG_ON(!bm);
126621 + bm_node = node;
126622 + bm_get_version(bm, &id, &major, &minor);
126623 + pr_info("Bman ver:%04x,%02x,%02x\n", id, major, minor);
126624 + if ((major == 1) && (minor == 0)) {
126625 + bman_ip_rev = BMAN_REV10;
126626 + bman_pool_max = 64;
126627 + } else if ((major == 2) && (minor == 0)) {
126628 + bman_ip_rev = BMAN_REV20;
126629 + bman_pool_max = 8;
126630 + } else if ((major == 2) && (minor == 1)) {
126631 + bman_ip_rev = BMAN_REV21;
126632 + bman_pool_max = 64;
126633 + } else {
126634 + pr_warn("unknown Bman version, default to rev1.0\n");
126635 + }
126636 +
126637 + if (standby) {
126638 + pr_info(" -> in standby mode\n");
126639 + return 0;
126640 + }
126641 + return 0;
126642 +}
126643 +
126644 +int bman_have_ccsr(void)
126645 +{
126646 + return bm ? 1 : 0;
126647 +}
126648 +
126649 +int bm_pool_set(u32 bpid, const u32 *thresholds)
126650 +{
126651 + if (!bm)
126652 + return -ENODEV;
126653 + bm_set_pool(bm, bpid, thresholds[0],
126654 + thresholds[1], thresholds[2],
126655 + thresholds[3]);
126656 + return 0;
126657 +}
126658 +EXPORT_SYMBOL(bm_pool_set);
126659 +
126660 +__init int bman_init_early(void)
126661 +{
126662 + struct device_node *dn;
126663 + int ret;
126664 +
126665 + for_each_compatible_node(dn, NULL, "fsl,bman") {
126666 + if (bm)
126667 + pr_err("%s: only one 'fsl,bman' allowed\n",
126668 + dn->full_name);
126669 + else {
126670 + if (!of_device_is_available(dn))
126671 + continue;
126672 +
126673 + ret = fsl_bman_init(dn);
126674 + BUG_ON(ret);
126675 + }
126676 + }
126677 + return 0;
126678 +}
126679 +postcore_initcall_sync(bman_init_early);
126680 +
126681 +
126682 +static void log_edata_bits(u32 bit_count)
126683 +{
126684 + u32 i, j, mask = 0xffffffff;
126685 +
126686 + pr_warn("Bman ErrInt, EDATA:\n");
126687 + i = bit_count/32;
126688 + if (bit_count%32) {
126689 + i++;
126690 + mask = ~(mask << bit_count%32);
126691 + }
126692 + j = 16-i;
126693 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)) & mask);
126694 + j++;
126695 + for (; j < 16; j++)
126696 + pr_warn(" 0x%08x\n", bm_in(EDATA(j)));
126697 +}
126698 +
126699 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
126700 +{
126701 + union bman_ecir ecir_val;
126702 + union bman_eadr eadr_val;
126703 +
126704 + ecir_val.ecir_raw = bm_in(ECIR);
126705 + /* Is portal info valid */
126706 + if (ecsr_val & PORTAL_ECSR_ERR) {
126707 + pr_warn("Bman ErrInt: SWP id %d, numb %d, pid %d\n",
126708 + ecir_val.info.portal_num, ecir_val.info.numb,
126709 + ecir_val.info.pid);
126710 + }
126711 + if (ecsr_val & (BM_EIRQ_SBEI|BM_EIRQ_MBEI)) {
126712 + eadr_val.eadr_raw = bm_in(EADR);
126713 + pr_warn("Bman ErrInt: EADR Memory: %s, 0x%x\n",
126714 + error_mdata[eadr_val.info.memid].txt,
126715 + error_mdata[eadr_val.info.memid].addr_mask
126716 + & eadr_val.info.eadr);
126717 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
126718 + }
126719 +}
126720 +
126721 +/* Bman interrupt handler */
126722 +static irqreturn_t bman_isr(int irq, void *ptr)
126723 +{
126724 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
126725 +
126726 + ier_val = bm_err_isr_enable_read(bm);
126727 + isr_val = bm_err_isr_status_read(bm);
126728 + ecsr_val = bm_in(ECSR);
126729 + isr_mask = isr_val & ier_val;
126730 +
126731 + if (!isr_mask)
126732 + return IRQ_NONE;
126733 + for (i = 0; i < BMAN_HWE_COUNT; i++) {
126734 + if (bman_hwerr_txts[i].mask & isr_mask) {
126735 + pr_warn("Bman ErrInt: %s\n", bman_hwerr_txts[i].txt);
126736 + if (bman_hwerr_txts[i].mask & ecsr_val) {
126737 + log_additional_error_info(isr_mask, ecsr_val);
126738 + /* Re-arm error capture registers */
126739 + bm_out(ECSR, ecsr_val);
126740 + }
126741 + if (bman_hwerr_txts[i].mask & BMAN_ERRS_TO_UNENABLE) {
126742 + pr_devel("Bman un-enabling error 0x%x\n",
126743 + bman_hwerr_txts[i].mask);
126744 + ier_val &= ~bman_hwerr_txts[i].mask;
126745 + bm_err_isr_enable_write(bm, ier_val);
126746 + }
126747 + }
126748 + }
126749 + bm_err_isr_status_clear(bm, isr_val);
126750 + return IRQ_HANDLED;
126751 +}
126752 +
126753 +static int __bind_irq(void)
126754 +{
126755 + int ret, err_irq;
126756 +
126757 + err_irq = of_irq_to_resource(bm_node, 0, NULL);
126758 + if (err_irq == 0) {
126759 + pr_info("Can't get %s property '%s'\n", bm_node->full_name,
126760 + "interrupts");
126761 + return -ENODEV;
126762 + }
126763 + ret = request_irq(err_irq, bman_isr, IRQF_SHARED, "bman-err", bm_node);
126764 + if (ret) {
126765 + pr_err("request_irq() failed %d for '%s'\n", ret,
126766 + bm_node->full_name);
126767 + return -ENODEV;
126768 + }
126769 + /* Disable Buffer Pool State Change */
126770 + bm_err_isr_disable_write(bm, BM_EIRQ_BSCN);
126771 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
126772 + * to resource allocation during driver init). */
126773 + bm_err_isr_status_clear(bm, 0xffffffff);
126774 + /* Enable Error Interrupts */
126775 + bm_err_isr_enable_write(bm, 0xffffffff);
126776 + return 0;
126777 +}
126778 +
126779 +int bman_init_ccsr(struct device_node *node)
126780 +{
126781 + int ret;
126782 + if (!bman_have_ccsr())
126783 + return 0;
126784 + if (node != bm_node)
126785 + return -EINVAL;
126786 + /* FBPR memory */
126787 + bm_set_memory(bm, fbpr_a, 0, fbpr_sz);
126788 + pr_info("bman-fbpr addr %pad size 0x%zx\n", &fbpr_a, fbpr_sz);
126789 +
126790 + ret = __bind_irq();
126791 + if (ret)
126792 + return ret;
126793 + return 0;
126794 +}
126795 +
126796 +u32 bm_pool_free_buffers(u32 bpid)
126797 +{
126798 + return bm_in(POOL_CONTENT(bpid));
126799 +}
126800 +
126801 +#ifdef CONFIG_SYSFS
126802 +
126803 +#define DRV_NAME "fsl-bman"
126804 +#define SBEC_MAX_ID 1
126805 +#define SBEC_MIN_ID 0
126806 +
126807 +static ssize_t show_fbpr_fpc(struct device *dev,
126808 + struct device_attribute *dev_attr, char *buf)
126809 +{
126810 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(FBPR_FPC));
126811 +};
126812 +
126813 +static ssize_t show_pool_count(struct device *dev,
126814 + struct device_attribute *dev_attr, char *buf)
126815 +{
126816 + u32 data;
126817 + int i;
126818 +
126819 + if (!sscanf(dev_attr->attr.name, "%d", &i) || (i >= bman_pool_max))
126820 + return -EINVAL;
126821 + data = bm_in(POOL_CONTENT(i));
126822 + return snprintf(buf, PAGE_SIZE, "%d\n", data);
126823 +};
126824 +
126825 +static ssize_t show_err_isr(struct device *dev,
126826 + struct device_attribute *dev_attr, char *buf)
126827 +{
126828 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", bm_in(ERR_ISR));
126829 +};
126830 +
126831 +static ssize_t show_sbec(struct device *dev,
126832 + struct device_attribute *dev_attr, char *buf)
126833 +{
126834 + int i;
126835 +
126836 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
126837 + return -EINVAL;
126838 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
126839 + return -EINVAL;
126840 + return snprintf(buf, PAGE_SIZE, "%u\n", bm_in(SBEC(i)));
126841 +};
126842 +
126843 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
126844 +static DEVICE_ATTR(fbpr_fpc, S_IRUSR, show_fbpr_fpc, NULL);
126845 +
126846 +/* Didn't use DEVICE_ATTR as 64 of this would be required.
126847 + * Initialize them when needed. */
126848 +static char *name_attrs_pool_count; /* "xx" + null-terminator */
126849 +static struct device_attribute *dev_attr_buffer_pool_count;
126850 +
126851 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
126852 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
126853 +
126854 +static struct attribute *bman_dev_attributes[] = {
126855 + &dev_attr_fbpr_fpc.attr,
126856 + &dev_attr_err_isr.attr,
126857 + NULL
126858 +};
126859 +
126860 +static struct attribute *bman_dev_ecr_attributes[] = {
126861 + &dev_attr_sbec_0.attr,
126862 + &dev_attr_sbec_1.attr,
126863 + NULL
126864 +};
126865 +
126866 +static struct attribute **bman_dev_pool_count_attributes;
126867 +
126868 +
126869 +/* root level */
126870 +static const struct attribute_group bman_dev_attr_grp = {
126871 + .name = NULL,
126872 + .attrs = bman_dev_attributes
126873 +};
126874 +static const struct attribute_group bman_dev_ecr_grp = {
126875 + .name = "error_capture",
126876 + .attrs = bman_dev_ecr_attributes
126877 +};
126878 +static struct attribute_group bman_dev_pool_countent_grp = {
126879 + .name = "pool_count",
126880 +};
126881 +
126882 +static int of_fsl_bman_remove(struct platform_device *ofdev)
126883 +{
126884 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
126885 + return 0;
126886 +};
126887 +
126888 +static int of_fsl_bman_probe(struct platform_device *ofdev)
126889 +{
126890 + int ret, i;
126891 +
126892 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
126893 + if (ret)
126894 + goto done;
126895 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
126896 + if (ret)
126897 + goto del_group_0;
126898 +
126899 + name_attrs_pool_count = kmalloc(sizeof(char) * bman_pool_max * 3,
126900 + GFP_KERNEL);
126901 + if (!name_attrs_pool_count) {
126902 + pr_err("Can't alloc name_attrs_pool_count\n");
126903 + goto del_group_1;
126904 + }
126905 +
126906 + dev_attr_buffer_pool_count = kmalloc(sizeof(struct device_attribute) *
126907 + bman_pool_max, GFP_KERNEL);
126908 + if (!dev_attr_buffer_pool_count) {
126909 + pr_err("Can't alloc dev_attr-buffer_pool_count\n");
126910 + goto del_group_2;
126911 + }
126912 +
126913 + bman_dev_pool_count_attributes = kmalloc(sizeof(struct attribute *) *
126914 + (bman_pool_max + 1), GFP_KERNEL);
126915 + if (!bman_dev_pool_count_attributes) {
126916 + pr_err("can't alloc bman_dev_pool_count_attributes\n");
126917 + goto del_group_3;
126918 + }
126919 +
126920 + for (i = 0; i < bman_pool_max; i++) {
126921 + ret = scnprintf((name_attrs_pool_count + i * 3), 3, "%d", i);
126922 + if (!ret)
126923 + goto del_group_4;
126924 + dev_attr_buffer_pool_count[i].attr.name =
126925 + (name_attrs_pool_count + i * 3);
126926 + dev_attr_buffer_pool_count[i].attr.mode = S_IRUSR;
126927 + dev_attr_buffer_pool_count[i].show = show_pool_count;
126928 + bman_dev_pool_count_attributes[i] =
126929 + &dev_attr_buffer_pool_count[i].attr;
126930 + sysfs_attr_init(bman_dev_pool_count_attributes[i]);
126931 + }
126932 + bman_dev_pool_count_attributes[bman_pool_max] = NULL;
126933 +
126934 + bman_dev_pool_countent_grp.attrs = bman_dev_pool_count_attributes;
126935 +
126936 + ret = sysfs_create_group(&ofdev->dev.kobj, &bman_dev_pool_countent_grp);
126937 + if (ret)
126938 + goto del_group_4;
126939 +
126940 + goto done;
126941 +
126942 +del_group_4:
126943 + kfree(bman_dev_pool_count_attributes);
126944 +del_group_3:
126945 + kfree(dev_attr_buffer_pool_count);
126946 +del_group_2:
126947 + kfree(name_attrs_pool_count);
126948 +del_group_1:
126949 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_ecr_grp);
126950 +del_group_0:
126951 + sysfs_remove_group(&ofdev->dev.kobj, &bman_dev_attr_grp);
126952 +done:
126953 + if (ret)
126954 + dev_err(&ofdev->dev,
126955 + "Cannot create dev attributes ret=%d\n", ret);
126956 + return ret;
126957 +};
126958 +
126959 +static struct of_device_id of_fsl_bman_ids[] = {
126960 + {
126961 + .compatible = "fsl,bman",
126962 + },
126963 + {}
126964 +};
126965 +MODULE_DEVICE_TABLE(of, of_fsl_bman_ids);
126966 +
126967 +#ifdef CONFIG_SUSPEND
126968 +static u32 saved_isdr;
126969 +
126970 +static int bman_pm_suspend_noirq(struct device *dev)
126971 +{
126972 + uint32_t idle_state;
126973 +
126974 + suspend_unused_bportal();
126975 + /* save isdr, disable all, clear isr */
126976 + saved_isdr = bm_err_isr_disable_read(bm);
126977 + bm_err_isr_disable_write(bm, 0xffffffff);
126978 + bm_err_isr_status_clear(bm, 0xffffffff);
126979 +
126980 + if (bman_ip_rev < BMAN_REV21) {
126981 +#ifdef CONFIG_PM_DEBUG
126982 + pr_info("Bman version doesn't have STATE_IDLE\n");
126983 +#endif
126984 + return 0;
126985 + }
126986 + idle_state = bm_in(STATE_IDLE);
126987 + if (!(idle_state & 0x1)) {
126988 + pr_err("Bman not idle 0x%x aborting\n", idle_state);
126989 + bm_err_isr_disable_write(bm, saved_isdr);
126990 + resume_unused_bportal();
126991 + return -EBUSY;
126992 + }
126993 +#ifdef CONFIG_PM_DEBUG
126994 + pr_info("Bman suspend code, IDLE_STAT = 0x%x\n", idle_state);
126995 +#endif
126996 + return 0;
126997 +}
126998 +
126999 +static int bman_pm_resume_noirq(struct device *dev)
127000 +{
127001 + /* restore isdr */
127002 + bm_err_isr_disable_write(bm, saved_isdr);
127003 + resume_unused_bportal();
127004 + return 0;
127005 +}
127006 +#else
127007 +#define bman_pm_suspend_noirq NULL
127008 +#define bman_pm_resume_noirq NULL
127009 +#endif
127010 +
127011 +static const struct dev_pm_ops bman_pm_ops = {
127012 + .suspend_noirq = bman_pm_suspend_noirq,
127013 + .resume_noirq = bman_pm_resume_noirq,
127014 +};
127015 +
127016 +static struct platform_driver of_fsl_bman_driver = {
127017 + .driver = {
127018 + .owner = THIS_MODULE,
127019 + .name = DRV_NAME,
127020 + .of_match_table = of_fsl_bman_ids,
127021 + .pm = &bman_pm_ops,
127022 + },
127023 + .probe = of_fsl_bman_probe,
127024 + .remove = of_fsl_bman_remove,
127025 +};
127026 +
127027 +static int bman_ctrl_init(void)
127028 +{
127029 + return platform_driver_register(&of_fsl_bman_driver);
127030 +}
127031 +
127032 +static void bman_ctrl_exit(void)
127033 +{
127034 + platform_driver_unregister(&of_fsl_bman_driver);
127035 +}
127036 +
127037 +module_init(bman_ctrl_init);
127038 +module_exit(bman_ctrl_exit);
127039 +
127040 +#endif /* CONFIG_SYSFS */
127041 --- /dev/null
127042 +++ b/drivers/staging/fsl_qbman/bman_debugfs.c
127043 @@ -0,0 +1,119 @@
127044 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
127045 + *
127046 + * Redistribution and use in source and binary forms, with or without
127047 + * modification, are permitted provided that the following conditions are met:
127048 + * * Redistributions of source code must retain the above copyright
127049 + * notice, this list of conditions and the following disclaimer.
127050 + * * Redistributions in binary form must reproduce the above copyright
127051 + * notice, this list of conditions and the following disclaimer in the
127052 + * documentation and/or other materials provided with the distribution.
127053 + * * Neither the name of Freescale Semiconductor nor the
127054 + * names of its contributors may be used to endorse or promote products
127055 + * derived from this software without specific prior written permission.
127056 + *
127057 + *
127058 + * ALTERNATIVELY, this software may be distributed under the terms of the
127059 + * GNU General Public License ("GPL") as published by the Free Software
127060 + * Foundation, either version 2 of that License or (at your option) any
127061 + * later version.
127062 + *
127063 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127064 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127065 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127066 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127067 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127068 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127069 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127070 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127071 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127072 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127073 + */
127074 +#include <linux/module.h>
127075 +#include <linux/fsl_bman.h>
127076 +#include <linux/debugfs.h>
127077 +#include <linux/seq_file.h>
127078 +#include <linux/uaccess.h>
127079 +
127080 +static struct dentry *dfs_root; /* debugfs root directory */
127081 +
127082 +/*******************************************************************************
127083 + * Query Buffer Pool State
127084 + ******************************************************************************/
127085 +static int query_bp_state_show(struct seq_file *file, void *offset)
127086 +{
127087 + int ret;
127088 + struct bm_pool_state state;
127089 + int i, j;
127090 + u32 mask;
127091 +
127092 + memset(&state, 0, sizeof(struct bm_pool_state));
127093 + ret = bman_query_pools(&state);
127094 + if (ret) {
127095 + seq_printf(file, "Error %d\n", ret);
127096 + return 0;
127097 + }
127098 + seq_puts(file, "bp_id free_buffers_avail bp_depleted\n");
127099 + for (i = 0; i < 2; i++) {
127100 + mask = 0x80000000;
127101 + for (j = 0; j < 32; j++) {
127102 + seq_printf(file,
127103 + " %-2u %-3s %-3s\n",
127104 + (i*32)+j,
127105 + (state.as.state.__state[i] & mask) ? "no" : "yes",
127106 + (state.ds.state.__state[i] & mask) ? "yes" : "no");
127107 + mask >>= 1;
127108 + }
127109 + }
127110 + return 0;
127111 +}
127112 +
127113 +static int query_bp_state_open(struct inode *inode, struct file *file)
127114 +{
127115 + return single_open(file, query_bp_state_show, NULL);
127116 +}
127117 +
127118 +static const struct file_operations query_bp_state_fops = {
127119 + .owner = THIS_MODULE,
127120 + .open = query_bp_state_open,
127121 + .read = seq_read,
127122 + .release = single_release,
127123 +};
127124 +
127125 +static int __init bman_debugfs_module_init(void)
127126 +{
127127 + int ret = 0;
127128 + struct dentry *d;
127129 +
127130 + dfs_root = debugfs_create_dir("bman", NULL);
127131 +
127132 + if (dfs_root == NULL) {
127133 + ret = -ENOMEM;
127134 + pr_err("Cannot create bman debugfs dir\n");
127135 + goto _return;
127136 + }
127137 + d = debugfs_create_file("query_bp_state",
127138 + S_IRUGO,
127139 + dfs_root,
127140 + NULL,
127141 + &query_bp_state_fops);
127142 + if (d == NULL) {
127143 + ret = -ENOMEM;
127144 + pr_err("Cannot create query_bp_state\n");
127145 + goto _return;
127146 + }
127147 + return 0;
127148 +
127149 +_return:
127150 + debugfs_remove_recursive(dfs_root);
127151 + return ret;
127152 +}
127153 +
127154 +static void __exit bman_debugfs_module_exit(void)
127155 +{
127156 + debugfs_remove_recursive(dfs_root);
127157 +}
127158 +
127159 +
127160 +module_init(bman_debugfs_module_init);
127161 +module_exit(bman_debugfs_module_exit);
127162 +MODULE_LICENSE("Dual BSD/GPL");
127163 --- /dev/null
127164 +++ b/drivers/staging/fsl_qbman/bman_driver.c
127165 @@ -0,0 +1,559 @@
127166 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
127167 + *
127168 + * Redistribution and use in source and binary forms, with or without
127169 + * modification, are permitted provided that the following conditions are met:
127170 + * * Redistributions of source code must retain the above copyright
127171 + * notice, this list of conditions and the following disclaimer.
127172 + * * Redistributions in binary form must reproduce the above copyright
127173 + * notice, this list of conditions and the following disclaimer in the
127174 + * documentation and/or other materials provided with the distribution.
127175 + * * Neither the name of Freescale Semiconductor nor the
127176 + * names of its contributors may be used to endorse or promote products
127177 + * derived from this software without specific prior written permission.
127178 + *
127179 + *
127180 + * ALTERNATIVELY, this software may be distributed under the terms of the
127181 + * GNU General Public License ("GPL") as published by the Free Software
127182 + * Foundation, either version 2 of that License or (at your option) any
127183 + * later version.
127184 + *
127185 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127186 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127187 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127188 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127189 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127190 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127191 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127192 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127193 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127194 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127195 + */
127196 +#include "bman_low.h"
127197 +#ifdef CONFIG_HOTPLUG_CPU
127198 +#include <linux/cpu.h>
127199 +#endif
127200 +/*
127201 + * Global variables of the max portal/pool number this bman version supported
127202 + */
127203 +u16 bman_ip_rev;
127204 +EXPORT_SYMBOL(bman_ip_rev);
127205 +u16 bman_pool_max;
127206 +EXPORT_SYMBOL(bman_pool_max);
127207 +static u16 bman_portal_max;
127208 +
127209 +/* After initialising cpus that own shared portal configs, we cache the
127210 + * resulting portals (ie. not just the configs) in this array. Then we
127211 + * initialise slave cpus that don't have their own portals, redirecting them to
127212 + * portals from this cache in a round-robin assignment. */
127213 +static struct bman_portal *shared_portals[NR_CPUS];
127214 +static int num_shared_portals;
127215 +static int shared_portals_idx;
127216 +static LIST_HEAD(unused_pcfgs);
127217 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
127218 +static void *affine_bportals[NR_CPUS];
127219 +
127220 +static int __init fsl_bpool_init(struct device_node *node)
127221 +{
127222 + int ret;
127223 + u32 *thresh, *bpid = (u32 *)of_get_property(node, "fsl,bpid", &ret);
127224 + if (!bpid || (ret != 4)) {
127225 + pr_err("Can't get %s property 'fsl,bpid'\n", node->full_name);
127226 + return -ENODEV;
127227 + }
127228 + thresh = (u32 *)of_get_property(node, "fsl,bpool-thresholds", &ret);
127229 + if (thresh) {
127230 + if (ret != 16) {
127231 + pr_err("Invalid %s property '%s'\n",
127232 + node->full_name, "fsl,bpool-thresholds");
127233 + return -ENODEV;
127234 + }
127235 + }
127236 + if (thresh) {
127237 +#ifdef CONFIG_FSL_BMAN_CONFIG
127238 + ret = bm_pool_set(be32_to_cpu(*bpid), thresh);
127239 + if (ret)
127240 + pr_err("No CCSR node for %s property '%s'\n",
127241 + node->full_name, "fsl,bpool-thresholds");
127242 + return ret;
127243 +#else
127244 + pr_err("Ignoring %s property '%s', no CCSR support\n",
127245 + node->full_name, "fsl,bpool-thresholds");
127246 +#endif
127247 + }
127248 + return 0;
127249 +}
127250 +
127251 +static int __init fsl_bpid_range_init(struct device_node *node)
127252 +{
127253 + int ret;
127254 + u32 *range = (u32 *)of_get_property(node, "fsl,bpid-range", &ret);
127255 + if (!range) {
127256 + pr_err("No 'fsl,bpid-range' property in node %s\n",
127257 + node->full_name);
127258 + return -EINVAL;
127259 + }
127260 + if (ret != 8) {
127261 + pr_err("'fsl,bpid-range' is not a 2-cell range in node %s\n",
127262 + node->full_name);
127263 + return -EINVAL;
127264 + }
127265 + bman_seed_bpid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
127266 + pr_info("Bman: BPID allocator includes range %d:%d\n",
127267 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
127268 + return 0;
127269 +}
127270 +
127271 +static struct bm_portal_config * __init parse_pcfg(struct device_node *node)
127272 +{
127273 + struct bm_portal_config *pcfg;
127274 + const u32 *index;
127275 + int irq, ret;
127276 + resource_size_t len;
127277 +
127278 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
127279 + if (!pcfg) {
127280 + pr_err("can't allocate portal config");
127281 + return NULL;
127282 + }
127283 +
127284 + if (of_device_is_compatible(node, "fsl,bman-portal-1.0") ||
127285 + of_device_is_compatible(node, "fsl,bman-portal-1.0.0")) {
127286 + bman_ip_rev = BMAN_REV10;
127287 + bman_pool_max = 64;
127288 + bman_portal_max = 10;
127289 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.0") ||
127290 + of_device_is_compatible(node, "fsl,bman-portal-2.0.8")) {
127291 + bman_ip_rev = BMAN_REV20;
127292 + bman_pool_max = 8;
127293 + bman_portal_max = 3;
127294 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.0")) {
127295 + bman_ip_rev = BMAN_REV21;
127296 + bman_pool_max = 64;
127297 + bman_portal_max = 50;
127298 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.1")) {
127299 + bman_ip_rev = BMAN_REV21;
127300 + bman_pool_max = 64;
127301 + bman_portal_max = 25;
127302 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.2")) {
127303 + bman_ip_rev = BMAN_REV21;
127304 + bman_pool_max = 64;
127305 + bman_portal_max = 18;
127306 + } else if (of_device_is_compatible(node, "fsl,bman-portal-2.1.3")) {
127307 + bman_ip_rev = BMAN_REV21;
127308 + bman_pool_max = 64;
127309 + bman_portal_max = 10;
127310 + } else {
127311 + pr_warn("unknown BMan version in portal node,"
127312 + "default to rev1.0\n");
127313 + bman_ip_rev = BMAN_REV10;
127314 + bman_pool_max = 64;
127315 + bman_portal_max = 10;
127316 + }
127317 +
127318 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
127319 + &pcfg->addr_phys[DPA_PORTAL_CE]);
127320 + if (ret) {
127321 + pr_err("Can't get %s property 'reg::CE'\n", node->full_name);
127322 + goto err;
127323 + }
127324 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
127325 + &pcfg->addr_phys[DPA_PORTAL_CI]);
127326 + if (ret) {
127327 + pr_err("Can't get %s property 'reg::CI'\n", node->full_name);
127328 + goto err;
127329 + }
127330 +
127331 + index = of_get_property(node, "cell-index", &ret);
127332 + if (!index || (ret != 4)) {
127333 + pr_err("Can't get %s property '%s'\n", node->full_name,
127334 + "cell-index");
127335 + goto err;
127336 + }
127337 + if (be32_to_cpu(*index) >= bman_portal_max) {
127338 + pr_err("BMan portal cell index %d out of range, max %d\n",
127339 + be32_to_cpu(*index), bman_portal_max);
127340 + goto err;
127341 + }
127342 +
127343 + pcfg->public_cfg.cpu = -1;
127344 +
127345 + irq = irq_of_parse_and_map(node, 0);
127346 + if (irq == 0) {
127347 + pr_err("Can't get %s property 'interrupts'\n", node->full_name);
127348 + goto err;
127349 + }
127350 + pcfg->public_cfg.irq = irq;
127351 + pcfg->public_cfg.index = be32_to_cpu(*index);
127352 + bman_depletion_fill(&pcfg->public_cfg.mask);
127353 +
127354 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
127355 + if (len != (unsigned long)len)
127356 + goto err;
127357 +
127358 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
127359 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
127360 + pcfg->addr_phys[DPA_PORTAL_CE].start,
127361 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
127362 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
127363 + pcfg->addr_phys[DPA_PORTAL_CI].start,
127364 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
127365 +
127366 +#else
127367 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
127368 + pcfg->addr_phys[DPA_PORTAL_CE].start,
127369 + (unsigned long)len,
127370 + 0);
127371 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
127372 + pcfg->addr_phys[DPA_PORTAL_CI].start,
127373 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
127374 + _PAGE_GUARDED | _PAGE_NO_CACHE);
127375 +#endif
127376 + /* disable bp depletion */
127377 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(0));
127378 + __raw_writel(0x0, pcfg->addr_virt[DPA_PORTAL_CI] + BM_REG_SCN(1));
127379 + return pcfg;
127380 +err:
127381 + kfree(pcfg);
127382 + return NULL;
127383 +}
127384 +
127385 +static struct bm_portal_config *get_pcfg(struct list_head *list)
127386 +{
127387 + struct bm_portal_config *pcfg;
127388 + if (list_empty(list))
127389 + return NULL;
127390 + pcfg = list_entry(list->prev, struct bm_portal_config, list);
127391 + list_del(&pcfg->list);
127392 + return pcfg;
127393 +}
127394 +
127395 +static struct bm_portal_config *get_pcfg_idx(struct list_head *list,
127396 + uint32_t idx)
127397 +{
127398 + struct bm_portal_config *pcfg;
127399 + if (list_empty(list))
127400 + return NULL;
127401 + list_for_each_entry(pcfg, list, list) {
127402 + if (pcfg->public_cfg.index == idx) {
127403 + list_del(&pcfg->list);
127404 + return pcfg;
127405 + }
127406 + }
127407 + return NULL;
127408 +}
127409 +
127410 +struct bm_portal_config *bm_get_unused_portal(void)
127411 +{
127412 + return bm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
127413 +}
127414 +
127415 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx)
127416 +{
127417 + struct bm_portal_config *ret;
127418 + spin_lock(&unused_pcfgs_lock);
127419 + if (idx == QBMAN_ANY_PORTAL_IDX)
127420 + ret = get_pcfg(&unused_pcfgs);
127421 + else
127422 + ret = get_pcfg_idx(&unused_pcfgs, idx);
127423 + spin_unlock(&unused_pcfgs_lock);
127424 + return ret;
127425 +}
127426 +
127427 +void bm_put_unused_portal(struct bm_portal_config *pcfg)
127428 +{
127429 + spin_lock(&unused_pcfgs_lock);
127430 + list_add(&pcfg->list, &unused_pcfgs);
127431 + spin_unlock(&unused_pcfgs_lock);
127432 +}
127433 +
127434 +static struct bman_portal *init_pcfg(struct bm_portal_config *pcfg)
127435 +{
127436 + struct bman_portal *p;
127437 + p = bman_create_affine_portal(pcfg);
127438 + if (p) {
127439 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
127440 + bman_p_irqsource_add(p, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
127441 +#endif
127442 + pr_info("Bman portal %sinitialised, cpu %d\n",
127443 + pcfg->public_cfg.is_shared ? "(shared) " : "",
127444 + pcfg->public_cfg.cpu);
127445 + affine_bportals[pcfg->public_cfg.cpu] = p;
127446 + } else
127447 + pr_crit("Bman portal failure on cpu %d\n",
127448 + pcfg->public_cfg.cpu);
127449 + return p;
127450 +}
127451 +
127452 +static void init_slave(int cpu)
127453 +{
127454 + struct bman_portal *p;
127455 + p = bman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
127456 + if (!p)
127457 + pr_err("Bman slave portal failure on cpu %d\n", cpu);
127458 + else
127459 + pr_info("Bman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
127460 + if (shared_portals_idx >= num_shared_portals)
127461 + shared_portals_idx = 0;
127462 + affine_bportals[cpu] = p;
127463 +}
127464 +
127465 +/* Bootarg "bportals=[...]" has the same syntax as "qportals=", and so the
127466 + * parsing is in dpa_sys.h. The syntax is a comma-separated list of indexes
127467 + * and/or ranges of indexes, with each being optionally prefixed by "s" to
127468 + * explicitly mark it or them for sharing.
127469 + * Eg;
127470 + * bportals=s0,1-3,s4
127471 + * means that cpus 1,2,3 get "unshared" portals, cpus 0 and 4 get "shared"
127472 + * portals, and any remaining cpus share the portals that are assigned to cpus 0
127473 + * or 4, selected in a round-robin fashion. (In this example, cpu 5 would share
127474 + * cpu 0's portal, cpu 6 would share cpu4's portal, and cpu 7 would share cpu
127475 + * 0's portal.) */
127476 +static struct cpumask want_unshared __initdata; /* cpus requested without "s" */
127477 +static struct cpumask want_shared __initdata; /* cpus requested with "s" */
127478 +
127479 +static int __init parse_bportals(char *str)
127480 +{
127481 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
127482 + "bportals");
127483 +}
127484 +__setup("bportals=", parse_bportals);
127485 +
127486 +static int bman_offline_cpu(unsigned int cpu)
127487 +{
127488 + struct bman_portal *p;
127489 + const struct bm_portal_config *pcfg;
127490 + p = (struct bman_portal *)affine_bportals[cpu];
127491 + if (p) {
127492 + pcfg = bman_get_bm_portal_config(p);
127493 + if (pcfg)
127494 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
127495 + }
127496 + return 0;
127497 +}
127498 +
127499 +#ifdef CONFIG_HOTPLUG_CPU
127500 +static int bman_online_cpu(unsigned int cpu)
127501 +{
127502 + struct bman_portal *p;
127503 + const struct bm_portal_config *pcfg;
127504 + p = (struct bman_portal *)affine_bportals[cpu];
127505 + if (p) {
127506 + pcfg = bman_get_bm_portal_config(p);
127507 + if (pcfg)
127508 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
127509 + }
127510 + return 0;
127511 +}
127512 +#endif /* CONFIG_HOTPLUG_CPU */
127513 +
127514 +/* Initialise the Bman driver. The meat of this function deals with portals. The
127515 + * following describes the flow of portal-handling, the code "steps" refer to
127516 + * this description;
127517 + * 1. Portal configs are parsed from the device-tree into 'unused_pcfgs', with
127518 + * ::cpu==-1. Regions and interrupts are mapped (but interrupts are not
127519 + * bound).
127520 + * 2. The "want_shared" and "want_unshared" lists (as filled by the
127521 + * "bportals=[...]" bootarg) are processed, allocating portals and assigning
127522 + * them to cpus, placing them in the relevant list and setting ::cpu as
127523 + * appropriate. If no "bportals" bootarg was present, the defaut is to try to
127524 + * assign portals to all online cpus at the time of driver initialisation.
127525 + * Any failure to allocate portals (when parsing the "want" lists or when
127526 + * using default behaviour) will be silently tolerated (the "fixup" logic in
127527 + * step 3 will determine what happens in this case).
127528 + * 3. Do fixups relative to cpu_online_mask(). If no portals are marked for
127529 + * sharing and sharing is required (because not all cpus have been assigned
127530 + * portals), then one portal will marked for sharing. Conversely if no
127531 + * sharing is required, any portals marked for sharing will not be shared. It
127532 + * may be that sharing occurs when it wasn't expected, if portal allocation
127533 + * failed to honour all the requested assignments (including the default
127534 + * assignments if no bootarg is present).
127535 + * 4. Unshared portals are initialised on their respective cpus.
127536 + * 5. Shared portals are initialised on their respective cpus.
127537 + * 6. Each remaining cpu is initialised to slave to one of the shared portals,
127538 + * which are selected in a round-robin fashion.
127539 + * Any portal configs left unused are available for USDPAA allocation.
127540 + */
127541 +__init int bman_init(void)
127542 +{
127543 + struct cpumask slave_cpus;
127544 + struct cpumask unshared_cpus = *cpu_none_mask;
127545 + struct cpumask shared_cpus = *cpu_none_mask;
127546 + LIST_HEAD(unshared_pcfgs);
127547 + LIST_HEAD(shared_pcfgs);
127548 + struct device_node *dn;
127549 + struct bm_portal_config *pcfg;
127550 + struct bman_portal *p;
127551 + int cpu, ret;
127552 + struct cpumask offline_cpus;
127553 +
127554 + /* Initialise the Bman (CCSR) device */
127555 + for_each_compatible_node(dn, NULL, "fsl,bman") {
127556 + if (!bman_init_ccsr(dn))
127557 + pr_info("Bman err interrupt handler present\n");
127558 + else
127559 + pr_err("Bman CCSR setup failed\n");
127560 + }
127561 + /* Initialise any declared buffer pools */
127562 + for_each_compatible_node(dn, NULL, "fsl,bpool") {
127563 + ret = fsl_bpool_init(dn);
127564 + if (ret)
127565 + return ret;
127566 + }
127567 + /* Step 1. See comments at the beginning of the file. */
127568 + for_each_compatible_node(dn, NULL, "fsl,bman-portal") {
127569 + if (!of_device_is_available(dn))
127570 + continue;
127571 + pcfg = parse_pcfg(dn);
127572 + if (pcfg)
127573 + list_add_tail(&pcfg->list, &unused_pcfgs);
127574 + }
127575 + /* Step 2. */
127576 + for_each_possible_cpu(cpu) {
127577 + if (cpumask_test_cpu(cpu, &want_shared)) {
127578 + pcfg = get_pcfg(&unused_pcfgs);
127579 + if (!pcfg)
127580 + break;
127581 + pcfg->public_cfg.cpu = cpu;
127582 + list_add_tail(&pcfg->list, &shared_pcfgs);
127583 + cpumask_set_cpu(cpu, &shared_cpus);
127584 + }
127585 + if (cpumask_test_cpu(cpu, &want_unshared)) {
127586 + if (cpumask_test_cpu(cpu, &shared_cpus))
127587 + continue;
127588 + pcfg = get_pcfg(&unused_pcfgs);
127589 + if (!pcfg)
127590 + break;
127591 + pcfg->public_cfg.cpu = cpu;
127592 + list_add_tail(&pcfg->list, &unshared_pcfgs);
127593 + cpumask_set_cpu(cpu, &unshared_cpus);
127594 + }
127595 + }
127596 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
127597 + /* Default, give an unshared portal to each online cpu */
127598 + for_each_online_cpu(cpu) {
127599 + pcfg = get_pcfg(&unused_pcfgs);
127600 + if (!pcfg)
127601 + break;
127602 + pcfg->public_cfg.cpu = cpu;
127603 + list_add_tail(&pcfg->list, &unshared_pcfgs);
127604 + cpumask_set_cpu(cpu, &unshared_cpus);
127605 + }
127606 + }
127607 + /* Step 3. */
127608 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
127609 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
127610 + if (cpumask_empty(&slave_cpus)) {
127611 + /* No sharing required */
127612 + if (!list_empty(&shared_pcfgs)) {
127613 + /* Migrate "shared" to "unshared" */
127614 + cpumask_or(&unshared_cpus, &unshared_cpus,
127615 + &shared_cpus);
127616 + cpumask_clear(&shared_cpus);
127617 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
127618 + INIT_LIST_HEAD(&shared_pcfgs);
127619 + }
127620 + } else {
127621 + /* Sharing required */
127622 + if (list_empty(&shared_pcfgs)) {
127623 + /* Migrate one "unshared" to "shared" */
127624 + pcfg = get_pcfg(&unshared_pcfgs);
127625 + if (!pcfg) {
127626 + pr_crit("No BMan portals available!\n");
127627 + return 0;
127628 + }
127629 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
127630 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
127631 + list_add_tail(&pcfg->list, &shared_pcfgs);
127632 + }
127633 + }
127634 + /* Step 4. */
127635 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
127636 + pcfg->public_cfg.is_shared = 0;
127637 + p = init_pcfg(pcfg);
127638 + if (!p) {
127639 + pr_crit("Unable to initialize bman portal\n");
127640 + return 0;
127641 + }
127642 + }
127643 + /* Step 5. */
127644 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
127645 + pcfg->public_cfg.is_shared = 1;
127646 + p = init_pcfg(pcfg);
127647 + if (p)
127648 + shared_portals[num_shared_portals++] = p;
127649 + }
127650 + /* Step 6. */
127651 + if (!cpumask_empty(&slave_cpus))
127652 + for_each_cpu(cpu, &slave_cpus)
127653 + init_slave(cpu);
127654 + pr_info("Bman portals initialised\n");
127655 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
127656 + for_each_cpu(cpu, &offline_cpus)
127657 + bman_offline_cpu(cpu);
127658 +#ifdef CONFIG_HOTPLUG_CPU
127659 + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
127660 + "soc/qbman_portal:online",
127661 + bman_online_cpu, bman_offline_cpu);
127662 + if (ret < 0) {
127663 + pr_err("bman: failed to register hotplug callbacks.\n");
127664 + return 0;
127665 + }
127666 +#endif
127667 + return 0;
127668 +}
127669 +
127670 +__init int bman_resource_init(void)
127671 +{
127672 + struct device_node *dn;
127673 + int ret;
127674 +
127675 + /* Initialise BPID allocation ranges */
127676 + for_each_compatible_node(dn, NULL, "fsl,bpid-range") {
127677 + ret = fsl_bpid_range_init(dn);
127678 + if (ret)
127679 + return ret;
127680 + }
127681 + return 0;
127682 +}
127683 +
127684 +#ifdef CONFIG_SUSPEND
127685 +void suspend_unused_bportal(void)
127686 +{
127687 + struct bm_portal_config *pcfg;
127688 +
127689 + if (list_empty(&unused_pcfgs))
127690 + return;
127691 +
127692 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
127693 +#ifdef CONFIG_PM_DEBUG
127694 + pr_info("Need to save bportal %d\n", pcfg->public_cfg.index);
127695 +#endif
127696 + /* save isdr, disable all via isdr, clear isr */
127697 + pcfg->saved_isdr =
127698 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
127699 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
127700 + 0xe08);
127701 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
127702 + 0xe00);
127703 + }
127704 + return;
127705 +}
127706 +
127707 +void resume_unused_bportal(void)
127708 +{
127709 + struct bm_portal_config *pcfg;
127710 +
127711 + if (list_empty(&unused_pcfgs))
127712 + return;
127713 +
127714 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
127715 +#ifdef CONFIG_PM_DEBUG
127716 + pr_info("Need to resume bportal %d\n", pcfg->public_cfg.index);
127717 +#endif
127718 + /* restore isdr */
127719 + __raw_writel(pcfg->saved_isdr,
127720 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
127721 + }
127722 + return;
127723 +}
127724 +#endif
127725 --- /dev/null
127726 +++ b/drivers/staging/fsl_qbman/bman_high.c
127727 @@ -0,0 +1,1145 @@
127728 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
127729 + *
127730 + * Redistribution and use in source and binary forms, with or without
127731 + * modification, are permitted provided that the following conditions are met:
127732 + * * Redistributions of source code must retain the above copyright
127733 + * notice, this list of conditions and the following disclaimer.
127734 + * * Redistributions in binary form must reproduce the above copyright
127735 + * notice, this list of conditions and the following disclaimer in the
127736 + * documentation and/or other materials provided with the distribution.
127737 + * * Neither the name of Freescale Semiconductor nor the
127738 + * names of its contributors may be used to endorse or promote products
127739 + * derived from this software without specific prior written permission.
127740 + *
127741 + *
127742 + * ALTERNATIVELY, this software may be distributed under the terms of the
127743 + * GNU General Public License ("GPL") as published by the Free Software
127744 + * Foundation, either version 2 of that License or (at your option) any
127745 + * later version.
127746 + *
127747 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
127748 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
127749 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
127750 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
127751 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
127752 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127753 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
127754 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
127755 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
127756 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
127757 + */
127758 +
127759 +#include "bman_low.h"
127760 +
127761 +/* Compilation constants */
127762 +#define RCR_THRESH 2 /* reread h/w CI when running out of space */
127763 +#define IRQNAME "BMan portal %d"
127764 +#define MAX_IRQNAME 16 /* big enough for "BMan portal %d" */
127765 +
127766 +struct bman_portal {
127767 + struct bm_portal p;
127768 + /* 2-element array. pools[0] is mask, pools[1] is snapshot. */
127769 + struct bman_depletion *pools;
127770 + int thresh_set;
127771 + unsigned long irq_sources;
127772 + u32 slowpoll; /* only used when interrupts are off */
127773 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
127774 + struct bman_pool *rcri_owned; /* only 1 release WAIT_SYNC at a time */
127775 +#endif
127776 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127777 + raw_spinlock_t sharing_lock; /* only used if is_shared */
127778 + int is_shared;
127779 + struct bman_portal *sharing_redirect;
127780 +#endif
127781 + /* When the cpu-affine portal is activated, this is non-NULL */
127782 + const struct bm_portal_config *config;
127783 + /* This is needed for power management */
127784 + struct platform_device *pdev;
127785 + /* 64-entry hash-table of pool objects that are tracking depletion
127786 + * entry/exit (ie. BMAN_POOL_FLAG_DEPLETION). This isn't fast-path, so
127787 + * we're not fussy about cache-misses and so forth - whereas the above
127788 + * members should all fit in one cacheline.
127789 + * BTW, with 64 entries in the hash table and 64 buffer pools to track,
127790 + * you'll never guess the hash-function ... */
127791 + struct bman_pool *cb[64];
127792 + char irqname[MAX_IRQNAME];
127793 + /* Track if the portal was alloced by the driver */
127794 + u8 alloced;
127795 + /* power management data */
127796 + u32 save_isdr;
127797 +};
127798 +
127799 +/* For an explanation of the locking, redirection, or affine-portal logic,
127800 + * please consult the Qman driver for details. This is the same, only simpler
127801 + * (no fiddly Qman-specific bits.) */
127802 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127803 +#define PORTAL_IRQ_LOCK(p, irqflags) \
127804 + do { \
127805 + if ((p)->is_shared) \
127806 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
127807 + else \
127808 + local_irq_save(irqflags); \
127809 + } while (0)
127810 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
127811 + do { \
127812 + if ((p)->is_shared) \
127813 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
127814 + irqflags); \
127815 + else \
127816 + local_irq_restore(irqflags); \
127817 + } while (0)
127818 +#else
127819 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
127820 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
127821 +#endif
127822 +
127823 +static cpumask_t affine_mask;
127824 +static DEFINE_SPINLOCK(affine_mask_lock);
127825 +static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
127826 +static inline struct bman_portal *get_raw_affine_portal(void)
127827 +{
127828 + return &get_cpu_var(bman_affine_portal);
127829 +}
127830 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
127831 +static inline struct bman_portal *get_affine_portal(void)
127832 +{
127833 + struct bman_portal *p = get_raw_affine_portal();
127834 + if (p->sharing_redirect)
127835 + return p->sharing_redirect;
127836 + return p;
127837 +}
127838 +#else
127839 +#define get_affine_portal() get_raw_affine_portal()
127840 +#endif
127841 +static inline void put_affine_portal(void)
127842 +{
127843 + put_cpu_var(bman_affine_portal);
127844 +}
127845 +static inline struct bman_portal *get_poll_portal(void)
127846 +{
127847 + return &get_cpu_var(bman_affine_portal);
127848 +}
127849 +#define put_poll_portal()
127850 +
127851 +/* GOTCHA: this object type refers to a pool, it isn't *the* pool. There may be
127852 + * more than one such object per Bman buffer pool, eg. if different users of the
127853 + * pool are operating via different portals. */
127854 +struct bman_pool {
127855 + struct bman_pool_params params;
127856 + /* Used for hash-table admin when using depletion notifications. */
127857 + struct bman_portal *portal;
127858 + struct bman_pool *next;
127859 + /* stockpile state - NULL unless BMAN_POOL_FLAG_STOCKPILE is set */
127860 + struct bm_buffer *sp;
127861 + unsigned int sp_fill;
127862 +#ifdef CONFIG_FSL_DPA_CHECKING
127863 + atomic_t in_use;
127864 +#endif
127865 +};
127866 +
127867 +/* (De)Registration of depletion notification callbacks */
127868 +static void depletion_link(struct bman_portal *portal, struct bman_pool *pool)
127869 +{
127870 + __maybe_unused unsigned long irqflags;
127871 + pool->portal = portal;
127872 + PORTAL_IRQ_LOCK(portal, irqflags);
127873 + pool->next = portal->cb[pool->params.bpid];
127874 + portal->cb[pool->params.bpid] = pool;
127875 + if (!pool->next)
127876 + /* First object for that bpid on this portal, enable the BSCN
127877 + * mask bit. */
127878 + bm_isr_bscn_mask(&portal->p, pool->params.bpid, 1);
127879 + PORTAL_IRQ_UNLOCK(portal, irqflags);
127880 +}
127881 +static void depletion_unlink(struct bman_pool *pool)
127882 +{
127883 + struct bman_pool *it, *last = NULL;
127884 + struct bman_pool **base = &pool->portal->cb[pool->params.bpid];
127885 + __maybe_unused unsigned long irqflags;
127886 + PORTAL_IRQ_LOCK(pool->portal, irqflags);
127887 + it = *base; /* <-- gotcha, don't do this prior to the irq_save */
127888 + while (it != pool) {
127889 + last = it;
127890 + it = it->next;
127891 + }
127892 + if (!last)
127893 + *base = pool->next;
127894 + else
127895 + last->next = pool->next;
127896 + if (!last && !pool->next) {
127897 + /* Last object for that bpid on this portal, disable the BSCN
127898 + * mask bit. */
127899 + bm_isr_bscn_mask(&pool->portal->p, pool->params.bpid, 0);
127900 + /* And "forget" that we last saw this pool as depleted */
127901 + bman_depletion_unset(&pool->portal->pools[1],
127902 + pool->params.bpid);
127903 + }
127904 + PORTAL_IRQ_UNLOCK(pool->portal, irqflags);
127905 +}
127906 +
127907 +/* In the case that the application's core loop calls qman_poll() and
127908 + * bman_poll(), we ought to balance how often we incur the overheads of the
127909 + * slow-path poll. We'll use two decrementer sources. The idle decrementer
127910 + * constant is used when the last slow-poll detected no work to do, and the busy
127911 + * decrementer constant when the last slow-poll had work to do. */
127912 +#define SLOW_POLL_IDLE 1000
127913 +#define SLOW_POLL_BUSY 10
127914 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is);
127915 +
127916 +/* Portal interrupt handler */
127917 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
127918 +{
127919 + struct bman_portal *p = ptr;
127920 + u32 clear = p->irq_sources;
127921 + u32 is = bm_isr_status_read(&p->p) & p->irq_sources;
127922 + clear |= __poll_portal_slow(p, is);
127923 + bm_isr_status_clear(&p->p, clear);
127924 + return IRQ_HANDLED;
127925 +}
127926 +
127927 +#ifdef CONFIG_SUSPEND
127928 +static int _bman_portal_suspend_noirq(struct device *dev)
127929 +{
127930 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
127931 +#ifdef CONFIG_PM_DEBUG
127932 + struct platform_device *pdev = to_platform_device(dev);
127933 +#endif
127934 + p->save_isdr = bm_isr_disable_read(&p->p);
127935 + bm_isr_disable_write(&p->p, 0xffffffff);
127936 + bm_isr_status_clear(&p->p, 0xffffffff);
127937 +#ifdef CONFIG_PM_DEBUG
127938 + pr_info("Suspend for %s\n", pdev->name);
127939 +#endif
127940 + return 0;
127941 +}
127942 +
127943 +static int _bman_portal_resume_noirq(struct device *dev)
127944 +{
127945 + struct bman_portal *p = (struct bman_portal *)dev->platform_data;
127946 +
127947 + /* restore isdr */
127948 + bm_isr_disable_write(&p->p, p->save_isdr);
127949 + return 0;
127950 +}
127951 +#else
127952 +#define _bman_portal_suspend_noirq NULL
127953 +#define _bman_portal_resume_noirq NULL
127954 +#endif
127955 +
127956 +struct dev_pm_domain bman_portal_device_pm_domain = {
127957 + .ops = {
127958 + USE_PLATFORM_PM_SLEEP_OPS
127959 + .suspend_noirq = _bman_portal_suspend_noirq,
127960 + .resume_noirq = _bman_portal_resume_noirq,
127961 + }
127962 +};
127963 +
127964 +struct bman_portal *bman_create_portal(
127965 + struct bman_portal *portal,
127966 + const struct bm_portal_config *config)
127967 +{
127968 + struct bm_portal *__p;
127969 + const struct bman_depletion *pools = &config->public_cfg.mask;
127970 + int ret;
127971 + u8 bpid = 0;
127972 + char buf[16];
127973 +
127974 + if (!portal) {
127975 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
127976 + if (!portal)
127977 + return portal;
127978 + portal->alloced = 1;
127979 + } else
127980 + portal->alloced = 0;
127981 +
127982 + __p = &portal->p;
127983 +
127984 + /* prep the low-level portal struct with the mapped addresses from the
127985 + * config, everything that follows depends on it and "config" is more
127986 + * for (de)reference... */
127987 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
127988 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
127989 + if (bm_rcr_init(__p, bm_rcr_pvb, bm_rcr_cce)) {
127990 + pr_err("Bman RCR initialisation failed\n");
127991 + goto fail_rcr;
127992 + }
127993 + if (bm_mc_init(__p)) {
127994 + pr_err("Bman MC initialisation failed\n");
127995 + goto fail_mc;
127996 + }
127997 + if (bm_isr_init(__p)) {
127998 + pr_err("Bman ISR initialisation failed\n");
127999 + goto fail_isr;
128000 + }
128001 + portal->pools = kmalloc(2 * sizeof(*pools), GFP_KERNEL);
128002 + if (!portal->pools)
128003 + goto fail_pools;
128004 + portal->pools[0] = *pools;
128005 + bman_depletion_init(portal->pools + 1);
128006 + while (bpid < bman_pool_max) {
128007 + /* Default to all BPIDs disabled, we enable as required at
128008 + * run-time. */
128009 + bm_isr_bscn_mask(__p, bpid, 0);
128010 + bpid++;
128011 + }
128012 + portal->slowpoll = 0;
128013 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128014 + portal->rcri_owned = NULL;
128015 +#endif
128016 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
128017 + raw_spin_lock_init(&portal->sharing_lock);
128018 + portal->is_shared = config->public_cfg.is_shared;
128019 + portal->sharing_redirect = NULL;
128020 +#endif
128021 + sprintf(buf, "bportal-%u", config->public_cfg.index);
128022 + portal->pdev = platform_device_alloc(buf, -1);
128023 + if (!portal->pdev)
128024 + goto fail_devalloc;
128025 + portal->pdev->dev.pm_domain = &bman_portal_device_pm_domain;
128026 + portal->pdev->dev.platform_data = portal;
128027 + ret = platform_device_add(portal->pdev);
128028 + if (ret)
128029 + goto fail_devadd;
128030 + memset(&portal->cb, 0, sizeof(portal->cb));
128031 + /* Write-to-clear any stale interrupt status bits */
128032 + bm_isr_disable_write(__p, 0xffffffff);
128033 + portal->irq_sources = 0;
128034 + bm_isr_enable_write(__p, portal->irq_sources);
128035 + bm_isr_status_clear(__p, 0xffffffff);
128036 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
128037 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
128038 + portal)) {
128039 + pr_err("request_irq() failed\n");
128040 + goto fail_irq;
128041 + }
128042 + if ((config->public_cfg.cpu != -1) &&
128043 + irq_can_set_affinity(config->public_cfg.irq) &&
128044 + irq_set_affinity(config->public_cfg.irq,
128045 + cpumask_of(config->public_cfg.cpu))) {
128046 + pr_err("irq_set_affinity() failed %s\n", portal->irqname);
128047 + goto fail_affinity;
128048 + }
128049 +
128050 + /* Need RCR to be empty before continuing */
128051 + ret = bm_rcr_get_fill(__p);
128052 + if (ret) {
128053 + pr_err("Bman RCR unclean\n");
128054 + goto fail_rcr_empty;
128055 + }
128056 + /* Success */
128057 + portal->config = config;
128058 +
128059 + bm_isr_disable_write(__p, 0);
128060 + bm_isr_uninhibit(__p);
128061 + return portal;
128062 +fail_rcr_empty:
128063 +fail_affinity:
128064 + free_irq(config->public_cfg.irq, portal);
128065 +fail_irq:
128066 + platform_device_del(portal->pdev);
128067 +fail_devadd:
128068 + platform_device_put(portal->pdev);
128069 +fail_devalloc:
128070 + kfree(portal->pools);
128071 +fail_pools:
128072 + bm_isr_finish(__p);
128073 +fail_isr:
128074 + bm_mc_finish(__p);
128075 +fail_mc:
128076 + bm_rcr_finish(__p);
128077 +fail_rcr:
128078 + if (portal->alloced)
128079 + kfree(portal);
128080 + return NULL;
128081 +}
128082 +
128083 +struct bman_portal *bman_create_affine_portal(
128084 + const struct bm_portal_config *config)
128085 +{
128086 + struct bman_portal *portal;
128087 +
128088 + portal = &per_cpu(bman_affine_portal, config->public_cfg.cpu);
128089 + portal = bman_create_portal(portal, config);
128090 + if (portal) {
128091 + spin_lock(&affine_mask_lock);
128092 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
128093 + spin_unlock(&affine_mask_lock);
128094 + }
128095 + return portal;
128096 +}
128097 +
128098 +
128099 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
128100 + int cpu)
128101 +{
128102 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
128103 + struct bman_portal *p;
128104 + p = &per_cpu(bman_affine_portal, cpu);
128105 + BUG_ON(p->config);
128106 + BUG_ON(p->is_shared);
128107 + BUG_ON(!redirect->config->public_cfg.is_shared);
128108 + p->irq_sources = 0;
128109 + p->sharing_redirect = redirect;
128110 + return p;
128111 +#else
128112 + BUG();
128113 + return NULL;
128114 +#endif
128115 +}
128116 +
128117 +void bman_destroy_portal(struct bman_portal *bm)
128118 +{
128119 + const struct bm_portal_config *pcfg;
128120 + pcfg = bm->config;
128121 + bm_rcr_cce_update(&bm->p);
128122 + bm_rcr_cce_update(&bm->p);
128123 +
128124 + free_irq(pcfg->public_cfg.irq, bm);
128125 +
128126 + kfree(bm->pools);
128127 + bm_isr_finish(&bm->p);
128128 + bm_mc_finish(&bm->p);
128129 + bm_rcr_finish(&bm->p);
128130 + bm->config = NULL;
128131 + if (bm->alloced)
128132 + kfree(bm);
128133 +}
128134 +
128135 +const struct bm_portal_config *bman_destroy_affine_portal(void)
128136 +{
128137 + struct bman_portal *bm = get_raw_affine_portal();
128138 + const struct bm_portal_config *pcfg;
128139 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
128140 + if (bm->sharing_redirect) {
128141 + bm->sharing_redirect = NULL;
128142 + put_affine_portal();
128143 + return NULL;
128144 + }
128145 + bm->is_shared = 0;
128146 +#endif
128147 + pcfg = bm->config;
128148 + bman_destroy_portal(bm);
128149 + spin_lock(&affine_mask_lock);
128150 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &affine_mask);
128151 + spin_unlock(&affine_mask_lock);
128152 + put_affine_portal();
128153 + return pcfg;
128154 +}
128155 +
128156 +/* When release logic waits on available RCR space, we need a global waitqueue
128157 + * in the case of "affine" use (as the waits wake on different cpus which means
128158 + * different portals - so we can't wait on any per-portal waitqueue). */
128159 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
128160 +
128161 +static u32 __poll_portal_slow(struct bman_portal *p, u32 is)
128162 +{
128163 + struct bman_depletion tmp;
128164 + u32 ret = is;
128165 +
128166 + /* There is a gotcha to be aware of. If we do the query before clearing
128167 + * the status register, we may miss state changes that occur between the
128168 + * two. If we write to clear the status register before the query, the
128169 + * cache-enabled query command may overtake the status register write
128170 + * unless we use a heavyweight sync (which we don't want). Instead, we
128171 + * write-to-clear the status register then *read it back* before doing
128172 + * the query, hence the odd while loop with the 'is' accumulation. */
128173 + if (is & BM_PIRQ_BSCN) {
128174 + struct bm_mc_result *mcr;
128175 + __maybe_unused unsigned long irqflags;
128176 + unsigned int i, j;
128177 + u32 __is;
128178 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
128179 + while ((__is = bm_isr_status_read(&p->p)) & BM_PIRQ_BSCN) {
128180 + is |= __is;
128181 + bm_isr_status_clear(&p->p, BM_PIRQ_BSCN);
128182 + }
128183 + is &= ~BM_PIRQ_BSCN;
128184 + PORTAL_IRQ_LOCK(p, irqflags);
128185 + bm_mc_start(&p->p);
128186 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
128187 + while (!(mcr = bm_mc_result(&p->p)))
128188 + cpu_relax();
128189 + tmp = mcr->query.ds.state;
128190 + tmp.__state[0] = be32_to_cpu(tmp.__state[0]);
128191 + tmp.__state[1] = be32_to_cpu(tmp.__state[1]);
128192 + PORTAL_IRQ_UNLOCK(p, irqflags);
128193 + for (i = 0; i < 2; i++) {
128194 + int idx = i * 32;
128195 + /* tmp is a mask of currently-depleted pools.
128196 + * pools[0] is mask of those we care about.
128197 + * pools[1] is our previous view (we only want to
128198 + * be told about changes). */
128199 + tmp.__state[i] &= p->pools[0].__state[i];
128200 + if (tmp.__state[i] == p->pools[1].__state[i])
128201 + /* fast-path, nothing to see, move along */
128202 + continue;
128203 + for (j = 0; j <= 31; j++, idx++) {
128204 + struct bman_pool *pool = p->cb[idx];
128205 + int b4 = bman_depletion_get(&p->pools[1], idx);
128206 + int af = bman_depletion_get(&tmp, idx);
128207 + if (b4 == af)
128208 + continue;
128209 + while (pool) {
128210 + pool->params.cb(p, pool,
128211 + pool->params.cb_ctx, af);
128212 + pool = pool->next;
128213 + }
128214 + }
128215 + }
128216 + p->pools[1] = tmp;
128217 + }
128218 +
128219 + if (is & BM_PIRQ_RCRI) {
128220 + __maybe_unused unsigned long irqflags;
128221 + PORTAL_IRQ_LOCK(p, irqflags);
128222 + bm_rcr_cce_update(&p->p);
128223 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128224 + /* If waiting for sync, we only cancel the interrupt threshold
128225 + * when the ring utilisation hits zero. */
128226 + if (p->rcri_owned) {
128227 + if (!bm_rcr_get_fill(&p->p)) {
128228 + p->rcri_owned = NULL;
128229 + bm_rcr_set_ithresh(&p->p, 0);
128230 + }
128231 + } else
128232 +#endif
128233 + bm_rcr_set_ithresh(&p->p, 0);
128234 + PORTAL_IRQ_UNLOCK(p, irqflags);
128235 + wake_up(&affine_queue);
128236 + bm_isr_status_clear(&p->p, BM_PIRQ_RCRI);
128237 + is &= ~BM_PIRQ_RCRI;
128238 + }
128239 +
128240 + /* There should be no status register bits left undefined */
128241 + DPA_ASSERT(!is);
128242 + return ret;
128243 +}
128244 +
128245 +const struct bman_portal_config *bman_get_portal_config(void)
128246 +{
128247 + struct bman_portal *p = get_affine_portal();
128248 + const struct bman_portal_config *ret = &p->config->public_cfg;
128249 + put_affine_portal();
128250 + return ret;
128251 +}
128252 +EXPORT_SYMBOL(bman_get_portal_config);
128253 +
128254 +u32 bman_irqsource_get(void)
128255 +{
128256 + struct bman_portal *p = get_raw_affine_portal();
128257 + u32 ret = p->irq_sources & BM_PIRQ_VISIBLE;
128258 + put_affine_portal();
128259 + return ret;
128260 +}
128261 +EXPORT_SYMBOL(bman_irqsource_get);
128262 +
128263 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits)
128264 +{
128265 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
128266 + if (p->sharing_redirect)
128267 + return -EINVAL;
128268 + else
128269 +#endif
128270 + {
128271 + __maybe_unused unsigned long irqflags;
128272 + PORTAL_IRQ_LOCK(p, irqflags);
128273 + set_bits(bits & BM_PIRQ_VISIBLE, &p->irq_sources);
128274 + bm_isr_enable_write(&p->p, p->irq_sources);
128275 + PORTAL_IRQ_UNLOCK(p, irqflags);
128276 + }
128277 + return 0;
128278 +}
128279 +EXPORT_SYMBOL(bman_p_irqsource_add);
128280 +
128281 +int bman_irqsource_add(__maybe_unused u32 bits)
128282 +{
128283 + struct bman_portal *p = get_raw_affine_portal();
128284 + int ret = 0;
128285 + ret = bman_p_irqsource_add(p, bits);
128286 + put_affine_portal();
128287 + return ret;
128288 +}
128289 +EXPORT_SYMBOL(bman_irqsource_add);
128290 +
128291 +int bman_irqsource_remove(u32 bits)
128292 +{
128293 + struct bman_portal *p = get_raw_affine_portal();
128294 + __maybe_unused unsigned long irqflags;
128295 + u32 ier;
128296 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
128297 + if (p->sharing_redirect) {
128298 + put_affine_portal();
128299 + return -EINVAL;
128300 + }
128301 +#endif
128302 + /* Our interrupt handler only processes+clears status register bits that
128303 + * are in p->irq_sources. As we're trimming that mask, if one of them
128304 + * were to assert in the status register just before we remove it from
128305 + * the enable register, there would be an interrupt-storm when we
128306 + * release the IRQ lock. So we wait for the enable register update to
128307 + * take effect in h/w (by reading it back) and then clear all other bits
128308 + * in the status register. Ie. we clear them from ISR once it's certain
128309 + * IER won't allow them to reassert. */
128310 + PORTAL_IRQ_LOCK(p, irqflags);
128311 + bits &= BM_PIRQ_VISIBLE;
128312 + clear_bits(bits, &p->irq_sources);
128313 + bm_isr_enable_write(&p->p, p->irq_sources);
128314 + ier = bm_isr_enable_read(&p->p);
128315 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
128316 + * data-dependency, ie. to protect against re-ordering. */
128317 + bm_isr_status_clear(&p->p, ~ier);
128318 + PORTAL_IRQ_UNLOCK(p, irqflags);
128319 + put_affine_portal();
128320 + return 0;
128321 +}
128322 +EXPORT_SYMBOL(bman_irqsource_remove);
128323 +
128324 +const cpumask_t *bman_affine_cpus(void)
128325 +{
128326 + return &affine_mask;
128327 +}
128328 +EXPORT_SYMBOL(bman_affine_cpus);
128329 +
128330 +u32 bman_poll_slow(void)
128331 +{
128332 + struct bman_portal *p = get_poll_portal();
128333 + u32 ret;
128334 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
128335 + if (unlikely(p->sharing_redirect))
128336 + ret = (u32)-1;
128337 + else
128338 +#endif
128339 + {
128340 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
128341 + ret = __poll_portal_slow(p, is);
128342 + bm_isr_status_clear(&p->p, ret);
128343 + }
128344 + put_poll_portal();
128345 + return ret;
128346 +}
128347 +EXPORT_SYMBOL(bman_poll_slow);
128348 +
128349 +/* Legacy wrapper */
128350 +void bman_poll(void)
128351 +{
128352 + struct bman_portal *p = get_poll_portal();
128353 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
128354 + if (unlikely(p->sharing_redirect))
128355 + goto done;
128356 +#endif
128357 + if (!(p->slowpoll--)) {
128358 + u32 is = bm_isr_status_read(&p->p) & ~p->irq_sources;
128359 + u32 active = __poll_portal_slow(p, is);
128360 + if (active)
128361 + p->slowpoll = SLOW_POLL_BUSY;
128362 + else
128363 + p->slowpoll = SLOW_POLL_IDLE;
128364 + }
128365 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
128366 +done:
128367 +#endif
128368 + put_poll_portal();
128369 +}
128370 +EXPORT_SYMBOL(bman_poll);
128371 +
128372 +static const u32 zero_thresholds[4] = {0, 0, 0, 0};
128373 +
128374 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params)
128375 +{
128376 + struct bman_pool *pool = NULL;
128377 + u32 bpid;
128378 +
128379 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID) {
128380 + int ret = bman_alloc_bpid(&bpid);
128381 + if (ret)
128382 + return NULL;
128383 + } else {
128384 + if (params->bpid >= bman_pool_max)
128385 + return NULL;
128386 + bpid = params->bpid;
128387 + }
128388 +#ifdef CONFIG_FSL_BMAN_CONFIG
128389 + if (params->flags & BMAN_POOL_FLAG_THRESH) {
128390 + int ret = bm_pool_set(bpid, params->thresholds);
128391 + if (ret)
128392 + goto err;
128393 + }
128394 +#else
128395 + if (params->flags & BMAN_POOL_FLAG_THRESH)
128396 + goto err;
128397 +#endif
128398 + pool = kmalloc(sizeof(*pool), GFP_KERNEL);
128399 + if (!pool)
128400 + goto err;
128401 + pool->sp = NULL;
128402 + pool->sp_fill = 0;
128403 + pool->params = *params;
128404 +#ifdef CONFIG_FSL_DPA_CHECKING
128405 + atomic_set(&pool->in_use, 1);
128406 +#endif
128407 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
128408 + pool->params.bpid = bpid;
128409 + if (params->flags & BMAN_POOL_FLAG_STOCKPILE) {
128410 + pool->sp = kmalloc(sizeof(struct bm_buffer) * BMAN_STOCKPILE_SZ,
128411 + GFP_KERNEL);
128412 + if (!pool->sp)
128413 + goto err;
128414 + }
128415 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION) {
128416 + struct bman_portal *p = get_affine_portal();
128417 + if (!p->pools || !bman_depletion_get(&p->pools[0], bpid)) {
128418 + pr_err("Depletion events disabled for bpid %d\n", bpid);
128419 + goto err;
128420 + }
128421 + depletion_link(p, pool);
128422 + put_affine_portal();
128423 + }
128424 + return pool;
128425 +err:
128426 +#ifdef CONFIG_FSL_BMAN_CONFIG
128427 + if (params->flags & BMAN_POOL_FLAG_THRESH)
128428 + bm_pool_set(bpid, zero_thresholds);
128429 +#endif
128430 + if (params->flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
128431 + bman_release_bpid(bpid);
128432 + if (pool) {
128433 + kfree(pool->sp);
128434 + kfree(pool);
128435 + }
128436 + return NULL;
128437 +}
128438 +EXPORT_SYMBOL(bman_new_pool);
128439 +
128440 +void bman_free_pool(struct bman_pool *pool)
128441 +{
128442 +#ifdef CONFIG_FSL_BMAN_CONFIG
128443 + if (pool->params.flags & BMAN_POOL_FLAG_THRESH)
128444 + bm_pool_set(pool->params.bpid, zero_thresholds);
128445 +#endif
128446 + if (pool->params.flags & BMAN_POOL_FLAG_DEPLETION)
128447 + depletion_unlink(pool);
128448 + if (pool->params.flags & BMAN_POOL_FLAG_STOCKPILE) {
128449 + if (pool->sp_fill)
128450 + pr_err("Stockpile not flushed, has %u in bpid %u.\n",
128451 + pool->sp_fill, pool->params.bpid);
128452 + kfree(pool->sp);
128453 + pool->sp = NULL;
128454 + pool->params.flags ^= BMAN_POOL_FLAG_STOCKPILE;
128455 + }
128456 + if (pool->params.flags & BMAN_POOL_FLAG_DYNAMIC_BPID)
128457 + bman_release_bpid(pool->params.bpid);
128458 + kfree(pool);
128459 +}
128460 +EXPORT_SYMBOL(bman_free_pool);
128461 +
128462 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool)
128463 +{
128464 + return &pool->params;
128465 +}
128466 +EXPORT_SYMBOL(bman_get_params);
128467 +
128468 +static noinline void update_rcr_ci(struct bman_portal *p, u8 avail)
128469 +{
128470 + if (avail)
128471 + bm_rcr_cce_prefetch(&p->p);
128472 + else
128473 + bm_rcr_cce_update(&p->p);
128474 +}
128475 +
128476 +int bman_rcr_is_empty(void)
128477 +{
128478 + __maybe_unused unsigned long irqflags;
128479 + struct bman_portal *p = get_affine_portal();
128480 + u8 avail;
128481 +
128482 + PORTAL_IRQ_LOCK(p, irqflags);
128483 + update_rcr_ci(p, 0);
128484 + avail = bm_rcr_get_fill(&p->p);
128485 + PORTAL_IRQ_UNLOCK(p, irqflags);
128486 + put_affine_portal();
128487 + return avail == 0;
128488 +}
128489 +EXPORT_SYMBOL(bman_rcr_is_empty);
128490 +
128491 +static inline struct bm_rcr_entry *try_rel_start(struct bman_portal **p,
128492 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
128493 + __maybe_unused struct bman_pool *pool,
128494 +#endif
128495 + __maybe_unused unsigned long *irqflags,
128496 + __maybe_unused u32 flags)
128497 +{
128498 + struct bm_rcr_entry *r;
128499 + u8 avail;
128500 +
128501 + *p = get_affine_portal();
128502 + PORTAL_IRQ_LOCK(*p, (*irqflags));
128503 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128504 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
128505 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
128506 + if ((*p)->rcri_owned) {
128507 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
128508 + put_affine_portal();
128509 + return NULL;
128510 + }
128511 + (*p)->rcri_owned = pool;
128512 + }
128513 +#endif
128514 + avail = bm_rcr_get_avail(&(*p)->p);
128515 + if (avail < 2)
128516 + update_rcr_ci(*p, avail);
128517 + r = bm_rcr_start(&(*p)->p);
128518 + if (unlikely(!r)) {
128519 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128520 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
128521 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC)))
128522 + (*p)->rcri_owned = NULL;
128523 +#endif
128524 + PORTAL_IRQ_UNLOCK(*p, (*irqflags));
128525 + put_affine_portal();
128526 + }
128527 + return r;
128528 +}
128529 +
128530 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
128531 +static noinline struct bm_rcr_entry *__wait_rel_start(struct bman_portal **p,
128532 + struct bman_pool *pool,
128533 + __maybe_unused unsigned long *irqflags,
128534 + u32 flags)
128535 +{
128536 + struct bm_rcr_entry *rcr = try_rel_start(p, pool, irqflags, flags);
128537 + if (!rcr)
128538 + bm_rcr_set_ithresh(&(*p)->p, 1);
128539 + return rcr;
128540 +}
128541 +
128542 +static noinline struct bm_rcr_entry *wait_rel_start(struct bman_portal **p,
128543 + struct bman_pool *pool,
128544 + __maybe_unused unsigned long *irqflags,
128545 + u32 flags)
128546 +{
128547 + struct bm_rcr_entry *rcr;
128548 +#ifndef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128549 + pool = NULL;
128550 +#endif
128551 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
128552 + /* NB: return NULL if signal occurs before completion. Signal
128553 + * can occur during return. Caller must check for signal */
128554 + wait_event_interruptible(affine_queue,
128555 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
128556 + else
128557 + wait_event(affine_queue,
128558 + (rcr = __wait_rel_start(p, pool, irqflags, flags)));
128559 + return rcr;
128560 +}
128561 +#endif
128562 +
128563 +static inline int __bman_release(struct bman_pool *pool,
128564 + const struct bm_buffer *bufs, u8 num, u32 flags)
128565 +{
128566 + struct bman_portal *p;
128567 + struct bm_rcr_entry *r;
128568 + __maybe_unused unsigned long irqflags;
128569 + u32 i = num - 1;
128570 +
128571 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
128572 + if (flags & BMAN_RELEASE_FLAG_WAIT)
128573 + r = wait_rel_start(&p, pool, &irqflags, flags);
128574 + else
128575 + r = try_rel_start(&p, pool, &irqflags, flags);
128576 +#else
128577 + r = try_rel_start(&p, &irqflags, flags);
128578 +#endif
128579 + if (!r)
128580 + return -EBUSY;
128581 + /* We can copy all but the first entry, as this can trigger badness
128582 + * with the valid-bit. Use the overlay to mask the verb byte. */
128583 + r->bufs[0].opaque =
128584 + ((cpu_to_be64((bufs[0].opaque |
128585 + ((u64)pool->params.bpid<<48))
128586 + & 0x00ffffffffffffff)));
128587 + if (i) {
128588 + for (i = 1; i < num; i++)
128589 + r->bufs[i].opaque =
128590 + cpu_to_be64(bufs[i].opaque);
128591 + }
128592 +
128593 + bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
128594 + (num & BM_RCR_VERB_BUFCOUNT_MASK));
128595 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128596 + /* if we wish to sync we need to set the threshold after h/w sees the
128597 + * new ring entry. As we're mixing cache-enabled and cache-inhibited
128598 + * accesses, this requires a heavy-weight sync. */
128599 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
128600 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
128601 + hwsync();
128602 + bm_rcr_set_ithresh(&p->p, 1);
128603 + }
128604 +#endif
128605 + PORTAL_IRQ_UNLOCK(p, irqflags);
128606 + put_affine_portal();
128607 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
128608 + if (unlikely((flags & BMAN_RELEASE_FLAG_WAIT) &&
128609 + (flags & BMAN_RELEASE_FLAG_WAIT_SYNC))) {
128610 + if (flags & BMAN_RELEASE_FLAG_WAIT_INT)
128611 + /* NB: return success even if signal occurs before
128612 + * condition is true. pvb_commit guarantees success */
128613 + wait_event_interruptible(affine_queue,
128614 + (p->rcri_owned != pool));
128615 + else
128616 + wait_event(affine_queue, (p->rcri_owned != pool));
128617 + }
128618 +#endif
128619 + return 0;
128620 +}
128621 +
128622 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
128623 + u32 flags)
128624 +{
128625 + int ret;
128626 +#ifdef CONFIG_FSL_DPA_CHECKING
128627 + if (!num || (num > 8))
128628 + return -EINVAL;
128629 + if (pool->params.flags & BMAN_POOL_FLAG_NO_RELEASE)
128630 + return -EINVAL;
128631 +#endif
128632 + /* Without stockpile, this API is a pass-through to the h/w operation */
128633 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
128634 + return __bman_release(pool, bufs, num, flags);
128635 +#ifdef CONFIG_FSL_DPA_CHECKING
128636 + if (!atomic_dec_and_test(&pool->in_use)) {
128637 + pr_crit("Parallel attempts to enter bman_released() detected.");
128638 + panic("only one instance of bman_released/acquired allowed");
128639 + }
128640 +#endif
128641 + /* Two movements of buffers are possible, and can occur in either order.
128642 + * A: moving buffers from the caller to the stockpile.
128643 + * B: moving buffers from the stockpile to hardware.
128644 + * Order 1: if there is already enough space in the stockpile for A
128645 + * then we want to do A first, and only do B if we trigger the
128646 + * stockpile-high threshold.
128647 + * Order 2: if there is not enough space in the stockpile for A, then
128648 + * we want to do B first, then do A if B had succeeded. However in this
128649 + * case B is dependent on how many buffers the user needs to release,
128650 + * not the stockpile-high threshold.
128651 + * Due to the different handling of B between the two cases, putting A
128652 + * and B in a while() loop would require quite obscure logic, so handle
128653 + * the different sequences explicitly. */
128654 + if ((pool->sp_fill + num) <= BMAN_STOCKPILE_SZ) {
128655 + /* Order 1: do A */
128656 + copy_words(pool->sp + pool->sp_fill, bufs,
128657 + sizeof(struct bm_buffer) * num);
128658 + pool->sp_fill += num;
128659 + /* do B relative to STOCKPILE_HIGH */
128660 + while (pool->sp_fill >= BMAN_STOCKPILE_HIGH) {
128661 + ret = __bman_release(pool,
128662 + pool->sp + (pool->sp_fill - 8), 8,
128663 + flags);
128664 + if (ret >= 0)
128665 + pool->sp_fill -= 8;
128666 + }
128667 + } else {
128668 + /* Order 2: do B relative to 'num' */
128669 + do {
128670 + ret = __bman_release(pool,
128671 + pool->sp + (pool->sp_fill - 8), 8,
128672 + flags);
128673 + if (ret < 0)
128674 + /* failure */
128675 + goto release_done;
128676 + pool->sp_fill -= 8;
128677 + } while ((pool->sp_fill + num) > BMAN_STOCKPILE_SZ);
128678 + /* do A */
128679 + copy_words(pool->sp + pool->sp_fill, bufs,
128680 + sizeof(struct bm_buffer) * num);
128681 + pool->sp_fill += num;
128682 + }
128683 + /* success */
128684 + ret = 0;
128685 +release_done:
128686 +#ifdef CONFIG_FSL_DPA_CHECKING
128687 + atomic_inc(&pool->in_use);
128688 +#endif
128689 + return ret;
128690 +}
128691 +EXPORT_SYMBOL(bman_release);
128692 +
128693 +static inline int __bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs,
128694 + u8 num)
128695 +{
128696 + struct bman_portal *p = get_affine_portal();
128697 + struct bm_mc_command *mcc;
128698 + struct bm_mc_result *mcr;
128699 + __maybe_unused unsigned long irqflags;
128700 + int ret, i;
128701 +
128702 + PORTAL_IRQ_LOCK(p, irqflags);
128703 + mcc = bm_mc_start(&p->p);
128704 + mcc->acquire.bpid = pool->params.bpid;
128705 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
128706 + (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
128707 + while (!(mcr = bm_mc_result(&p->p)))
128708 + cpu_relax();
128709 + ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
128710 + if (bufs) {
128711 + for (i = 0; i < num; i++)
128712 + bufs[i].opaque =
128713 + be64_to_cpu(mcr->acquire.bufs[i].opaque);
128714 + }
128715 + PORTAL_IRQ_UNLOCK(p, irqflags);
128716 + put_affine_portal();
128717 + if (ret != num)
128718 + ret = -ENOMEM;
128719 + return ret;
128720 +}
128721 +
128722 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
128723 + u32 flags)
128724 +{
128725 + int ret;
128726 +#ifdef CONFIG_FSL_DPA_CHECKING
128727 + if (!num || (num > 8))
128728 + return -EINVAL;
128729 + if (pool->params.flags & BMAN_POOL_FLAG_ONLY_RELEASE)
128730 + return -EINVAL;
128731 +#endif
128732 + /* Without stockpile, this API is a pass-through to the h/w operation */
128733 + if (!(pool->params.flags & BMAN_POOL_FLAG_STOCKPILE))
128734 + return __bman_acquire(pool, bufs, num);
128735 +#ifdef CONFIG_FSL_DPA_CHECKING
128736 + if (!atomic_dec_and_test(&pool->in_use)) {
128737 + pr_crit("Parallel attempts to enter bman_acquire() detected.");
128738 + panic("only one instance of bman_released/acquired allowed");
128739 + }
128740 +#endif
128741 + /* Two movements of buffers are possible, and can occur in either order.
128742 + * A: moving buffers from stockpile to the caller.
128743 + * B: moving buffers from hardware to the stockpile.
128744 + * Order 1: if there are already enough buffers in the stockpile for A
128745 + * then we want to do A first, and only do B if we trigger the
128746 + * stockpile-low threshold.
128747 + * Order 2: if there are not enough buffers in the stockpile for A,
128748 + * then we want to do B first, then do A if B had succeeded. However in
128749 + * this case B is dependent on how many buffers the user needs, not the
128750 + * stockpile-low threshold.
128751 + * Due to the different handling of B between the two cases, putting A
128752 + * and B in a while() loop would require quite obscure logic, so handle
128753 + * the different sequences explicitly. */
128754 + if (num <= pool->sp_fill) {
128755 + /* Order 1: do A */
128756 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
128757 + sizeof(struct bm_buffer) * num);
128758 + pool->sp_fill -= num;
128759 + /* do B relative to STOCKPILE_LOW */
128760 + while (pool->sp_fill <= BMAN_STOCKPILE_LOW) {
128761 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
128762 + if (ret < 0)
128763 + ret = __bman_acquire(pool,
128764 + pool->sp + pool->sp_fill, 1);
128765 + if (ret < 0)
128766 + break;
128767 + pool->sp_fill += ret;
128768 + }
128769 + } else {
128770 + /* Order 2: do B relative to 'num' */
128771 + do {
128772 + ret = __bman_acquire(pool, pool->sp + pool->sp_fill, 8);
128773 + if (ret < 0)
128774 + ret = __bman_acquire(pool,
128775 + pool->sp + pool->sp_fill, 1);
128776 + if (ret < 0)
128777 + /* failure */
128778 + goto acquire_done;
128779 + pool->sp_fill += ret;
128780 + } while (pool->sp_fill < num);
128781 + /* do A */
128782 + copy_words(bufs, pool->sp + (pool->sp_fill - num),
128783 + sizeof(struct bm_buffer) * num);
128784 + pool->sp_fill -= num;
128785 + }
128786 + /* success */
128787 + ret = num;
128788 +acquire_done:
128789 +#ifdef CONFIG_FSL_DPA_CHECKING
128790 + atomic_inc(&pool->in_use);
128791 +#endif
128792 + return ret;
128793 +}
128794 +EXPORT_SYMBOL(bman_acquire);
128795 +
128796 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags)
128797 +{
128798 + u8 num;
128799 + int ret;
128800 +
128801 + while (pool->sp_fill) {
128802 + num = ((pool->sp_fill > 8) ? 8 : pool->sp_fill);
128803 + ret = __bman_release(pool, pool->sp + (pool->sp_fill - num),
128804 + num, flags);
128805 + if (ret)
128806 + return ret;
128807 + pool->sp_fill -= num;
128808 + }
128809 + return 0;
128810 +}
128811 +EXPORT_SYMBOL(bman_flush_stockpile);
128812 +
128813 +int bman_query_pools(struct bm_pool_state *state)
128814 +{
128815 + struct bman_portal *p = get_affine_portal();
128816 + struct bm_mc_result *mcr;
128817 + __maybe_unused unsigned long irqflags;
128818 +
128819 + PORTAL_IRQ_LOCK(p, irqflags);
128820 + bm_mc_start(&p->p);
128821 + bm_mc_commit(&p->p, BM_MCC_VERB_CMD_QUERY);
128822 + while (!(mcr = bm_mc_result(&p->p)))
128823 + cpu_relax();
128824 + DPA_ASSERT((mcr->verb & BM_MCR_VERB_CMD_MASK) == BM_MCR_VERB_CMD_QUERY);
128825 + *state = mcr->query;
128826 + state->as.state.__state[0] = be32_to_cpu(state->as.state.__state[0]);
128827 + state->as.state.__state[1] = be32_to_cpu(state->as.state.__state[1]);
128828 + state->ds.state.__state[0] = be32_to_cpu(state->ds.state.__state[0]);
128829 + state->ds.state.__state[1] = be32_to_cpu(state->ds.state.__state[1]);
128830 + PORTAL_IRQ_UNLOCK(p, irqflags);
128831 + put_affine_portal();
128832 + return 0;
128833 +}
128834 +EXPORT_SYMBOL(bman_query_pools);
128835 +
128836 +#ifdef CONFIG_FSL_BMAN_CONFIG
128837 +u32 bman_query_free_buffers(struct bman_pool *pool)
128838 +{
128839 + return bm_pool_free_buffers(pool->params.bpid);
128840 +}
128841 +EXPORT_SYMBOL(bman_query_free_buffers);
128842 +
128843 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds)
128844 +{
128845 + u32 bpid;
128846 +
128847 + bpid = bman_get_params(pool)->bpid;
128848 +
128849 + return bm_pool_set(bpid, thresholds);
128850 +}
128851 +EXPORT_SYMBOL(bman_update_pool_thresholds);
128852 +#endif
128853 +
128854 +int bman_shutdown_pool(u32 bpid)
128855 +{
128856 + struct bman_portal *p = get_affine_portal();
128857 + __maybe_unused unsigned long irqflags;
128858 + int ret;
128859 +
128860 + PORTAL_IRQ_LOCK(p, irqflags);
128861 + ret = bm_shutdown_pool(&p->p, bpid);
128862 + PORTAL_IRQ_UNLOCK(p, irqflags);
128863 + put_affine_portal();
128864 + return ret;
128865 +}
128866 +EXPORT_SYMBOL(bman_shutdown_pool);
128867 +
128868 +const struct bm_portal_config *bman_get_bm_portal_config(
128869 + struct bman_portal *portal)
128870 +{
128871 + return portal->sharing_redirect ? NULL : portal->config;
128872 +}
128873 --- /dev/null
128874 +++ b/drivers/staging/fsl_qbman/bman_low.h
128875 @@ -0,0 +1,565 @@
128876 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
128877 + *
128878 + * Redistribution and use in source and binary forms, with or without
128879 + * modification, are permitted provided that the following conditions are met:
128880 + * * Redistributions of source code must retain the above copyright
128881 + * notice, this list of conditions and the following disclaimer.
128882 + * * Redistributions in binary form must reproduce the above copyright
128883 + * notice, this list of conditions and the following disclaimer in the
128884 + * documentation and/or other materials provided with the distribution.
128885 + * * Neither the name of Freescale Semiconductor nor the
128886 + * names of its contributors may be used to endorse or promote products
128887 + * derived from this software without specific prior written permission.
128888 + *
128889 + *
128890 + * ALTERNATIVELY, this software may be distributed under the terms of the
128891 + * GNU General Public License ("GPL") as published by the Free Software
128892 + * Foundation, either version 2 of that License or (at your option) any
128893 + * later version.
128894 + *
128895 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
128896 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
128897 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128898 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
128899 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
128900 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
128901 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128902 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
128903 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
128904 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
128905 + */
128906 +
128907 +#include "bman_private.h"
128908 +
128909 +/***************************/
128910 +/* Portal register assists */
128911 +/***************************/
128912 +
128913 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
128914 +
128915 +/* Cache-inhibited register offsets */
128916 +#define BM_REG_RCR_PI_CINH 0x0000
128917 +#define BM_REG_RCR_CI_CINH 0x0004
128918 +#define BM_REG_RCR_ITR 0x0008
128919 +#define BM_REG_CFG 0x0100
128920 +#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
128921 +#define BM_REG_ISR 0x0e00
128922 +#define BM_REG_IIR 0x0e0c
128923 +
128924 +/* Cache-enabled register offsets */
128925 +#define BM_CL_CR 0x0000
128926 +#define BM_CL_RR0 0x0100
128927 +#define BM_CL_RR1 0x0140
128928 +#define BM_CL_RCR 0x1000
128929 +#define BM_CL_RCR_PI_CENA 0x3000
128930 +#define BM_CL_RCR_CI_CENA 0x3100
128931 +
128932 +#endif
128933 +
128934 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
128935 +
128936 +/* Cache-inhibited register offsets */
128937 +#define BM_REG_RCR_PI_CINH 0x3000
128938 +#define BM_REG_RCR_CI_CINH 0x3100
128939 +#define BM_REG_RCR_ITR 0x3200
128940 +#define BM_REG_CFG 0x3300
128941 +#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
128942 +#define BM_REG_ISR 0x3e00
128943 +#define BM_REG_IIR 0x3ec0
128944 +
128945 +/* Cache-enabled register offsets */
128946 +#define BM_CL_CR 0x0000
128947 +#define BM_CL_RR0 0x0100
128948 +#define BM_CL_RR1 0x0140
128949 +#define BM_CL_RCR 0x1000
128950 +#define BM_CL_RCR_PI_CENA 0x3000
128951 +#define BM_CL_RCR_CI_CENA 0x3100
128952 +
128953 +#endif
128954 +
128955 +/* BTW, the drivers (and h/w programming model) already obtain the required
128956 + * synchronisation for portal accesses via lwsync(), hwsync(), and
128957 + * data-dependencies. Use of barrier()s or other order-preserving primitives
128958 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
128959 + * simply ensure that the compiler treats the portal registers as volatile (ie.
128960 + * non-coherent). */
128961 +
128962 +/* Cache-inhibited register access. */
128963 +#define __bm_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ci + (o)))
128964 +#define __bm_out(bm, o, val) __raw_writel(cpu_to_be32(val), \
128965 + (bm)->addr_ci + (o));
128966 +#define bm_in(reg) __bm_in(&portal->addr, BM_REG_##reg)
128967 +#define bm_out(reg, val) __bm_out(&portal->addr, BM_REG_##reg, val)
128968 +
128969 +/* Cache-enabled (index) register access */
128970 +#define __bm_cl_touch_ro(bm, o) dcbt_ro((bm)->addr_ce + (o))
128971 +#define __bm_cl_touch_rw(bm, o) dcbt_rw((bm)->addr_ce + (o))
128972 +#define __bm_cl_in(bm, o) be32_to_cpu(__raw_readl((bm)->addr_ce + (o)))
128973 +#define __bm_cl_out(bm, o, val) \
128974 + do { \
128975 + u32 *__tmpclout = (bm)->addr_ce + (o); \
128976 + __raw_writel(cpu_to_be32(val), __tmpclout); \
128977 + dcbf(__tmpclout); \
128978 + } while (0)
128979 +#define __bm_cl_invalidate(bm, o) dcbi((bm)->addr_ce + (o))
128980 +#define bm_cl_touch_ro(reg) __bm_cl_touch_ro(&portal->addr, BM_CL_##reg##_CENA)
128981 +#define bm_cl_touch_rw(reg) __bm_cl_touch_rw(&portal->addr, BM_CL_##reg##_CENA)
128982 +#define bm_cl_in(reg) __bm_cl_in(&portal->addr, BM_CL_##reg##_CENA)
128983 +#define bm_cl_out(reg, val) __bm_cl_out(&portal->addr, BM_CL_##reg##_CENA, val)
128984 +#define bm_cl_invalidate(reg)\
128985 + __bm_cl_invalidate(&portal->addr, BM_CL_##reg##_CENA)
128986 +
128987 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
128988 + * analysis, look at using the "extra" bit in the ring index registers to avoid
128989 + * cyclic issues. */
128990 +static inline u8 bm_cyc_diff(u8 ringsize, u8 first, u8 last)
128991 +{
128992 + /* 'first' is included, 'last' is excluded */
128993 + if (first <= last)
128994 + return last - first;
128995 + return ringsize + last - first;
128996 +}
128997 +
128998 +/* Portal modes.
128999 + * Enum types;
129000 + * pmode == production mode
129001 + * cmode == consumption mode,
129002 + * Enum values use 3 letter codes. First letter matches the portal mode,
129003 + * remaining two letters indicate;
129004 + * ci == cache-inhibited portal register
129005 + * ce == cache-enabled portal register
129006 + * vb == in-band valid-bit (cache-enabled)
129007 + */
129008 +enum bm_rcr_pmode { /* matches BCSP_CFG::RPM */
129009 + bm_rcr_pci = 0, /* PI index, cache-inhibited */
129010 + bm_rcr_pce = 1, /* PI index, cache-enabled */
129011 + bm_rcr_pvb = 2 /* valid-bit */
129012 +};
129013 +enum bm_rcr_cmode { /* s/w-only */
129014 + bm_rcr_cci, /* CI index, cache-inhibited */
129015 + bm_rcr_cce /* CI index, cache-enabled */
129016 +};
129017 +
129018 +
129019 +/* ------------------------- */
129020 +/* --- Portal structures --- */
129021 +
129022 +#define BM_RCR_SIZE 8
129023 +
129024 +struct bm_rcr {
129025 + struct bm_rcr_entry *ring, *cursor;
129026 + u8 ci, available, ithresh, vbit;
129027 +#ifdef CONFIG_FSL_DPA_CHECKING
129028 + u32 busy;
129029 + enum bm_rcr_pmode pmode;
129030 + enum bm_rcr_cmode cmode;
129031 +#endif
129032 +};
129033 +
129034 +struct bm_mc {
129035 + struct bm_mc_command *cr;
129036 + struct bm_mc_result *rr;
129037 + u8 rridx, vbit;
129038 +#ifdef CONFIG_FSL_DPA_CHECKING
129039 + enum {
129040 + /* Can only be _mc_start()ed */
129041 + mc_idle,
129042 + /* Can only be _mc_commit()ed or _mc_abort()ed */
129043 + mc_user,
129044 + /* Can only be _mc_retry()ed */
129045 + mc_hw
129046 + } state;
129047 +#endif
129048 +};
129049 +
129050 +struct bm_addr {
129051 + void __iomem *addr_ce; /* cache-enabled */
129052 + void __iomem *addr_ci; /* cache-inhibited */
129053 +};
129054 +
129055 +struct bm_portal {
129056 + struct bm_addr addr;
129057 + struct bm_rcr rcr;
129058 + struct bm_mc mc;
129059 + struct bm_portal_config config;
129060 +} ____cacheline_aligned;
129061 +
129062 +
129063 +/* --------------- */
129064 +/* --- RCR API --- */
129065 +
129066 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
129067 +#define RCR_CARRYCLEAR(p) \
129068 + (void *)((unsigned long)(p) & (~(unsigned long)(BM_RCR_SIZE << 6)))
129069 +
129070 +/* Bit-wise logic to convert a ring pointer to a ring index */
129071 +static inline u8 RCR_PTR2IDX(struct bm_rcr_entry *e)
129072 +{
129073 + return ((uintptr_t)e >> 6) & (BM_RCR_SIZE - 1);
129074 +}
129075 +
129076 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
129077 +static inline void RCR_INC(struct bm_rcr *rcr)
129078 +{
129079 + /* NB: this is odd-looking, but experiments show that it generates
129080 + * fast code with essentially no branching overheads. We increment to
129081 + * the next RCR pointer and handle overflow and 'vbit'. */
129082 + struct bm_rcr_entry *partial = rcr->cursor + 1;
129083 + rcr->cursor = RCR_CARRYCLEAR(partial);
129084 + if (partial != rcr->cursor)
129085 + rcr->vbit ^= BM_RCR_VERB_VBIT;
129086 +}
129087 +
129088 +static inline int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
129089 + __maybe_unused enum bm_rcr_cmode cmode)
129090 +{
129091 + /* This use of 'register', as well as all other occurrences, is because
129092 + * it has been observed to generate much faster code with gcc than is
129093 + * otherwise the case. */
129094 + register struct bm_rcr *rcr = &portal->rcr;
129095 + u32 cfg;
129096 + u8 pi;
129097 +
129098 + rcr->ring = portal->addr.addr_ce + BM_CL_RCR;
129099 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
129100 +
129101 + pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
129102 + rcr->cursor = rcr->ring + pi;
129103 + rcr->vbit = (bm_in(RCR_PI_CINH) & BM_RCR_SIZE) ? BM_RCR_VERB_VBIT : 0;
129104 + rcr->available = BM_RCR_SIZE - 1
129105 + - bm_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
129106 + rcr->ithresh = bm_in(RCR_ITR);
129107 +#ifdef CONFIG_FSL_DPA_CHECKING
129108 + rcr->busy = 0;
129109 + rcr->pmode = pmode;
129110 + rcr->cmode = cmode;
129111 +#endif
129112 + cfg = (bm_in(CFG) & 0xffffffe0) | (pmode & 0x3); /* BCSP_CFG::RPM */
129113 + bm_out(CFG, cfg);
129114 + return 0;
129115 +}
129116 +
129117 +static inline void bm_rcr_finish(struct bm_portal *portal)
129118 +{
129119 + register struct bm_rcr *rcr = &portal->rcr;
129120 + u8 pi = bm_in(RCR_PI_CINH) & (BM_RCR_SIZE - 1);
129121 + u8 ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
129122 + DPA_ASSERT(!rcr->busy);
129123 + if (pi != RCR_PTR2IDX(rcr->cursor))
129124 + pr_crit("losing uncommited RCR entries\n");
129125 + if (ci != rcr->ci)
129126 + pr_crit("missing existing RCR completions\n");
129127 + if (rcr->ci != RCR_PTR2IDX(rcr->cursor))
129128 + pr_crit("RCR destroyed unquiesced\n");
129129 +}
129130 +
129131 +static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
129132 +{
129133 + register struct bm_rcr *rcr = &portal->rcr;
129134 + DPA_ASSERT(!rcr->busy);
129135 + if (!rcr->available)
129136 + return NULL;
129137 +#ifdef CONFIG_FSL_DPA_CHECKING
129138 + rcr->busy = 1;
129139 +#endif
129140 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
129141 + dcbz_64(rcr->cursor);
129142 +#endif
129143 + return rcr->cursor;
129144 +}
129145 +
129146 +static inline void bm_rcr_abort(struct bm_portal *portal)
129147 +{
129148 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
129149 + DPA_ASSERT(rcr->busy);
129150 +#ifdef CONFIG_FSL_DPA_CHECKING
129151 + rcr->busy = 0;
129152 +#endif
129153 +}
129154 +
129155 +static inline struct bm_rcr_entry *bm_rcr_pend_and_next(
129156 + struct bm_portal *portal, u8 myverb)
129157 +{
129158 + register struct bm_rcr *rcr = &portal->rcr;
129159 + DPA_ASSERT(rcr->busy);
129160 + DPA_ASSERT(rcr->pmode != bm_rcr_pvb);
129161 + if (rcr->available == 1)
129162 + return NULL;
129163 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
129164 + dcbf_64(rcr->cursor);
129165 + RCR_INC(rcr);
129166 + rcr->available--;
129167 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
129168 + dcbz_64(rcr->cursor);
129169 +#endif
129170 + return rcr->cursor;
129171 +}
129172 +
129173 +static inline void bm_rcr_pci_commit(struct bm_portal *portal, u8 myverb)
129174 +{
129175 + register struct bm_rcr *rcr = &portal->rcr;
129176 + DPA_ASSERT(rcr->busy);
129177 + DPA_ASSERT(rcr->pmode == bm_rcr_pci);
129178 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
129179 + RCR_INC(rcr);
129180 + rcr->available--;
129181 + hwsync();
129182 + bm_out(RCR_PI_CINH, RCR_PTR2IDX(rcr->cursor));
129183 +#ifdef CONFIG_FSL_DPA_CHECKING
129184 + rcr->busy = 0;
129185 +#endif
129186 +}
129187 +
129188 +static inline void bm_rcr_pce_prefetch(struct bm_portal *portal)
129189 +{
129190 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
129191 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
129192 + bm_cl_invalidate(RCR_PI);
129193 + bm_cl_touch_rw(RCR_PI);
129194 +}
129195 +
129196 +static inline void bm_rcr_pce_commit(struct bm_portal *portal, u8 myverb)
129197 +{
129198 + register struct bm_rcr *rcr = &portal->rcr;
129199 + DPA_ASSERT(rcr->busy);
129200 + DPA_ASSERT(rcr->pmode == bm_rcr_pce);
129201 + rcr->cursor->__dont_write_directly__verb = myverb | rcr->vbit;
129202 + RCR_INC(rcr);
129203 + rcr->available--;
129204 + lwsync();
129205 + bm_cl_out(RCR_PI, RCR_PTR2IDX(rcr->cursor));
129206 +#ifdef CONFIG_FSL_DPA_CHECKING
129207 + rcr->busy = 0;
129208 +#endif
129209 +}
129210 +
129211 +static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
129212 +{
129213 + register struct bm_rcr *rcr = &portal->rcr;
129214 + struct bm_rcr_entry *rcursor;
129215 + DPA_ASSERT(rcr->busy);
129216 + DPA_ASSERT(rcr->pmode == bm_rcr_pvb);
129217 + lwsync();
129218 + rcursor = rcr->cursor;
129219 + rcursor->__dont_write_directly__verb = myverb | rcr->vbit;
129220 + dcbf_64(rcursor);
129221 + RCR_INC(rcr);
129222 + rcr->available--;
129223 +#ifdef CONFIG_FSL_DPA_CHECKING
129224 + rcr->busy = 0;
129225 +#endif
129226 +}
129227 +
129228 +static inline u8 bm_rcr_cci_update(struct bm_portal *portal)
129229 +{
129230 + register struct bm_rcr *rcr = &portal->rcr;
129231 + u8 diff, old_ci = rcr->ci;
129232 + DPA_ASSERT(rcr->cmode == bm_rcr_cci);
129233 + rcr->ci = bm_in(RCR_CI_CINH) & (BM_RCR_SIZE - 1);
129234 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
129235 + rcr->available += diff;
129236 + return diff;
129237 +}
129238 +
129239 +static inline void bm_rcr_cce_prefetch(struct bm_portal *portal)
129240 +{
129241 + __maybe_unused register struct bm_rcr *rcr = &portal->rcr;
129242 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
129243 + bm_cl_touch_ro(RCR_CI);
129244 +}
129245 +
129246 +static inline u8 bm_rcr_cce_update(struct bm_portal *portal)
129247 +{
129248 + register struct bm_rcr *rcr = &portal->rcr;
129249 + u8 diff, old_ci = rcr->ci;
129250 + DPA_ASSERT(rcr->cmode == bm_rcr_cce);
129251 + rcr->ci = bm_cl_in(RCR_CI) & (BM_RCR_SIZE - 1);
129252 + bm_cl_invalidate(RCR_CI);
129253 + diff = bm_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
129254 + rcr->available += diff;
129255 + return diff;
129256 +}
129257 +
129258 +static inline u8 bm_rcr_get_ithresh(struct bm_portal *portal)
129259 +{
129260 + register struct bm_rcr *rcr = &portal->rcr;
129261 + return rcr->ithresh;
129262 +}
129263 +
129264 +static inline void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
129265 +{
129266 + register struct bm_rcr *rcr = &portal->rcr;
129267 + rcr->ithresh = ithresh;
129268 + bm_out(RCR_ITR, ithresh);
129269 +}
129270 +
129271 +static inline u8 bm_rcr_get_avail(struct bm_portal *portal)
129272 +{
129273 + register struct bm_rcr *rcr = &portal->rcr;
129274 + return rcr->available;
129275 +}
129276 +
129277 +static inline u8 bm_rcr_get_fill(struct bm_portal *portal)
129278 +{
129279 + register struct bm_rcr *rcr = &portal->rcr;
129280 + return BM_RCR_SIZE - 1 - rcr->available;
129281 +}
129282 +
129283 +
129284 +/* ------------------------------ */
129285 +/* --- Management command API --- */
129286 +
129287 +static inline int bm_mc_init(struct bm_portal *portal)
129288 +{
129289 + register struct bm_mc *mc = &portal->mc;
129290 + mc->cr = portal->addr.addr_ce + BM_CL_CR;
129291 + mc->rr = portal->addr.addr_ce + BM_CL_RR0;
129292 + mc->rridx = (__raw_readb(&mc->cr->__dont_write_directly__verb) &
129293 + BM_MCC_VERB_VBIT) ? 0 : 1;
129294 + mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
129295 +#ifdef CONFIG_FSL_DPA_CHECKING
129296 + mc->state = mc_idle;
129297 +#endif
129298 + return 0;
129299 +}
129300 +
129301 +static inline void bm_mc_finish(struct bm_portal *portal)
129302 +{
129303 + __maybe_unused register struct bm_mc *mc = &portal->mc;
129304 + DPA_ASSERT(mc->state == mc_idle);
129305 +#ifdef CONFIG_FSL_DPA_CHECKING
129306 + if (mc->state != mc_idle)
129307 + pr_crit("Losing incomplete MC command\n");
129308 +#endif
129309 +}
129310 +
129311 +static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
129312 +{
129313 + register struct bm_mc *mc = &portal->mc;
129314 + DPA_ASSERT(mc->state == mc_idle);
129315 +#ifdef CONFIG_FSL_DPA_CHECKING
129316 + mc->state = mc_user;
129317 +#endif
129318 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
129319 + dcbz_64(mc->cr);
129320 +#endif
129321 + return mc->cr;
129322 +}
129323 +
129324 +static inline void bm_mc_abort(struct bm_portal *portal)
129325 +{
129326 + __maybe_unused register struct bm_mc *mc = &portal->mc;
129327 + DPA_ASSERT(mc->state == mc_user);
129328 +#ifdef CONFIG_FSL_DPA_CHECKING
129329 + mc->state = mc_idle;
129330 +#endif
129331 +}
129332 +
129333 +static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
129334 +{
129335 + register struct bm_mc *mc = &portal->mc;
129336 + struct bm_mc_result *rr = mc->rr + mc->rridx;
129337 + DPA_ASSERT(mc->state == mc_user);
129338 + lwsync();
129339 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
129340 + dcbf(mc->cr);
129341 + dcbit_ro(rr);
129342 +#ifdef CONFIG_FSL_DPA_CHECKING
129343 + mc->state = mc_hw;
129344 +#endif
129345 +}
129346 +
129347 +static inline struct bm_mc_result *bm_mc_result(struct bm_portal *portal)
129348 +{
129349 + register struct bm_mc *mc = &portal->mc;
129350 + struct bm_mc_result *rr = mc->rr + mc->rridx;
129351 + DPA_ASSERT(mc->state == mc_hw);
129352 + /* The inactive response register's verb byte always returns zero until
129353 + * its command is submitted and completed. This includes the valid-bit,
129354 + * in case you were wondering... */
129355 + if (!__raw_readb(&rr->verb)) {
129356 + dcbit_ro(rr);
129357 + return NULL;
129358 + }
129359 + mc->rridx ^= 1;
129360 + mc->vbit ^= BM_MCC_VERB_VBIT;
129361 +#ifdef CONFIG_FSL_DPA_CHECKING
129362 + mc->state = mc_idle;
129363 +#endif
129364 + return rr;
129365 +}
129366 +
129367 +
129368 +/* ------------------------------------- */
129369 +/* --- Portal interrupt register API --- */
129370 +
129371 +static inline int bm_isr_init(__always_unused struct bm_portal *portal)
129372 +{
129373 + return 0;
129374 +}
129375 +
129376 +static inline void bm_isr_finish(__always_unused struct bm_portal *portal)
129377 +{
129378 +}
129379 +
129380 +#define SCN_REG(bpid) BM_REG_SCN((bpid) / 32)
129381 +#define SCN_BIT(bpid) (0x80000000 >> (bpid & 31))
129382 +static inline void bm_isr_bscn_mask(struct bm_portal *portal, u8 bpid,
129383 + int enable)
129384 +{
129385 + u32 val;
129386 + DPA_ASSERT(bpid < bman_pool_max);
129387 + /* REG_SCN for bpid=0..31, REG_SCN+4 for bpid=32..63 */
129388 + val = __bm_in(&portal->addr, SCN_REG(bpid));
129389 + if (enable)
129390 + val |= SCN_BIT(bpid);
129391 + else
129392 + val &= ~SCN_BIT(bpid);
129393 + __bm_out(&portal->addr, SCN_REG(bpid), val);
129394 +}
129395 +
129396 +static inline u32 __bm_isr_read(struct bm_portal *portal, enum bm_isr_reg n)
129397 +{
129398 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
129399 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 6));
129400 +#else
129401 + return __bm_in(&portal->addr, BM_REG_ISR + (n << 2));
129402 +#endif
129403 +}
129404 +
129405 +static inline void __bm_isr_write(struct bm_portal *portal, enum bm_isr_reg n,
129406 + u32 val)
129407 +{
129408 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
129409 + __bm_out(&portal->addr, BM_REG_ISR + (n << 6), val);
129410 +#else
129411 + __bm_out(&portal->addr, BM_REG_ISR + (n << 2), val);
129412 +#endif
129413 +}
129414 +
129415 +/* Buffer Pool Cleanup */
129416 +static inline int bm_shutdown_pool(struct bm_portal *p, u32 bpid)
129417 +{
129418 + struct bm_mc_command *bm_cmd;
129419 + struct bm_mc_result *bm_res;
129420 +
129421 + int aq_count = 0;
129422 + bool stop = false;
129423 + while (!stop) {
129424 + /* Acquire buffers until empty */
129425 + bm_cmd = bm_mc_start(p);
129426 + bm_cmd->acquire.bpid = bpid;
129427 + bm_mc_commit(p, BM_MCC_VERB_CMD_ACQUIRE | 1);
129428 + while (!(bm_res = bm_mc_result(p)))
129429 + cpu_relax();
129430 + if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
129431 + /* Pool is empty */
129432 + /* TBD : Should we do a few extra iterations in
129433 + case some other some blocks keep buffers 'on deck',
129434 + which may also be problematic */
129435 + stop = true;
129436 + } else
129437 + ++aq_count;
129438 + }
129439 + return 0;
129440 +}
129441 --- /dev/null
129442 +++ b/drivers/staging/fsl_qbman/bman_private.h
129443 @@ -0,0 +1,166 @@
129444 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
129445 + *
129446 + * Redistribution and use in source and binary forms, with or without
129447 + * modification, are permitted provided that the following conditions are met:
129448 + * * Redistributions of source code must retain the above copyright
129449 + * notice, this list of conditions and the following disclaimer.
129450 + * * Redistributions in binary form must reproduce the above copyright
129451 + * notice, this list of conditions and the following disclaimer in the
129452 + * documentation and/or other materials provided with the distribution.
129453 + * * Neither the name of Freescale Semiconductor nor the
129454 + * names of its contributors may be used to endorse or promote products
129455 + * derived from this software without specific prior written permission.
129456 + *
129457 + *
129458 + * ALTERNATIVELY, this software may be distributed under the terms of the
129459 + * GNU General Public License ("GPL") as published by the Free Software
129460 + * Foundation, either version 2 of that License or (at your option) any
129461 + * later version.
129462 + *
129463 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129464 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129465 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129466 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129467 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129468 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129469 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129470 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129471 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129472 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129473 + */
129474 +
129475 +#include "dpa_sys.h"
129476 +#include <linux/fsl_bman.h>
129477 +
129478 +/* Revision info (for errata and feature handling) */
129479 +#define BMAN_REV10 0x0100
129480 +#define BMAN_REV20 0x0200
129481 +#define BMAN_REV21 0x0201
129482 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
129483 +extern u16 bman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
129484 +
129485 +/*
129486 + * Global variables of the max portal/pool number this bman version supported
129487 + */
129488 +extern u16 bman_pool_max;
129489 +
129490 +/* used by CCSR and portal interrupt code */
129491 +enum bm_isr_reg {
129492 + bm_isr_status = 0,
129493 + bm_isr_enable = 1,
129494 + bm_isr_disable = 2,
129495 + bm_isr_inhibit = 3
129496 +};
129497 +
129498 +struct bm_portal_config {
129499 + /* Corenet portal addresses;
129500 + * [0]==cache-enabled, [1]==cache-inhibited. */
129501 + __iomem void *addr_virt[2];
129502 + struct resource addr_phys[2];
129503 + /* Allow these to be joined in lists */
129504 + struct list_head list;
129505 + /* User-visible portal configuration settings */
129506 + struct bman_portal_config public_cfg;
129507 + /* power management saved data */
129508 + u32 saved_isdr;
129509 +};
129510 +
129511 +#ifdef CONFIG_FSL_BMAN_CONFIG
129512 +/* Hooks from bman_driver.c to bman_config.c */
129513 +int bman_init_ccsr(struct device_node *node);
129514 +#endif
129515 +
129516 +/* Hooks from bman_driver.c in to bman_high.c */
129517 +struct bman_portal *bman_create_portal(
129518 + struct bman_portal *portal,
129519 + const struct bm_portal_config *config);
129520 +struct bman_portal *bman_create_affine_portal(
129521 + const struct bm_portal_config *config);
129522 +struct bman_portal *bman_create_affine_slave(struct bman_portal *redirect,
129523 + int cpu);
129524 +void bman_destroy_portal(struct bman_portal *bm);
129525 +
129526 +const struct bm_portal_config *bman_destroy_affine_portal(void);
129527 +
129528 +/* Hooks from fsl_usdpaa.c to bman_driver.c */
129529 +struct bm_portal_config *bm_get_unused_portal(void);
129530 +struct bm_portal_config *bm_get_unused_portal_idx(uint32_t idx);
129531 +void bm_put_unused_portal(struct bm_portal_config *pcfg);
129532 +void bm_set_liodns(struct bm_portal_config *pcfg);
129533 +
129534 +/* Pool logic in the portal driver, during initialisation, needs to know if
129535 + * there's access to CCSR or not (if not, it'll cripple the pool allocator). */
129536 +#ifdef CONFIG_FSL_BMAN_CONFIG
129537 +int bman_have_ccsr(void);
129538 +#else
129539 +#define bman_have_ccsr() 0
129540 +#endif
129541 +
129542 +/* Stockpile build constants. The _LOW value: when bman_acquire() is called and
129543 + * the stockpile fill-level is <= _LOW, an acquire is attempted from h/w but it
129544 + * might fail (if the buffer pool is depleted). So this value provides some
129545 + * "stagger" in that the bman_acquire() function will only fail if lots of bufs
129546 + * are requested at once or if h/w has been tested a couple of times without
129547 + * luck. The _HIGH value: when bman_release() is called and the stockpile
129548 + * fill-level is >= _HIGH, a release is attempted to h/w but it might fail (if
129549 + * the release ring is full). So this value provides some "stagger" so that
129550 + * ring-access is retried a couple of times prior to the API returning a
129551 + * failure. The following *must* be true;
129552 + * BMAN_STOCKPILE_HIGH-BMAN_STOCKPILE_LOW > 8
129553 + * (to avoid thrashing)
129554 + * BMAN_STOCKPILE_SZ >= 16
129555 + * (as the release logic expects to either send 8 buffers to hw prior to
129556 + * adding the given buffers to the stockpile or add the buffers to the
129557 + * stockpile before sending 8 to hw, as the API must be an all-or-nothing
129558 + * success/fail.)
129559 + */
129560 +#define BMAN_STOCKPILE_SZ 16u /* number of bufs in per-pool cache */
129561 +#define BMAN_STOCKPILE_LOW 2u /* when fill is <= this, acquire from hw */
129562 +#define BMAN_STOCKPILE_HIGH 14u /* when fill is >= this, release to hw */
129563 +
129564 +/*************************************************/
129565 +/* BMan s/w corenet portal, low-level i/face */
129566 +/*************************************************/
129567 +
129568 +/* Used by all portal interrupt registers except 'inhibit'
129569 + * This mask contains all the "irqsource" bits visible to API users
129570 + */
129571 +#define BM_PIRQ_VISIBLE (BM_PIRQ_RCRI | BM_PIRQ_BSCN)
129572 +
129573 +/* These are bm_<reg>_<verb>(). So for example, bm_disable_write() means "write
129574 + * the disable register" rather than "disable the ability to write". */
129575 +#define bm_isr_status_read(bm) __bm_isr_read(bm, bm_isr_status)
129576 +#define bm_isr_status_clear(bm, m) __bm_isr_write(bm, bm_isr_status, m)
129577 +#define bm_isr_enable_read(bm) __bm_isr_read(bm, bm_isr_enable)
129578 +#define bm_isr_enable_write(bm, v) __bm_isr_write(bm, bm_isr_enable, v)
129579 +#define bm_isr_disable_read(bm) __bm_isr_read(bm, bm_isr_disable)
129580 +#define bm_isr_disable_write(bm, v) __bm_isr_write(bm, bm_isr_disable, v)
129581 +#define bm_isr_inhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 1)
129582 +#define bm_isr_uninhibit(bm) __bm_isr_write(bm, bm_isr_inhibit, 0)
129583 +
129584 +#ifdef CONFIG_FSL_BMAN_CONFIG
129585 +/* Set depletion thresholds associated with a buffer pool. Requires that the
129586 + * operating system have access to Bman CCSR (ie. compiled in support and
129587 + * run-time access courtesy of the device-tree). */
129588 +int bm_pool_set(u32 bpid, const u32 *thresholds);
129589 +#define BM_POOL_THRESH_SW_ENTER 0
129590 +#define BM_POOL_THRESH_SW_EXIT 1
129591 +#define BM_POOL_THRESH_HW_ENTER 2
129592 +#define BM_POOL_THRESH_HW_EXIT 3
129593 +
129594 +/* Read the free buffer count for a given buffer */
129595 +u32 bm_pool_free_buffers(u32 bpid);
129596 +
129597 +__init int bman_init(void);
129598 +__init int bman_resource_init(void);
129599 +
129600 +const struct bm_portal_config *bman_get_bm_portal_config(
129601 + struct bman_portal *portal);
129602 +
129603 +/* power management */
129604 +#ifdef CONFIG_SUSPEND
129605 +void suspend_unused_bportal(void);
129606 +void resume_unused_bportal(void);
129607 +#endif
129608 +
129609 +#endif /* CONFIG_FSL_BMAN_CONFIG */
129610 --- /dev/null
129611 +++ b/drivers/staging/fsl_qbman/bman_test.c
129612 @@ -0,0 +1,56 @@
129613 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
129614 + *
129615 + * Redistribution and use in source and binary forms, with or without
129616 + * modification, are permitted provided that the following conditions are met:
129617 + * * Redistributions of source code must retain the above copyright
129618 + * notice, this list of conditions and the following disclaimer.
129619 + * * Redistributions in binary form must reproduce the above copyright
129620 + * notice, this list of conditions and the following disclaimer in the
129621 + * documentation and/or other materials provided with the distribution.
129622 + * * Neither the name of Freescale Semiconductor nor the
129623 + * names of its contributors may be used to endorse or promote products
129624 + * derived from this software without specific prior written permission.
129625 + *
129626 + *
129627 + * ALTERNATIVELY, this software may be distributed under the terms of the
129628 + * GNU General Public License ("GPL") as published by the Free Software
129629 + * Foundation, either version 2 of that License or (at your option) any
129630 + * later version.
129631 + *
129632 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129633 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129634 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129635 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129636 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129637 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129638 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129639 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129640 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129641 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129642 + */
129643 +
129644 +#include "bman_test.h"
129645 +
129646 +MODULE_AUTHOR("Geoff Thorpe");
129647 +MODULE_LICENSE("Dual BSD/GPL");
129648 +MODULE_DESCRIPTION("Bman testing");
129649 +
129650 +static int test_init(void)
129651 +{
129652 +#ifdef CONFIG_FSL_BMAN_TEST_HIGH
129653 + int loop = 1;
129654 + while (loop--)
129655 + bman_test_high();
129656 +#endif
129657 +#ifdef CONFIG_FSL_BMAN_TEST_THRESH
129658 + bman_test_thresh();
129659 +#endif
129660 + return 0;
129661 +}
129662 +
129663 +static void test_exit(void)
129664 +{
129665 +}
129666 +
129667 +module_init(test_init);
129668 +module_exit(test_exit);
129669 --- /dev/null
129670 +++ b/drivers/staging/fsl_qbman/bman_test.h
129671 @@ -0,0 +1,44 @@
129672 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
129673 + *
129674 + * Redistribution and use in source and binary forms, with or without
129675 + * modification, are permitted provided that the following conditions are met:
129676 + * * Redistributions of source code must retain the above copyright
129677 + * notice, this list of conditions and the following disclaimer.
129678 + * * Redistributions in binary form must reproduce the above copyright
129679 + * notice, this list of conditions and the following disclaimer in the
129680 + * documentation and/or other materials provided with the distribution.
129681 + * * Neither the name of Freescale Semiconductor nor the
129682 + * names of its contributors may be used to endorse or promote products
129683 + * derived from this software without specific prior written permission.
129684 + *
129685 + *
129686 + * ALTERNATIVELY, this software may be distributed under the terms of the
129687 + * GNU General Public License ("GPL") as published by the Free Software
129688 + * Foundation, either version 2 of that License or (at your option) any
129689 + * later version.
129690 + *
129691 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129692 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129693 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129694 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129695 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129696 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129697 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129698 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129699 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129700 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129701 + */
129702 +
129703 +#include <linux/kernel.h>
129704 +#include <linux/errno.h>
129705 +#include <linux/io.h>
129706 +#include <linux/slab.h>
129707 +#include <linux/module.h>
129708 +#include <linux/interrupt.h>
129709 +#include <linux/delay.h>
129710 +#include <linux/kthread.h>
129711 +
129712 +#include <linux/fsl_bman.h>
129713 +
129714 +void bman_test_high(void);
129715 +void bman_test_thresh(void);
129716 --- /dev/null
129717 +++ b/drivers/staging/fsl_qbman/bman_test_high.c
129718 @@ -0,0 +1,183 @@
129719 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
129720 + *
129721 + * Redistribution and use in source and binary forms, with or without
129722 + * modification, are permitted provided that the following conditions are met:
129723 + * * Redistributions of source code must retain the above copyright
129724 + * notice, this list of conditions and the following disclaimer.
129725 + * * Redistributions in binary form must reproduce the above copyright
129726 + * notice, this list of conditions and the following disclaimer in the
129727 + * documentation and/or other materials provided with the distribution.
129728 + * * Neither the name of Freescale Semiconductor nor the
129729 + * names of its contributors may be used to endorse or promote products
129730 + * derived from this software without specific prior written permission.
129731 + *
129732 + *
129733 + * ALTERNATIVELY, this software may be distributed under the terms of the
129734 + * GNU General Public License ("GPL") as published by the Free Software
129735 + * Foundation, either version 2 of that License or (at your option) any
129736 + * later version.
129737 + *
129738 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129739 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129740 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129741 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129742 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129743 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129744 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129745 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129746 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129747 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129748 + */
129749 +
129750 +#include "bman_test.h"
129751 +#include "bman_private.h"
129752 +
129753 +/*************/
129754 +/* constants */
129755 +/*************/
129756 +
129757 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
129758 +#define POOL_OPAQUE ((void *)0xdeadabba)
129759 +#define NUM_BUFS 93
129760 +#define LOOPS 3
129761 +#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU
129762 +
129763 +/***************/
129764 +/* global vars */
129765 +/***************/
129766 +
129767 +static struct bman_pool *pool;
129768 +static int depleted;
129769 +static struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned;
129770 +static struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned;
129771 +static int bufs_received;
129772 +
129773 +/* Predeclare the callback so we can instantiate pool parameters */
129774 +static void depletion_cb(struct bman_portal *, struct bman_pool *, void *, int);
129775 +
129776 +/**********************/
129777 +/* internal functions */
129778 +/**********************/
129779 +
129780 +static void bufs_init(void)
129781 +{
129782 + int i;
129783 + for (i = 0; i < NUM_BUFS; i++)
129784 + bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i);
129785 + bufs_received = 0;
129786 +}
129787 +
129788 +static inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b)
129789 +{
129790 + if ((bman_ip_rev == BMAN_REV20) || (bman_ip_rev == BMAN_REV21)) {
129791 +
129792 + /* On SoCs with Bman revison 2.0, Bman only respects the 40
129793 + * LS-bits of buffer addresses, masking off the upper 8-bits on
129794 + * release commands. The API provides for 48-bit addresses
129795 + * because some SoCs support all 48-bits. When generating
129796 + * garbage addresses for testing, we either need to zero the
129797 + * upper 8-bits when releasing to Bman (otherwise we'll be
129798 + * disappointed when the buffers we acquire back from Bman
129799 + * don't match), or we need to mask the upper 8-bits off when
129800 + * comparing. We do the latter.
129801 + */
129802 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
129803 + < (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
129804 + return -1;
129805 + if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK)
129806 + > (bm_buffer_get64(b) & BMAN_TOKEN_MASK))
129807 + return 1;
129808 + } else {
129809 + if (bm_buffer_get64(a) < bm_buffer_get64(b))
129810 + return -1;
129811 + if (bm_buffer_get64(a) > bm_buffer_get64(b))
129812 + return 1;
129813 + }
129814 +
129815 + return 0;
129816 +}
129817 +
129818 +static void bufs_confirm(void)
129819 +{
129820 + int i, j;
129821 + for (i = 0; i < NUM_BUFS; i++) {
129822 + int matches = 0;
129823 + for (j = 0; j < NUM_BUFS; j++)
129824 + if (!bufs_cmp(&bufs_in[i], &bufs_out[j]))
129825 + matches++;
129826 + BUG_ON(matches != 1);
129827 + }
129828 +}
129829 +
129830 +/********/
129831 +/* test */
129832 +/********/
129833 +
129834 +static void depletion_cb(struct bman_portal *__portal, struct bman_pool *__pool,
129835 + void *pool_ctx, int __depleted)
129836 +{
129837 + BUG_ON(__pool != pool);
129838 + BUG_ON(pool_ctx != POOL_OPAQUE);
129839 + depleted = __depleted;
129840 +}
129841 +
129842 +void bman_test_high(void)
129843 +{
129844 + struct bman_pool_params pparams = {
129845 + .flags = BMAN_POOL_FLAG_DEPLETION | BMAN_POOL_FLAG_DYNAMIC_BPID,
129846 + .cb = depletion_cb,
129847 + .cb_ctx = POOL_OPAQUE,
129848 + };
129849 + int i, loops = LOOPS;
129850 + struct bm_buffer tmp_buf;
129851 +
129852 + bufs_init();
129853 +
129854 + pr_info("BMAN: --- starting high-level test ---\n");
129855 +
129856 + pool = bman_new_pool(&pparams);
129857 + BUG_ON(!pool);
129858 +
129859 + /*******************/
129860 + /* Release buffers */
129861 + /*******************/
129862 +do_loop:
129863 + i = 0;
129864 + while (i < NUM_BUFS) {
129865 + u32 flags = BMAN_RELEASE_FLAG_WAIT;
129866 + int num = 8;
129867 + if ((i + num) > NUM_BUFS)
129868 + num = NUM_BUFS - i;
129869 + if ((i + num) == NUM_BUFS)
129870 + flags |= BMAN_RELEASE_FLAG_WAIT_SYNC;
129871 + if (bman_release(pool, bufs_in + i, num, flags))
129872 + panic("bman_release() failed\n");
129873 + i += num;
129874 + }
129875 +
129876 + /*******************/
129877 + /* Acquire buffers */
129878 + /*******************/
129879 + while (i > 0) {
129880 + int tmp, num = 8;
129881 + if (num > i)
129882 + num = i;
129883 + tmp = bman_acquire(pool, bufs_out + i - num, num, 0);
129884 + BUG_ON(tmp != num);
129885 + i -= num;
129886 + }
129887 +
129888 + i = bman_acquire(pool, &tmp_buf, 1, 0);
129889 + BUG_ON(i > 0);
129890 +
129891 + bufs_confirm();
129892 +
129893 + if (--loops)
129894 + goto do_loop;
129895 +
129896 + /************/
129897 + /* Clean up */
129898 + /************/
129899 + bman_free_pool(pool);
129900 + pr_info("BMAN: --- finished high-level test ---\n");
129901 +}
129902 --- /dev/null
129903 +++ b/drivers/staging/fsl_qbman/bman_test_thresh.c
129904 @@ -0,0 +1,196 @@
129905 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
129906 + *
129907 + * Redistribution and use in source and binary forms, with or without
129908 + * modification, are permitted provided that the following conditions are met:
129909 + * * Redistributions of source code must retain the above copyright
129910 + * notice, this list of conditions and the following disclaimer.
129911 + * * Redistributions in binary form must reproduce the above copyright
129912 + * notice, this list of conditions and the following disclaimer in the
129913 + * documentation and/or other materials provided with the distribution.
129914 + * * Neither the name of Freescale Semiconductor nor the
129915 + * names of its contributors may be used to endorse or promote products
129916 + * derived from this software without specific prior written permission.
129917 + *
129918 + *
129919 + * ALTERNATIVELY, this software may be distributed under the terms of the
129920 + * GNU General Public License ("GPL") as published by the Free Software
129921 + * Foundation, either version 2 of that License or (at your option) any
129922 + * later version.
129923 + *
129924 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
129925 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
129926 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
129927 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
129928 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
129929 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
129930 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
129931 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129932 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
129933 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
129934 + */
129935 +
129936 +#include "bman_test.h"
129937 +
129938 +/* Test constants */
129939 +#define TEST_NUMBUFS 129728
129940 +#define TEST_EXIT 129536
129941 +#define TEST_ENTRY 129024
129942 +
129943 +struct affine_test_data {
129944 + struct task_struct *t;
129945 + int cpu;
129946 + int expect_affinity;
129947 + int drain;
129948 + int num_enter;
129949 + int num_exit;
129950 + struct list_head node;
129951 + struct completion wakethread;
129952 + struct completion wakeparent;
129953 +};
129954 +
129955 +static void cb_depletion(struct bman_portal *portal,
129956 + struct bman_pool *pool,
129957 + void *opaque,
129958 + int depleted)
129959 +{
129960 + struct affine_test_data *data = opaque;
129961 + int c = smp_processor_id();
129962 + pr_info("cb_depletion: bpid=%d, depleted=%d, cpu=%d, original=%d\n",
129963 + bman_get_params(pool)->bpid, !!depleted, c, data->cpu);
129964 + /* We should be executing on the CPU of the thread that owns the pool if
129965 + * and that CPU has an affine portal (ie. it isn't slaved). */
129966 + BUG_ON((c != data->cpu) && data->expect_affinity);
129967 + BUG_ON((c == data->cpu) && !data->expect_affinity);
129968 + if (depleted)
129969 + data->num_enter++;
129970 + else
129971 + data->num_exit++;
129972 +}
129973 +
129974 +/* Params used to set up a pool, this also dynamically allocates a BPID */
129975 +static const struct bman_pool_params params_nocb = {
129976 + .flags = BMAN_POOL_FLAG_DYNAMIC_BPID | BMAN_POOL_FLAG_THRESH,
129977 + .thresholds = { TEST_ENTRY, TEST_EXIT, 0, 0 }
129978 +};
129979 +
129980 +/* Params used to set up each cpu's pool with callbacks enabled */
129981 +static struct bman_pool_params params_cb = {
129982 + .bpid = 0, /* will be replaced to match pool_nocb */
129983 + .flags = BMAN_POOL_FLAG_DEPLETION,
129984 + .cb = cb_depletion
129985 +};
129986 +
129987 +static struct bman_pool *pool_nocb;
129988 +static LIST_HEAD(threads);
129989 +
129990 +static int affine_test(void *__data)
129991 +{
129992 + struct bman_pool *pool;
129993 + struct affine_test_data *data = __data;
129994 + struct bman_pool_params my_params = params_cb;
129995 +
129996 + pr_info("thread %d: starting\n", data->cpu);
129997 + /* create the pool */
129998 + my_params.cb_ctx = data;
129999 + pool = bman_new_pool(&my_params);
130000 + BUG_ON(!pool);
130001 + complete(&data->wakeparent);
130002 + wait_for_completion(&data->wakethread);
130003 + init_completion(&data->wakethread);
130004 +
130005 + /* if we're the drainer, we get signalled for that */
130006 + if (data->drain) {
130007 + struct bm_buffer buf;
130008 + int ret;
130009 + pr_info("thread %d: draining...\n", data->cpu);
130010 + do {
130011 + ret = bman_acquire(pool, &buf, 1, 0);
130012 + } while (ret > 0);
130013 + pr_info("thread %d: draining done.\n", data->cpu);
130014 + complete(&data->wakeparent);
130015 + wait_for_completion(&data->wakethread);
130016 + init_completion(&data->wakethread);
130017 + }
130018 +
130019 + /* cleanup */
130020 + bman_free_pool(pool);
130021 + while (!kthread_should_stop())
130022 + cpu_relax();
130023 + pr_info("thread %d: exiting\n", data->cpu);
130024 + return 0;
130025 +}
130026 +
130027 +static struct affine_test_data *start_affine_test(int cpu, int drain)
130028 +{
130029 + struct affine_test_data *data = kmalloc(sizeof(*data), GFP_KERNEL);
130030 +
130031 + if (!data)
130032 + return NULL;
130033 + data->cpu = cpu;
130034 + data->expect_affinity = cpumask_test_cpu(cpu, bman_affine_cpus());
130035 + data->drain = drain;
130036 + data->num_enter = 0;
130037 + data->num_exit = 0;
130038 + init_completion(&data->wakethread);
130039 + init_completion(&data->wakeparent);
130040 + list_add_tail(&data->node, &threads);
130041 + data->t = kthread_create(affine_test, data, "threshtest%d", cpu);
130042 + BUG_ON(IS_ERR(data->t));
130043 + kthread_bind(data->t, cpu);
130044 + wake_up_process(data->t);
130045 + return data;
130046 +}
130047 +
130048 +void bman_test_thresh(void)
130049 +{
130050 + int loop = TEST_NUMBUFS;
130051 + int ret, num_cpus = 0;
130052 + struct affine_test_data *data, *drainer = NULL;
130053 +
130054 + pr_info("bman_test_thresh: start\n");
130055 +
130056 + /* allocate a BPID and seed it */
130057 + pool_nocb = bman_new_pool(&params_nocb);
130058 + BUG_ON(!pool_nocb);
130059 + while (loop--) {
130060 + struct bm_buffer buf;
130061 + bm_buffer_set64(&buf, 0x0badbeef + loop);
130062 + ret = bman_release(pool_nocb, &buf, 1,
130063 + BMAN_RELEASE_FLAG_WAIT);
130064 + BUG_ON(ret);
130065 + }
130066 + while (!bman_rcr_is_empty())
130067 + cpu_relax();
130068 + pr_info("bman_test_thresh: buffers are in\n");
130069 +
130070 + /* create threads and wait for them to create pools */
130071 + params_cb.bpid = bman_get_params(pool_nocb)->bpid;
130072 + for_each_cpu(loop, cpu_online_mask) {
130073 + data = start_affine_test(loop, drainer ? 0 : 1);
130074 + BUG_ON(!data);
130075 + if (!drainer)
130076 + drainer = data;
130077 + num_cpus++;
130078 + wait_for_completion(&data->wakeparent);
130079 + }
130080 +
130081 + /* signal the drainer to start draining */
130082 + complete(&drainer->wakethread);
130083 + wait_for_completion(&drainer->wakeparent);
130084 + init_completion(&drainer->wakeparent);
130085 +
130086 + /* tear down */
130087 + list_for_each_entry_safe(data, drainer, &threads, node) {
130088 + complete(&data->wakethread);
130089 + ret = kthread_stop(data->t);
130090 + BUG_ON(ret);
130091 + list_del(&data->node);
130092 + /* check that we get the expected callbacks (and no others) */
130093 + BUG_ON(data->num_enter != 1);
130094 + BUG_ON(data->num_exit != 0);
130095 + kfree(data);
130096 + }
130097 + bman_free_pool(pool_nocb);
130098 +
130099 + pr_info("bman_test_thresh: done\n");
130100 +}
130101 --- /dev/null
130102 +++ b/drivers/staging/fsl_qbman/dpa_alloc.c
130103 @@ -0,0 +1,706 @@
130104 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
130105 + *
130106 + * Redistribution and use in source and binary forms, with or without
130107 + * modification, are permitted provided that the following conditions are met:
130108 + * * Redistributions of source code must retain the above copyright
130109 + * notice, this list of conditions and the following disclaimer.
130110 + * * Redistributions in binary form must reproduce the above copyright
130111 + * notice, this list of conditions and the following disclaimer in the
130112 + * documentation and/or other materials provided with the distribution.
130113 + * * Neither the name of Freescale Semiconductor nor the
130114 + * names of its contributors may be used to endorse or promote products
130115 + * derived from this software without specific prior written permission.
130116 + *
130117 + *
130118 + * ALTERNATIVELY, this software may be distributed under the terms of the
130119 + * GNU General Public License ("GPL") as published by the Free Software
130120 + * Foundation, either version 2 of that License or (at your option) any
130121 + * later version.
130122 + *
130123 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
130124 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
130125 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130126 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
130127 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
130128 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
130129 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
130130 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130131 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
130132 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130133 + */
130134 +
130135 +#include "dpa_sys.h"
130136 +#include <linux/fsl_qman.h>
130137 +#include <linux/fsl_bman.h>
130138 +
130139 +/* Qman and Bman APIs are front-ends to the common code; */
130140 +
130141 +static DECLARE_DPA_ALLOC(bpalloc); /* BPID allocator */
130142 +static DECLARE_DPA_ALLOC(fqalloc); /* FQID allocator */
130143 +static DECLARE_DPA_ALLOC(qpalloc); /* pool-channel allocator */
130144 +static DECLARE_DPA_ALLOC(cgralloc); /* CGR ID allocator */
130145 +static DECLARE_DPA_ALLOC(ceetm0_challoc); /* CEETM Channel ID allocator */
130146 +static DECLARE_DPA_ALLOC(ceetm0_lfqidalloc); /* CEETM LFQID allocator */
130147 +static DECLARE_DPA_ALLOC(ceetm1_challoc); /* CEETM Channel ID allocator */
130148 +static DECLARE_DPA_ALLOC(ceetm1_lfqidalloc); /* CEETM LFQID allocator */
130149 +
130150 +/* This is a sort-of-conditional dpa_alloc_free() routine. Eg. when releasing
130151 + * FQIDs (probably from user-space), it can filter out those that aren't in the
130152 + * OOS state (better to leak a h/w resource than to crash). This function
130153 + * returns the number of invalid IDs that were not released. */
130154 +static u32 release_id_range(struct dpa_alloc *alloc, u32 id, u32 count,
130155 + int (*is_valid)(u32 id))
130156 +{
130157 + int valid_mode = 0;
130158 + u32 loop = id, total_invalid = 0;
130159 + while (loop < (id + count)) {
130160 + int isvalid = is_valid ? is_valid(loop) : 1;
130161 + if (!valid_mode) {
130162 + /* We're looking for a valid ID to terminate an invalid
130163 + * range */
130164 + if (isvalid) {
130165 + /* We finished a range of invalid IDs, a valid
130166 + * range is now underway */
130167 + valid_mode = 1;
130168 + count -= (loop - id);
130169 + id = loop;
130170 + } else
130171 + total_invalid++;
130172 + } else {
130173 + /* We're looking for an invalid ID to terminate a
130174 + * valid range */
130175 + if (!isvalid) {
130176 + /* Release the range of valid IDs, an unvalid
130177 + * range is now underway */
130178 + if (loop > id)
130179 + dpa_alloc_free(alloc, id, loop - id);
130180 + valid_mode = 0;
130181 + }
130182 + }
130183 + loop++;
130184 + }
130185 + /* Release any unterminated range of valid IDs */
130186 + if (valid_mode && count)
130187 + dpa_alloc_free(alloc, id, count);
130188 + return total_invalid;
130189 +}
130190 +
130191 +/* BPID allocator front-end */
130192 +
130193 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial)
130194 +{
130195 + return dpa_alloc_new(&bpalloc, result, count, align, partial);
130196 +}
130197 +EXPORT_SYMBOL(bman_alloc_bpid_range);
130198 +
130199 +static int bp_cleanup(u32 bpid)
130200 +{
130201 + return bman_shutdown_pool(bpid) == 0;
130202 +}
130203 +void bman_release_bpid_range(u32 bpid, u32 count)
130204 +{
130205 + u32 total_invalid = release_id_range(&bpalloc, bpid, count, bp_cleanup);
130206 + if (total_invalid)
130207 + pr_err("BPID range [%d..%d] (%d) had %d leaks\n",
130208 + bpid, bpid + count - 1, count, total_invalid);
130209 +}
130210 +EXPORT_SYMBOL(bman_release_bpid_range);
130211 +
130212 +void bman_seed_bpid_range(u32 bpid, u32 count)
130213 +{
130214 + dpa_alloc_seed(&bpalloc, bpid, count);
130215 +}
130216 +EXPORT_SYMBOL(bman_seed_bpid_range);
130217 +
130218 +int bman_reserve_bpid_range(u32 bpid, u32 count)
130219 +{
130220 + return dpa_alloc_reserve(&bpalloc, bpid, count);
130221 +}
130222 +EXPORT_SYMBOL(bman_reserve_bpid_range);
130223 +
130224 +
130225 +/* FQID allocator front-end */
130226 +
130227 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial)
130228 +{
130229 + return dpa_alloc_new(&fqalloc, result, count, align, partial);
130230 +}
130231 +EXPORT_SYMBOL(qman_alloc_fqid_range);
130232 +
130233 +static int fq_cleanup(u32 fqid)
130234 +{
130235 + return qman_shutdown_fq(fqid) == 0;
130236 +}
130237 +void qman_release_fqid_range(u32 fqid, u32 count)
130238 +{
130239 + u32 total_invalid = release_id_range(&fqalloc, fqid, count, fq_cleanup);
130240 + if (total_invalid)
130241 + pr_err("FQID range [%d..%d] (%d) had %d leaks\n",
130242 + fqid, fqid + count - 1, count, total_invalid);
130243 +}
130244 +EXPORT_SYMBOL(qman_release_fqid_range);
130245 +
130246 +int qman_reserve_fqid_range(u32 fqid, u32 count)
130247 +{
130248 + return dpa_alloc_reserve(&fqalloc, fqid, count);
130249 +}
130250 +EXPORT_SYMBOL(qman_reserve_fqid_range);
130251 +
130252 +void qman_seed_fqid_range(u32 fqid, u32 count)
130253 +{
130254 + dpa_alloc_seed(&fqalloc, fqid, count);
130255 +}
130256 +EXPORT_SYMBOL(qman_seed_fqid_range);
130257 +
130258 +/* Pool-channel allocator front-end */
130259 +
130260 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial)
130261 +{
130262 + return dpa_alloc_new(&qpalloc, result, count, align, partial);
130263 +}
130264 +EXPORT_SYMBOL(qman_alloc_pool_range);
130265 +
130266 +static int qpool_cleanup(u32 qp)
130267 +{
130268 + /* We query all FQDs starting from
130269 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
130270 + * whose destination channel is the pool-channel being released.
130271 + * When a non-OOS FQD is found we attempt to clean it up */
130272 + struct qman_fq fq = {
130273 + .fqid = 1
130274 + };
130275 + int err;
130276 + do {
130277 + struct qm_mcr_queryfq_np np;
130278 + err = qman_query_fq_np(&fq, &np);
130279 + if (err)
130280 + /* FQID range exceeded, found no problems */
130281 + return 1;
130282 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
130283 + struct qm_fqd fqd;
130284 + err = qman_query_fq(&fq, &fqd);
130285 + BUG_ON(err);
130286 + if (fqd.dest.channel == qp) {
130287 + /* The channel is the FQ's target, clean it */
130288 + if (qman_shutdown_fq(fq.fqid) != 0)
130289 + /* Couldn't shut down the FQ
130290 + so the pool must be leaked */
130291 + return 0;
130292 + }
130293 + }
130294 + /* Move to the next FQID */
130295 + fq.fqid++;
130296 + } while (1);
130297 +}
130298 +void qman_release_pool_range(u32 qp, u32 count)
130299 +{
130300 + u32 total_invalid = release_id_range(&qpalloc, qp,
130301 + count, qpool_cleanup);
130302 + if (total_invalid) {
130303 + /* Pool channels are almost always used individually */
130304 + if (count == 1)
130305 + pr_err("Pool channel 0x%x had %d leaks\n",
130306 + qp, total_invalid);
130307 + else
130308 + pr_err("Pool channels [%d..%d] (%d) had %d leaks\n",
130309 + qp, qp + count - 1, count, total_invalid);
130310 + }
130311 +}
130312 +EXPORT_SYMBOL(qman_release_pool_range);
130313 +
130314 +
130315 +void qman_seed_pool_range(u32 poolid, u32 count)
130316 +{
130317 + dpa_alloc_seed(&qpalloc, poolid, count);
130318 +
130319 +}
130320 +EXPORT_SYMBOL(qman_seed_pool_range);
130321 +
130322 +int qman_reserve_pool_range(u32 poolid, u32 count)
130323 +{
130324 + return dpa_alloc_reserve(&qpalloc, poolid, count);
130325 +}
130326 +EXPORT_SYMBOL(qman_reserve_pool_range);
130327 +
130328 +
130329 +/* CGR ID allocator front-end */
130330 +
130331 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial)
130332 +{
130333 + return dpa_alloc_new(&cgralloc, result, count, align, partial);
130334 +}
130335 +EXPORT_SYMBOL(qman_alloc_cgrid_range);
130336 +
130337 +static int cqr_cleanup(u32 cgrid)
130338 +{
130339 + /* We query all FQDs starting from
130340 + * FQID 1 until we get an "invalid FQID" error, looking for non-OOS FQDs
130341 + * whose CGR is the CGR being released.
130342 + */
130343 + struct qman_fq fq = {
130344 + .fqid = 1
130345 + };
130346 + int err;
130347 + do {
130348 + struct qm_mcr_queryfq_np np;
130349 + err = qman_query_fq_np(&fq, &np);
130350 + if (err)
130351 + /* FQID range exceeded, found no problems */
130352 + return 1;
130353 + if ((np.state & QM_MCR_NP_STATE_MASK) != QM_MCR_NP_STATE_OOS) {
130354 + struct qm_fqd fqd;
130355 + err = qman_query_fq(&fq, &fqd);
130356 + BUG_ON(err);
130357 + if ((fqd.fq_ctrl & QM_FQCTRL_CGE) &&
130358 + (fqd.cgid == cgrid)) {
130359 + pr_err("CRGID 0x%x is being used by FQID 0x%x,"
130360 + " CGR will be leaked\n",
130361 + cgrid, fq.fqid);
130362 + return 1;
130363 + }
130364 + }
130365 + /* Move to the next FQID */
130366 + fq.fqid++;
130367 + } while (1);
130368 +}
130369 +
130370 +void qman_release_cgrid_range(u32 cgrid, u32 count)
130371 +{
130372 + u32 total_invalid = release_id_range(&cgralloc, cgrid,
130373 + count, cqr_cleanup);
130374 + if (total_invalid)
130375 + pr_err("CGRID range [%d..%d] (%d) had %d leaks\n",
130376 + cgrid, cgrid + count - 1, count, total_invalid);
130377 +}
130378 +EXPORT_SYMBOL(qman_release_cgrid_range);
130379 +
130380 +void qman_seed_cgrid_range(u32 cgrid, u32 count)
130381 +{
130382 + dpa_alloc_seed(&cgralloc, cgrid, count);
130383 +
130384 +}
130385 +EXPORT_SYMBOL(qman_seed_cgrid_range);
130386 +
130387 +/* CEETM CHANNEL ID allocator front-end */
130388 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
130389 + int partial)
130390 +{
130391 + return dpa_alloc_new(&ceetm0_challoc, result, count, align, partial);
130392 +}
130393 +EXPORT_SYMBOL(qman_alloc_ceetm0_channel_range);
130394 +
130395 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
130396 + int partial)
130397 +{
130398 + return dpa_alloc_new(&ceetm1_challoc, result, count, align, partial);
130399 +}
130400 +EXPORT_SYMBOL(qman_alloc_ceetm1_channel_range);
130401 +
130402 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count)
130403 +{
130404 + u32 total_invalid;
130405 +
130406 + total_invalid = release_id_range(&ceetm0_challoc, channelid, count,
130407 + NULL);
130408 + if (total_invalid)
130409 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
130410 + channelid, channelid + count - 1, count, total_invalid);
130411 +}
130412 +EXPORT_SYMBOL(qman_release_ceetm0_channel_range);
130413 +
130414 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count)
130415 +{
130416 + dpa_alloc_seed(&ceetm0_challoc, channelid, count);
130417 +
130418 +}
130419 +EXPORT_SYMBOL(qman_seed_ceetm0_channel_range);
130420 +
130421 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count)
130422 +{
130423 + u32 total_invalid;
130424 + total_invalid = release_id_range(&ceetm1_challoc, channelid, count,
130425 + NULL);
130426 + if (total_invalid)
130427 + pr_err("CEETM channel range [%d..%d] (%d) had %d leaks\n",
130428 + channelid, channelid + count - 1, count, total_invalid);
130429 +}
130430 +EXPORT_SYMBOL(qman_release_ceetm1_channel_range);
130431 +
130432 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count)
130433 +{
130434 + dpa_alloc_seed(&ceetm1_challoc, channelid, count);
130435 +
130436 +}
130437 +EXPORT_SYMBOL(qman_seed_ceetm1_channel_range);
130438 +
130439 +/* CEETM LFQID allocator front-end */
130440 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
130441 + int partial)
130442 +{
130443 + return dpa_alloc_new(&ceetm0_lfqidalloc, result, count, align, partial);
130444 +}
130445 +EXPORT_SYMBOL(qman_alloc_ceetm0_lfqid_range);
130446 +
130447 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
130448 + int partial)
130449 +{
130450 + return dpa_alloc_new(&ceetm1_lfqidalloc, result, count, align, partial);
130451 +}
130452 +EXPORT_SYMBOL(qman_alloc_ceetm1_lfqid_range);
130453 +
130454 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count)
130455 +{
130456 + u32 total_invalid;
130457 +
130458 + total_invalid = release_id_range(&ceetm0_lfqidalloc, lfqid, count,
130459 + NULL);
130460 + if (total_invalid)
130461 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
130462 + lfqid, lfqid + count - 1, count, total_invalid);
130463 +}
130464 +EXPORT_SYMBOL(qman_release_ceetm0_lfqid_range);
130465 +
130466 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count)
130467 +{
130468 + dpa_alloc_seed(&ceetm0_lfqidalloc, lfqid, count);
130469 +
130470 +}
130471 +EXPORT_SYMBOL(qman_seed_ceetm0_lfqid_range);
130472 +
130473 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count)
130474 +{
130475 + u32 total_invalid;
130476 +
130477 + total_invalid = release_id_range(&ceetm1_lfqidalloc, lfqid, count,
130478 + NULL);
130479 + if (total_invalid)
130480 + pr_err("CEETM LFQID range [0x%x..0x%x] (%d) had %d leaks\n",
130481 + lfqid, lfqid + count - 1, count, total_invalid);
130482 +}
130483 +EXPORT_SYMBOL(qman_release_ceetm1_lfqid_range);
130484 +
130485 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count)
130486 +{
130487 + dpa_alloc_seed(&ceetm1_lfqidalloc, lfqid, count);
130488 +
130489 +}
130490 +EXPORT_SYMBOL(qman_seed_ceetm1_lfqid_range);
130491 +
130492 +
130493 +/* Everything else is the common backend to all the allocators */
130494 +
130495 +/* The allocator is a (possibly-empty) list of these; */
130496 +struct alloc_node {
130497 + struct list_head list;
130498 + u32 base;
130499 + u32 num;
130500 + /* refcount and is_alloced are only set
130501 + when the node is in the used list */
130502 + unsigned int refcount;
130503 + int is_alloced;
130504 +};
130505 +
130506 +/* #define DPA_ALLOC_DEBUG */
130507 +
130508 +#ifdef DPA_ALLOC_DEBUG
130509 +#define DPRINT pr_info
130510 +static void DUMP(struct dpa_alloc *alloc)
130511 +{
130512 + int off = 0;
130513 + char buf[256];
130514 + struct alloc_node *p;
130515 + pr_info("Free Nodes\n");
130516 + list_for_each_entry(p, &alloc->free, list) {
130517 + if (off < 255)
130518 + off += snprintf(buf + off, 255-off, "{%d,%d}",
130519 + p->base, p->base + p->num - 1);
130520 + }
130521 + pr_info("%s\n", buf);
130522 +
130523 + off = 0;
130524 + pr_info("Used Nodes\n");
130525 + list_for_each_entry(p, &alloc->used, list) {
130526 + if (off < 255)
130527 + off += snprintf(buf + off, 255-off, "{%d,%d}",
130528 + p->base, p->base + p->num - 1);
130529 + }
130530 + pr_info("%s\n", buf);
130531 +
130532 +
130533 +
130534 +}
130535 +#else
130536 +#define DPRINT(x...)
130537 +#define DUMP(a)
130538 +#endif
130539 +
130540 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
130541 + int partial)
130542 +{
130543 + struct alloc_node *i = NULL, *next_best = NULL, *used_node = NULL;
130544 + u32 base, next_best_base = 0, num = 0, next_best_num = 0;
130545 + struct alloc_node *margin_left, *margin_right;
130546 +
130547 + *result = (u32)-1;
130548 + DPRINT("alloc_range(%d,%d,%d)\n", count, align, partial);
130549 + DUMP(alloc);
130550 + /* If 'align' is 0, it should behave as though it was 1 */
130551 + if (!align)
130552 + align = 1;
130553 + margin_left = kmalloc(sizeof(*margin_left), GFP_KERNEL);
130554 + if (!margin_left)
130555 + goto err;
130556 + margin_right = kmalloc(sizeof(*margin_right), GFP_KERNEL);
130557 + if (!margin_right) {
130558 + kfree(margin_left);
130559 + goto err;
130560 + }
130561 + spin_lock_irq(&alloc->lock);
130562 + list_for_each_entry(i, &alloc->free, list) {
130563 + base = (i->base + align - 1) / align;
130564 + base *= align;
130565 + if ((base - i->base) >= i->num)
130566 + /* alignment is impossible, regardless of count */
130567 + continue;
130568 + num = i->num - (base - i->base);
130569 + if (num >= count) {
130570 + /* this one will do nicely */
130571 + num = count;
130572 + goto done;
130573 + }
130574 + if (num > next_best_num) {
130575 + next_best = i;
130576 + next_best_base = base;
130577 + next_best_num = num;
130578 + }
130579 + }
130580 + if (partial && next_best) {
130581 + i = next_best;
130582 + base = next_best_base;
130583 + num = next_best_num;
130584 + } else
130585 + i = NULL;
130586 +done:
130587 + if (i) {
130588 + if (base != i->base) {
130589 + margin_left->base = i->base;
130590 + margin_left->num = base - i->base;
130591 + list_add_tail(&margin_left->list, &i->list);
130592 + } else
130593 + kfree(margin_left);
130594 + if ((base + num) < (i->base + i->num)) {
130595 + margin_right->base = base + num;
130596 + margin_right->num = (i->base + i->num) -
130597 + (base + num);
130598 + list_add(&margin_right->list, &i->list);
130599 + } else
130600 + kfree(margin_right);
130601 + list_del(&i->list);
130602 + kfree(i);
130603 + *result = base;
130604 + } else {
130605 + spin_unlock_irq(&alloc->lock);
130606 + kfree(margin_left);
130607 + kfree(margin_right);
130608 + }
130609 +
130610 +err:
130611 + DPRINT("returning %d\n", i ? num : -ENOMEM);
130612 + DUMP(alloc);
130613 + if (!i)
130614 + return -ENOMEM;
130615 +
130616 + /* Add the allocation to the used list with a refcount of 1 */
130617 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
130618 + if (!used_node) {
130619 + spin_unlock_irq(&alloc->lock);
130620 + return -ENOMEM;
130621 + }
130622 + used_node->base = *result;
130623 + used_node->num = num;
130624 + used_node->refcount = 1;
130625 + used_node->is_alloced = 1;
130626 + list_add_tail(&used_node->list, &alloc->used);
130627 + spin_unlock_irq(&alloc->lock);
130628 + return (int)num;
130629 +}
130630 +
130631 +/* Allocate the list node using GFP_ATOMIC, because we *really* want to avoid
130632 + * forcing error-handling on to users in the deallocation path. */
130633 +static void _dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
130634 +{
130635 + struct alloc_node *i, *node = kmalloc(sizeof(*node), GFP_ATOMIC);
130636 + BUG_ON(!node);
130637 + DPRINT("release_range(%d,%d)\n", base_id, count);
130638 + DUMP(alloc);
130639 + BUG_ON(!count);
130640 + spin_lock_irq(&alloc->lock);
130641 +
130642 +
130643 + node->base = base_id;
130644 + node->num = count;
130645 + list_for_each_entry(i, &alloc->free, list) {
130646 + if (i->base >= node->base) {
130647 + /* BUG_ON(any overlapping) */
130648 + BUG_ON(i->base < (node->base + node->num));
130649 + list_add_tail(&node->list, &i->list);
130650 + goto done;
130651 + }
130652 + }
130653 + list_add_tail(&node->list, &alloc->free);
130654 +done:
130655 + /* Merge to the left */
130656 + i = list_entry(node->list.prev, struct alloc_node, list);
130657 + if (node->list.prev != &alloc->free) {
130658 + BUG_ON((i->base + i->num) > node->base);
130659 + if ((i->base + i->num) == node->base) {
130660 + node->base = i->base;
130661 + node->num += i->num;
130662 + list_del(&i->list);
130663 + kfree(i);
130664 + }
130665 + }
130666 + /* Merge to the right */
130667 + i = list_entry(node->list.next, struct alloc_node, list);
130668 + if (node->list.next != &alloc->free) {
130669 + BUG_ON((node->base + node->num) > i->base);
130670 + if ((node->base + node->num) == i->base) {
130671 + node->num += i->num;
130672 + list_del(&i->list);
130673 + kfree(i);
130674 + }
130675 + }
130676 + spin_unlock_irq(&alloc->lock);
130677 + DUMP(alloc);
130678 +}
130679 +
130680 +
130681 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count)
130682 +{
130683 + struct alloc_node *i = NULL;
130684 + spin_lock_irq(&alloc->lock);
130685 +
130686 + /* First find the node in the used list and decrement its ref count */
130687 + list_for_each_entry(i, &alloc->used, list) {
130688 + if (i->base == base_id && i->num == count) {
130689 + --i->refcount;
130690 + if (i->refcount == 0) {
130691 + list_del(&i->list);
130692 + spin_unlock_irq(&alloc->lock);
130693 + if (i->is_alloced)
130694 + _dpa_alloc_free(alloc, base_id, count);
130695 + kfree(i);
130696 + return;
130697 + }
130698 + spin_unlock_irq(&alloc->lock);
130699 + return;
130700 + }
130701 + }
130702 + /* Couldn't find the allocation */
130703 + pr_err("Attempt to free ID 0x%x COUNT %d that wasn't alloc'd or reserved\n",
130704 + base_id, count);
130705 + spin_unlock_irq(&alloc->lock);
130706 +}
130707 +
130708 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 base_id, u32 count)
130709 +{
130710 + /* Same as free but no previous allocation checking is needed */
130711 + _dpa_alloc_free(alloc, base_id, count);
130712 +}
130713 +
130714 +
130715 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base, u32 num)
130716 +{
130717 + struct alloc_node *i = NULL, *used_node;
130718 +
130719 + DPRINT("alloc_reserve(%d,%d)\n", base, num);
130720 + DUMP(alloc);
130721 +
130722 + spin_lock_irq(&alloc->lock);
130723 +
130724 + /* Check for the node in the used list.
130725 + If found, increase it's refcount */
130726 + list_for_each_entry(i, &alloc->used, list) {
130727 + if ((i->base == base) && (i->num == num)) {
130728 + ++i->refcount;
130729 + spin_unlock_irq(&alloc->lock);
130730 + return 0;
130731 + }
130732 + if ((base >= i->base) && (base < (i->base + i->num))) {
130733 + /* This is an attempt to reserve a region that was
130734 + already reserved or alloced with a different
130735 + base or num */
130736 + pr_err("Cannot reserve %d - %d, it overlaps with"
130737 + " existing reservation from %d - %d\n",
130738 + base, base + num - 1, i->base,
130739 + i->base + i->num - 1);
130740 + spin_unlock_irq(&alloc->lock);
130741 + return -1;
130742 + }
130743 + }
130744 + /* Check to make sure this ID isn't in the free list */
130745 + list_for_each_entry(i, &alloc->free, list) {
130746 + if ((base >= i->base) && (base < (i->base + i->num))) {
130747 + /* yep, the reservation is within this node */
130748 + pr_err("Cannot reserve %d - %d, it overlaps with"
130749 + " free range %d - %d and must be alloced\n",
130750 + base, base + num - 1,
130751 + i->base, i->base + i->num - 1);
130752 + spin_unlock_irq(&alloc->lock);
130753 + return -1;
130754 + }
130755 + }
130756 + /* Add the allocation to the used list with a refcount of 1 */
130757 + used_node = kmalloc(sizeof(*used_node), GFP_KERNEL);
130758 + if (!used_node) {
130759 + spin_unlock_irq(&alloc->lock);
130760 + return -ENOMEM;
130761 +
130762 + }
130763 + used_node->base = base;
130764 + used_node->num = num;
130765 + used_node->refcount = 1;
130766 + used_node->is_alloced = 0;
130767 + list_add_tail(&used_node->list, &alloc->used);
130768 + spin_unlock_irq(&alloc->lock);
130769 + return 0;
130770 +}
130771 +
130772 +
130773 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count)
130774 +{
130775 + struct alloc_node *i = NULL;
130776 + DPRINT("alloc_pop()\n");
130777 + DUMP(alloc);
130778 + spin_lock_irq(&alloc->lock);
130779 + if (!list_empty(&alloc->free)) {
130780 + i = list_entry(alloc->free.next, struct alloc_node, list);
130781 + list_del(&i->list);
130782 + }
130783 + spin_unlock_irq(&alloc->lock);
130784 + DPRINT("returning %d\n", i ? 0 : -ENOMEM);
130785 + DUMP(alloc);
130786 + if (!i)
130787 + return -ENOMEM;
130788 + *result = i->base;
130789 + *count = i->num;
130790 + kfree(i);
130791 + return 0;
130792 +}
130793 +
130794 +int dpa_alloc_check(struct dpa_alloc *list_head, u32 item)
130795 +{
130796 + struct alloc_node *i = NULL;
130797 + int res = 0;
130798 + DPRINT("alloc_check()\n");
130799 + spin_lock_irq(&list_head->lock);
130800 +
130801 + list_for_each_entry(i, &list_head->free, list) {
130802 + if ((item >= i->base) && (item < (i->base + i->num))) {
130803 + res = 1;
130804 + break;
130805 + }
130806 + }
130807 + spin_unlock_irq(&list_head->lock);
130808 + return res;
130809 +}
130810 --- /dev/null
130811 +++ b/drivers/staging/fsl_qbman/dpa_sys.h
130812 @@ -0,0 +1,259 @@
130813 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
130814 + *
130815 + * Redistribution and use in source and binary forms, with or without
130816 + * modification, are permitted provided that the following conditions are met:
130817 + * * Redistributions of source code must retain the above copyright
130818 + * notice, this list of conditions and the following disclaimer.
130819 + * * Redistributions in binary form must reproduce the above copyright
130820 + * notice, this list of conditions and the following disclaimer in the
130821 + * documentation and/or other materials provided with the distribution.
130822 + * * Neither the name of Freescale Semiconductor nor the
130823 + * names of its contributors may be used to endorse or promote products
130824 + * derived from this software without specific prior written permission.
130825 + *
130826 + *
130827 + * ALTERNATIVELY, this software may be distributed under the terms of the
130828 + * GNU General Public License ("GPL") as published by the Free Software
130829 + * Foundation, either version 2 of that License or (at your option) any
130830 + * later version.
130831 + *
130832 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
130833 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
130834 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
130835 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
130836 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
130837 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
130838 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
130839 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
130840 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
130841 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
130842 + */
130843 +
130844 +#ifndef DPA_SYS_H
130845 +#define DPA_SYS_H
130846 +
130847 +#include <linux/kernel.h>
130848 +#include <linux/errno.h>
130849 +#include <linux/io.h>
130850 +#include <linux/dma-mapping.h>
130851 +#include <linux/bootmem.h>
130852 +#include <linux/slab.h>
130853 +#include <linux/module.h>
130854 +#include <linux/init.h>
130855 +#include <linux/interrupt.h>
130856 +#include <linux/delay.h>
130857 +#include <linux/of_platform.h>
130858 +#include <linux/of_address.h>
130859 +#include <linux/of_irq.h>
130860 +#include <linux/kthread.h>
130861 +#include <linux/memblock.h>
130862 +#include <linux/completion.h>
130863 +#include <linux/log2.h>
130864 +#include <linux/types.h>
130865 +#include <linux/ioctl.h>
130866 +#include <linux/miscdevice.h>
130867 +#include <linux/uaccess.h>
130868 +#include <linux/debugfs.h>
130869 +#include <linux/seq_file.h>
130870 +#include <linux/device.h>
130871 +#include <linux/uio_driver.h>
130872 +#include <linux/smp.h>
130873 +#include <linux/fsl_hypervisor.h>
130874 +#include <linux/vmalloc.h>
130875 +#include <linux/ctype.h>
130876 +#include <linux/math64.h>
130877 +#include <linux/bitops.h>
130878 +
130879 +#include <linux/fsl_usdpaa.h>
130880 +
130881 +/* When copying aligned words or shorts, try to avoid memcpy() */
130882 +#define CONFIG_TRY_BETTER_MEMCPY
130883 +
130884 +/* For 2-element tables related to cache-inhibited and cache-enabled mappings */
130885 +#define DPA_PORTAL_CE 0
130886 +#define DPA_PORTAL_CI 1
130887 +
130888 +/***********************/
130889 +/* Misc inline assists */
130890 +/***********************/
130891 +
130892 +#if defined CONFIG_PPC32
130893 +#include "dpa_sys_ppc32.h"
130894 +#elif defined CONFIG_PPC64
130895 +#include "dpa_sys_ppc64.h"
130896 +#elif defined CONFIG_ARM
130897 +#include "dpa_sys_arm.h"
130898 +#elif defined CONFIG_ARM64
130899 +#include "dpa_sys_arm64.h"
130900 +#endif
130901 +
130902 +
130903 +#ifdef CONFIG_FSL_DPA_CHECKING
130904 +#define DPA_ASSERT(x) \
130905 + do { \
130906 + if (!(x)) { \
130907 + pr_crit("ASSERT: (%s:%d) %s\n", __FILE__, __LINE__, \
130908 + __stringify_1(x)); \
130909 + dump_stack(); \
130910 + panic("assertion failure"); \
130911 + } \
130912 + } while (0)
130913 +#else
130914 +#define DPA_ASSERT(x)
130915 +#endif
130916 +
130917 +/* memcpy() stuff - when you know alignments in advance */
130918 +#ifdef CONFIG_TRY_BETTER_MEMCPY
130919 +static inline void copy_words(void *dest, const void *src, size_t sz)
130920 +{
130921 + u32 *__dest = dest;
130922 + const u32 *__src = src;
130923 + size_t __sz = sz >> 2;
130924 + BUG_ON((unsigned long)dest & 0x3);
130925 + BUG_ON((unsigned long)src & 0x3);
130926 + BUG_ON(sz & 0x3);
130927 + while (__sz--)
130928 + *(__dest++) = *(__src++);
130929 +}
130930 +static inline void copy_shorts(void *dest, const void *src, size_t sz)
130931 +{
130932 + u16 *__dest = dest;
130933 + const u16 *__src = src;
130934 + size_t __sz = sz >> 1;
130935 + BUG_ON((unsigned long)dest & 0x1);
130936 + BUG_ON((unsigned long)src & 0x1);
130937 + BUG_ON(sz & 0x1);
130938 + while (__sz--)
130939 + *(__dest++) = *(__src++);
130940 +}
130941 +static inline void copy_bytes(void *dest, const void *src, size_t sz)
130942 +{
130943 + u8 *__dest = dest;
130944 + const u8 *__src = src;
130945 + while (sz--)
130946 + *(__dest++) = *(__src++);
130947 +}
130948 +#else
130949 +#define copy_words memcpy
130950 +#define copy_shorts memcpy
130951 +#define copy_bytes memcpy
130952 +#endif
130953 +
130954 +/************/
130955 +/* RB-trees */
130956 +/************/
130957 +
130958 +/* We encapsulate RB-trees so that its easier to use non-linux forms in
130959 + * non-linux systems. This also encapsulates the extra plumbing that linux code
130960 + * usually provides when using RB-trees. This encapsulation assumes that the
130961 + * data type held by the tree is u32. */
130962 +
130963 +struct dpa_rbtree {
130964 + struct rb_root root;
130965 +};
130966 +#define DPA_RBTREE { .root = RB_ROOT }
130967 +
130968 +static inline void dpa_rbtree_init(struct dpa_rbtree *tree)
130969 +{
130970 + tree->root = RB_ROOT;
130971 +}
130972 +
130973 +#define IMPLEMENT_DPA_RBTREE(name, type, node_field, val_field) \
130974 +static inline int name##_push(struct dpa_rbtree *tree, type *obj) \
130975 +{ \
130976 + struct rb_node *parent = NULL, **p = &tree->root.rb_node; \
130977 + while (*p) { \
130978 + u32 item; \
130979 + parent = *p; \
130980 + item = rb_entry(parent, type, node_field)->val_field; \
130981 + if (obj->val_field < item) \
130982 + p = &parent->rb_left; \
130983 + else if (obj->val_field > item) \
130984 + p = &parent->rb_right; \
130985 + else \
130986 + return -EBUSY; \
130987 + } \
130988 + rb_link_node(&obj->node_field, parent, p); \
130989 + rb_insert_color(&obj->node_field, &tree->root); \
130990 + return 0; \
130991 +} \
130992 +static inline void name##_del(struct dpa_rbtree *tree, type *obj) \
130993 +{ \
130994 + rb_erase(&obj->node_field, &tree->root); \
130995 +} \
130996 +static inline type *name##_find(struct dpa_rbtree *tree, u32 val) \
130997 +{ \
130998 + type *ret; \
130999 + struct rb_node *p = tree->root.rb_node; \
131000 + while (p) { \
131001 + ret = rb_entry(p, type, node_field); \
131002 + if (val < ret->val_field) \
131003 + p = p->rb_left; \
131004 + else if (val > ret->val_field) \
131005 + p = p->rb_right; \
131006 + else \
131007 + return ret; \
131008 + } \
131009 + return NULL; \
131010 +}
131011 +
131012 +/************/
131013 +/* Bootargs */
131014 +/************/
131015 +
131016 +/* Qman has "qportals=" and Bman has "bportals=", they use the same syntax
131017 + * though; a comma-separated list of items, each item being a cpu index and/or a
131018 + * range of cpu indices, and each item optionally be prefixed by "s" to indicate
131019 + * that the portal associated with that cpu should be shared. See bman_driver.c
131020 + * for more specifics. */
131021 +static int __parse_portals_cpu(const char **s, unsigned int *cpu)
131022 +{
131023 + *cpu = 0;
131024 + if (!isdigit(**s))
131025 + return -EINVAL;
131026 + while (isdigit(**s))
131027 + *cpu = *cpu * 10 + (*((*s)++) - '0');
131028 + return 0;
131029 +}
131030 +static inline int parse_portals_bootarg(char *str, struct cpumask *want_shared,
131031 + struct cpumask *want_unshared,
131032 + const char *argname)
131033 +{
131034 + const char *s = str;
131035 + unsigned int shared, cpu1, cpu2, loop;
131036 +
131037 +keep_going:
131038 + if (*s == 's') {
131039 + shared = 1;
131040 + s++;
131041 + } else
131042 + shared = 0;
131043 + if (__parse_portals_cpu(&s, &cpu1))
131044 + goto err;
131045 + if (*s == '-') {
131046 + s++;
131047 + if (__parse_portals_cpu(&s, &cpu2))
131048 + goto err;
131049 + if (cpu2 < cpu1)
131050 + goto err;
131051 + } else
131052 + cpu2 = cpu1;
131053 + for (loop = cpu1; loop <= cpu2; loop++)
131054 + cpumask_set_cpu(loop, shared ? want_shared : want_unshared);
131055 + if (*s == ',') {
131056 + s++;
131057 + goto keep_going;
131058 + } else if ((*s == '\0') || isspace(*s))
131059 + return 0;
131060 +err:
131061 + pr_crit("Malformed %s argument: %s, offset: %lu\n", argname, str,
131062 + (unsigned long)s - (unsigned long)str);
131063 + return -EINVAL;
131064 +}
131065 +#ifdef CONFIG_FSL_USDPAA
131066 +/* Hooks from fsl_usdpaa_irq.c to fsl_usdpaa.c */
131067 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
131068 + enum usdpaa_portal_type ptype, unsigned int *irq,
131069 + void **iir_reg);
131070 +#endif
131071 +#endif /* DPA_SYS_H */
131072 --- /dev/null
131073 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm.h
131074 @@ -0,0 +1,95 @@
131075 +/* Copyright 2016 Freescale Semiconductor, Inc.
131076 + *
131077 + * Redistribution and use in source and binary forms, with or without
131078 + * modification, are permitted provided that the following conditions are met:
131079 + * * Redistributions of source code must retain the above copyright
131080 + * notice, this list of conditions and the following disclaimer.
131081 + * * Redistributions in binary form must reproduce the above copyright
131082 + * notice, this list of conditions and the following disclaimer in the
131083 + * documentation and/or other materials provided with the distribution.
131084 + * * Neither the name of Freescale Semiconductor nor the
131085 + * names of its contributors may be used to endorse or promote products
131086 + * derived from this software without specific prior written permission.
131087 + *
131088 + *
131089 + * ALTERNATIVELY, this software may be distributed under the terms of the
131090 + * GNU General Public License ("GPL") as published by the Free Software
131091 + * Foundation, either version 2 of that License or (at your option) any
131092 + * later version.
131093 + *
131094 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131095 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131096 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131097 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131098 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131099 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131100 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131101 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131102 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131103 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131104 + */
131105 +
131106 +#ifndef DPA_SYS_ARM_H
131107 +#define DPA_SYS_ARM_H
131108 +
131109 +#include <asm/cacheflush.h>
131110 +#include <asm/barrier.h>
131111 +
131112 +/* Implementation of ARM specific routines */
131113 +
131114 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
131115 + * barriers and that dcb*() won't fall victim to compiler or execution
131116 + * reordering with respect to other code/instructions that manipulate the same
131117 + * cacheline. */
131118 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
131119 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
131120 +#define dcbf(p) { asm volatile("mcr p15, 0, %0, c7, c10, 1" : : "r" (p) : "memory"); }
131121 +#define dcbt_ro(p) { asm volatile("pld [%0, #64];": : "r" (p)); }
131122 +#define dcbt_rw(p) { asm volatile("pldw [%0, #64];": : "r" (p)); }
131123 +#define dcbi(p) { asm volatile("mcr p15, 0, %0, c7, c6, 1" : : "r" (p) : "memory"); }
131124 +
131125 +#define dcbz_64(p) { memset(p, 0, sizeof(*p)); }
131126 +
131127 +#define dcbf_64(p) \
131128 + do { \
131129 + dcbf((u32)p); \
131130 + } while (0)
131131 +/* Commonly used combo */
131132 +#define dcbit_ro(p) \
131133 + do { \
131134 + dcbi((u32)p); \
131135 + dcbt_ro((u32)p); \
131136 + } while (0)
131137 +
131138 +static inline u64 mfatb(void)
131139 +{
131140 + return get_cycles();
131141 +}
131142 +
131143 +static inline u32 in_be32(volatile void *addr)
131144 +{
131145 + return be32_to_cpu(*((volatile u32 *) addr));
131146 +}
131147 +
131148 +static inline void out_be32(void *addr, u32 val)
131149 +{
131150 + *((u32 *) addr) = cpu_to_be32(val);
131151 +}
131152 +
131153 +
131154 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
131155 +{
131156 + *p |= mask;
131157 +}
131158 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
131159 +{
131160 + *p &= ~mask;
131161 +}
131162 +
131163 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
131164 +{
131165 + __cpuc_flush_dcache_area((void *) start, stop - start);
131166 +}
131167 +
131168 +#define hard_smp_processor_id() raw_smp_processor_id()
131169 +#endif
131170 --- /dev/null
131171 +++ b/drivers/staging/fsl_qbman/dpa_sys_arm64.h
131172 @@ -0,0 +1,102 @@
131173 +/* Copyright 2014 Freescale Semiconductor, Inc.
131174 + *
131175 + * Redistribution and use in source and binary forms, with or without
131176 + * modification, are permitted provided that the following conditions are met:
131177 + * * Redistributions of source code must retain the above copyright
131178 + * notice, this list of conditions and the following disclaimer.
131179 + * * Redistributions in binary form must reproduce the above copyright
131180 + * notice, this list of conditions and the following disclaimer in the
131181 + * documentation and/or other materials provided with the distribution.
131182 + * * Neither the name of Freescale Semiconductor nor the
131183 + * names of its contributors may be used to endorse or promote products
131184 + * derived from this software without specific prior written permission.
131185 + *
131186 + *
131187 + * ALTERNATIVELY, this software may be distributed under the terms of the
131188 + * GNU General Public License ("GPL") as published by the Free Software
131189 + * Foundation, either version 2 of that License or (at your option) any
131190 + * later version.
131191 + *
131192 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131193 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131194 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131195 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131196 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131197 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131198 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131199 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131200 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131201 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131202 + */
131203 +
131204 +#ifndef DPA_SYS_ARM64_H
131205 +#define DPA_SYS_ARM64_H
131206 +
131207 +#include <asm/cacheflush.h>
131208 +#include <asm/barrier.h>
131209 +
131210 +/* Implementation of ARM 64 bit specific routines */
131211 +
131212 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
131213 + * barriers and that dcb*() won't fall victim to compiler or execution
131214 + * reordering with respect to other code/instructions that manipulate the same
131215 + * cacheline. */
131216 +#define hwsync() { asm volatile("dmb st" : : : "memory"); }
131217 +#define lwsync() { asm volatile("dmb st" : : : "memory"); }
131218 +#define dcbf(p) { asm volatile("dc cvac, %0;" : : "r" (p) : "memory"); }
131219 +#define dcbt_ro(p) { asm volatile("prfm pldl1keep, [%0, #0]" : : "r" (p)); }
131220 +#define dcbt_rw(p) { asm volatile("prfm pstl1keep, [%0, #0]" : : "r" (p)); }
131221 +#define dcbi(p) { asm volatile("dc ivac, %0" : : "r"(p) : "memory"); }
131222 +#define dcbz(p) { asm volatile("dc zva, %0" : : "r" (p) : "memory"); }
131223 +
131224 +#define dcbz_64(p) \
131225 + do { \
131226 + dcbz(p); \
131227 + } while (0)
131228 +
131229 +#define dcbf_64(p) \
131230 + do { \
131231 + dcbf(p); \
131232 + } while (0)
131233 +/* Commonly used combo */
131234 +#define dcbit_ro(p) \
131235 + do { \
131236 + dcbi(p); \
131237 + dcbt_ro(p); \
131238 + } while (0)
131239 +
131240 +static inline u64 mfatb(void)
131241 +{
131242 + return get_cycles();
131243 +}
131244 +
131245 +static inline u32 in_be32(volatile void *addr)
131246 +{
131247 + return be32_to_cpu(*((volatile u32 *) addr));
131248 +}
131249 +
131250 +static inline void out_be32(void *addr, u32 val)
131251 +{
131252 + *((u32 *) addr) = cpu_to_be32(val);
131253 +}
131254 +
131255 +
131256 +static inline void set_bits(unsigned long mask, volatile unsigned long *p)
131257 +{
131258 + *p |= mask;
131259 +}
131260 +static inline void clear_bits(unsigned long mask, volatile unsigned long *p)
131261 +{
131262 + *p &= ~mask;
131263 +}
131264 +
131265 +static inline void flush_dcache_range(unsigned long start, unsigned long stop)
131266 +{
131267 + __flush_dcache_area((void *) start, stop - start);
131268 +}
131269 +
131270 +#define hard_smp_processor_id() raw_smp_processor_id()
131271 +
131272 +
131273 +
131274 +#endif
131275 --- /dev/null
131276 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc32.h
131277 @@ -0,0 +1,70 @@
131278 +/* Copyright 2014 Freescale Semiconductor, Inc.
131279 + *
131280 + * Redistribution and use in source and binary forms, with or without
131281 + * modification, are permitted provided that the following conditions are met:
131282 + * * Redistributions of source code must retain the above copyright
131283 + * notice, this list of conditions and the following disclaimer.
131284 + * * Redistributions in binary form must reproduce the above copyright
131285 + * notice, this list of conditions and the following disclaimer in the
131286 + * documentation and/or other materials provided with the distribution.
131287 + * * Neither the name of Freescale Semiconductor nor the
131288 + * names of its contributors may be used to endorse or promote products
131289 + * derived from this software without specific prior written permission.
131290 + *
131291 + *
131292 + * ALTERNATIVELY, this software may be distributed under the terms of the
131293 + * GNU General Public License ("GPL") as published by the Free Software
131294 + * Foundation, either version 2 of that License or (at your option) any
131295 + * later version.
131296 + *
131297 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131298 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131299 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131300 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131301 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131302 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131303 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131304 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131305 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131306 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131307 + */
131308 +
131309 +#ifndef DPA_SYS_PPC32_H
131310 +#define DPA_SYS_PPC32_H
131311 +
131312 +/* Implementation of PowerPC 32 bit specific routines */
131313 +
131314 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
131315 + * barriers and that dcb*() won't fall victim to compiler or execution
131316 + * reordering with respect to other code/instructions that manipulate the same
131317 + * cacheline. */
131318 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
131319 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
131320 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
131321 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
131322 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
131323 +#define dcbi(p) dcbf(p)
131324 +
131325 +#define dcbzl(p) __asm__ __volatile__ ("dcbzl 0,%0" : : "r" (p))
131326 +#define dcbz_64(p) dcbzl(p)
131327 +#define dcbf_64(p) dcbf(p)
131328 +
131329 +/* Commonly used combo */
131330 +#define dcbit_ro(p) \
131331 + do { \
131332 + dcbi(p); \
131333 + dcbt_ro(p); \
131334 + } while (0)
131335 +
131336 +static inline u64 mfatb(void)
131337 +{
131338 + u32 hi, lo, chk;
131339 + do {
131340 + hi = mfspr(SPRN_ATBU);
131341 + lo = mfspr(SPRN_ATBL);
131342 + chk = mfspr(SPRN_ATBU);
131343 + } while (unlikely(hi != chk));
131344 + return ((u64)hi << 32) | (u64)lo;
131345 +}
131346 +
131347 +#endif
131348 --- /dev/null
131349 +++ b/drivers/staging/fsl_qbman/dpa_sys_ppc64.h
131350 @@ -0,0 +1,79 @@
131351 +/* Copyright 2014 Freescale Semiconductor, Inc.
131352 + *
131353 + * Redistribution and use in source and binary forms, with or without
131354 + * modification, are permitted provided that the following conditions are met:
131355 + * * Redistributions of source code must retain the above copyright
131356 + * notice, this list of conditions and the following disclaimer.
131357 + * * Redistributions in binary form must reproduce the above copyright
131358 + * notice, this list of conditions and the following disclaimer in the
131359 + * documentation and/or other materials provided with the distribution.
131360 + * * Neither the name of Freescale Semiconductor nor the
131361 + * names of its contributors may be used to endorse or promote products
131362 + * derived from this software without specific prior written permission.
131363 + *
131364 + *
131365 + * ALTERNATIVELY, this software may be distributed under the terms of the
131366 + * GNU General Public License ("GPL") as published by the Free Software
131367 + * Foundation, either version 2 of that License or (at your option) any
131368 + * later version.
131369 + *
131370 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
131371 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
131372 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
131373 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
131374 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
131375 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
131376 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
131377 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
131378 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
131379 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131380 + */
131381 +
131382 +#ifndef DPA_SYS_PPC64_H
131383 +#define DPA_SYS_PPC64_H
131384 +
131385 +/* Implementation of PowerPC 64 bit specific routines */
131386 +
131387 +/* TODO: NB, we currently assume that hwsync() and lwsync() imply compiler
131388 + * barriers and that dcb*() won't fall victim to compiler or execution
131389 + * reordering with respect to other code/instructions that manipulate the same
131390 + * cacheline. */
131391 +#define hwsync() __asm__ __volatile__ ("sync" : : : "memory")
131392 +#define lwsync() __asm__ __volatile__ (stringify_in_c(LWSYNC) : : : "memory")
131393 +#define dcbf(p) __asm__ __volatile__ ("dcbf 0,%0" : : "r" (p) : "memory")
131394 +#define dcbt_ro(p) __asm__ __volatile__ ("dcbt 0,%0" : : "r" (p))
131395 +#define dcbt_rw(p) __asm__ __volatile__ ("dcbtst 0,%0" : : "r" (p))
131396 +#define dcbi(p) dcbf(p)
131397 +
131398 +#define dcbz(p) __asm__ __volatile__ ("dcbz 0,%0" : : "r" (p))
131399 +#define dcbz_64(p) \
131400 + do { \
131401 + dcbz((void*)p + 32); \
131402 + dcbz(p); \
131403 + } while (0)
131404 +#define dcbf_64(p) \
131405 + do { \
131406 + dcbf((void*)p + 32); \
131407 + dcbf(p); \
131408 + } while (0)
131409 +/* Commonly used combo */
131410 +#define dcbit_ro(p) \
131411 + do { \
131412 + dcbi(p); \
131413 + dcbi((void*)p + 32); \
131414 + dcbt_ro(p); \
131415 + dcbt_ro((void*)p + 32); \
131416 + } while (0)
131417 +
131418 +static inline u64 mfatb(void)
131419 +{
131420 + u32 hi, lo, chk;
131421 + do {
131422 + hi = mfspr(SPRN_ATBU);
131423 + lo = mfspr(SPRN_ATBL);
131424 + chk = mfspr(SPRN_ATBU);
131425 + } while (unlikely(hi != chk));
131426 + return ((u64)hi << 32) | (u64)lo;
131427 +}
131428 +
131429 +#endif
131430 --- /dev/null
131431 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa.c
131432 @@ -0,0 +1,2008 @@
131433 +/* Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
131434 + * Authors: Andy Fleming <afleming@freescale.com>
131435 + * Timur Tabi <timur@freescale.com>
131436 + * Geoff Thorpe <Geoff.Thorpe@freescale.com>
131437 + *
131438 + * This file is licensed under the terms of the GNU General Public License
131439 + * version 2. This program is licensed "as is" without any warranty of any
131440 + * kind, whether express or implied.
131441 + */
131442 +
131443 +
131444 +#include <linux/miscdevice.h>
131445 +#include <linux/fs.h>
131446 +#include <linux/cdev.h>
131447 +#include <linux/mm.h>
131448 +#include <linux/of.h>
131449 +#include <linux/memblock.h>
131450 +#include <linux/slab.h>
131451 +#include <linux/mman.h>
131452 +#include <linux/of_reserved_mem.h>
131453 +
131454 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
131455 +#include <mm/mmu_decl.h>
131456 +#endif
131457 +
131458 +#include "dpa_sys.h"
131459 +#include <linux/fsl_usdpaa.h>
131460 +#include "bman_low.h"
131461 +#include "qman_low.h"
131462 +
131463 +/* Physical address range of the memory reservation, exported for mm/mem.c */
131464 +static u64 phys_start;
131465 +static u64 phys_size;
131466 +static u64 arg_phys_size;
131467 +
131468 +/* PFN versions of the above */
131469 +static unsigned long pfn_start;
131470 +static unsigned long pfn_size;
131471 +
131472 +/* Memory reservations are manipulated under this spinlock (which is why 'refs'
131473 + * isn't atomic_t). */
131474 +static DEFINE_SPINLOCK(mem_lock);
131475 +
131476 +/* The range of TLB1 indices */
131477 +static unsigned int first_tlb;
131478 +static unsigned int num_tlb = 1;
131479 +static unsigned int current_tlb; /* loops around for fault handling */
131480 +
131481 +/* Memory reservation is represented as a list of 'mem_fragment's, some of which
131482 + * may be mapped. Unmapped fragments are always merged where possible. */
131483 +static LIST_HEAD(mem_list);
131484 +
131485 +struct mem_mapping;
131486 +
131487 +/* Memory fragments are in 'mem_list'. */
131488 +struct mem_fragment {
131489 + u64 base;
131490 + u64 len;
131491 + unsigned long pfn_base; /* PFN version of 'base' */
131492 + unsigned long pfn_len; /* PFN version of 'len' */
131493 + unsigned int refs; /* zero if unmapped */
131494 + u64 root_len; /* Size of the orignal fragment */
131495 + unsigned long root_pfn; /* PFN of the orignal fragment */
131496 + struct list_head list;
131497 + /* if mapped, flags+name captured at creation time */
131498 + u32 flags;
131499 + char name[USDPAA_DMA_NAME_MAX];
131500 + u64 map_len;
131501 + /* support multi-process locks per-memory-fragment. */
131502 + int has_locking;
131503 + wait_queue_head_t wq;
131504 + struct mem_mapping *owner;
131505 +};
131506 +
131507 +/* Mappings of memory fragments in 'struct ctx'. These are created from
131508 + * ioctl(USDPAA_IOCTL_DMA_MAP), though the actual mapping then happens via a
131509 + * mmap(). */
131510 +struct mem_mapping {
131511 + struct mem_fragment *root_frag;
131512 + u32 frag_count;
131513 + u64 total_size;
131514 + struct list_head list;
131515 + int refs;
131516 + void *virt_addr;
131517 +};
131518 +
131519 +struct portal_mapping {
131520 + struct usdpaa_ioctl_portal_map user;
131521 + union {
131522 + struct qm_portal_config *qportal;
131523 + struct bm_portal_config *bportal;
131524 + };
131525 + /* Declare space for the portals in case the process
131526 + exits unexpectedly and needs to be cleaned by the kernel */
131527 + union {
131528 + struct qm_portal qman_portal_low;
131529 + struct bm_portal bman_portal_low;
131530 + };
131531 + struct list_head list;
131532 + struct resource *phys;
131533 + struct iommu_domain *iommu_domain;
131534 +};
131535 +
131536 +/* Track the DPAA resources the process is using */
131537 +struct active_resource {
131538 + struct list_head list;
131539 + u32 id;
131540 + u32 num;
131541 + unsigned int refcount;
131542 +};
131543 +
131544 +/* Per-FD state (which should also be per-process but we don't enforce that) */
131545 +struct ctx {
131546 + /* Lock to protect the context */
131547 + spinlock_t lock;
131548 + /* Allocated resources get put here for accounting */
131549 + struct list_head resources[usdpaa_id_max];
131550 + /* list of DMA maps */
131551 + struct list_head maps;
131552 + /* list of portal maps */
131553 + struct list_head portals;
131554 +};
131555 +
131556 +/* Different resource classes */
131557 +static const struct alloc_backend {
131558 + enum usdpaa_id_type id_type;
131559 + int (*alloc)(u32 *, u32, u32, int);
131560 + void (*release)(u32 base, unsigned int count);
131561 + int (*reserve)(u32 base, unsigned int count);
131562 + const char *acronym;
131563 +} alloc_backends[] = {
131564 + {
131565 + .id_type = usdpaa_id_fqid,
131566 + .alloc = qman_alloc_fqid_range,
131567 + .release = qman_release_fqid_range,
131568 + .reserve = qman_reserve_fqid_range,
131569 + .acronym = "FQID"
131570 + },
131571 + {
131572 + .id_type = usdpaa_id_bpid,
131573 + .alloc = bman_alloc_bpid_range,
131574 + .release = bman_release_bpid_range,
131575 + .reserve = bman_reserve_bpid_range,
131576 + .acronym = "BPID"
131577 + },
131578 + {
131579 + .id_type = usdpaa_id_qpool,
131580 + .alloc = qman_alloc_pool_range,
131581 + .release = qman_release_pool_range,
131582 + .reserve = qman_reserve_pool_range,
131583 + .acronym = "QPOOL"
131584 + },
131585 + {
131586 + .id_type = usdpaa_id_cgrid,
131587 + .alloc = qman_alloc_cgrid_range,
131588 + .release = qman_release_cgrid_range,
131589 + .acronym = "CGRID"
131590 + },
131591 + {
131592 + .id_type = usdpaa_id_ceetm0_lfqid,
131593 + .alloc = qman_alloc_ceetm0_lfqid_range,
131594 + .release = qman_release_ceetm0_lfqid_range,
131595 + .acronym = "CEETM0_LFQID"
131596 + },
131597 + {
131598 + .id_type = usdpaa_id_ceetm0_channelid,
131599 + .alloc = qman_alloc_ceetm0_channel_range,
131600 + .release = qman_release_ceetm0_channel_range,
131601 + .acronym = "CEETM0_LFQID"
131602 + },
131603 + {
131604 + .id_type = usdpaa_id_ceetm1_lfqid,
131605 + .alloc = qman_alloc_ceetm1_lfqid_range,
131606 + .release = qman_release_ceetm1_lfqid_range,
131607 + .acronym = "CEETM1_LFQID"
131608 + },
131609 + {
131610 + .id_type = usdpaa_id_ceetm1_channelid,
131611 + .alloc = qman_alloc_ceetm1_channel_range,
131612 + .release = qman_release_ceetm1_channel_range,
131613 + .acronym = "CEETM1_LFQID"
131614 + },
131615 + {
131616 + /* This terminates the array */
131617 + .id_type = usdpaa_id_max
131618 + }
131619 +};
131620 +
131621 +/* Determines the largest acceptable page size for a given size
131622 + The sizes are determined by what the TLB1 acceptable page sizes are */
131623 +static u32 largest_page_size(u32 size)
131624 +{
131625 + int shift = 30; /* Start at 1G size */
131626 + if (size < 4096)
131627 + return 0;
131628 + do {
131629 + if (size >= (1<<shift))
131630 + return 1<<shift;
131631 + shift -= 2;
131632 + } while (shift >= 12); /* Up to 4k */
131633 + return 0;
131634 +}
131635 +
131636 +/* Determine if value is power of 4 */
131637 +static inline bool is_power_of_4(u64 x)
131638 +{
131639 + if (x == 0 || ((x & (x - 1)) != 0))
131640 + return false;
131641 + return !!(x & 0x5555555555555555ull);
131642 +}
131643 +
131644 +/* Helper for ioctl_dma_map() when we have a larger fragment than we need. This
131645 + * splits the fragment into 4 and returns the upper-most. (The caller can loop
131646 + * until it has a suitable fragment size.) */
131647 +static struct mem_fragment *split_frag(struct mem_fragment *frag)
131648 +{
131649 + struct mem_fragment *x[3];
131650 +
131651 + x[0] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
131652 + x[1] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
131653 + x[2] = kmalloc(sizeof(struct mem_fragment), GFP_ATOMIC);
131654 + if (!x[0] || !x[1] || !x[2]) {
131655 + kfree(x[0]);
131656 + kfree(x[1]);
131657 + kfree(x[2]);
131658 + return NULL;
131659 + }
131660 + BUG_ON(frag->refs);
131661 + frag->len >>= 2;
131662 + frag->pfn_len >>= 2;
131663 + x[0]->base = frag->base + frag->len;
131664 + x[1]->base = x[0]->base + frag->len;
131665 + x[2]->base = x[1]->base + frag->len;
131666 + x[0]->len = x[1]->len = x[2]->len = frag->len;
131667 + x[0]->pfn_base = frag->pfn_base + frag->pfn_len;
131668 + x[1]->pfn_base = x[0]->pfn_base + frag->pfn_len;
131669 + x[2]->pfn_base = x[1]->pfn_base + frag->pfn_len;
131670 + x[0]->pfn_len = x[1]->pfn_len = x[2]->pfn_len = frag->pfn_len;
131671 + x[0]->refs = x[1]->refs = x[2]->refs = 0;
131672 + x[0]->root_len = x[1]->root_len = x[2]->root_len = frag->root_len;
131673 + x[0]->root_pfn = x[1]->root_pfn = x[2]->root_pfn = frag->root_pfn;
131674 + x[0]->name[0] = x[1]->name[0] = x[2]->name[0] = 0;
131675 + list_add_tail(&x[0]->list, &frag->list);
131676 + list_add_tail(&x[1]->list, &x[0]->list);
131677 + list_add_tail(&x[2]->list, &x[1]->list);
131678 + return x[2];
131679 +}
131680 +
131681 +static __maybe_unused void dump_frags(void)
131682 +{
131683 + struct mem_fragment *frag;
131684 + int i = 0;
131685 + list_for_each_entry(frag, &mem_list, list) {
131686 + 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",
131687 + i, frag->base, frag->pfn_base,
131688 + frag->len, frag->root_len, frag->root_pfn,
131689 + frag->refs, frag->name);
131690 + ++i;
131691 + }
131692 +}
131693 +
131694 +/* Walk the list of fragments and adjoin neighbouring segments if possible */
131695 +static void compress_frags(void)
131696 +{
131697 + /* Walk the fragment list and combine fragments */
131698 + struct mem_fragment *frag, *nxtfrag;
131699 + u64 len = 0;
131700 +
131701 + int i, numfrags;
131702 +
131703 +
131704 + frag = list_entry(mem_list.next, struct mem_fragment, list);
131705 +
131706 + while (&frag->list != &mem_list) {
131707 + /* Must combine consecutive fragemenst with
131708 + same root_pfn such that they are power of 4 */
131709 + if (frag->refs != 0) {
131710 + frag = list_entry(frag->list.next,
131711 + struct mem_fragment, list);
131712 + continue; /* Not this window */
131713 + }
131714 + len = frag->len;
131715 + numfrags = 0;
131716 + nxtfrag = list_entry(frag->list.next,
131717 + struct mem_fragment, list);
131718 + while (true) {
131719 + if (&nxtfrag->list == &mem_list) {
131720 + numfrags = 0;
131721 + break; /* End of list */
131722 + }
131723 + if (nxtfrag->refs) {
131724 + numfrags = 0;
131725 + break; /* In use still */
131726 + }
131727 + if (nxtfrag->root_pfn != frag->root_pfn) {
131728 + numfrags = 0;
131729 + break; /* Crosses root fragment boundary */
131730 + }
131731 + len += nxtfrag->len;
131732 + numfrags++;
131733 + if (is_power_of_4(len)) {
131734 + /* These fragments can be combined */
131735 + break;
131736 + }
131737 + nxtfrag = list_entry(nxtfrag->list.next,
131738 + struct mem_fragment, list);
131739 + }
131740 + if (numfrags == 0) {
131741 + frag = list_entry(frag->list.next,
131742 + struct mem_fragment, list);
131743 + continue; /* try the next window */
131744 + }
131745 + for (i = 0; i < numfrags; i++) {
131746 + struct mem_fragment *todel =
131747 + list_entry(nxtfrag->list.prev,
131748 + struct mem_fragment, list);
131749 + nxtfrag->len += todel->len;
131750 + nxtfrag->pfn_len += todel->pfn_len;
131751 + list_del(&todel->list);
131752 + }
131753 + /* Re evaluate the list, things may merge now */
131754 + frag = list_entry(mem_list.next, struct mem_fragment, list);
131755 + }
131756 +}
131757 +
131758 +/* Hook from arch/powerpc/mm/mem.c */
131759 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size)
131760 +{
131761 + struct mem_fragment *frag;
131762 + int idx = -1;
131763 + if ((pfn < pfn_start) || (pfn >= (pfn_start + pfn_size)))
131764 + return -1;
131765 + /* It's in-range, we need to find the fragment */
131766 + spin_lock(&mem_lock);
131767 + list_for_each_entry(frag, &mem_list, list) {
131768 + if ((pfn >= frag->pfn_base) && (pfn < (frag->pfn_base +
131769 + frag->pfn_len))) {
131770 + *phys_addr = frag->base;
131771 + *size = frag->len;
131772 + idx = current_tlb++;
131773 + if (current_tlb >= (first_tlb + num_tlb))
131774 + current_tlb = first_tlb;
131775 + break;
131776 + }
131777 + }
131778 + spin_unlock(&mem_lock);
131779 + return idx;
131780 +}
131781 +
131782 +static int usdpaa_open(struct inode *inode, struct file *filp)
131783 +{
131784 + const struct alloc_backend *backend = &alloc_backends[0];
131785 + struct ctx *ctx = kmalloc(sizeof(struct ctx), GFP_KERNEL);
131786 + if (!ctx)
131787 + return -ENOMEM;
131788 + filp->private_data = ctx;
131789 +
131790 + while (backend->id_type != usdpaa_id_max) {
131791 + INIT_LIST_HEAD(&ctx->resources[backend->id_type]);
131792 + backend++;
131793 + }
131794 +
131795 + INIT_LIST_HEAD(&ctx->maps);
131796 + INIT_LIST_HEAD(&ctx->portals);
131797 + spin_lock_init(&ctx->lock);
131798 +
131799 + //filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi;
131800 +
131801 + return 0;
131802 +}
131803 +
131804 +#define DQRR_MAXFILL 15
131805 +
131806 +
131807 +/* Invalidate a portal */
131808 +void dbci_portal(void *addr)
131809 +{
131810 + int i;
131811 +
131812 + for (i = 0; i < 0x4000; i += 64)
131813 + dcbi(addr + i);
131814 +}
131815 +
131816 +/* Reset a QMan portal to its default state */
131817 +static int init_qm_portal(struct qm_portal_config *config,
131818 + struct qm_portal *portal)
131819 +{
131820 + const struct qm_dqrr_entry *dqrr = NULL;
131821 + int i;
131822 +
131823 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
131824 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
131825 +
131826 + /* Make sure interrupts are inhibited */
131827 + qm_out(IIR, 1);
131828 +
131829 + /*
131830 + * Invalidate the entire CE portal are to ensure no stale
131831 + * cachelines are present. This should be done on all
131832 + * cores as the portal is mapped as M=0 (non-coherent).
131833 + */
131834 + on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
131835 +
131836 + /* Initialize the DQRR. This will stop any dequeue
131837 + commands that are in progress */
131838 + if (qm_dqrr_init(portal, config, qm_dqrr_dpush, qm_dqrr_pvb,
131839 + qm_dqrr_cdc, DQRR_MAXFILL)) {
131840 + pr_err("qm_dqrr_init() failed when trying to"
131841 + " recover portal, portal will be leaked\n");
131842 + return 1;
131843 + }
131844 +
131845 + /* Discard any entries on the DQRR */
131846 + /* If we consume the ring twice something is wrong */
131847 + for (i = 0; i < DQRR_MAXFILL * 2; i++) {
131848 + qm_dqrr_pvb_update(portal);
131849 + dqrr = qm_dqrr_current(portal);
131850 + if (!dqrr)
131851 + break;
131852 + qm_dqrr_cdc_consume_1ptr(portal, dqrr, 0);
131853 + qm_dqrr_pvb_update(portal);
131854 + qm_dqrr_next(portal);
131855 + }
131856 + /* Initialize the EQCR */
131857 + if (qm_eqcr_init(portal, qm_eqcr_pvb,
131858 + qm_eqcr_get_ci_stashing(portal), 1)) {
131859 + pr_err("Qman EQCR initialisation failed\n");
131860 + return 1;
131861 + }
131862 + /* initialize the MR */
131863 + if (qm_mr_init(portal, qm_mr_pvb, qm_mr_cci)) {
131864 + pr_err("Qman MR initialisation failed\n");
131865 + return 1;
131866 + }
131867 + qm_mr_pvb_update(portal);
131868 + while (qm_mr_current(portal)) {
131869 + qm_mr_next(portal);
131870 + qm_mr_cci_consume_to_current(portal);
131871 + qm_mr_pvb_update(portal);
131872 + }
131873 +
131874 + if (qm_mc_init(portal)) {
131875 + pr_err("Qman MC initialisation failed\n");
131876 + return 1;
131877 + }
131878 + return 0;
131879 +}
131880 +
131881 +static int init_bm_portal(struct bm_portal_config *config,
131882 + struct bm_portal *portal)
131883 +{
131884 + portal->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
131885 + portal->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
131886 +
131887 + /*
131888 + * Invalidate the entire CE portal are to ensure no stale
131889 + * cachelines are present. This should be done on all
131890 + * cores as the portal is mapped as M=0 (non-coherent).
131891 + */
131892 + on_each_cpu(dbci_portal, portal->addr.addr_ce, 1);
131893 +
131894 + if (bm_rcr_init(portal, bm_rcr_pvb, bm_rcr_cce)) {
131895 + pr_err("Bman RCR initialisation failed\n");
131896 + return 1;
131897 + }
131898 + if (bm_mc_init(portal)) {
131899 + pr_err("Bman MC initialisation failed\n");
131900 + return 1;
131901 + }
131902 + return 0;
131903 +}
131904 +
131905 +/* Function that will scan all FQ's in the system. For each FQ that is not
131906 + OOS it will call the check_channel helper to determine if the FQ should
131907 + be torn down. If the check_channel helper returns true the FQ will be
131908 + transitioned to the OOS state */
131909 +static int qm_check_and_destroy_fqs(struct qm_portal *portal, void *ctx,
131910 + bool (*check_channel)(void*, u32))
131911 +{
131912 + u32 fq_id = 0;
131913 + while (1) {
131914 + struct qm_mc_command *mcc;
131915 + struct qm_mc_result *mcr;
131916 + u8 state;
131917 + u32 channel;
131918 +
131919 + /* Determine the channel for the FQID */
131920 + mcc = qm_mc_start(portal);
131921 + mcc->queryfq.fqid = fq_id;
131922 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ);
131923 + while (!(mcr = qm_mc_result(portal)))
131924 + cpu_relax();
131925 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
131926 + == QM_MCR_VERB_QUERYFQ);
131927 + if (mcr->result != QM_MCR_RESULT_OK)
131928 + break; /* End of valid FQIDs */
131929 +
131930 + channel = mcr->queryfq.fqd.dest.channel;
131931 + /* Determine the state of the FQID */
131932 + mcc = qm_mc_start(portal);
131933 + mcc->queryfq_np.fqid = fq_id;
131934 + qm_mc_commit(portal, QM_MCC_VERB_QUERYFQ_NP);
131935 + while (!(mcr = qm_mc_result(portal)))
131936 + cpu_relax();
131937 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK)
131938 + == QM_MCR_VERB_QUERYFQ_NP);
131939 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
131940 + if (state == QM_MCR_NP_STATE_OOS)
131941 + /* Already OOS, no need to do anymore checks */
131942 + goto next;
131943 +
131944 + if (check_channel(ctx, channel))
131945 + qm_shutdown_fq(&portal, 1, fq_id);
131946 + next:
131947 + ++fq_id;
131948 + }
131949 + return 0;
131950 +}
131951 +
131952 +static bool check_channel_device(void *_ctx, u32 channel)
131953 +{
131954 + struct ctx *ctx = _ctx;
131955 + struct portal_mapping *portal, *tmpportal;
131956 + struct active_resource *res;
131957 +
131958 + /* See if the FQ is destined for one of the portals we're cleaning up */
131959 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
131960 + if (portal->user.type == usdpaa_portal_qman) {
131961 + if (portal->qportal->public_cfg.channel == channel) {
131962 + /* This FQs destination is a portal
131963 + we're cleaning, send a retire */
131964 + return true;
131965 + }
131966 + }
131967 + }
131968 +
131969 + /* Check the pool channels that will be released as well */
131970 + list_for_each_entry(res, &ctx->resources[usdpaa_id_qpool], list) {
131971 + if ((res->id >= channel) &&
131972 + ((res->id + res->num - 1) <= channel))
131973 + return true;
131974 + }
131975 + return false;
131976 +}
131977 +
131978 +static bool check_portal_channel(void *ctx, u32 channel)
131979 +{
131980 + u32 portal_channel = *(u32 *)ctx;
131981 + if (portal_channel == channel) {
131982 + /* This FQs destination is a portal
131983 + we're cleaning, send a retire */
131984 + return true;
131985 + }
131986 + return false;
131987 +}
131988 +
131989 +
131990 +
131991 +
131992 +static int usdpaa_release(struct inode *inode, struct file *filp)
131993 +{
131994 + struct ctx *ctx = filp->private_data;
131995 + struct mem_mapping *map, *tmpmap;
131996 + struct portal_mapping *portal, *tmpportal;
131997 + const struct alloc_backend *backend = &alloc_backends[0];
131998 + struct active_resource *res;
131999 + struct qm_portal *qm_cleanup_portal = NULL;
132000 + struct bm_portal *bm_cleanup_portal = NULL;
132001 + struct qm_portal_config *qm_alloced_portal = NULL;
132002 + struct bm_portal_config *bm_alloced_portal = NULL;
132003 +
132004 + struct qm_portal *portal_array[qman_portal_max];
132005 + int portal_count = 0;
132006 +
132007 + /* Ensure the release operation cannot be migrated to another
132008 + CPU as CPU specific variables may be needed during cleanup */
132009 +#ifdef CONFIG_PREEMPT_RT_FULL
132010 + migrate_disable();
132011 +#endif
132012 + /* The following logic is used to recover resources that were not
132013 + correctly released by the process that is closing the FD.
132014 + Step 1: syncronize the HW with the qm_portal/bm_portal structures
132015 + in the kernel
132016 + */
132017 +
132018 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
132019 + /* Try to recover any portals that weren't shut down */
132020 + if (portal->user.type == usdpaa_portal_qman) {
132021 + portal_array[portal_count] = &portal->qman_portal_low;
132022 + ++portal_count;
132023 + init_qm_portal(portal->qportal,
132024 + &portal->qman_portal_low);
132025 + if (!qm_cleanup_portal) {
132026 + qm_cleanup_portal = &portal->qman_portal_low;
132027 + } else {
132028 + /* Clean FQs on the dedicated channel */
132029 + u32 chan = portal->qportal->public_cfg.channel;
132030 + qm_check_and_destroy_fqs(
132031 + &portal->qman_portal_low, &chan,
132032 + check_portal_channel);
132033 + }
132034 + } else {
132035 + /* BMAN */
132036 + init_bm_portal(portal->bportal,
132037 + &portal->bman_portal_low);
132038 + if (!bm_cleanup_portal)
132039 + bm_cleanup_portal = &portal->bman_portal_low;
132040 + }
132041 + }
132042 + /* If no portal was found, allocate one for cleanup */
132043 + if (!qm_cleanup_portal) {
132044 + qm_alloced_portal = qm_get_unused_portal();
132045 + if (!qm_alloced_portal) {
132046 + pr_crit("No QMan portal avalaible for cleanup\n");
132047 +#ifdef CONFIG_PREEMPT_RT_FULL
132048 + migrate_enable();
132049 +#endif
132050 + return -1;
132051 + }
132052 + qm_cleanup_portal = kmalloc(sizeof(struct qm_portal),
132053 + GFP_KERNEL);
132054 + if (!qm_cleanup_portal) {
132055 +#ifdef CONFIG_PREEMPT_RT_FULL
132056 + migrate_enable();
132057 +#endif
132058 + return -ENOMEM;
132059 + }
132060 + init_qm_portal(qm_alloced_portal, qm_cleanup_portal);
132061 + portal_array[portal_count] = qm_cleanup_portal;
132062 + ++portal_count;
132063 + }
132064 + if (!bm_cleanup_portal) {
132065 + bm_alloced_portal = bm_get_unused_portal();
132066 + if (!bm_alloced_portal) {
132067 + pr_crit("No BMan portal avalaible for cleanup\n");
132068 +#ifdef CONFIG_PREEMPT_RT_FULL
132069 + migrate_enable();
132070 +#endif
132071 + return -1;
132072 + }
132073 + bm_cleanup_portal = kmalloc(sizeof(struct bm_portal),
132074 + GFP_KERNEL);
132075 + if (!bm_cleanup_portal) {
132076 +#ifdef CONFIG_PREEMPT_RT_FULL
132077 + migrate_enable();
132078 +#endif
132079 + return -ENOMEM;
132080 + }
132081 + init_bm_portal(bm_alloced_portal, bm_cleanup_portal);
132082 + }
132083 +
132084 + /* OOS the FQs associated with this process */
132085 + qm_check_and_destroy_fqs(qm_cleanup_portal, ctx, check_channel_device);
132086 +
132087 + while (backend->id_type != usdpaa_id_max) {
132088 + int leaks = 0;
132089 + list_for_each_entry(res, &ctx->resources[backend->id_type],
132090 + list) {
132091 + if (backend->id_type == usdpaa_id_fqid) {
132092 + int i = 0;
132093 + for (; i < res->num; i++) {
132094 + /* Clean FQs with the cleanup portal */
132095 + qm_shutdown_fq(portal_array,
132096 + portal_count,
132097 + res->id + i);
132098 + }
132099 + }
132100 + leaks += res->num;
132101 + backend->release(res->id, res->num);
132102 + }
132103 + if (leaks)
132104 + pr_crit("USDPAA process leaking %d %s%s\n", leaks,
132105 + backend->acronym, (leaks > 1) ? "s" : "");
132106 + backend++;
132107 + }
132108 + /* Release any DMA regions */
132109 + spin_lock(&mem_lock);
132110 + list_for_each_entry_safe(map, tmpmap, &ctx->maps, list) {
132111 + struct mem_fragment *current_frag = map->root_frag;
132112 + int i;
132113 + if (map->root_frag->has_locking &&
132114 + (map->root_frag->owner == map)) {
132115 + map->root_frag->owner = NULL;
132116 + wake_up(&map->root_frag->wq);
132117 + }
132118 + /* Check each fragment and merge if the ref count is 0 */
132119 + for (i = 0; i < map->frag_count; i++) {
132120 + --current_frag->refs;
132121 + current_frag = list_entry(current_frag->list.prev,
132122 + struct mem_fragment, list);
132123 + }
132124 +
132125 + compress_frags();
132126 + list_del(&map->list);
132127 + kfree(map);
132128 + }
132129 + spin_unlock(&mem_lock);
132130 +
132131 + /* Return portals */
132132 + list_for_each_entry_safe(portal, tmpportal, &ctx->portals, list) {
132133 + if (portal->user.type == usdpaa_portal_qman) {
132134 + /* Give the portal back to the allocator */
132135 + init_qm_portal(portal->qportal,
132136 + &portal->qman_portal_low);
132137 + qm_put_unused_portal(portal->qportal);
132138 + } else {
132139 + init_bm_portal(portal->bportal,
132140 + &portal->bman_portal_low);
132141 + bm_put_unused_portal(portal->bportal);
132142 + }
132143 + list_del(&portal->list);
132144 + kfree(portal);
132145 + }
132146 + if (qm_alloced_portal) {
132147 + qm_put_unused_portal(qm_alloced_portal);
132148 + kfree(qm_cleanup_portal);
132149 + }
132150 + if (bm_alloced_portal) {
132151 + bm_put_unused_portal(bm_alloced_portal);
132152 + kfree(bm_cleanup_portal);
132153 + }
132154 +
132155 + kfree(ctx);
132156 +#ifdef CONFIG_PREEMPT_RT_FULL
132157 + migrate_enable();
132158 +#endif
132159 + return 0;
132160 +}
132161 +
132162 +static int check_mmap_dma(struct ctx *ctx, struct vm_area_struct *vma,
132163 + int *match, unsigned long *pfn)
132164 +{
132165 + struct mem_mapping *map;
132166 +
132167 + list_for_each_entry(map, &ctx->maps, list) {
132168 + int i;
132169 + struct mem_fragment *frag = map->root_frag;
132170 +
132171 + for (i = 0; i < map->frag_count; i++) {
132172 + if (frag->pfn_base == vma->vm_pgoff) {
132173 + *match = 1;
132174 + *pfn = frag->pfn_base;
132175 + return 0;
132176 + }
132177 + frag = list_entry(frag->list.next, struct mem_fragment,
132178 + list);
132179 + }
132180 + }
132181 + *match = 0;
132182 + return 0;
132183 +}
132184 +
132185 +static int check_mmap_resource(struct resource *res, struct vm_area_struct *vma,
132186 + int *match, unsigned long *pfn)
132187 +{
132188 + *pfn = res->start >> PAGE_SHIFT;
132189 + if (*pfn == vma->vm_pgoff) {
132190 + *match = 1;
132191 + if ((vma->vm_end - vma->vm_start) != resource_size(res))
132192 + return -EINVAL;
132193 + } else
132194 + *match = 0;
132195 + return 0;
132196 +}
132197 +
132198 +static int check_mmap_portal(struct ctx *ctx, struct vm_area_struct *vma,
132199 + int *match, unsigned long *pfn)
132200 +{
132201 + struct portal_mapping *portal;
132202 + int ret;
132203 +
132204 + list_for_each_entry(portal, &ctx->portals, list) {
132205 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CE], vma,
132206 + match, pfn);
132207 + if (*match) {
132208 + vma->vm_page_prot =
132209 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
132210 + pgprot_cached_ns(vma->vm_page_prot);
132211 +#else
132212 + pgprot_cached_noncoherent(vma->vm_page_prot);
132213 +#endif
132214 + return ret;
132215 + }
132216 + ret = check_mmap_resource(&portal->phys[DPA_PORTAL_CI], vma,
132217 + match, pfn);
132218 + if (*match) {
132219 + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
132220 + return ret;
132221 + }
132222 + }
132223 + *match = 0;
132224 + return 0;
132225 +}
132226 +
132227 +static int usdpaa_mmap(struct file *filp, struct vm_area_struct *vma)
132228 +{
132229 + struct ctx *ctx = filp->private_data;
132230 + unsigned long pfn = 0;
132231 + int match, ret;
132232 +
132233 + spin_lock(&mem_lock);
132234 + ret = check_mmap_dma(ctx, vma, &match, &pfn);
132235 + if (!match)
132236 + ret = check_mmap_portal(ctx, vma, &match, &pfn);
132237 + spin_unlock(&mem_lock);
132238 + if (!match)
132239 + return -EINVAL;
132240 + if (!ret)
132241 + ret = remap_pfn_range(vma, vma->vm_start, pfn,
132242 + vma->vm_end - vma->vm_start,
132243 + vma->vm_page_prot);
132244 + return ret;
132245 +}
132246 +
132247 +/* Return the nearest rounded-up address >= 'addr' that is 'sz'-aligned. 'sz'
132248 + * must be a power of 2, but both 'addr' and 'sz' can be expressions. */
132249 +#define USDPAA_MEM_ROUNDUP(addr, sz) \
132250 + ({ \
132251 + unsigned long foo_align = (sz) - 1; \
132252 + ((addr) + foo_align) & ~foo_align; \
132253 + })
132254 +/* Searching for a size-aligned virtual address range starting from 'addr' */
132255 +static unsigned long usdpaa_get_unmapped_area(struct file *file,
132256 + unsigned long addr,
132257 + unsigned long len,
132258 + unsigned long pgoff,
132259 + unsigned long flags)
132260 +{
132261 + struct vm_area_struct *vma;
132262 +
132263 + if (len % PAGE_SIZE)
132264 + return -EINVAL;
132265 + if (!len)
132266 + return -EINVAL;
132267 +
132268 + /* Need to align the address to the largest pagesize of the mapping
132269 + * because the MMU requires the virtual address to have the same
132270 + * alignment as the physical address */
132271 + addr = USDPAA_MEM_ROUNDUP(addr, largest_page_size(len));
132272 + vma = find_vma(current->mm, addr);
132273 + /* Keep searching until we reach the end of currently-used virtual
132274 + * address-space or we find a big enough gap. */
132275 + while (vma) {
132276 + if ((addr + len) < vma->vm_start)
132277 + return addr;
132278 +
132279 + addr = USDPAA_MEM_ROUNDUP(vma->vm_end, largest_page_size(len));
132280 + vma = vma->vm_next;
132281 + }
132282 + if ((TASK_SIZE - len) < addr)
132283 + return -ENOMEM;
132284 + return addr;
132285 +}
132286 +
132287 +static long ioctl_id_alloc(struct ctx *ctx, void __user *arg)
132288 +{
132289 + struct usdpaa_ioctl_id_alloc i;
132290 + const struct alloc_backend *backend;
132291 + struct active_resource *res;
132292 + int ret = copy_from_user(&i, arg, sizeof(i));
132293 + if (ret)
132294 + return ret;
132295 + if ((i.id_type >= usdpaa_id_max) || !i.num)
132296 + return -EINVAL;
132297 + backend = &alloc_backends[i.id_type];
132298 + /* Allocate the required resource type */
132299 + ret = backend->alloc(&i.base, i.num, i.align, i.partial);
132300 + if (ret < 0)
132301 + return ret;
132302 + i.num = ret;
132303 + /* Copy the result to user-space */
132304 + ret = copy_to_user(arg, &i, sizeof(i));
132305 + if (ret) {
132306 + backend->release(i.base, i.num);
132307 + return ret;
132308 + }
132309 + /* Assign the allocated range to the FD accounting */
132310 + res = kmalloc(sizeof(*res), GFP_KERNEL);
132311 + if (!res) {
132312 + backend->release(i.base, i.num);
132313 + return -ENOMEM;
132314 + }
132315 + spin_lock(&ctx->lock);
132316 + res->id = i.base;
132317 + res->num = i.num;
132318 + res->refcount = 1;
132319 + list_add(&res->list, &ctx->resources[i.id_type]);
132320 + spin_unlock(&ctx->lock);
132321 + return 0;
132322 +}
132323 +
132324 +static long ioctl_id_release(struct ctx *ctx, void __user *arg)
132325 +{
132326 + struct usdpaa_ioctl_id_release i;
132327 + const struct alloc_backend *backend;
132328 + struct active_resource *tmp, *pos;
132329 +
132330 + int ret = copy_from_user(&i, arg, sizeof(i));
132331 + if (ret)
132332 + return ret;
132333 + if ((i.id_type >= usdpaa_id_max) || !i.num)
132334 + return -EINVAL;
132335 + backend = &alloc_backends[i.id_type];
132336 + /* Pull the range out of the FD accounting - the range is valid iff this
132337 + * succeeds. */
132338 + spin_lock(&ctx->lock);
132339 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
132340 + if (pos->id == i.base && pos->num == i.num) {
132341 + pos->refcount--;
132342 + if (pos->refcount) {
132343 + spin_unlock(&ctx->lock);
132344 + return 0; /* Still being used */
132345 + }
132346 + list_del(&pos->list);
132347 + kfree(pos);
132348 + spin_unlock(&ctx->lock);
132349 + goto found;
132350 + }
132351 + }
132352 + /* Failed to find the resource */
132353 + spin_unlock(&ctx->lock);
132354 + pr_err("Couldn't find resource type %d base 0x%x num %d\n",
132355 + i.id_type, i.base, i.num);
132356 + return -EINVAL;
132357 +found:
132358 + /* Release the resource to the backend */
132359 + backend->release(i.base, i.num);
132360 + return 0;
132361 +}
132362 +
132363 +static long ioctl_id_reserve(struct ctx *ctx, void __user *arg)
132364 +{
132365 + struct usdpaa_ioctl_id_reserve i;
132366 + const struct alloc_backend *backend;
132367 + struct active_resource *tmp, *pos;
132368 +
132369 + int ret = copy_from_user(&i, arg, sizeof(i));
132370 + if (ret)
132371 + return ret;
132372 + if ((i.id_type >= usdpaa_id_max) || !i.num)
132373 + return -EINVAL;
132374 + backend = &alloc_backends[i.id_type];
132375 + if (!backend->reserve)
132376 + return -EINVAL;
132377 + /* Pull the range out of the FD accounting - the range is valid iff this
132378 + * succeeds. */
132379 + spin_lock(&ctx->lock);
132380 + list_for_each_entry_safe(pos, tmp, &ctx->resources[i.id_type], list) {
132381 + if (pos->id == i.base && pos->num == i.num) {
132382 + pos->refcount++;
132383 + spin_unlock(&ctx->lock);
132384 + return 0;
132385 + }
132386 + }
132387 +
132388 + /* Failed to find the resource */
132389 + spin_unlock(&ctx->lock);
132390 +
132391 + /* Reserve the resource in the backend */
132392 + ret = backend->reserve(i.base, i.num);
132393 + if (ret)
132394 + return ret;
132395 + /* Assign the reserved range to the FD accounting */
132396 + pos = kmalloc(sizeof(*pos), GFP_KERNEL);
132397 + if (!pos) {
132398 + backend->release(i.base, i.num);
132399 + return -ENOMEM;
132400 + }
132401 + spin_lock(&ctx->lock);
132402 + pos->id = i.base;
132403 + pos->num = i.num;
132404 + pos->refcount = 1;
132405 + list_add(&pos->list, &ctx->resources[i.id_type]);
132406 + spin_unlock(&ctx->lock);
132407 + return 0;
132408 +}
132409 +
132410 +static long ioctl_dma_map(struct file *fp, struct ctx *ctx,
132411 + struct usdpaa_ioctl_dma_map *i)
132412 +{
132413 + struct mem_fragment *frag, *start_frag, *next_frag;
132414 + struct mem_mapping *map, *tmp;
132415 + int ret = 0;
132416 + u32 largest_page, so_far = 0;
132417 + int frag_count = 0;
132418 + unsigned long next_addr = PAGE_SIZE, populate;
132419 +
132420 + /* error checking to ensure values copied from user space are valid */
132421 + if (i->len % PAGE_SIZE)
132422 + return -EINVAL;
132423 +
132424 + map = kmalloc(sizeof(*map), GFP_KERNEL);
132425 + if (!map)
132426 + return -ENOMEM;
132427 +
132428 + spin_lock(&mem_lock);
132429 + if (i->flags & USDPAA_DMA_FLAG_SHARE) {
132430 + list_for_each_entry(frag, &mem_list, list) {
132431 + if (frag->refs && (frag->flags &
132432 + USDPAA_DMA_FLAG_SHARE) &&
132433 + !strncmp(i->name, frag->name,
132434 + USDPAA_DMA_NAME_MAX)) {
132435 + /* Matching entry */
132436 + if ((i->flags & USDPAA_DMA_FLAG_CREATE) &&
132437 + !(i->flags & USDPAA_DMA_FLAG_LAZY)) {
132438 + ret = -EBUSY;
132439 + goto out;
132440 + }
132441 +
132442 + /* Check to ensure size matches record */
132443 + if (i->len != frag->map_len && i->len) {
132444 + pr_err("ioctl_dma_map() Size requested does not match %s and is none zero\n",
132445 + frag->name);
132446 + return -EINVAL;
132447 + }
132448 +
132449 + /* Check if this has already been mapped
132450 + to this process */
132451 + list_for_each_entry(tmp, &ctx->maps, list)
132452 + if (tmp->root_frag == frag) {
132453 + /* Already mapped, just need to
132454 + inc ref count */
132455 + tmp->refs++;
132456 + kfree(map);
132457 + i->did_create = 0;
132458 + i->len = tmp->total_size;
132459 + i->phys_addr = frag->base;
132460 + i->ptr = tmp->virt_addr;
132461 + spin_unlock(&mem_lock);
132462 + return 0;
132463 + }
132464 + /* Matching entry - just need to map */
132465 + i->has_locking = frag->has_locking;
132466 + i->did_create = 0;
132467 + i->len = frag->map_len;
132468 + start_frag = frag;
132469 + goto do_map;
132470 + }
132471 + }
132472 + /* No matching entry */
132473 + if (!(i->flags & USDPAA_DMA_FLAG_CREATE)) {
132474 + pr_err("ioctl_dma_map() No matching entry\n");
132475 + ret = -ENOMEM;
132476 + goto out;
132477 + }
132478 + }
132479 + /* New fragment required, size must be provided. */
132480 + if (!i->len) {
132481 + ret = -EINVAL;
132482 + goto out;
132483 + }
132484 +
132485 + /* Find one of more contiguous fragments that satisfy the total length
132486 + trying to minimize the number of fragments
132487 + compute the largest page size that the allocation could use */
132488 + largest_page = largest_page_size(i->len);
132489 + start_frag = NULL;
132490 + while (largest_page &&
132491 + largest_page <= largest_page_size(phys_size) &&
132492 + start_frag == NULL) {
132493 + /* Search the list for a frag of that size */
132494 + list_for_each_entry(frag, &mem_list, list) {
132495 + if (!frag->refs && (frag->len == largest_page)) {
132496 + /* See if the next x fragments are free
132497 + and can accomidate the size */
132498 + u32 found_size = largest_page;
132499 + next_frag = list_entry(frag->list.prev,
132500 + struct mem_fragment,
132501 + list);
132502 + /* If the fragement is too small check
132503 + if the neighbours cab support it */
132504 + while (found_size < i->len) {
132505 + if (&mem_list == &next_frag->list)
132506 + break; /* End of list */
132507 + if (next_frag->refs != 0 ||
132508 + next_frag->len == 0)
132509 + break; /* not enough space */
132510 + found_size += next_frag->len;
132511 + next_frag = list_entry(
132512 + next_frag->list.prev,
132513 + struct mem_fragment,
132514 + list);
132515 + }
132516 + if (found_size >= i->len) {
132517 + /* Success! there is enough contigous
132518 + free space */
132519 + start_frag = frag;
132520 + break;
132521 + }
132522 + }
132523 + } /* next frag loop */
132524 + /* Couldn't statisfy the request with this
132525 + largest page size, try a smaller one */
132526 + largest_page <<= 2;
132527 + }
132528 + if (start_frag == NULL) {
132529 + /* Couldn't find proper amount of space */
132530 + ret = -ENOMEM;
132531 + goto out;
132532 + }
132533 + i->did_create = 1;
132534 +do_map:
132535 + /* Verify there is sufficient space to do the mapping */
132536 + down_write(&current->mm->mmap_sem);
132537 + next_addr = usdpaa_get_unmapped_area(fp, next_addr, i->len, 0, 0);
132538 + up_write(&current->mm->mmap_sem);
132539 +
132540 + if (next_addr & ~PAGE_MASK) {
132541 + ret = -ENOMEM;
132542 + goto out;
132543 + }
132544 +
132545 + /* We may need to divide the final fragment to accomidate the mapping */
132546 + next_frag = start_frag;
132547 + while (so_far != i->len) {
132548 + BUG_ON(next_frag->len == 0);
132549 + while ((next_frag->len + so_far) > i->len) {
132550 + /* Split frag until they match */
132551 + split_frag(next_frag);
132552 + }
132553 + so_far += next_frag->len;
132554 + next_frag->refs++;
132555 + ++frag_count;
132556 + next_frag = list_entry(next_frag->list.prev,
132557 + struct mem_fragment, list);
132558 + }
132559 + if (i->did_create) {
132560 + size_t name_len = 0;
132561 + start_frag->flags = i->flags;
132562 + strncpy(start_frag->name, i->name, USDPAA_DMA_NAME_MAX);
132563 + name_len = strnlen(start_frag->name, USDPAA_DMA_NAME_MAX);
132564 + if (name_len >= USDPAA_DMA_NAME_MAX) {
132565 + ret = -EFAULT;
132566 + goto out;
132567 + }
132568 + start_frag->map_len = i->len;
132569 + start_frag->has_locking = i->has_locking;
132570 + init_waitqueue_head(&start_frag->wq);
132571 + start_frag->owner = NULL;
132572 + }
132573 +
132574 + /* Setup the map entry */
132575 + map->root_frag = start_frag;
132576 + map->total_size = i->len;
132577 + map->frag_count = frag_count;
132578 + map->refs = 1;
132579 + list_add(&map->list, &ctx->maps);
132580 + i->phys_addr = start_frag->base;
132581 +out:
132582 + spin_unlock(&mem_lock);
132583 +
132584 + if (!ret) {
132585 + unsigned long longret;
132586 + down_write(&current->mm->mmap_sem);
132587 + longret = do_mmap_pgoff(fp, next_addr, map->total_size,
132588 + PROT_READ |
132589 + (i->flags &
132590 + USDPAA_DMA_FLAG_RDONLY ? 0
132591 + : PROT_WRITE),
132592 + MAP_SHARED,
132593 + start_frag->pfn_base,
132594 + &populate,
132595 + NULL);
132596 + up_write(&current->mm->mmap_sem);
132597 + if (longret & ~PAGE_MASK) {
132598 + ret = (int)longret;
132599 + } else {
132600 + i->ptr = (void *)longret;
132601 + map->virt_addr = i->ptr;
132602 + }
132603 + } else
132604 + kfree(map);
132605 + return ret;
132606 +}
132607 +
132608 +static long ioctl_dma_unmap(struct ctx *ctx, void __user *arg)
132609 +{
132610 + struct mem_mapping *map;
132611 + struct vm_area_struct *vma;
132612 + int ret, i;
132613 + struct mem_fragment *current_frag;
132614 + size_t sz;
132615 + unsigned long base;
132616 + unsigned long vaddr;
132617 +
132618 + down_write(&current->mm->mmap_sem);
132619 + vma = find_vma(current->mm, (unsigned long)arg);
132620 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
132621 + up_write(&current->mm->mmap_sem);
132622 + return -EFAULT;
132623 + }
132624 + spin_lock(&mem_lock);
132625 + list_for_each_entry(map, &ctx->maps, list) {
132626 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
132627 + /* Drop the map lock if we hold it */
132628 + if (map->root_frag->has_locking &&
132629 + (map->root_frag->owner == map)) {
132630 + map->root_frag->owner = NULL;
132631 + wake_up(&map->root_frag->wq);
132632 + }
132633 + goto map_match;
132634 + }
132635 + }
132636 + /* Failed to find a matching mapping for this process */
132637 + ret = -EFAULT;
132638 + spin_unlock(&mem_lock);
132639 + goto out;
132640 +map_match:
132641 + map->refs--;
132642 + if (map->refs != 0) {
132643 + /* Another call the dma_map is referencing this */
132644 + ret = 0;
132645 + spin_unlock(&mem_lock);
132646 + goto out;
132647 + }
132648 +
132649 + current_frag = map->root_frag;
132650 + vaddr = (unsigned long) map->virt_addr;
132651 + for (i = 0; i < map->frag_count; i++) {
132652 + DPA_ASSERT(current_frag->refs > 0);
132653 + --current_frag->refs;
132654 +#if !(defined(CONFIG_ARM) || defined(CONFIG_ARM64))
132655 + /*
132656 + * Make sure we invalidate the TLB entry for
132657 + * this fragment, otherwise a remap of a different
132658 + * page to this vaddr would give acces to an
132659 + * incorrect piece of memory
132660 + */
132661 + cleartlbcam(vaddr, mfspr(SPRN_PID));
132662 +#endif
132663 + vaddr += current_frag->len;
132664 + current_frag = list_entry(current_frag->list.prev,
132665 + struct mem_fragment, list);
132666 + }
132667 + map->root_frag->name[0] = 0;
132668 + list_del(&map->list);
132669 + compress_frags();
132670 + spin_unlock(&mem_lock);
132671 +
132672 + base = vma->vm_start;
132673 + sz = vma->vm_end - vma->vm_start;
132674 + do_munmap(current->mm, base, sz, NULL);
132675 + ret = 0;
132676 + out:
132677 + up_write(&current->mm->mmap_sem);
132678 + return ret;
132679 +}
132680 +
132681 +static long ioctl_dma_stats(struct ctx *ctx, void __user *arg)
132682 +{
132683 + struct mem_fragment *frag;
132684 + struct usdpaa_ioctl_dma_used result;
132685 +
132686 + result.free_bytes = 0;
132687 + result.total_bytes = phys_size;
132688 +
132689 + list_for_each_entry(frag, &mem_list, list) {
132690 + if (frag->refs == 0)
132691 + result.free_bytes += frag->len;
132692 + }
132693 +
132694 + return copy_to_user(arg, &result, sizeof(result)); }
132695 +
132696 +static int test_lock(struct mem_mapping *map)
132697 +{
132698 + int ret = 0;
132699 + spin_lock(&mem_lock);
132700 + if (!map->root_frag->owner) {
132701 + map->root_frag->owner = map;
132702 + ret = 1;
132703 + }
132704 + spin_unlock(&mem_lock);
132705 + return ret;
132706 +}
132707 +
132708 +static long ioctl_dma_lock(struct ctx *ctx, void __user *arg)
132709 +{
132710 + struct mem_mapping *map;
132711 + struct vm_area_struct *vma;
132712 +
132713 + down_read(&current->mm->mmap_sem);
132714 + vma = find_vma(current->mm, (unsigned long)arg);
132715 + if (!vma || (vma->vm_start > (unsigned long)arg)) {
132716 + up_read(&current->mm->mmap_sem);
132717 + return -EFAULT;
132718 + }
132719 + spin_lock(&mem_lock);
132720 + list_for_each_entry(map, &ctx->maps, list) {
132721 + if (map->root_frag->pfn_base == vma->vm_pgoff)
132722 + goto map_match;
132723 + }
132724 + map = NULL;
132725 +map_match:
132726 + spin_unlock(&mem_lock);
132727 + up_read(&current->mm->mmap_sem);
132728 +
132729 + if (!map)
132730 + return -EFAULT;
132731 + if (!map->root_frag->has_locking)
132732 + return -ENODEV;
132733 + return wait_event_interruptible(map->root_frag->wq, test_lock(map));
132734 +}
132735 +
132736 +static long ioctl_dma_unlock(struct ctx *ctx, void __user *arg)
132737 +{
132738 + struct mem_mapping *map;
132739 + struct vm_area_struct *vma;
132740 + int ret;
132741 +
132742 + down_read(&current->mm->mmap_sem);
132743 + vma = find_vma(current->mm, (unsigned long)arg);
132744 + if (!vma || (vma->vm_start > (unsigned long)arg))
132745 + ret = -EFAULT;
132746 + else {
132747 + spin_lock(&mem_lock);
132748 + list_for_each_entry(map, &ctx->maps, list) {
132749 + if (map->root_frag->pfn_base == vma->vm_pgoff) {
132750 + if (!map->root_frag->has_locking)
132751 + ret = -ENODEV;
132752 + else if (map->root_frag->owner == map) {
132753 + map->root_frag->owner = NULL;
132754 + wake_up(&map->root_frag->wq);
132755 + ret = 0;
132756 + } else
132757 + ret = -EBUSY;
132758 + goto map_match;
132759 + }
132760 + }
132761 + ret = -EINVAL;
132762 +map_match:
132763 + spin_unlock(&mem_lock);
132764 + }
132765 + up_read(&current->mm->mmap_sem);
132766 + return ret;
132767 +}
132768 +
132769 +static int portal_mmap(struct file *fp, struct resource *res, void **ptr)
132770 +{
132771 + unsigned long longret = 0, populate;
132772 + resource_size_t len;
132773 +
132774 + down_write(&current->mm->mmap_sem);
132775 + len = resource_size(res);
132776 + if (len != (unsigned long)len)
132777 + return -EINVAL;
132778 + longret = do_mmap_pgoff(fp, PAGE_SIZE, (unsigned long)len,
132779 + PROT_READ | PROT_WRITE, MAP_SHARED,
132780 + res->start >> PAGE_SHIFT, &populate, NULL);
132781 + up_write(&current->mm->mmap_sem);
132782 +
132783 + if (longret & ~PAGE_MASK)
132784 + return (int)longret;
132785 +
132786 + *ptr = (void *) longret;
132787 + return 0;
132788 +}
132789 +
132790 +static void portal_munmap(struct resource *res, void *ptr)
132791 +{
132792 + down_write(&current->mm->mmap_sem);
132793 + do_munmap(current->mm, (unsigned long)ptr, resource_size(res), NULL);
132794 + up_write(&current->mm->mmap_sem);
132795 +}
132796 +
132797 +static long ioctl_portal_map(struct file *fp, struct ctx *ctx,
132798 + struct usdpaa_ioctl_portal_map *arg)
132799 +{
132800 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
132801 + int ret;
132802 +
132803 + if (!mapping)
132804 + return -ENOMEM;
132805 +
132806 + mapping->user = *arg;
132807 + mapping->iommu_domain = NULL;
132808 +
132809 + if (mapping->user.type == usdpaa_portal_qman) {
132810 + mapping->qportal =
132811 + qm_get_unused_portal_idx(mapping->user.index);
132812 + if (!mapping->qportal) {
132813 + ret = -ENODEV;
132814 + goto err_get_portal;
132815 + }
132816 + mapping->phys = &mapping->qportal->addr_phys[0];
132817 + mapping->user.channel = mapping->qportal->public_cfg.channel;
132818 + mapping->user.pools = mapping->qportal->public_cfg.pools;
132819 + mapping->user.index = mapping->qportal->public_cfg.index;
132820 + } else if (mapping->user.type == usdpaa_portal_bman) {
132821 + mapping->bportal =
132822 + bm_get_unused_portal_idx(mapping->user.index);
132823 + if (!mapping->bportal) {
132824 + ret = -ENODEV;
132825 + goto err_get_portal;
132826 + }
132827 + mapping->phys = &mapping->bportal->addr_phys[0];
132828 + mapping->user.index = mapping->bportal->public_cfg.index;
132829 + } else {
132830 + ret = -EINVAL;
132831 + goto err_copy_from_user;
132832 + }
132833 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
132834 + * handlers look it up. */
132835 + spin_lock(&mem_lock);
132836 + list_add(&mapping->list, &ctx->portals);
132837 + spin_unlock(&mem_lock);
132838 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CE],
132839 + &mapping->user.addr.cena);
132840 + if (ret)
132841 + goto err_mmap_cena;
132842 + ret = portal_mmap(fp, &mapping->phys[DPA_PORTAL_CI],
132843 + &mapping->user.addr.cinh);
132844 + if (ret)
132845 + goto err_mmap_cinh;
132846 + *arg = mapping->user;
132847 + return ret;
132848 +
132849 +err_mmap_cinh:
132850 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
132851 +err_mmap_cena:
132852 + if ((mapping->user.type == usdpaa_portal_qman) && mapping->qportal)
132853 + qm_put_unused_portal(mapping->qportal);
132854 + else if ((mapping->user.type == usdpaa_portal_bman) && mapping->bportal)
132855 + bm_put_unused_portal(mapping->bportal);
132856 + spin_lock(&mem_lock);
132857 + list_del(&mapping->list);
132858 + spin_unlock(&mem_lock);
132859 +err_get_portal:
132860 +err_copy_from_user:
132861 + kfree(mapping);
132862 + return ret;
132863 +}
132864 +
132865 +static long ioctl_portal_unmap(struct ctx *ctx, struct usdpaa_portal_map *i)
132866 +{
132867 + struct portal_mapping *mapping;
132868 + struct vm_area_struct *vma;
132869 + unsigned long pfn;
132870 + u32 channel;
132871 +
132872 + /* Get the PFN corresponding to one of the virt addresses */
132873 + down_read(&current->mm->mmap_sem);
132874 + vma = find_vma(current->mm, (unsigned long)i->cinh);
132875 + if (!vma || (vma->vm_start > (unsigned long)i->cinh)) {
132876 + up_read(&current->mm->mmap_sem);
132877 + return -EFAULT;
132878 + }
132879 + pfn = vma->vm_pgoff;
132880 + up_read(&current->mm->mmap_sem);
132881 +
132882 + /* Find the corresponding portal */
132883 + spin_lock(&mem_lock);
132884 + list_for_each_entry(mapping, &ctx->portals, list) {
132885 + if (pfn == (mapping->phys[DPA_PORTAL_CI].start >> PAGE_SHIFT))
132886 + goto found;
132887 + }
132888 + mapping = NULL;
132889 +found:
132890 + if (mapping)
132891 + list_del(&mapping->list);
132892 + spin_unlock(&mem_lock);
132893 + if (!mapping)
132894 + return -ENODEV;
132895 + portal_munmap(&mapping->phys[DPA_PORTAL_CI], mapping->user.addr.cinh);
132896 + portal_munmap(&mapping->phys[DPA_PORTAL_CE], mapping->user.addr.cena);
132897 + if (mapping->user.type == usdpaa_portal_qman) {
132898 + init_qm_portal(mapping->qportal,
132899 + &mapping->qman_portal_low);
132900 +
132901 + /* Tear down any FQs this portal is referencing */
132902 + channel = mapping->qportal->public_cfg.channel;
132903 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
132904 + &channel,
132905 + check_portal_channel);
132906 + qm_put_unused_portal(mapping->qportal);
132907 + } else if (mapping->user.type == usdpaa_portal_bman) {
132908 + init_bm_portal(mapping->bportal,
132909 + &mapping->bman_portal_low);
132910 + bm_put_unused_portal(mapping->bportal);
132911 + }
132912 + kfree(mapping);
132913 + return 0;
132914 +}
132915 +
132916 +static void portal_config_pamu(struct qm_portal_config *pcfg, uint8_t sdest,
132917 + uint32_t cpu, uint32_t cache, uint32_t window)
132918 +{
132919 +#ifdef CONFIG_FSL_PAMU
132920 + int ret;
132921 + int window_count = 1;
132922 + struct iommu_domain_geometry geom_attr;
132923 + struct pamu_stash_attribute stash_attr;
132924 +
132925 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
132926 + if (!pcfg->iommu_domain) {
132927 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
132928 + __func__);
132929 + goto _no_iommu;
132930 + }
132931 + geom_attr.aperture_start = 0;
132932 + geom_attr.aperture_end =
132933 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
132934 + geom_attr.force_aperture = true;
132935 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
132936 + &geom_attr);
132937 + if (ret < 0) {
132938 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
132939 + __func__, ret);
132940 + goto _iommu_domain_free;
132941 + }
132942 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
132943 + &window_count);
132944 + if (ret < 0) {
132945 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
132946 + __func__, ret);
132947 + goto _iommu_domain_free;
132948 + }
132949 + stash_attr.cpu = cpu;
132950 + stash_attr.cache = cache;
132951 + /* set stash information for the window */
132952 + stash_attr.window = 0;
132953 +
132954 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
132955 + DOMAIN_ATTR_FSL_PAMU_STASH,
132956 + &stash_attr);
132957 + if (ret < 0) {
132958 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
132959 + __func__, ret);
132960 + goto _iommu_domain_free;
132961 + }
132962 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
132963 + IOMMU_READ | IOMMU_WRITE);
132964 + if (ret < 0) {
132965 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
132966 + __func__, ret);
132967 + goto _iommu_domain_free;
132968 + }
132969 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
132970 + if (ret < 0) {
132971 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
132972 + __func__, ret);
132973 + goto _iommu_domain_free;
132974 + }
132975 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
132976 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
132977 + &window_count);
132978 + if (ret < 0) {
132979 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
132980 + __func__, ret);
132981 + goto _iommu_detach_device;
132982 + }
132983 +_no_iommu:
132984 +#endif
132985 +
132986 +#ifdef CONFIG_FSL_QMAN_CONFIG
132987 + if (qman_set_sdest(pcfg->public_cfg.channel, sdest))
132988 +#endif
132989 + pr_warn("Failed to set QMan portal's stash request queue\n");
132990 +
132991 + return;
132992 +
132993 +#ifdef CONFIG_FSL_PAMU
132994 +_iommu_detach_device:
132995 + iommu_detach_device(pcfg->iommu_domain, NULL);
132996 +_iommu_domain_free:
132997 + iommu_domain_free(pcfg->iommu_domain);
132998 +#endif
132999 +}
133000 +
133001 +static long ioctl_allocate_raw_portal(struct file *fp, struct ctx *ctx,
133002 + struct usdpaa_ioctl_raw_portal *arg)
133003 +{
133004 + struct portal_mapping *mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
133005 + int ret;
133006 +
133007 + if (!mapping)
133008 + return -ENOMEM;
133009 +
133010 + mapping->user.type = arg->type;
133011 + mapping->iommu_domain = NULL;
133012 + if (arg->type == usdpaa_portal_qman) {
133013 + mapping->qportal = qm_get_unused_portal_idx(arg->index);
133014 + if (!mapping->qportal) {
133015 + ret = -ENODEV;
133016 + goto err;
133017 + }
133018 + mapping->phys = &mapping->qportal->addr_phys[0];
133019 + arg->index = mapping->qportal->public_cfg.index;
133020 + arg->cinh = mapping->qportal->addr_phys[DPA_PORTAL_CI].start;
133021 + arg->cena = mapping->qportal->addr_phys[DPA_PORTAL_CE].start;
133022 + if (arg->enable_stash) {
133023 + /* Setup the PAMU with the supplied parameters */
133024 + portal_config_pamu(mapping->qportal, arg->sdest,
133025 + arg->cpu, arg->cache, arg->window);
133026 + }
133027 + } else if (mapping->user.type == usdpaa_portal_bman) {
133028 + mapping->bportal =
133029 + bm_get_unused_portal_idx(arg->index);
133030 + if (!mapping->bportal) {
133031 + ret = -ENODEV;
133032 + goto err;
133033 + }
133034 + mapping->phys = &mapping->bportal->addr_phys[0];
133035 + arg->index = mapping->bportal->public_cfg.index;
133036 + arg->cinh = mapping->bportal->addr_phys[DPA_PORTAL_CI].start;
133037 + arg->cena = mapping->bportal->addr_phys[DPA_PORTAL_CE].start;
133038 + } else {
133039 + ret = -EINVAL;
133040 + goto err;
133041 + }
133042 + /* Need to put pcfg in ctx's list before the mmaps because the mmap
133043 + * handlers look it up. */
133044 + spin_lock(&mem_lock);
133045 + list_add(&mapping->list, &ctx->portals);
133046 + spin_unlock(&mem_lock);
133047 + return 0;
133048 +err:
133049 + kfree(mapping);
133050 + return ret;
133051 +}
133052 +
133053 +static long ioctl_free_raw_portal(struct file *fp, struct ctx *ctx,
133054 + struct usdpaa_ioctl_raw_portal *arg)
133055 +{
133056 + struct portal_mapping *mapping;
133057 + u32 channel;
133058 +
133059 + /* Find the corresponding portal */
133060 + spin_lock(&mem_lock);
133061 + list_for_each_entry(mapping, &ctx->portals, list) {
133062 + if (mapping->phys[DPA_PORTAL_CI].start == arg->cinh)
133063 + goto found;
133064 + }
133065 + mapping = NULL;
133066 +found:
133067 + if (mapping)
133068 + list_del(&mapping->list);
133069 + spin_unlock(&mem_lock);
133070 + if (!mapping)
133071 + return -ENODEV;
133072 + if (mapping->user.type == usdpaa_portal_qman) {
133073 + init_qm_portal(mapping->qportal,
133074 + &mapping->qman_portal_low);
133075 +
133076 + /* Tear down any FQs this portal is referencing */
133077 + channel = mapping->qportal->public_cfg.channel;
133078 + qm_check_and_destroy_fqs(&mapping->qman_portal_low,
133079 + &channel,
133080 + check_portal_channel);
133081 + qm_put_unused_portal(mapping->qportal);
133082 + } else if (mapping->user.type == usdpaa_portal_bman) {
133083 + init_bm_portal(mapping->bportal,
133084 + &mapping->bman_portal_low);
133085 + bm_put_unused_portal(mapping->bportal);
133086 + }
133087 + kfree(mapping);
133088 + return 0;
133089 +}
133090 +
133091 +static long usdpaa_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
133092 +{
133093 + struct ctx *ctx = fp->private_data;
133094 + void __user *a = (void __user *)arg;
133095 + switch (cmd) {
133096 + case USDPAA_IOCTL_ID_ALLOC:
133097 + return ioctl_id_alloc(ctx, a);
133098 + case USDPAA_IOCTL_ID_RELEASE:
133099 + return ioctl_id_release(ctx, a);
133100 + case USDPAA_IOCTL_ID_RESERVE:
133101 + return ioctl_id_reserve(ctx, a);
133102 + case USDPAA_IOCTL_DMA_MAP:
133103 + {
133104 + struct usdpaa_ioctl_dma_map input;
133105 + int ret;
133106 + if (copy_from_user(&input, a, sizeof(input)))
133107 + return -EFAULT;
133108 + ret = ioctl_dma_map(fp, ctx, &input);
133109 + if (copy_to_user(a, &input, sizeof(input)))
133110 + return -EFAULT;
133111 + return ret;
133112 + }
133113 + case USDPAA_IOCTL_DMA_UNMAP:
133114 + return ioctl_dma_unmap(ctx, a);
133115 + case USDPAA_IOCTL_DMA_LOCK:
133116 + return ioctl_dma_lock(ctx, a);
133117 + case USDPAA_IOCTL_DMA_UNLOCK:
133118 + return ioctl_dma_unlock(ctx, a);
133119 + case USDPAA_IOCTL_PORTAL_MAP:
133120 + {
133121 + struct usdpaa_ioctl_portal_map input;
133122 + int ret;
133123 + if (copy_from_user(&input, a, sizeof(input)))
133124 + return -EFAULT;
133125 + ret = ioctl_portal_map(fp, ctx, &input);
133126 + if (copy_to_user(a, &input, sizeof(input)))
133127 + return -EFAULT;
133128 + return ret;
133129 + }
133130 + case USDPAA_IOCTL_PORTAL_UNMAP:
133131 + {
133132 + struct usdpaa_portal_map input;
133133 + if (copy_from_user(&input, a, sizeof(input)))
133134 + return -EFAULT;
133135 + return ioctl_portal_unmap(ctx, &input);
133136 + }
133137 + case USDPAA_IOCTL_DMA_USED:
133138 + return ioctl_dma_stats(ctx, a);
133139 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL:
133140 + {
133141 + struct usdpaa_ioctl_raw_portal input;
133142 + int ret;
133143 + if (copy_from_user(&input, a, sizeof(input)))
133144 + return -EFAULT;
133145 + ret = ioctl_allocate_raw_portal(fp, ctx, &input);
133146 + if (copy_to_user(a, &input, sizeof(input)))
133147 + return -EFAULT;
133148 + return ret;
133149 + }
133150 + case USDPAA_IOCTL_FREE_RAW_PORTAL:
133151 + {
133152 + struct usdpaa_ioctl_raw_portal input;
133153 + if (copy_from_user(&input, a, sizeof(input)))
133154 + return -EFAULT;
133155 + return ioctl_free_raw_portal(fp, ctx, &input);
133156 + }
133157 + }
133158 + return -EINVAL;
133159 +}
133160 +
133161 +static long usdpaa_ioctl_compat(struct file *fp, unsigned int cmd,
133162 + unsigned long arg)
133163 +{
133164 +#ifdef CONFIG_COMPAT
133165 + struct ctx *ctx = fp->private_data;
133166 + void __user *a = (void __user *)arg;
133167 +#endif
133168 + switch (cmd) {
133169 +#ifdef CONFIG_COMPAT
133170 + case USDPAA_IOCTL_DMA_MAP_COMPAT:
133171 + {
133172 + int ret;
133173 + struct usdpaa_ioctl_dma_map_compat input;
133174 + struct usdpaa_ioctl_dma_map converted;
133175 +
133176 + if (copy_from_user(&input, a, sizeof(input)))
133177 + return -EFAULT;
133178 +
133179 + converted.ptr = compat_ptr(input.ptr);
133180 + converted.phys_addr = input.phys_addr;
133181 + converted.len = input.len;
133182 + converted.flags = input.flags;
133183 + strncpy(converted.name, input.name, USDPAA_DMA_NAME_MAX);
133184 + converted.has_locking = input.has_locking;
133185 + converted.did_create = input.did_create;
133186 +
133187 + ret = ioctl_dma_map(fp, ctx, &converted);
133188 + input.ptr = ptr_to_compat(converted.ptr);
133189 + input.phys_addr = converted.phys_addr;
133190 + input.len = converted.len;
133191 + input.flags = converted.flags;
133192 + strncpy(input.name, converted.name, USDPAA_DMA_NAME_MAX);
133193 + input.has_locking = converted.has_locking;
133194 + input.did_create = converted.did_create;
133195 + if (copy_to_user(a, &input, sizeof(input)))
133196 + return -EFAULT;
133197 + return ret;
133198 + }
133199 + case USDPAA_IOCTL_PORTAL_MAP_COMPAT:
133200 + {
133201 + int ret;
133202 + struct compat_usdpaa_ioctl_portal_map input;
133203 + struct usdpaa_ioctl_portal_map converted;
133204 + if (copy_from_user(&input, a, sizeof(input)))
133205 + return -EFAULT;
133206 + converted.type = input.type;
133207 + converted.index = input.index;
133208 + ret = ioctl_portal_map(fp, ctx, &converted);
133209 + input.addr.cinh = ptr_to_compat(converted.addr.cinh);
133210 + input.addr.cena = ptr_to_compat(converted.addr.cena);
133211 + input.channel = converted.channel;
133212 + input.pools = converted.pools;
133213 + input.index = converted.index;
133214 + if (copy_to_user(a, &input, sizeof(input)))
133215 + return -EFAULT;
133216 + return ret;
133217 + }
133218 + case USDPAA_IOCTL_PORTAL_UNMAP_COMPAT:
133219 + {
133220 + struct usdpaa_portal_map_compat input;
133221 + struct usdpaa_portal_map converted;
133222 +
133223 + if (copy_from_user(&input, a, sizeof(input)))
133224 + return -EFAULT;
133225 + converted.cinh = compat_ptr(input.cinh);
133226 + converted.cena = compat_ptr(input.cena);
133227 + return ioctl_portal_unmap(ctx, &converted);
133228 + }
133229 + case USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT:
133230 + {
133231 + int ret;
133232 + struct usdpaa_ioctl_raw_portal converted;
133233 + struct compat_ioctl_raw_portal input;
133234 + if (copy_from_user(&input, a, sizeof(input)))
133235 + return -EFAULT;
133236 + converted.type = input.type;
133237 + converted.index = input.index;
133238 + converted.enable_stash = input.enable_stash;
133239 + converted.cpu = input.cpu;
133240 + converted.cache = input.cache;
133241 + converted.window = input.window;
133242 + converted.sdest = input.sdest;
133243 + ret = ioctl_allocate_raw_portal(fp, ctx, &converted);
133244 +
133245 + input.cinh = converted.cinh;
133246 + input.cena = converted.cena;
133247 + input.index = converted.index;
133248 +
133249 + if (copy_to_user(a, &input, sizeof(input)))
133250 + return -EFAULT;
133251 + return ret;
133252 + }
133253 + case USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT:
133254 + {
133255 + struct usdpaa_ioctl_raw_portal converted;
133256 + struct compat_ioctl_raw_portal input;
133257 + if (copy_from_user(&input, a, sizeof(input)))
133258 + return -EFAULT;
133259 + converted.type = input.type;
133260 + converted.index = input.index;
133261 + converted.cinh = input.cinh;
133262 + converted.cena = input.cena;
133263 + return ioctl_free_raw_portal(fp, ctx, &converted);
133264 + }
133265 +#endif
133266 + default:
133267 + return usdpaa_ioctl(fp, cmd, arg);
133268 + }
133269 + return -EINVAL;
133270 +}
133271 +
133272 +int usdpaa_get_portal_config(struct file *filp, void *cinh,
133273 + enum usdpaa_portal_type ptype, unsigned int *irq,
133274 + void **iir_reg)
133275 +{
133276 + /* Walk the list of portals for filp and return the config
133277 + for the portal that matches the hint */
133278 + struct ctx *context;
133279 + struct portal_mapping *portal;
133280 +
133281 + /* First sanitize the filp */
133282 + if (filp->f_op->open != usdpaa_open)
133283 + return -ENODEV;
133284 + context = filp->private_data;
133285 + spin_lock(&context->lock);
133286 + list_for_each_entry(portal, &context->portals, list) {
133287 + if (portal->user.type == ptype &&
133288 + portal->user.addr.cinh == cinh) {
133289 + if (ptype == usdpaa_portal_qman) {
133290 + *irq = portal->qportal->public_cfg.irq;
133291 + *iir_reg = portal->qportal->addr_virt[1] +
133292 + QM_REG_IIR;
133293 + } else {
133294 + *irq = portal->bportal->public_cfg.irq;
133295 + *iir_reg = portal->bportal->addr_virt[1] +
133296 + BM_REG_IIR;
133297 + }
133298 + spin_unlock(&context->lock);
133299 + return 0;
133300 + }
133301 + }
133302 + spin_unlock(&context->lock);
133303 + return -EINVAL;
133304 +}
133305 +
133306 +static const struct file_operations usdpaa_fops = {
133307 + .open = usdpaa_open,
133308 + .release = usdpaa_release,
133309 + .mmap = usdpaa_mmap,
133310 + .get_unmapped_area = usdpaa_get_unmapped_area,
133311 + .unlocked_ioctl = usdpaa_ioctl,
133312 + .compat_ioctl = usdpaa_ioctl_compat
133313 +};
133314 +
133315 +static struct miscdevice usdpaa_miscdev = {
133316 + .name = "fsl-usdpaa",
133317 + .fops = &usdpaa_fops,
133318 + .minor = MISC_DYNAMIC_MINOR,
133319 +};
133320 +
133321 +/* Early-boot memory allocation. The boot-arg "usdpaa_mem=<x>" is used to
133322 + * indicate how much memory (if any) to allocate during early boot. If the
133323 + * format "usdpaa_mem=<x>,<y>" is used, then <y> will be interpreted as the
133324 + * number of TLB1 entries to reserve (default is 1). If there are more mappings
133325 + * than there are TLB1 entries, fault-handling will occur. */
133326 +
133327 +static __init int usdpaa_mem(char *arg)
133328 +{
133329 + pr_warn("uspdaa_mem argument is depracated\n");
133330 + arg_phys_size = memparse(arg, &arg);
133331 + num_tlb = 1;
133332 + if (*arg == ',') {
133333 + unsigned long ul;
133334 + int err = kstrtoul(arg + 1, 0, &ul);
133335 + if (err < 0) {
133336 + num_tlb = 1;
133337 + pr_warn("ERROR, usdpaa_mem arg is invalid\n");
133338 + } else
133339 + num_tlb = (unsigned int)ul;
133340 + }
133341 + return 0;
133342 +}
133343 +early_param("usdpaa_mem", usdpaa_mem);
133344 +
133345 +static int usdpaa_mem_init(struct reserved_mem *rmem)
133346 +{
133347 + phys_start = rmem->base;
133348 + phys_size = rmem->size;
133349 +
133350 + WARN_ON(!(phys_start && phys_size));
133351 +
133352 + return 0;
133353 +}
133354 +RESERVEDMEM_OF_DECLARE(usdpaa_mem_init, "fsl,usdpaa-mem", usdpaa_mem_init);
133355 +
133356 +__init int fsl_usdpaa_init_early(void)
133357 +{
133358 + if (!phys_size || !phys_start) {
133359 + pr_info("No USDPAA memory, no 'fsl,usdpaa-mem' in device-tree\n");
133360 + return 0;
133361 + }
133362 + if (phys_size % PAGE_SIZE) {
133363 + pr_err("'fsl,usdpaa-mem' size must be a multiple of page size\n");
133364 + phys_size = 0;
133365 + return 0;
133366 + }
133367 + if (arg_phys_size && phys_size != arg_phys_size) {
133368 + pr_err("'usdpaa_mem argument size (0x%llx) does not match device tree size (0x%llx)\n",
133369 + arg_phys_size, phys_size);
133370 + phys_size = 0;
133371 + return 0;
133372 + }
133373 + pfn_start = phys_start >> PAGE_SHIFT;
133374 + pfn_size = phys_size >> PAGE_SHIFT;
133375 +#ifdef CONFIG_PPC
133376 + first_tlb = current_tlb = tlbcam_index;
133377 + tlbcam_index += num_tlb;
133378 +#endif
133379 + pr_info("USDPAA region at %llx:%llx(%lx:%lx), %d TLB1 entries)\n",
133380 + phys_start, phys_size, pfn_start, pfn_size, num_tlb);
133381 + return 0;
133382 +}
133383 +subsys_initcall(fsl_usdpaa_init_early);
133384 +
133385 +
133386 +static int __init usdpaa_init(void)
133387 +{
133388 + struct mem_fragment *frag;
133389 + int ret;
133390 + u64 tmp_size = phys_size;
133391 + u64 tmp_start = phys_start;
133392 + u64 tmp_pfn_size = pfn_size;
133393 + u64 tmp_pfn_start = pfn_start;
133394 +
133395 + pr_info("Freescale USDPAA process driver\n");
133396 + if (!phys_start) {
133397 + pr_warn("fsl-usdpaa: no region found\n");
133398 + return 0;
133399 + }
133400 +
133401 + while (tmp_size != 0) {
133402 + u32 frag_size = largest_page_size(tmp_size);
133403 + frag = kmalloc(sizeof(*frag), GFP_KERNEL);
133404 + if (!frag) {
133405 + pr_err("Failed to setup USDPAA memory accounting\n");
133406 + return -ENOMEM;
133407 + }
133408 + frag->base = tmp_start;
133409 + frag->len = frag->root_len = frag_size;
133410 + frag->root_pfn = tmp_pfn_start;
133411 + frag->pfn_base = tmp_pfn_start;
133412 + frag->pfn_len = frag_size / PAGE_SIZE;
133413 + frag->refs = 0;
133414 + init_waitqueue_head(&frag->wq);
133415 + frag->owner = NULL;
133416 + list_add(&frag->list, &mem_list);
133417 +
133418 + /* Adjust for this frag */
133419 + tmp_start += frag_size;
133420 + tmp_size -= frag_size;
133421 + tmp_pfn_start += frag_size / PAGE_SIZE;
133422 + tmp_pfn_size -= frag_size / PAGE_SIZE;
133423 + }
133424 + ret = misc_register(&usdpaa_miscdev);
133425 + if (ret)
133426 + pr_err("fsl-usdpaa: failed to register misc device\n");
133427 + return ret;
133428 +}
133429 +
133430 +static void __exit usdpaa_exit(void)
133431 +{
133432 + misc_deregister(&usdpaa_miscdev);
133433 +}
133434 +
133435 +module_init(usdpaa_init);
133436 +module_exit(usdpaa_exit);
133437 +
133438 +MODULE_LICENSE("GPL");
133439 +MODULE_AUTHOR("Freescale Semiconductor");
133440 +MODULE_DESCRIPTION("Freescale USDPAA process driver");
133441 --- /dev/null
133442 +++ b/drivers/staging/fsl_qbman/fsl_usdpaa_irq.c
133443 @@ -0,0 +1,289 @@
133444 +/* Copyright (c) 2013 Freescale Semiconductor, Inc.
133445 + * All rights reserved.
133446 + *
133447 + * Redistribution and use in source and binary forms, with or without
133448 + * modification, are permitted provided that the following conditions are met:
133449 + * * Redistributions of source code must retain the above copyright
133450 + * notice, this list of conditions and the following disclaimer.
133451 + * * Redistributions in binary form must reproduce the above copyright
133452 + * notice, this list of conditions and the following disclaimer in the
133453 + * documentation and/or other materials provided with the distribution.
133454 + * * Neither the name of Freescale Semiconductor nor the
133455 + * names of its contributors may be used to endorse or promote products
133456 + * derived from this software without specific prior written permission.
133457 + *
133458 + *
133459 + * ALTERNATIVELY, this software may be distributed under the terms of the
133460 + * GNU General Public License ("GPL") as published by the Free Software
133461 + * Foundation, either version 2 of that License or (at your option) any
133462 + * later version.
133463 + *
133464 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133465 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133466 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133467 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133468 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133469 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133470 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133471 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133472 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133473 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133474 + */
133475 +
133476 +/* define a device that allows USPDAA processes to open a file
133477 + descriptor and specify which IRQ it wants to montior using an ioctl()
133478 + When an IRQ is received, the device becomes readable so that a process
133479 + can use read() or select() type calls to monitor for IRQs */
133480 +
133481 +#include <linux/miscdevice.h>
133482 +#include <linux/fs.h>
133483 +#include <linux/cdev.h>
133484 +#include <linux/slab.h>
133485 +#include <linux/interrupt.h>
133486 +#include <linux/poll.h>
133487 +#include <linux/uaccess.h>
133488 +#include <linux/fsl_usdpaa.h>
133489 +#include <linux/module.h>
133490 +#include <linux/fdtable.h>
133491 +#include <linux/file.h>
133492 +
133493 +#include "qman_low.h"
133494 +#include "bman_low.h"
133495 +
133496 +struct usdpaa_irq_ctx {
133497 + int irq_set; /* Set to true once the irq is set via ioctl */
133498 + unsigned int irq_num;
133499 + u32 last_irq_count; /* Last value returned from read */
133500 + u32 irq_count; /* Number of irqs since last read */
133501 + wait_queue_head_t wait_queue; /* Waiting processes */
133502 + spinlock_t lock;
133503 + void *inhibit_addr; /* inhibit register address */
133504 + struct file *usdpaa_filp;
133505 + char irq_name[128];
133506 +};
133507 +
133508 +static int usdpaa_irq_open(struct inode *inode, struct file *filp)
133509 +{
133510 + struct usdpaa_irq_ctx *ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
133511 + if (!ctx)
133512 + return -ENOMEM;
133513 + ctx->irq_set = 0;
133514 + ctx->irq_count = 0;
133515 + ctx->last_irq_count = 0;
133516 + init_waitqueue_head(&ctx->wait_queue);
133517 + spin_lock_init(&ctx->lock);
133518 + filp->private_data = ctx;
133519 + return 0;
133520 +}
133521 +
133522 +static int usdpaa_irq_release(struct inode *inode, struct file *filp)
133523 +{
133524 + struct usdpaa_irq_ctx *ctx = filp->private_data;
133525 + if (ctx->irq_set) {
133526 + /* Inhibit the IRQ */
133527 + out_be32(ctx->inhibit_addr, 0x1);
133528 + irq_set_affinity_hint(ctx->irq_num, NULL);
133529 + free_irq(ctx->irq_num, ctx);
133530 + ctx->irq_set = 0;
133531 + fput(ctx->usdpaa_filp);
133532 + }
133533 + kfree(filp->private_data);
133534 + return 0;
133535 +}
133536 +
133537 +static irqreturn_t usdpaa_irq_handler(int irq, void *_ctx)
133538 +{
133539 + unsigned long flags;
133540 + struct usdpaa_irq_ctx *ctx = _ctx;
133541 + spin_lock_irqsave(&ctx->lock, flags);
133542 + ++ctx->irq_count;
133543 + spin_unlock_irqrestore(&ctx->lock, flags);
133544 + wake_up_all(&ctx->wait_queue);
133545 + /* Set the inhibit register. This will be reenabled
133546 + once the USDPAA code handles the IRQ */
133547 + out_be32(ctx->inhibit_addr, 0x1);
133548 + pr_debug("Inhibit at %p count %d", ctx->inhibit_addr, ctx->irq_count);
133549 + return IRQ_HANDLED;
133550 +}
133551 +
133552 +static int map_irq(struct file *fp, struct usdpaa_ioctl_irq_map *irq_map)
133553 +{
133554 + struct usdpaa_irq_ctx *ctx = fp->private_data;
133555 + int ret;
133556 +
133557 + if (ctx->irq_set) {
133558 + pr_debug("Setting USDPAA IRQ when it was already set!\n");
133559 + return -EBUSY;
133560 + }
133561 +
133562 + ctx->usdpaa_filp = fget(irq_map->fd);
133563 + if (!ctx->usdpaa_filp) {
133564 + pr_debug("USDPAA fget(%d) returned NULL\n", irq_map->fd);
133565 + return -EINVAL;
133566 + }
133567 +
133568 + ret = usdpaa_get_portal_config(ctx->usdpaa_filp, irq_map->portal_cinh,
133569 + irq_map->type, &ctx->irq_num,
133570 + &ctx->inhibit_addr);
133571 + if (ret) {
133572 + pr_debug("USDPAA IRQ couldn't identify portal\n");
133573 + fput(ctx->usdpaa_filp);
133574 + return ret;
133575 + }
133576 +
133577 + ctx->irq_set = 1;
133578 +
133579 + snprintf(ctx->irq_name, sizeof(ctx->irq_name),
133580 + "usdpaa_irq %d", ctx->irq_num);
133581 +
133582 + ret = request_irq(ctx->irq_num, usdpaa_irq_handler, 0,
133583 + ctx->irq_name, ctx);
133584 + if (ret) {
133585 + pr_err("USDPAA request_irq(%d) failed, ret= %d\n",
133586 + ctx->irq_num, ret);
133587 + ctx->irq_set = 0;
133588 + fput(ctx->usdpaa_filp);
133589 + return ret;
133590 + }
133591 + ret = irq_set_affinity(ctx->irq_num, &current->cpus_allowed);
133592 + if (ret)
133593 + pr_err("USDPAA irq_set_affinity() failed, ret= %d\n", ret);
133594 +
133595 + ret = irq_set_affinity_hint(ctx->irq_num, &current->cpus_allowed);
133596 + if (ret)
133597 + pr_err("USDPAA irq_set_affinity_hint() failed, ret= %d\n", ret);
133598 +
133599 + return 0;
133600 +}
133601 +
133602 +static long usdpaa_irq_ioctl(struct file *fp, unsigned int cmd,
133603 + unsigned long arg)
133604 +{
133605 + int ret;
133606 + struct usdpaa_ioctl_irq_map irq_map;
133607 +
133608 + if (cmd != USDPAA_IOCTL_PORTAL_IRQ_MAP) {
133609 + pr_debug("USDPAA IRQ unknown command 0x%x\n", cmd);
133610 + return -EINVAL;
133611 + }
133612 +
133613 + ret = copy_from_user(&irq_map, (void __user *)arg,
133614 + sizeof(irq_map));
133615 + if (ret)
133616 + return ret;
133617 + return map_irq(fp, &irq_map);
133618 +}
133619 +
133620 +static ssize_t usdpaa_irq_read(struct file *filp, char __user *buff,
133621 + size_t count, loff_t *offp)
133622 +{
133623 + struct usdpaa_irq_ctx *ctx = filp->private_data;
133624 + int ret;
133625 +
133626 + if (!ctx->irq_set) {
133627 + pr_debug("Reading USDPAA IRQ before it was set\n");
133628 + return -EINVAL;
133629 + }
133630 +
133631 + if (count < sizeof(ctx->irq_count)) {
133632 + pr_debug("USDPAA IRQ Read too small\n");
133633 + return -EINVAL;
133634 + }
133635 + if (ctx->irq_count == ctx->last_irq_count) {
133636 + if (filp->f_flags & O_NONBLOCK)
133637 + return -EAGAIN;
133638 +
133639 + ret = wait_event_interruptible(ctx->wait_queue,
133640 + ctx->irq_count != ctx->last_irq_count);
133641 + if (ret == -ERESTARTSYS)
133642 + return ret;
133643 + }
133644 +
133645 + ctx->last_irq_count = ctx->irq_count;
133646 +
133647 + if (copy_to_user(buff, &ctx->last_irq_count,
133648 + sizeof(ctx->last_irq_count)))
133649 + return -EFAULT;
133650 + return sizeof(ctx->irq_count);
133651 +}
133652 +
133653 +static unsigned int usdpaa_irq_poll(struct file *filp, poll_table *wait)
133654 +{
133655 + struct usdpaa_irq_ctx *ctx = filp->private_data;
133656 + unsigned int ret = 0;
133657 + unsigned long flags;
133658 +
133659 + if (!ctx->irq_set)
133660 + return POLLHUP;
133661 +
133662 + poll_wait(filp, &ctx->wait_queue, wait);
133663 +
133664 + spin_lock_irqsave(&ctx->lock, flags);
133665 + if (ctx->irq_count != ctx->last_irq_count)
133666 + ret |= POLLIN | POLLRDNORM;
133667 + spin_unlock_irqrestore(&ctx->lock, flags);
133668 + return ret;
133669 +}
133670 +
133671 +static long usdpaa_irq_ioctl_compat(struct file *fp, unsigned int cmd,
133672 + unsigned long arg)
133673 +{
133674 +#ifdef CONFIG_COMPAT
133675 + void __user *a = (void __user *)arg;
133676 +#endif
133677 + switch (cmd) {
133678 +#ifdef CONFIG_COMPAT
133679 + case USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT:
133680 + {
133681 + struct compat_ioctl_irq_map input;
133682 + struct usdpaa_ioctl_irq_map converted;
133683 + if (copy_from_user(&input, a, sizeof(input)))
133684 + return -EFAULT;
133685 + converted.type = input.type;
133686 + converted.fd = input.fd;
133687 + converted.portal_cinh = compat_ptr(input.portal_cinh);
133688 + return map_irq(fp, &converted);
133689 + }
133690 +#endif
133691 + default:
133692 + return usdpaa_irq_ioctl(fp, cmd, arg);
133693 + }
133694 +}
133695 +
133696 +static const struct file_operations usdpaa_irq_fops = {
133697 + .open = usdpaa_irq_open,
133698 + .release = usdpaa_irq_release,
133699 + .unlocked_ioctl = usdpaa_irq_ioctl,
133700 + .compat_ioctl = usdpaa_irq_ioctl_compat,
133701 + .read = usdpaa_irq_read,
133702 + .poll = usdpaa_irq_poll
133703 +};
133704 +
133705 +static struct miscdevice usdpaa_miscdev = {
133706 + .name = "fsl-usdpaa-irq",
133707 + .fops = &usdpaa_irq_fops,
133708 + .minor = MISC_DYNAMIC_MINOR,
133709 +};
133710 +
133711 +static int __init usdpaa_irq_init(void)
133712 +{
133713 + int ret;
133714 +
133715 + pr_info("Freescale USDPAA process IRQ driver\n");
133716 + ret = misc_register(&usdpaa_miscdev);
133717 + if (ret)
133718 + pr_err("fsl-usdpaa-irq: failed to register misc device\n");
133719 + return ret;
133720 +}
133721 +
133722 +static void __exit usdpaa_irq_exit(void)
133723 +{
133724 + misc_deregister(&usdpaa_miscdev);
133725 +}
133726 +
133727 +module_init(usdpaa_irq_init);
133728 +module_exit(usdpaa_irq_exit);
133729 +
133730 +MODULE_LICENSE("GPL");
133731 +MODULE_AUTHOR("Freescale Semiconductor");
133732 +MODULE_DESCRIPTION("Freescale USDPAA process IRQ driver");
133733 --- /dev/null
133734 +++ b/drivers/staging/fsl_qbman/qbman_driver.c
133735 @@ -0,0 +1,88 @@
133736 +/* Copyright 2013 Freescale Semiconductor, Inc.
133737 + *
133738 + * Redistribution and use in source and binary forms, with or without
133739 + * modification, are permitted provided that the following conditions are met:
133740 + * * Redistributions of source code must retain the above copyright
133741 + * notice, this list of conditions and the following disclaimer.
133742 + * * Redistributions in binary form must reproduce the above copyright
133743 + * notice, this list of conditions and the following disclaimer in the
133744 + * documentation and/or other materials provided with the distribution.
133745 + * * Neither the name of Freescale Semiconductor nor the
133746 + * names of its contributors may be used to endorse or promote products
133747 + * derived from this software without specific prior written permission.
133748 + *
133749 + *
133750 + * ALTERNATIVELY, this software may be distributed under the terms of the
133751 + * GNU General Public License ("GPL") as published by the Free Software
133752 + * Foundation, either version 2 of that License or (at your option) any
133753 + * later version.
133754 + *
133755 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133756 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133757 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133758 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133759 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133760 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133761 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133762 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133763 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133764 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133765 + */
133766 +
133767 +#include <linux/time.h>
133768 +#include "qman_private.h"
133769 +#include "bman_private.h"
133770 +__init void qman_init_early(void);
133771 +__init void bman_init_early(void);
133772 +
133773 +static __init int qbman_init(void)
133774 +{
133775 + struct device_node *dn;
133776 + u32 is_portal_available;
133777 +
133778 + bman_init();
133779 + qman_init();
133780 +
133781 + is_portal_available = 0;
133782 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
133783 + if (!of_device_is_available(dn))
133784 + continue;
133785 + else
133786 + is_portal_available = 1;
133787 + }
133788 +
133789 + if (!qman_have_ccsr() && is_portal_available) {
133790 + struct qman_fq fq = {
133791 + .fqid = 1
133792 + };
133793 + struct qm_mcr_queryfq_np np;
133794 + int err, retry = CONFIG_FSL_QMAN_INIT_TIMEOUT;
133795 + struct timespec nowts, diffts, startts = current_kernel_time();
133796 + /* Loop while querying given fqid succeeds or time out */
133797 + while (1) {
133798 + err = qman_query_fq_np(&fq, &np);
133799 + if (!err) {
133800 + /* success, control-plane has configured QMan */
133801 + break;
133802 + } else if (err != -ERANGE) {
133803 + pr_err("QMan: I/O error, continuing anyway\n");
133804 + break;
133805 + }
133806 + nowts = current_kernel_time();
133807 + diffts = timespec_sub(nowts, startts);
133808 + if (diffts.tv_sec > 0) {
133809 + if (!retry--) {
133810 + pr_err("QMan: time out, control-plane"
133811 + " dead?\n");
133812 + break;
133813 + }
133814 + pr_warn("QMan: polling for the control-plane"
133815 + " (%d)\n", retry);
133816 + }
133817 + }
133818 + }
133819 + bman_resource_init();
133820 + qman_resource_init();
133821 + return 0;
133822 +}
133823 +subsys_initcall(qbman_init);
133824 --- /dev/null
133825 +++ b/drivers/staging/fsl_qbman/qman_config.c
133826 @@ -0,0 +1,1224 @@
133827 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
133828 + *
133829 + * Redistribution and use in source and binary forms, with or without
133830 + * modification, are permitted provided that the following conditions are met:
133831 + * * Redistributions of source code must retain the above copyright
133832 + * notice, this list of conditions and the following disclaimer.
133833 + * * Redistributions in binary form must reproduce the above copyright
133834 + * notice, this list of conditions and the following disclaimer in the
133835 + * documentation and/or other materials provided with the distribution.
133836 + * * Neither the name of Freescale Semiconductor nor the
133837 + * names of its contributors may be used to endorse or promote products
133838 + * derived from this software without specific prior written permission.
133839 + *
133840 + *
133841 + * ALTERNATIVELY, this software may be distributed under the terms of the
133842 + * GNU General Public License ("GPL") as published by the Free Software
133843 + * Foundation, either version 2 of that License or (at your option) any
133844 + * later version.
133845 + *
133846 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
133847 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
133848 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
133849 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
133850 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
133851 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
133852 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
133853 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
133854 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
133855 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
133856 + */
133857 +
133858 +#include <asm/cacheflush.h>
133859 +#include "qman_private.h"
133860 +#include <linux/highmem.h>
133861 +#include <linux/of_reserved_mem.h>
133862 +
133863 +/* Last updated for v00.800 of the BG */
133864 +
133865 +/* Register offsets */
133866 +#define REG_QCSP_LIO_CFG(n) (0x0000 + ((n) * 0x10))
133867 +#define REG_QCSP_IO_CFG(n) (0x0004 + ((n) * 0x10))
133868 +#define REG_QCSP_DD_CFG(n) (0x000c + ((n) * 0x10))
133869 +#define REG_DD_CFG 0x0200
133870 +#define REG_DCP_CFG(n) (0x0300 + ((n) * 0x10))
133871 +#define REG_DCP_DD_CFG(n) (0x0304 + ((n) * 0x10))
133872 +#define REG_DCP_DLM_AVG(n) (0x030c + ((n) * 0x10))
133873 +#define REG_PFDR_FPC 0x0400
133874 +#define REG_PFDR_FP_HEAD 0x0404
133875 +#define REG_PFDR_FP_TAIL 0x0408
133876 +#define REG_PFDR_FP_LWIT 0x0410
133877 +#define REG_PFDR_CFG 0x0414
133878 +#define REG_SFDR_CFG 0x0500
133879 +#define REG_SFDR_IN_USE 0x0504
133880 +#define REG_WQ_CS_CFG(n) (0x0600 + ((n) * 0x04))
133881 +#define REG_WQ_DEF_ENC_WQID 0x0630
133882 +#define REG_WQ_SC_DD_CFG(n) (0x640 + ((n) * 0x04))
133883 +#define REG_WQ_PC_DD_CFG(n) (0x680 + ((n) * 0x04))
133884 +#define REG_WQ_DC0_DD_CFG(n) (0x6c0 + ((n) * 0x04))
133885 +#define REG_WQ_DC1_DD_CFG(n) (0x700 + ((n) * 0x04))
133886 +#define REG_WQ_DCn_DD_CFG(n) (0x6c0 + ((n) * 0x40)) /* n=2,3 */
133887 +#define REG_CM_CFG 0x0800
133888 +#define REG_ECSR 0x0a00
133889 +#define REG_ECIR 0x0a04
133890 +#define REG_EADR 0x0a08
133891 +#define REG_ECIR2 0x0a0c
133892 +#define REG_EDATA(n) (0x0a10 + ((n) * 0x04))
133893 +#define REG_SBEC(n) (0x0a80 + ((n) * 0x04))
133894 +#define REG_MCR 0x0b00
133895 +#define REG_MCP(n) (0x0b04 + ((n) * 0x04))
133896 +#define REG_MISC_CFG 0x0be0
133897 +#define REG_HID_CFG 0x0bf0
133898 +#define REG_IDLE_STAT 0x0bf4
133899 +#define REG_IP_REV_1 0x0bf8
133900 +#define REG_IP_REV_2 0x0bfc
133901 +#define REG_FQD_BARE 0x0c00
133902 +#define REG_PFDR_BARE 0x0c20
133903 +#define REG_offset_BAR 0x0004 /* relative to REG_[FQD|PFDR]_BARE */
133904 +#define REG_offset_AR 0x0010 /* relative to REG_[FQD|PFDR]_BARE */
133905 +#define REG_QCSP_BARE 0x0c80
133906 +#define REG_QCSP_BAR 0x0c84
133907 +#define REG_CI_SCHED_CFG 0x0d00
133908 +#define REG_SRCIDR 0x0d04
133909 +#define REG_LIODNR 0x0d08
133910 +#define REG_CI_RLM_AVG 0x0d14
133911 +#define REG_ERR_ISR 0x0e00 /* + "enum qm_isr_reg" */
133912 +#define REG_REV3_QCSP_LIO_CFG(n) (0x1000 + ((n) * 0x10))
133913 +#define REG_REV3_QCSP_IO_CFG(n) (0x1004 + ((n) * 0x10))
133914 +#define REG_REV3_QCSP_DD_CFG(n) (0x100c + ((n) * 0x10))
133915 +#define REG_CEETM_CFG_IDX 0x900
133916 +#define REG_CEETM_CFG_PRES 0x904
133917 +#define REG_CEETM_XSFDR_IN_USE 0x908
133918 +
133919 +/* Assists for QMAN_MCR */
133920 +#define MCR_INIT_PFDR 0x01000000
133921 +#define MCR_get_rslt(v) (u8)((v) >> 24)
133922 +#define MCR_rslt_idle(r) (!rslt || (rslt >= 0xf0))
133923 +#define MCR_rslt_ok(r) (rslt == 0xf0)
133924 +#define MCR_rslt_eaccess(r) (rslt == 0xf8)
133925 +#define MCR_rslt_inval(r) (rslt == 0xff)
133926 +
133927 +struct qman;
133928 +
133929 +/* Follows WQ_CS_CFG0-5 */
133930 +enum qm_wq_class {
133931 + qm_wq_portal = 0,
133932 + qm_wq_pool = 1,
133933 + qm_wq_fman0 = 2,
133934 + qm_wq_fman1 = 3,
133935 + qm_wq_caam = 4,
133936 + qm_wq_pme = 5,
133937 + qm_wq_first = qm_wq_portal,
133938 + qm_wq_last = qm_wq_pme
133939 +};
133940 +
133941 +/* Follows FQD_[BARE|BAR|AR] and PFDR_[BARE|BAR|AR] */
133942 +enum qm_memory {
133943 + qm_memory_fqd,
133944 + qm_memory_pfdr
133945 +};
133946 +
133947 +/* Used by all error interrupt registers except 'inhibit' */
133948 +#define QM_EIRQ_CIDE 0x20000000 /* Corenet Initiator Data Error */
133949 +#define QM_EIRQ_CTDE 0x10000000 /* Corenet Target Data Error */
133950 +#define QM_EIRQ_CITT 0x08000000 /* Corenet Invalid Target Transaction */
133951 +#define QM_EIRQ_PLWI 0x04000000 /* PFDR Low Watermark */
133952 +#define QM_EIRQ_MBEI 0x02000000 /* Multi-bit ECC Error */
133953 +#define QM_EIRQ_SBEI 0x01000000 /* Single-bit ECC Error */
133954 +#define QM_EIRQ_PEBI 0x00800000 /* PFDR Enqueues Blocked Interrupt */
133955 +#define QM_EIRQ_IFSI 0x00020000 /* Invalid FQ Flow Control State */
133956 +#define QM_EIRQ_ICVI 0x00010000 /* Invalid Command Verb */
133957 +#define QM_EIRQ_IDDI 0x00000800 /* Invalid Dequeue (Direct-connect) */
133958 +#define QM_EIRQ_IDFI 0x00000400 /* Invalid Dequeue FQ */
133959 +#define QM_EIRQ_IDSI 0x00000200 /* Invalid Dequeue Source */
133960 +#define QM_EIRQ_IDQI 0x00000100 /* Invalid Dequeue Queue */
133961 +#define QM_EIRQ_IECE 0x00000010 /* Invalid Enqueue Configuration */
133962 +#define QM_EIRQ_IEOI 0x00000008 /* Invalid Enqueue Overflow */
133963 +#define QM_EIRQ_IESI 0x00000004 /* Invalid Enqueue State */
133964 +#define QM_EIRQ_IECI 0x00000002 /* Invalid Enqueue Channel */
133965 +#define QM_EIRQ_IEQI 0x00000001 /* Invalid Enqueue Queue */
133966 +
133967 +/* QMAN_ECIR valid error bit */
133968 +#define PORTAL_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IESI | QM_EIRQ_IEOI | \
133969 + QM_EIRQ_IDQI | QM_EIRQ_IDSI | QM_EIRQ_IDFI | \
133970 + QM_EIRQ_IDDI | QM_EIRQ_ICVI | QM_EIRQ_IFSI)
133971 +#define FQID_ECSR_ERR (QM_EIRQ_IEQI | QM_EIRQ_IECI | QM_EIRQ_IESI | \
133972 + QM_EIRQ_IEOI | QM_EIRQ_IDQI | QM_EIRQ_IDFI | \
133973 + QM_EIRQ_IFSI)
133974 +
133975 +union qman_ecir {
133976 + u32 ecir_raw;
133977 + struct {
133978 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
133979 + u32 __reserved:2;
133980 + u32 portal_type:1;
133981 + u32 portal_num:5;
133982 + u32 fqid:24;
133983 +#else
133984 + u32 fqid:24;
133985 + u32 portal_num:5;
133986 + u32 portal_type:1;
133987 + u32 __reserved:2;
133988 +#endif
133989 + } __packed info;
133990 +};
133991 +
133992 +union qman_ecir2 {
133993 + u32 ecir2_raw;
133994 + struct {
133995 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
133996 + u32 portal_type:1;
133997 + u32 __reserved:21;
133998 + u32 portal_num:10;
133999 +#else
134000 + u32 portal_num:10;
134001 + u32 __reserved:21;
134002 + u32 portal_type:1;
134003 +#endif
134004 + } __packed info;
134005 +};
134006 +
134007 +union qman_eadr {
134008 + u32 eadr_raw;
134009 + struct {
134010 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
134011 + u32 __reserved1:4;
134012 + u32 memid:4;
134013 + u32 __reserved2:12;
134014 + u32 eadr:12;
134015 +#else
134016 + u32 eadr:12;
134017 + u32 __reserved2:12;
134018 + u32 memid:4;
134019 + u32 __reserved1:4;
134020 +#endif
134021 + } __packed info;
134022 + struct {
134023 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
134024 + u32 __reserved1:3;
134025 + u32 memid:5;
134026 + u32 __reserved:8;
134027 + u32 eadr:16;
134028 +#else
134029 + u32 eadr:16;
134030 + u32 __reserved:8;
134031 + u32 memid:5;
134032 + u32 __reserved1:3;
134033 +#endif
134034 + } __packed info_rev3;
134035 +};
134036 +
134037 +struct qman_hwerr_txt {
134038 + u32 mask;
134039 + const char *txt;
134040 +};
134041 +
134042 +#define QMAN_HWE_TXT(a, b) { .mask = QM_EIRQ_##a, .txt = b }
134043 +
134044 +static const struct qman_hwerr_txt qman_hwerr_txts[] = {
134045 + QMAN_HWE_TXT(CIDE, "Corenet Initiator Data Error"),
134046 + QMAN_HWE_TXT(CTDE, "Corenet Target Data Error"),
134047 + QMAN_HWE_TXT(CITT, "Corenet Invalid Target Transaction"),
134048 + QMAN_HWE_TXT(PLWI, "PFDR Low Watermark"),
134049 + QMAN_HWE_TXT(MBEI, "Multi-bit ECC Error"),
134050 + QMAN_HWE_TXT(SBEI, "Single-bit ECC Error"),
134051 + QMAN_HWE_TXT(PEBI, "PFDR Enqueues Blocked Interrupt"),
134052 + QMAN_HWE_TXT(ICVI, "Invalid Command Verb"),
134053 + QMAN_HWE_TXT(IFSI, "Invalid Flow Control State"),
134054 + QMAN_HWE_TXT(IDDI, "Invalid Dequeue (Direct-connect)"),
134055 + QMAN_HWE_TXT(IDFI, "Invalid Dequeue FQ"),
134056 + QMAN_HWE_TXT(IDSI, "Invalid Dequeue Source"),
134057 + QMAN_HWE_TXT(IDQI, "Invalid Dequeue Queue"),
134058 + QMAN_HWE_TXT(IECE, "Invalid Enqueue Configuration"),
134059 + QMAN_HWE_TXT(IEOI, "Invalid Enqueue Overflow"),
134060 + QMAN_HWE_TXT(IESI, "Invalid Enqueue State"),
134061 + QMAN_HWE_TXT(IECI, "Invalid Enqueue Channel"),
134062 + QMAN_HWE_TXT(IEQI, "Invalid Enqueue Queue")
134063 +};
134064 +#define QMAN_HWE_COUNT (sizeof(qman_hwerr_txts)/sizeof(struct qman_hwerr_txt))
134065 +
134066 +struct qman_error_info_mdata {
134067 + u16 addr_mask;
134068 + u16 bits;
134069 + const char *txt;
134070 +};
134071 +
134072 +#define QMAN_ERR_MDATA(a, b, c) { .addr_mask = a, .bits = b, .txt = c}
134073 +static const struct qman_error_info_mdata error_mdata[] = {
134074 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 0"),
134075 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 1"),
134076 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 2"),
134077 + QMAN_ERR_MDATA(0x01FF, 24, "FQD cache tag memory 3"),
134078 + QMAN_ERR_MDATA(0x0FFF, 512, "FQD cache memory"),
134079 + QMAN_ERR_MDATA(0x07FF, 128, "SFDR memory"),
134080 + QMAN_ERR_MDATA(0x01FF, 72, "WQ context memory"),
134081 + QMAN_ERR_MDATA(0x00FF, 240, "CGR memory"),
134082 + QMAN_ERR_MDATA(0x00FF, 302, "Internal Order Restoration List memory"),
134083 + QMAN_ERR_MDATA(0x7FFF, 256, "SW portal ring memory"),
134084 + QMAN_ERR_MDATA(0x07FF, 181, "CEETM class queue descriptor memory"),
134085 + QMAN_ERR_MDATA(0x0FFF, 140, "CEETM extended SFDR memory"),
134086 + QMAN_ERR_MDATA(0x0FFF, 25, "CEETM logical FQ mapping memory"),
134087 + QMAN_ERR_MDATA(0x0FFF, 96, "CEETM dequeue context memory"),
134088 + QMAN_ERR_MDATA(0x07FF, 396, "CEETM ccgr memory"),
134089 + QMAN_ERR_MDATA(0x00FF, 146, "CEETM CQ channel shaping memory"),
134090 + QMAN_ERR_MDATA(0x007F, 256, "CEETM CQ channel scheduling memory"),
134091 + QMAN_ERR_MDATA(0x01FF, 88, "CEETM dequeue statistics memory"),
134092 +};
134093 +#define QMAN_ERR_MDATA_COUNT \
134094 + (sizeof(error_mdata)/sizeof(struct qman_error_info_mdata))
134095 +
134096 +/* Add this in Kconfig */
134097 +#define QMAN_ERRS_TO_UNENABLE (QM_EIRQ_PLWI | QM_EIRQ_PEBI)
134098 +
134099 +/**
134100 + * qm_err_isr_<reg>_<verb> - Manipulate global interrupt registers
134101 + * @v: for accessors that write values, this is the 32-bit value
134102 + *
134103 + * Manipulates QMAN_ERR_ISR, QMAN_ERR_IER, QMAN_ERR_ISDR, QMAN_ERR_IIR. All
134104 + * manipulations except qm_err_isr_[un]inhibit() use 32-bit masks composed of
134105 + * the QM_EIRQ_*** definitions. Note that "qm_err_isr_enable_write" means
134106 + * "write the enable register" rather than "enable the write register"!
134107 + */
134108 +#define qm_err_isr_status_read(qm) \
134109 + __qm_err_isr_read(qm, qm_isr_status)
134110 +#define qm_err_isr_status_clear(qm, m) \
134111 + __qm_err_isr_write(qm, qm_isr_status, m)
134112 +#define qm_err_isr_enable_read(qm) \
134113 + __qm_err_isr_read(qm, qm_isr_enable)
134114 +#define qm_err_isr_enable_write(qm, v) \
134115 + __qm_err_isr_write(qm, qm_isr_enable, v)
134116 +#define qm_err_isr_disable_read(qm) \
134117 + __qm_err_isr_read(qm, qm_isr_disable)
134118 +#define qm_err_isr_disable_write(qm, v) \
134119 + __qm_err_isr_write(qm, qm_isr_disable, v)
134120 +#define qm_err_isr_inhibit(qm) \
134121 + __qm_err_isr_write(qm, qm_isr_inhibit, 1)
134122 +#define qm_err_isr_uninhibit(qm) \
134123 + __qm_err_isr_write(qm, qm_isr_inhibit, 0)
134124 +
134125 +/*
134126 + * TODO: unimplemented registers
134127 + *
134128 + * Keeping a list here of Qman registers I have not yet covered;
134129 + * QCSP_DD_IHRSR, QCSP_DD_IHRFR, QCSP_DD_HASR,
134130 + * DCP_DD_IHRSR, DCP_DD_IHRFR, DCP_DD_HASR, CM_CFG,
134131 + * QMAN_EECC, QMAN_SBET, QMAN_EINJ, QMAN_SBEC0-12
134132 + */
134133 +
134134 +/* Encapsulate "struct qman *" as a cast of the register space address. */
134135 +
134136 +static struct qman *qm_create(void *regs)
134137 +{
134138 + return (struct qman *)regs;
134139 +}
134140 +
134141 +static inline u32 __qm_in(struct qman *qm, u32 offset)
134142 +{
134143 + return in_be32((void *)qm + offset);
134144 +}
134145 +static inline void __qm_out(struct qman *qm, u32 offset, u32 val)
134146 +{
134147 + out_be32((void *)qm + offset, val);
134148 +}
134149 +#define qm_in(reg) __qm_in(qm, REG_##reg)
134150 +#define qm_out(reg, val) __qm_out(qm, REG_##reg, val)
134151 +
134152 +static u32 __qm_err_isr_read(struct qman *qm, enum qm_isr_reg n)
134153 +{
134154 + return __qm_in(qm, REG_ERR_ISR + (n << 2));
134155 +}
134156 +
134157 +static void __qm_err_isr_write(struct qman *qm, enum qm_isr_reg n, u32 val)
134158 +{
134159 + __qm_out(qm, REG_ERR_ISR + (n << 2), val);
134160 +}
134161 +
134162 +static void qm_set_dc(struct qman *qm, enum qm_dc_portal portal,
134163 + int ed, u8 sernd)
134164 +{
134165 + DPA_ASSERT(!ed || (portal == qm_dc_portal_fman0) ||
134166 + (portal == qm_dc_portal_fman1));
134167 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
134168 + qm_out(DCP_CFG(portal), (ed ? 0x1000 : 0) | (sernd & 0x3ff));
134169 + else
134170 + qm_out(DCP_CFG(portal), (ed ? 0x100 : 0) | (sernd & 0x1f));
134171 +}
134172 +
134173 +static void qm_set_wq_scheduling(struct qman *qm, enum qm_wq_class wq_class,
134174 + u8 cs_elev, u8 csw2, u8 csw3, u8 csw4, u8 csw5,
134175 + u8 csw6, u8 csw7)
134176 +{
134177 + qm_out(WQ_CS_CFG(wq_class), ((cs_elev & 0xff) << 24) |
134178 + ((csw2 & 0x7) << 20) | ((csw3 & 0x7) << 16) |
134179 + ((csw4 & 0x7) << 12) | ((csw5 & 0x7) << 8) |
134180 + ((csw6 & 0x7) << 4) | (csw7 & 0x7));
134181 +}
134182 +
134183 +static void qm_set_hid(struct qman *qm)
134184 +{
134185 + qm_out(HID_CFG, 0);
134186 +}
134187 +
134188 +static void qm_set_corenet_initiator(struct qman *qm)
134189 +{
134190 + qm_out(CI_SCHED_CFG,
134191 + 0x80000000 | /* write srcciv enable */
134192 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRCCIV << 24) |
134193 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_SRQ_W << 8) |
134194 + (CONFIG_FSL_QMAN_CI_SCHED_CFG_RW_W << 4) |
134195 + CONFIG_FSL_QMAN_CI_SCHED_CFG_BMAN_W);
134196 +}
134197 +
134198 +static void qm_get_version(struct qman *qm, u16 *id, u8 *major, u8 *minor,
134199 + u8 *cfg)
134200 +{
134201 + u32 v = qm_in(IP_REV_1);
134202 + u32 v2 = qm_in(IP_REV_2);
134203 + *id = (v >> 16);
134204 + *major = (v >> 8) & 0xff;
134205 + *minor = v & 0xff;
134206 + *cfg = v2 & 0xff;
134207 +}
134208 +
134209 +static void qm_set_memory(struct qman *qm, enum qm_memory memory, u64 ba,
134210 + int enable, int prio, int stash, u32 size)
134211 +{
134212 + u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
134213 + u32 exp = ilog2(size);
134214 + /* choke if size isn't within range */
134215 + DPA_ASSERT((size >= 4096) && (size <= 1073741824) &&
134216 + is_power_of_2(size));
134217 + /* choke if 'ba' has lower-alignment than 'size' */
134218 + DPA_ASSERT(!(ba & (size - 1)));
134219 + __qm_out(qm, offset, upper_32_bits(ba));
134220 + __qm_out(qm, offset + REG_offset_BAR, lower_32_bits(ba));
134221 + __qm_out(qm, offset + REG_offset_AR,
134222 + (enable ? 0x80000000 : 0) |
134223 + (prio ? 0x40000000 : 0) |
134224 + (stash ? 0x20000000 : 0) |
134225 + (exp - 1));
134226 +}
134227 +
134228 +static void qm_set_pfdr_threshold(struct qman *qm, u32 th, u8 k)
134229 +{
134230 + qm_out(PFDR_FP_LWIT, th & 0xffffff);
134231 + qm_out(PFDR_CFG, k);
134232 +}
134233 +
134234 +static void qm_set_sfdr_threshold(struct qman *qm, u16 th)
134235 +{
134236 + qm_out(SFDR_CFG, th & 0x3ff);
134237 +}
134238 +
134239 +static int qm_init_pfdr(struct qman *qm, u32 pfdr_start, u32 num)
134240 +{
134241 + u8 rslt = MCR_get_rslt(qm_in(MCR));
134242 +
134243 + DPA_ASSERT(pfdr_start && !(pfdr_start & 7) && !(num & 7) && num);
134244 + /* Make sure the command interface is 'idle' */
134245 + if (!MCR_rslt_idle(rslt))
134246 + panic("QMAN_MCR isn't idle");
134247 +
134248 + /* Write the MCR command params then the verb */
134249 + qm_out(MCP(0), pfdr_start);
134250 + /* TODO: remove this - it's a workaround for a model bug that is
134251 + * corrected in more recent versions. We use the workaround until
134252 + * everyone has upgraded. */
134253 + qm_out(MCP(1), (pfdr_start + num - 16));
134254 + lwsync();
134255 + qm_out(MCR, MCR_INIT_PFDR);
134256 + /* Poll for the result */
134257 + do {
134258 + rslt = MCR_get_rslt(qm_in(MCR));
134259 + } while (!MCR_rslt_idle(rslt));
134260 + if (MCR_rslt_ok(rslt))
134261 + return 0;
134262 + if (MCR_rslt_eaccess(rslt))
134263 + return -EACCES;
134264 + if (MCR_rslt_inval(rslt))
134265 + return -EINVAL;
134266 + pr_crit("Unexpected result from MCR_INIT_PFDR: %02x\n", rslt);
134267 + return -ENOSYS;
134268 +}
134269 +
134270 +/*****************/
134271 +/* Config driver */
134272 +/*****************/
134273 +
134274 +#define DEFAULT_FQD_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ)
134275 +#define DEFAULT_PFDR_SZ (PAGE_SIZE << CONFIG_FSL_QMAN_PFDR_SZ)
134276 +
134277 +/* We support only one of these */
134278 +static struct qman *qm;
134279 +static struct device_node *qm_node;
134280 +
134281 +/* And this state belongs to 'qm'. It is set during fsl_qman_init(), but used
134282 + * during qman_init_ccsr(). */
134283 +static dma_addr_t fqd_a, pfdr_a;
134284 +static size_t fqd_sz = DEFAULT_FQD_SZ, pfdr_sz = DEFAULT_PFDR_SZ;
134285 +
134286 +static int qman_fqd(struct reserved_mem *rmem)
134287 +{
134288 + fqd_a = rmem->base;
134289 + fqd_sz = rmem->size;
134290 +
134291 + WARN_ON(!(fqd_a && fqd_sz));
134292 +
134293 + return 0;
134294 +}
134295 +RESERVEDMEM_OF_DECLARE(qman_fqd, "fsl,qman-fqd", qman_fqd);
134296 +
134297 +static int qman_pfdr(struct reserved_mem *rmem)
134298 +{
134299 + pfdr_a = rmem->base;
134300 + pfdr_sz = rmem->size;
134301 +
134302 + WARN_ON(!(pfdr_a && pfdr_sz));
134303 +
134304 + return 0;
134305 +}
134306 +RESERVEDMEM_OF_DECLARE(qman_fbpr, "fsl,qman-pfdr", qman_pfdr);
134307 +
134308 +size_t get_qman_fqd_size()
134309 +{
134310 + return fqd_sz;
134311 +}
134312 +
134313 +/* Parse the <name> property to extract the memory location and size and
134314 + * memblock_reserve() it. If it isn't supplied, memblock_alloc() the default
134315 + * size. Also flush this memory range from data cache so that QMAN originated
134316 + * transactions for this memory region could be marked non-coherent.
134317 + */
134318 +static __init int parse_mem_property(struct device_node *node, const char *name,
134319 + dma_addr_t *addr, size_t *sz, int zero)
134320 +{
134321 + int ret;
134322 +
134323 + /* If using a "zero-pma", don't try to zero it, even if you asked */
134324 + if (zero && of_find_property(node, "zero-pma", &ret)) {
134325 + pr_info(" it's a 'zero-pma', not zeroing from s/w\n");
134326 + zero = 0;
134327 + }
134328 +
134329 + if (zero) {
134330 + /* map as cacheable, non-guarded */
134331 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
134332 + void __iomem *tmpp = ioremap_cache(*addr, *sz);
134333 +#else
134334 + void __iomem *tmpp = ioremap(*addr, *sz);
134335 +#endif
134336 +
134337 + if (!tmpp)
134338 + return -ENOMEM;
134339 + memset_io(tmpp, 0, *sz);
134340 + flush_dcache_range((unsigned long)tmpp,
134341 + (unsigned long)tmpp + *sz);
134342 + iounmap(tmpp);
134343 + }
134344 +
134345 + return 0;
134346 +}
134347 +
134348 +/* TODO:
134349 + * - there is obviously no handling of errors,
134350 + * - the calls to qm_set_memory() hard-code the priority and CPC-stashing for
134351 + * both memory resources to zero.
134352 + */
134353 +static int __init fsl_qman_init(struct device_node *node)
134354 +{
134355 + struct resource res;
134356 + resource_size_t len;
134357 + u32 __iomem *regs;
134358 + const char *s;
134359 + int ret, standby = 0;
134360 + u16 id;
134361 + u8 major, minor, cfg;
134362 + ret = of_address_to_resource(node, 0, &res);
134363 + if (ret) {
134364 + pr_err("Can't get %s property '%s'\n", node->full_name, "reg");
134365 + return ret;
134366 + }
134367 + s = of_get_property(node, "fsl,hv-claimable", &ret);
134368 + if (s && !strcmp(s, "standby"))
134369 + standby = 1;
134370 + if (!standby) {
134371 + ret = parse_mem_property(node, "fsl,qman-fqd",
134372 + &fqd_a, &fqd_sz, 1);
134373 + pr_info("qman-fqd addr %pad size 0x%zx\n", &fqd_a, fqd_sz);
134374 + BUG_ON(ret);
134375 + ret = parse_mem_property(node, "fsl,qman-pfdr",
134376 + &pfdr_a, &pfdr_sz, 0);
134377 + pr_info("qman-pfdr addr %pad size 0x%zx\n", &pfdr_a, pfdr_sz);
134378 + BUG_ON(ret);
134379 + }
134380 + /* Global configuration */
134381 + len = resource_size(&res);
134382 + if (len != (unsigned long)len)
134383 + return -EINVAL;
134384 + regs = ioremap(res.start, (unsigned long)len);
134385 + qm = qm_create(regs);
134386 + qm_node = node;
134387 + qm_get_version(qm, &id, &major, &minor, &cfg);
134388 + pr_info("Qman ver:%04x,%02x,%02x,%02x\n", id, major, minor, cfg);
134389 + if (!qman_ip_rev) {
134390 + if ((major == 1) && (minor == 0)) {
134391 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
134392 + iounmap(regs);
134393 + return -ENODEV;
134394 + } else if ((major == 1) && (minor == 1))
134395 + qman_ip_rev = QMAN_REV11;
134396 + else if ((major == 1) && (minor == 2))
134397 + qman_ip_rev = QMAN_REV12;
134398 + else if ((major == 2) && (minor == 0))
134399 + qman_ip_rev = QMAN_REV20;
134400 + else if ((major == 3) && (minor == 0))
134401 + qman_ip_rev = QMAN_REV30;
134402 + else if ((major == 3) && (minor == 1))
134403 + qman_ip_rev = QMAN_REV31;
134404 + else if ((major == 3) && (minor == 2))
134405 + qman_ip_rev = QMAN_REV32;
134406 + else {
134407 + pr_warn("unknown Qman version, default to rev1.1\n");
134408 + qman_ip_rev = QMAN_REV11;
134409 + }
134410 + qman_ip_cfg = cfg;
134411 + }
134412 +
134413 + if (standby) {
134414 + pr_info(" -> in standby mode\n");
134415 + return 0;
134416 + }
134417 + return 0;
134418 +}
134419 +
134420 +int qman_have_ccsr(void)
134421 +{
134422 + return qm ? 1 : 0;
134423 +}
134424 +
134425 +__init int qman_init_early(void)
134426 +{
134427 + struct device_node *dn;
134428 + int ret;
134429 +
134430 + for_each_compatible_node(dn, NULL, "fsl,qman") {
134431 + if (qm)
134432 + pr_err("%s: only one 'fsl,qman' allowed\n",
134433 + dn->full_name);
134434 + else {
134435 + if (!of_device_is_available(dn))
134436 + continue;
134437 +
134438 + ret = fsl_qman_init(dn);
134439 + BUG_ON(ret);
134440 + }
134441 + }
134442 + return 0;
134443 +}
134444 +postcore_initcall_sync(qman_init_early);
134445 +
134446 +static void log_edata_bits(u32 bit_count)
134447 +{
134448 + u32 i, j, mask = 0xffffffff;
134449 +
134450 + pr_warn("Qman ErrInt, EDATA:\n");
134451 + i = bit_count/32;
134452 + if (bit_count%32) {
134453 + i++;
134454 + mask = ~(mask << bit_count%32);
134455 + }
134456 + j = 16-i;
134457 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)) & mask);
134458 + j++;
134459 + for (; j < 16; j++)
134460 + pr_warn(" 0x%08x\n", qm_in(EDATA(j)));
134461 +}
134462 +
134463 +static void log_additional_error_info(u32 isr_val, u32 ecsr_val)
134464 +{
134465 + union qman_ecir ecir_val;
134466 + union qman_eadr eadr_val;
134467 +
134468 + ecir_val.ecir_raw = qm_in(ECIR);
134469 + /* Is portal info valid */
134470 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
134471 + union qman_ecir2 ecir2_val;
134472 + ecir2_val.ecir2_raw = qm_in(ECIR2);
134473 + if (ecsr_val & PORTAL_ECSR_ERR) {
134474 + pr_warn("Qman ErrInt: %s id %d\n",
134475 + (ecir2_val.info.portal_type) ?
134476 + "DCP" : "SWP", ecir2_val.info.portal_num);
134477 + }
134478 + if (ecsr_val & (FQID_ECSR_ERR | QM_EIRQ_IECE)) {
134479 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
134480 + ecir_val.info.fqid);
134481 + }
134482 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
134483 + eadr_val.eadr_raw = qm_in(EADR);
134484 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
134485 + error_mdata[eadr_val.info_rev3.memid].txt,
134486 + error_mdata[eadr_val.info_rev3.memid].addr_mask
134487 + & eadr_val.info_rev3.eadr);
134488 + log_edata_bits(
134489 + error_mdata[eadr_val.info_rev3.memid].bits);
134490 + }
134491 + } else {
134492 + if (ecsr_val & PORTAL_ECSR_ERR) {
134493 + pr_warn("Qman ErrInt: %s id %d\n",
134494 + (ecir_val.info.portal_type) ?
134495 + "DCP" : "SWP", ecir_val.info.portal_num);
134496 + }
134497 + if (ecsr_val & FQID_ECSR_ERR) {
134498 + pr_warn("Qman ErrInt: ecir.fqid 0x%x\n",
134499 + ecir_val.info.fqid);
134500 + }
134501 + if (ecsr_val & (QM_EIRQ_SBEI|QM_EIRQ_MBEI)) {
134502 + eadr_val.eadr_raw = qm_in(EADR);
134503 + pr_warn("Qman ErrInt: EADR Memory: %s, 0x%x\n",
134504 + error_mdata[eadr_val.info.memid].txt,
134505 + error_mdata[eadr_val.info.memid].addr_mask
134506 + & eadr_val.info.eadr);
134507 + log_edata_bits(error_mdata[eadr_val.info.memid].bits);
134508 + }
134509 + }
134510 +}
134511 +
134512 +/* Qman interrupt handler */
134513 +static irqreturn_t qman_isr(int irq, void *ptr)
134514 +{
134515 + u32 isr_val, ier_val, ecsr_val, isr_mask, i;
134516 +
134517 + ier_val = qm_err_isr_enable_read(qm);
134518 + isr_val = qm_err_isr_status_read(qm);
134519 + ecsr_val = qm_in(ECSR);
134520 + isr_mask = isr_val & ier_val;
134521 +
134522 + if (!isr_mask)
134523 + return IRQ_NONE;
134524 + for (i = 0; i < QMAN_HWE_COUNT; i++) {
134525 + if (qman_hwerr_txts[i].mask & isr_mask) {
134526 + pr_warn("Qman ErrInt: %s\n", qman_hwerr_txts[i].txt);
134527 + if (qman_hwerr_txts[i].mask & ecsr_val) {
134528 + log_additional_error_info(isr_mask, ecsr_val);
134529 + /* Re-arm error capture registers */
134530 + qm_out(ECSR, ecsr_val);
134531 + }
134532 + if (qman_hwerr_txts[i].mask & QMAN_ERRS_TO_UNENABLE) {
134533 + pr_devel("Qman un-enabling error 0x%x\n",
134534 + qman_hwerr_txts[i].mask);
134535 + ier_val &= ~qman_hwerr_txts[i].mask;
134536 + qm_err_isr_enable_write(qm, ier_val);
134537 + }
134538 + }
134539 + }
134540 + qm_err_isr_status_clear(qm, isr_val);
134541 + return IRQ_HANDLED;
134542 +}
134543 +
134544 +static int __bind_irq(void)
134545 +{
134546 + int ret, err_irq;
134547 +
134548 + err_irq = of_irq_to_resource(qm_node, 0, NULL);
134549 + if (err_irq == 0) {
134550 + pr_info("Can't get %s property '%s'\n", qm_node->full_name,
134551 + "interrupts");
134552 + return -ENODEV;
134553 + }
134554 + ret = request_irq(err_irq, qman_isr, IRQF_SHARED, "qman-err", qm_node);
134555 + if (ret) {
134556 + pr_err("request_irq() failed %d for '%s'\n", ret,
134557 + qm_node->full_name);
134558 + return -ENODEV;
134559 + }
134560 + /* Write-to-clear any stale bits, (eg. starvation being asserted prior
134561 + * to resource allocation during driver init). */
134562 + qm_err_isr_status_clear(qm, 0xffffffff);
134563 + /* Enable Error Interrupts */
134564 + qm_err_isr_enable_write(qm, 0xffffffff);
134565 + return 0;
134566 +}
134567 +
134568 +int qman_init_ccsr(struct device_node *node)
134569 +{
134570 + int ret;
134571 + if (!qman_have_ccsr())
134572 + return 0;
134573 + if (node != qm_node)
134574 + return -EINVAL;
134575 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
134576 + /* TEMP for LS1043 : should be done in uboot */
134577 + qm_out(QCSP_BARE, 0x5);
134578 + qm_out(QCSP_BAR, 0x0);
134579 +#endif
134580 + /* FQD memory */
134581 + qm_set_memory(qm, qm_memory_fqd, fqd_a, 1, 0, 0, fqd_sz);
134582 + /* PFDR memory */
134583 + qm_set_memory(qm, qm_memory_pfdr, pfdr_a, 1, 0, 0, pfdr_sz);
134584 + qm_init_pfdr(qm, 8, pfdr_sz / 64 - 8);
134585 + /* thresholds */
134586 + qm_set_pfdr_threshold(qm, 512, 64);
134587 + qm_set_sfdr_threshold(qm, 128);
134588 + /* clear stale PEBI bit from interrupt status register */
134589 + qm_err_isr_status_clear(qm, QM_EIRQ_PEBI);
134590 + /* corenet initiator settings */
134591 + qm_set_corenet_initiator(qm);
134592 + /* HID settings */
134593 + qm_set_hid(qm);
134594 + /* Set scheduling weights to defaults */
134595 + for (ret = qm_wq_first; ret <= qm_wq_last; ret++)
134596 + qm_set_wq_scheduling(qm, ret, 0, 0, 0, 0, 0, 0, 0);
134597 + /* We are not prepared to accept ERNs for hardware enqueues */
134598 + qm_set_dc(qm, qm_dc_portal_fman0, 1, 0);
134599 + qm_set_dc(qm, qm_dc_portal_fman1, 1, 0);
134600 + /* Initialise Error Interrupt Handler */
134601 + ret = __bind_irq();
134602 + if (ret)
134603 + return ret;
134604 + return 0;
134605 +}
134606 +
134607 +#define LIO_CFG_LIODN_MASK 0x0fff0000
134608 +void qman_liodn_fixup(u16 channel)
134609 +{
134610 + static int done;
134611 + static u32 liodn_offset;
134612 + u32 before, after;
134613 + int idx = channel - QM_CHANNEL_SWPORTAL0;
134614 +
134615 + if (!qman_have_ccsr())
134616 + return;
134617 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
134618 + before = qm_in(REV3_QCSP_LIO_CFG(idx));
134619 + else
134620 + before = qm_in(QCSP_LIO_CFG(idx));
134621 + if (!done) {
134622 + liodn_offset = before & LIO_CFG_LIODN_MASK;
134623 + done = 1;
134624 + return;
134625 + }
134626 + after = (before & (~LIO_CFG_LIODN_MASK)) | liodn_offset;
134627 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
134628 + qm_out(REV3_QCSP_LIO_CFG(idx), after);
134629 + else
134630 + qm_out(QCSP_LIO_CFG(idx), after);
134631 +}
134632 +
134633 +#define IO_CFG_SDEST_MASK 0x00ff0000
134634 +int qman_set_sdest(u16 channel, unsigned int cpu_idx)
134635 +{
134636 + int idx = channel - QM_CHANNEL_SWPORTAL0;
134637 + u32 before, after;
134638 +
134639 + if (!qman_have_ccsr())
134640 + return -ENODEV;
134641 + if ((qman_ip_rev & 0xFF00) == QMAN_REV31) {
134642 + /* LS1043A - only one L2 cache */
134643 + cpu_idx = 0;
134644 + }
134645 +
134646 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
134647 + before = qm_in(REV3_QCSP_IO_CFG(idx));
134648 + /* Each pair of vcpu share the same SRQ(SDEST) */
134649 + cpu_idx /= 2;
134650 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
134651 + qm_out(REV3_QCSP_IO_CFG(idx), after);
134652 + } else {
134653 + before = qm_in(QCSP_IO_CFG(idx));
134654 + after = (before & (~IO_CFG_SDEST_MASK)) | (cpu_idx << 16);
134655 + qm_out(QCSP_IO_CFG(idx), after);
134656 + }
134657 + return 0;
134658 +}
134659 +
134660 +#define MISC_CFG_WPM_MASK 0x00000002
134661 +int qm_set_wpm(int wpm)
134662 +{
134663 + u32 before;
134664 + u32 after;
134665 +
134666 + if (!qman_have_ccsr())
134667 + return -ENODEV;
134668 +
134669 + before = qm_in(MISC_CFG);
134670 + after = (before & (~MISC_CFG_WPM_MASK)) | (wpm << 1);
134671 + qm_out(MISC_CFG, after);
134672 + return 0;
134673 +}
134674 +
134675 +int qm_get_wpm(int *wpm)
134676 +{
134677 + u32 before;
134678 +
134679 + if (!qman_have_ccsr())
134680 + return -ENODEV;
134681 +
134682 + before = qm_in(MISC_CFG);
134683 + *wpm = (before & MISC_CFG_WPM_MASK) >> 1;
134684 + return 0;
134685 +}
134686 +
134687 +/* CEETM_CFG_PRES register has PRES field which is calculated by:
134688 + * PRES = (2^22 / credit update reference period) * QMan clock period
134689 + * = (2^22 * 10^9)/ CONFIG_QMAN_CEETM_UPDATE_PERIOD) / qman_clk
134690 + */
134691 +
134692 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal)
134693 +{
134694 + u64 temp;
134695 + u16 pres;
134696 +
134697 + if (!qman_have_ccsr())
134698 + return -ENODEV;
134699 +
134700 + temp = 0x400000 * 100;
134701 + do_div(temp, CONFIG_QMAN_CEETM_UPDATE_PERIOD);
134702 + temp *= 10000000;
134703 + do_div(temp, qman_clk);
134704 + pres = (u16) temp;
134705 + qm_out(CEETM_CFG_IDX, portal);
134706 + qm_out(CEETM_CFG_PRES, pres);
134707 + return 0;
134708 +}
134709 +
134710 +int qman_ceetm_get_prescaler(u16 *pres)
134711 +{
134712 + if (!qman_have_ccsr())
134713 + return -ENODEV;
134714 + *pres = (u16)qm_in(CEETM_CFG_PRES);
134715 + return 0;
134716 +}
134717 +
134718 +#define DCP_CFG_CEETME_MASK 0xFFFF0000
134719 +#define QM_SP_ENABLE_CEETM(n) (0x80000000 >> (n))
134720 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
134721 +{
134722 + u32 dcp_cfg;
134723 +
134724 + if (!qman_have_ccsr())
134725 + return -ENODEV;
134726 +
134727 + dcp_cfg = qm_in(DCP_CFG(portal));
134728 + dcp_cfg |= QM_SP_ENABLE_CEETM(sub_portal);
134729 + qm_out(DCP_CFG(portal), dcp_cfg);
134730 + return 0;
134731 +}
134732 +
134733 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal)
134734 +{
134735 + u32 dcp_cfg;
134736 +
134737 + if (!qman_have_ccsr())
134738 + return -ENODEV;
134739 + dcp_cfg = qm_in(DCP_CFG(portal));
134740 + dcp_cfg &= ~(QM_SP_ENABLE_CEETM(sub_portal));
134741 + qm_out(DCP_CFG(portal), dcp_cfg);
134742 + return 0;
134743 +}
134744 +
134745 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num)
134746 +{
134747 + if (!qman_have_ccsr())
134748 + return -ENODEV;
134749 + *num = qm_in(CEETM_XSFDR_IN_USE);
134750 + return 0;
134751 +}
134752 +EXPORT_SYMBOL(qman_ceetm_get_xsfdr);
134753 +
134754 +#ifdef CONFIG_SYSFS
134755 +
134756 +#define DRV_NAME "fsl-qman"
134757 +#define DCP_MAX_ID 3
134758 +#define DCP_MIN_ID 0
134759 +
134760 +static ssize_t show_pfdr_fpc(struct device *dev,
134761 + struct device_attribute *dev_attr, char *buf)
134762 +{
134763 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_FPC));
134764 +};
134765 +
134766 +static ssize_t show_dlm_avg(struct device *dev,
134767 + struct device_attribute *dev_attr, char *buf)
134768 +{
134769 + u32 data;
134770 + int i;
134771 +
134772 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
134773 + return -EINVAL;
134774 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
134775 + return -EINVAL;
134776 + data = qm_in(DCP_DLM_AVG(i));
134777 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
134778 + (data & 0x000000ff)*390625);
134779 +};
134780 +
134781 +static ssize_t set_dlm_avg(struct device *dev,
134782 + struct device_attribute *dev_attr, const char *buf, size_t count)
134783 +{
134784 + unsigned long val;
134785 + int i;
134786 +
134787 + if (!sscanf(dev_attr->attr.name, "dcp%d_dlm_avg", &i))
134788 + return -EINVAL;
134789 + if (i < DCP_MIN_ID || i > DCP_MAX_ID)
134790 + return -EINVAL;
134791 + if (kstrtoul(buf, 0, &val)) {
134792 + dev_dbg(dev, "invalid input %s\n", buf);
134793 + return -EINVAL;
134794 + }
134795 + qm_out(DCP_DLM_AVG(i), val);
134796 + return count;
134797 +};
134798 +
134799 +static ssize_t show_pfdr_cfg(struct device *dev,
134800 + struct device_attribute *dev_attr, char *buf)
134801 +{
134802 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(PFDR_CFG));
134803 +};
134804 +
134805 +static ssize_t set_pfdr_cfg(struct device *dev,
134806 + struct device_attribute *dev_attr, const char *buf, size_t count)
134807 +{
134808 + unsigned long val;
134809 +
134810 + if (kstrtoul(buf, 0, &val)) {
134811 + dev_dbg(dev, "invalid input %s\n", buf);
134812 + return -EINVAL;
134813 + }
134814 + qm_out(PFDR_CFG, val);
134815 + return count;
134816 +};
134817 +
134818 +static ssize_t show_sfdr_in_use(struct device *dev,
134819 + struct device_attribute *dev_attr, char *buf)
134820 +{
134821 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SFDR_IN_USE));
134822 +};
134823 +
134824 +static ssize_t show_idle_stat(struct device *dev,
134825 + struct device_attribute *dev_attr, char *buf)
134826 +{
134827 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(IDLE_STAT));
134828 +};
134829 +
134830 +static ssize_t show_ci_rlm_avg(struct device *dev,
134831 + struct device_attribute *dev_attr, char *buf)
134832 +{
134833 + u32 data = qm_in(CI_RLM_AVG);
134834 + return snprintf(buf, PAGE_SIZE, "%d.%08d\n", data>>8,
134835 + (data & 0x000000ff)*390625);
134836 +};
134837 +
134838 +static ssize_t set_ci_rlm_avg(struct device *dev,
134839 + struct device_attribute *dev_attr, const char *buf, size_t count)
134840 +{
134841 + unsigned long val;
134842 +
134843 + if (kstrtoul(buf, 0, &val)) {
134844 + dev_dbg(dev, "invalid input %s\n", buf);
134845 + return -EINVAL;
134846 + }
134847 + qm_out(CI_RLM_AVG, val);
134848 + return count;
134849 +};
134850 +
134851 +static ssize_t show_err_isr(struct device *dev,
134852 + struct device_attribute *dev_attr, char *buf)
134853 +{
134854 + return snprintf(buf, PAGE_SIZE, "0x%08x\n", qm_in(ERR_ISR));
134855 +};
134856 +
134857 +#define SBEC_MAX_ID 14
134858 +#define SBEC_MIN_ID 0
134859 +
134860 +static ssize_t show_sbec(struct device *dev,
134861 + struct device_attribute *dev_attr, char *buf)
134862 +{
134863 + int i;
134864 +
134865 + if (!sscanf(dev_attr->attr.name, "sbec_%d", &i))
134866 + return -EINVAL;
134867 + if (i < SBEC_MIN_ID || i > SBEC_MAX_ID)
134868 + return -EINVAL;
134869 + return snprintf(buf, PAGE_SIZE, "%u\n", qm_in(SBEC(i)));
134870 +};
134871 +
134872 +static DEVICE_ATTR(pfdr_fpc, S_IRUSR, show_pfdr_fpc, NULL);
134873 +static DEVICE_ATTR(pfdr_cfg, S_IRUSR, show_pfdr_cfg, set_pfdr_cfg);
134874 +static DEVICE_ATTR(idle_stat, S_IRUSR, show_idle_stat, NULL);
134875 +static DEVICE_ATTR(ci_rlm_avg, (S_IRUSR|S_IWUSR),
134876 + show_ci_rlm_avg, set_ci_rlm_avg);
134877 +static DEVICE_ATTR(err_isr, S_IRUSR, show_err_isr, NULL);
134878 +static DEVICE_ATTR(sfdr_in_use, S_IRUSR, show_sfdr_in_use, NULL);
134879 +
134880 +static DEVICE_ATTR(dcp0_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
134881 +static DEVICE_ATTR(dcp1_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
134882 +static DEVICE_ATTR(dcp2_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
134883 +static DEVICE_ATTR(dcp3_dlm_avg, (S_IRUSR|S_IWUSR), show_dlm_avg, set_dlm_avg);
134884 +
134885 +static DEVICE_ATTR(sbec_0, S_IRUSR, show_sbec, NULL);
134886 +static DEVICE_ATTR(sbec_1, S_IRUSR, show_sbec, NULL);
134887 +static DEVICE_ATTR(sbec_2, S_IRUSR, show_sbec, NULL);
134888 +static DEVICE_ATTR(sbec_3, S_IRUSR, show_sbec, NULL);
134889 +static DEVICE_ATTR(sbec_4, S_IRUSR, show_sbec, NULL);
134890 +static DEVICE_ATTR(sbec_5, S_IRUSR, show_sbec, NULL);
134891 +static DEVICE_ATTR(sbec_6, S_IRUSR, show_sbec, NULL);
134892 +static DEVICE_ATTR(sbec_7, S_IRUSR, show_sbec, NULL);
134893 +static DEVICE_ATTR(sbec_8, S_IRUSR, show_sbec, NULL);
134894 +static DEVICE_ATTR(sbec_9, S_IRUSR, show_sbec, NULL);
134895 +static DEVICE_ATTR(sbec_10, S_IRUSR, show_sbec, NULL);
134896 +static DEVICE_ATTR(sbec_11, S_IRUSR, show_sbec, NULL);
134897 +static DEVICE_ATTR(sbec_12, S_IRUSR, show_sbec, NULL);
134898 +static DEVICE_ATTR(sbec_13, S_IRUSR, show_sbec, NULL);
134899 +static DEVICE_ATTR(sbec_14, S_IRUSR, show_sbec, NULL);
134900 +
134901 +static struct attribute *qman_dev_attributes[] = {
134902 + &dev_attr_pfdr_fpc.attr,
134903 + &dev_attr_pfdr_cfg.attr,
134904 + &dev_attr_idle_stat.attr,
134905 + &dev_attr_ci_rlm_avg.attr,
134906 + &dev_attr_err_isr.attr,
134907 + &dev_attr_dcp0_dlm_avg.attr,
134908 + &dev_attr_dcp1_dlm_avg.attr,
134909 + &dev_attr_dcp2_dlm_avg.attr,
134910 + &dev_attr_dcp3_dlm_avg.attr,
134911 + /* sfdr_in_use will be added if necessary */
134912 + NULL
134913 +};
134914 +
134915 +static struct attribute *qman_dev_ecr_attributes[] = {
134916 + &dev_attr_sbec_0.attr,
134917 + &dev_attr_sbec_1.attr,
134918 + &dev_attr_sbec_2.attr,
134919 + &dev_attr_sbec_3.attr,
134920 + &dev_attr_sbec_4.attr,
134921 + &dev_attr_sbec_5.attr,
134922 + &dev_attr_sbec_6.attr,
134923 + &dev_attr_sbec_7.attr,
134924 + &dev_attr_sbec_8.attr,
134925 + &dev_attr_sbec_9.attr,
134926 + &dev_attr_sbec_10.attr,
134927 + &dev_attr_sbec_11.attr,
134928 + &dev_attr_sbec_12.attr,
134929 + &dev_attr_sbec_13.attr,
134930 + &dev_attr_sbec_14.attr,
134931 + NULL
134932 +};
134933 +
134934 +/* root level */
134935 +static const struct attribute_group qman_dev_attr_grp = {
134936 + .name = NULL,
134937 + .attrs = qman_dev_attributes
134938 +};
134939 +static const struct attribute_group qman_dev_ecr_grp = {
134940 + .name = "error_capture",
134941 + .attrs = qman_dev_ecr_attributes
134942 +};
134943 +
134944 +static int of_fsl_qman_remove(struct platform_device *ofdev)
134945 +{
134946 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
134947 + return 0;
134948 +};
134949 +
134950 +static int of_fsl_qman_probe(struct platform_device *ofdev)
134951 +{
134952 + int ret;
134953 +
134954 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
134955 + if (ret)
134956 + goto done;
134957 + ret = sysfs_add_file_to_group(&ofdev->dev.kobj,
134958 + &dev_attr_sfdr_in_use.attr, qman_dev_attr_grp.name);
134959 + if (ret)
134960 + goto del_group_0;
134961 + ret = sysfs_create_group(&ofdev->dev.kobj, &qman_dev_ecr_grp);
134962 + if (ret)
134963 + goto del_group_0;
134964 +
134965 + goto done;
134966 +
134967 +del_group_0:
134968 + sysfs_remove_group(&ofdev->dev.kobj, &qman_dev_attr_grp);
134969 +done:
134970 + if (ret)
134971 + dev_err(&ofdev->dev,
134972 + "Cannot create dev attributes ret=%d\n", ret);
134973 + return ret;
134974 +};
134975 +
134976 +static struct of_device_id of_fsl_qman_ids[] = {
134977 + {
134978 + .compatible = "fsl,qman",
134979 + },
134980 + {}
134981 +};
134982 +MODULE_DEVICE_TABLE(of, of_fsl_qman_ids);
134983 +
134984 +#ifdef CONFIG_SUSPEND
134985 +
134986 +static u32 saved_isdr;
134987 +static int qman_pm_suspend_noirq(struct device *dev)
134988 +{
134989 + uint32_t idle_state;
134990 +
134991 + suspend_unused_qportal();
134992 + /* save isdr, disable all, clear isr */
134993 + saved_isdr = qm_err_isr_disable_read(qm);
134994 + qm_err_isr_disable_write(qm, 0xffffffff);
134995 + qm_err_isr_status_clear(qm, 0xffffffff);
134996 + idle_state = qm_in(IDLE_STAT);
134997 + if (!(idle_state & 0x1)) {
134998 + pr_err("Qman not idle 0x%x aborting\n", idle_state);
134999 + qm_err_isr_disable_write(qm, saved_isdr);
135000 + resume_unused_qportal();
135001 + return -EBUSY;
135002 + }
135003 +#ifdef CONFIG_PM_DEBUG
135004 + pr_info("Qman suspend code, IDLE_STAT = 0x%x\n", idle_state);
135005 +#endif
135006 + return 0;
135007 +}
135008 +
135009 +static int qman_pm_resume_noirq(struct device *dev)
135010 +{
135011 + /* restore isdr */
135012 + qm_err_isr_disable_write(qm, saved_isdr);
135013 + resume_unused_qportal();
135014 + return 0;
135015 +}
135016 +#else
135017 +#define qman_pm_suspend_noirq NULL
135018 +#define qman_pm_resume_noirq NULL
135019 +#endif
135020 +
135021 +static const struct dev_pm_ops qman_pm_ops = {
135022 + .suspend_noirq = qman_pm_suspend_noirq,
135023 + .resume_noirq = qman_pm_resume_noirq,
135024 +};
135025 +
135026 +static struct platform_driver of_fsl_qman_driver = {
135027 + .driver = {
135028 + .owner = THIS_MODULE,
135029 + .name = DRV_NAME,
135030 + .of_match_table = of_fsl_qman_ids,
135031 + .pm = &qman_pm_ops,
135032 + },
135033 + .probe = of_fsl_qman_probe,
135034 + .remove = of_fsl_qman_remove,
135035 +};
135036 +
135037 +static int qman_ctrl_init(void)
135038 +{
135039 + return platform_driver_register(&of_fsl_qman_driver);
135040 +}
135041 +
135042 +static void qman_ctrl_exit(void)
135043 +{
135044 + platform_driver_unregister(&of_fsl_qman_driver);
135045 +}
135046 +
135047 +module_init(qman_ctrl_init);
135048 +module_exit(qman_ctrl_exit);
135049 +
135050 +#endif /* CONFIG_SYSFS */
135051 --- /dev/null
135052 +++ b/drivers/staging/fsl_qbman/qman_debugfs.c
135053 @@ -0,0 +1,1594 @@
135054 +/* Copyright 2010-2011 Freescale Semiconductor, Inc.
135055 + *
135056 + * Redistribution and use in source and binary forms, with or without
135057 + * modification, are permitted provided that the following conditions are met:
135058 + * * Redistributions of source code must retain the above copyright
135059 + * notice, this list of conditions and the following disclaimer.
135060 + * * Redistributions in binary form must reproduce the above copyright
135061 + * notice, this list of conditions and the following disclaimer in the
135062 + * documentation and/or other materials provided with the distribution.
135063 + * * Neither the name of Freescale Semiconductor nor the
135064 + * names of its contributors may be used to endorse or promote products
135065 + * derived from this software without specific prior written permission.
135066 + *
135067 + *
135068 + * ALTERNATIVELY, this software may be distributed under the terms of the
135069 + * GNU General Public License ("GPL") as published by the Free Software
135070 + * Foundation, either version 2 of that License or (at your option) any
135071 + * later version.
135072 + *
135073 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
135074 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
135075 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
135076 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
135077 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
135078 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
135079 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
135080 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135081 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
135082 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135083 + */
135084 +#include "qman_private.h"
135085 +
135086 +#define MAX_FQID (0x00ffffff)
135087 +#define QM_FQD_BLOCK_SIZE 64
135088 +#define QM_FQD_AR (0xC10)
135089 +
135090 +static u32 fqid_max;
135091 +static u64 qman_ccsr_start;
135092 +static u64 qman_ccsr_size;
135093 +
135094 +static const char * const state_txt[] = {
135095 + "Out of Service",
135096 + "Retired",
135097 + "Tentatively Scheduled",
135098 + "Truly Scheduled",
135099 + "Parked",
135100 + "Active, Active Held or Held Suspended",
135101 + "Unknown State 6",
135102 + "Unknown State 7",
135103 + NULL,
135104 +};
135105 +
135106 +static const u8 fqd_states[] = {
135107 + QM_MCR_NP_STATE_OOS, QM_MCR_NP_STATE_RETIRED, QM_MCR_NP_STATE_TEN_SCHED,
135108 + QM_MCR_NP_STATE_TRU_SCHED, QM_MCR_NP_STATE_PARKED,
135109 + QM_MCR_NP_STATE_ACTIVE};
135110 +
135111 +struct mask_to_text {
135112 + u16 mask;
135113 + const char *txt;
135114 +};
135115 +
135116 +struct mask_filter_s {
135117 + u16 mask;
135118 + u8 filter;
135119 +};
135120 +
135121 +static const struct mask_filter_s mask_filter[] = {
135122 + {QM_FQCTRL_PREFERINCACHE, 0},
135123 + {QM_FQCTRL_PREFERINCACHE, 1},
135124 + {QM_FQCTRL_HOLDACTIVE, 0},
135125 + {QM_FQCTRL_HOLDACTIVE, 1},
135126 + {QM_FQCTRL_AVOIDBLOCK, 0},
135127 + {QM_FQCTRL_AVOIDBLOCK, 1},
135128 + {QM_FQCTRL_FORCESFDR, 0},
135129 + {QM_FQCTRL_FORCESFDR, 1},
135130 + {QM_FQCTRL_CPCSTASH, 0},
135131 + {QM_FQCTRL_CPCSTASH, 1},
135132 + {QM_FQCTRL_CTXASTASHING, 0},
135133 + {QM_FQCTRL_CTXASTASHING, 1},
135134 + {QM_FQCTRL_ORP, 0},
135135 + {QM_FQCTRL_ORP, 1},
135136 + {QM_FQCTRL_TDE, 0},
135137 + {QM_FQCTRL_TDE, 1},
135138 + {QM_FQCTRL_CGE, 0},
135139 + {QM_FQCTRL_CGE, 1}
135140 +};
135141 +
135142 +static const struct mask_to_text fq_ctrl_text_list[] = {
135143 + {
135144 + .mask = QM_FQCTRL_PREFERINCACHE,
135145 + .txt = "Prefer in cache",
135146 + },
135147 + {
135148 + .mask = QM_FQCTRL_HOLDACTIVE,
135149 + .txt = "Hold active in portal",
135150 + },
135151 + {
135152 + .mask = QM_FQCTRL_AVOIDBLOCK,
135153 + .txt = "Avoid Blocking",
135154 + },
135155 + {
135156 + .mask = QM_FQCTRL_FORCESFDR,
135157 + .txt = "High-priority SFDRs",
135158 + },
135159 + {
135160 + .mask = QM_FQCTRL_CPCSTASH,
135161 + .txt = "CPC Stash Enable",
135162 + },
135163 + {
135164 + .mask = QM_FQCTRL_CTXASTASHING,
135165 + .txt = "Context-A stashing",
135166 + },
135167 + {
135168 + .mask = QM_FQCTRL_ORP,
135169 + .txt = "ORP Enable",
135170 + },
135171 + {
135172 + .mask = QM_FQCTRL_TDE,
135173 + .txt = "Tail-Drop Enable",
135174 + },
135175 + {
135176 + .mask = QM_FQCTRL_CGE,
135177 + .txt = "Congestion Group Enable",
135178 + },
135179 + {
135180 + .mask = 0,
135181 + .txt = NULL,
135182 + }
135183 +};
135184 +
135185 +static const char *get_fqd_ctrl_text(u16 mask)
135186 +{
135187 + int i = 0;
135188 +
135189 + while (fq_ctrl_text_list[i].txt != NULL) {
135190 + if (fq_ctrl_text_list[i].mask == mask)
135191 + return fq_ctrl_text_list[i].txt;
135192 + i++;
135193 + }
135194 + return NULL;
135195 +}
135196 +
135197 +static const struct mask_to_text stashing_text_list[] = {
135198 + {
135199 + .mask = QM_STASHING_EXCL_CTX,
135200 + .txt = "FQ Ctx Stash"
135201 + },
135202 + {
135203 + .mask = QM_STASHING_EXCL_DATA,
135204 + .txt = "Frame Data Stash",
135205 + },
135206 + {
135207 + .mask = QM_STASHING_EXCL_ANNOTATION,
135208 + .txt = "Frame Annotation Stash",
135209 + },
135210 + {
135211 + .mask = 0,
135212 + .txt = NULL,
135213 + },
135214 +};
135215 +
135216 +static int user_input_convert(const char __user *user_buf, size_t count,
135217 + unsigned long *val)
135218 +{
135219 + char buf[12];
135220 +
135221 + if (count > sizeof(buf) - 1)
135222 + return -EINVAL;
135223 + if (copy_from_user(buf, user_buf, count))
135224 + return -EFAULT;
135225 + buf[count] = '\0';
135226 + if (kstrtoul(buf, 0, val))
135227 + return -EINVAL;
135228 + return 0;
135229 +}
135230 +
135231 +struct line_buffer_fq {
135232 + u32 buf[8];
135233 + u32 buf_cnt;
135234 + int line_cnt;
135235 +};
135236 +
135237 +static void add_to_line_buffer(struct line_buffer_fq *line_buf, u32 fqid,
135238 + struct seq_file *file)
135239 +{
135240 + line_buf->buf[line_buf->buf_cnt] = fqid;
135241 + line_buf->buf_cnt++;
135242 + if (line_buf->buf_cnt == 8) {
135243 + /* Buffer is full, flush it */
135244 + if (line_buf->line_cnt != 0)
135245 + seq_puts(file, ",\n");
135246 + seq_printf(file, "0x%06x,0x%06x,0x%06x,0x%06x,0x%06x,"
135247 + "0x%06x,0x%06x,0x%06x",
135248 + line_buf->buf[0], line_buf->buf[1], line_buf->buf[2],
135249 + line_buf->buf[3], line_buf->buf[4], line_buf->buf[5],
135250 + line_buf->buf[6], line_buf->buf[7]);
135251 + line_buf->buf_cnt = 0;
135252 + line_buf->line_cnt++;
135253 + }
135254 +}
135255 +
135256 +static void flush_line_buffer(struct line_buffer_fq *line_buf,
135257 + struct seq_file *file)
135258 +{
135259 + if (line_buf->buf_cnt) {
135260 + int y = 0;
135261 + if (line_buf->line_cnt != 0)
135262 + seq_puts(file, ",\n");
135263 + while (y != line_buf->buf_cnt) {
135264 + if (y+1 == line_buf->buf_cnt)
135265 + seq_printf(file, "0x%06x", line_buf->buf[y]);
135266 + else
135267 + seq_printf(file, "0x%06x,", line_buf->buf[y]);
135268 + y++;
135269 + }
135270 + line_buf->line_cnt++;
135271 + }
135272 + if (line_buf->line_cnt)
135273 + seq_putc(file, '\n');
135274 +}
135275 +
135276 +static struct dentry *dfs_root; /* debugfs root directory */
135277 +
135278 +/*******************************************************************************
135279 + * Query Frame Queue Non Programmable Fields
135280 + ******************************************************************************/
135281 +struct query_fq_np_fields_data_s {
135282 + u32 fqid;
135283 +};
135284 +static struct query_fq_np_fields_data_s query_fq_np_fields_data = {
135285 + .fqid = 1,
135286 +};
135287 +
135288 +static int query_fq_np_fields_show(struct seq_file *file, void *offset)
135289 +{
135290 + int ret;
135291 + struct qm_mcr_queryfq_np np;
135292 + struct qman_fq fq;
135293 +
135294 + fq.fqid = query_fq_np_fields_data.fqid;
135295 + ret = qman_query_fq_np(&fq, &np);
135296 + if (ret)
135297 + return ret;
135298 + /* Print state */
135299 + seq_printf(file, "Query FQ Non Programmable Fields Result fqid 0x%x\n",
135300 + fq.fqid);
135301 + seq_printf(file, " force eligible pending: %s\n",
135302 + (np.state & QM_MCR_NP_STATE_FE) ? "yes" : "no");
135303 + seq_printf(file, " retirement pending: %s\n",
135304 + (np.state & QM_MCR_NP_STATE_R) ? "yes" : "no");
135305 + seq_printf(file, " state: %s\n",
135306 + state_txt[np.state & QM_MCR_NP_STATE_MASK]);
135307 + seq_printf(file, " fq_link: 0x%x\n", np.fqd_link);
135308 + seq_printf(file, " odp_seq: %u\n", np.odp_seq);
135309 + seq_printf(file, " orp_nesn: %u\n", np.orp_nesn);
135310 + seq_printf(file, " orp_ea_hseq: %u\n", np.orp_ea_hseq);
135311 + seq_printf(file, " orp_ea_tseq: %u\n", np.orp_ea_tseq);
135312 + seq_printf(file, " orp_ea_hptr: 0x%x\n", np.orp_ea_hptr);
135313 + seq_printf(file, " orp_ea_tptr: 0x%x\n", np.orp_ea_tptr);
135314 + seq_printf(file, " pfdr_hptr: 0x%x\n", np.pfdr_hptr);
135315 + seq_printf(file, " pfdr_tptr: 0x%x\n", np.pfdr_tptr);
135316 + seq_printf(file, " is: ics_surp contains a %s\n",
135317 + (np.is) ? "deficit" : "surplus");
135318 + seq_printf(file, " ics_surp: %u\n", np.ics_surp);
135319 + seq_printf(file, " byte_cnt: %u\n", np.byte_cnt);
135320 + seq_printf(file, " frm_cnt: %u\n", np.frm_cnt);
135321 + seq_printf(file, " ra1_sfdr: 0x%x\n", np.ra1_sfdr);
135322 + seq_printf(file, " ra2_sfdr: 0x%x\n", np.ra2_sfdr);
135323 + seq_printf(file, " od1_sfdr: 0x%x\n", np.od1_sfdr);
135324 + seq_printf(file, " od2_sfdr: 0x%x\n", np.od2_sfdr);
135325 + seq_printf(file, " od3_sfdr: 0x%x\n", np.od3_sfdr);
135326 + return 0;
135327 +}
135328 +
135329 +static int query_fq_np_fields_open(struct inode *inode,
135330 + struct file *file)
135331 +{
135332 + return single_open(file, query_fq_np_fields_show, NULL);
135333 +}
135334 +
135335 +static ssize_t query_fq_np_fields_write(struct file *f,
135336 + const char __user *buf, size_t count, loff_t *off)
135337 +{
135338 + int ret;
135339 + unsigned long val;
135340 +
135341 + ret = user_input_convert(buf, count, &val);
135342 + if (ret)
135343 + return ret;
135344 + if (val > MAX_FQID)
135345 + return -EINVAL;
135346 + query_fq_np_fields_data.fqid = (u32)val;
135347 + return count;
135348 +}
135349 +
135350 +static const struct file_operations query_fq_np_fields_fops = {
135351 + .owner = THIS_MODULE,
135352 + .open = query_fq_np_fields_open,
135353 + .read = seq_read,
135354 + .write = query_fq_np_fields_write,
135355 + .release = single_release,
135356 +};
135357 +
135358 +/*******************************************************************************
135359 + * Frame Queue Programmable Fields
135360 + ******************************************************************************/
135361 +struct query_fq_fields_data_s {
135362 + u32 fqid;
135363 +};
135364 +
135365 +static struct query_fq_fields_data_s query_fq_fields_data = {
135366 + .fqid = 1,
135367 +};
135368 +
135369 +static int query_fq_fields_show(struct seq_file *file, void *offset)
135370 +{
135371 + int ret;
135372 + struct qm_fqd fqd;
135373 + struct qman_fq fq;
135374 + int i = 0;
135375 +
135376 + memset(&fqd, 0, sizeof(struct qm_fqd));
135377 + fq.fqid = query_fq_fields_data.fqid;
135378 + ret = qman_query_fq(&fq, &fqd);
135379 + if (ret)
135380 + return ret;
135381 + seq_printf(file, "Query FQ Programmable Fields Result fqid 0x%x\n",
135382 + fq.fqid);
135383 + seq_printf(file, " orprws: %u\n", fqd.orprws);
135384 + seq_printf(file, " oa: %u\n", fqd.oa);
135385 + seq_printf(file, " olws: %u\n", fqd.olws);
135386 +
135387 + seq_printf(file, " cgid: %u\n", fqd.cgid);
135388 +
135389 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) == 0)
135390 + seq_puts(file, " fq_ctrl: None\n");
135391 + else {
135392 + i = 0;
135393 + seq_puts(file, " fq_ctrl:\n");
135394 + while (fq_ctrl_text_list[i].txt != NULL) {
135395 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
135396 + fq_ctrl_text_list[i].mask)
135397 + seq_printf(file, " %s\n",
135398 + fq_ctrl_text_list[i].txt);
135399 + i++;
135400 + }
135401 + }
135402 + seq_printf(file, " dest_channel: %u\n", fqd.dest.channel);
135403 + seq_printf(file, " dest_wq: %u\n", fqd.dest.wq);
135404 + seq_printf(file, " ics_cred: %u\n", fqd.ics_cred);
135405 + seq_printf(file, " td_mant: %u\n", fqd.td.mant);
135406 + seq_printf(file, " td_exp: %u\n", fqd.td.exp);
135407 +
135408 + seq_printf(file, " ctx_b: 0x%x\n", fqd.context_b);
135409 +
135410 + seq_printf(file, " ctx_a: 0x%llx\n", qm_fqd_stashing_get64(&fqd));
135411 + /* Any stashing configured */
135412 + if ((fqd.context_a.stashing.exclusive & 0x7) == 0)
135413 + seq_puts(file, " ctx_a_stash_exclusive: None\n");
135414 + else {
135415 + seq_puts(file, " ctx_a_stash_exclusive:\n");
135416 + i = 0;
135417 + while (stashing_text_list[i].txt != NULL) {
135418 + if ((fqd.fq_ctrl & 0x7) & stashing_text_list[i].mask)
135419 + seq_printf(file, " %s\n",
135420 + stashing_text_list[i].txt);
135421 + i++;
135422 + }
135423 + }
135424 + seq_printf(file, " ctx_a_stash_annotation_cl: %u\n",
135425 + fqd.context_a.stashing.annotation_cl);
135426 + seq_printf(file, " ctx_a_stash_data_cl: %u\n",
135427 + fqd.context_a.stashing.data_cl);
135428 + seq_printf(file, " ctx_a_stash_context_cl: %u\n",
135429 + fqd.context_a.stashing.context_cl);
135430 + return 0;
135431 +}
135432 +
135433 +static int query_fq_fields_open(struct inode *inode,
135434 + struct file *file)
135435 +{
135436 + return single_open(file, query_fq_fields_show, NULL);
135437 +}
135438 +
135439 +static ssize_t query_fq_fields_write(struct file *f,
135440 + const char __user *buf, size_t count, loff_t *off)
135441 +{
135442 + int ret;
135443 + unsigned long val;
135444 +
135445 + ret = user_input_convert(buf, count, &val);
135446 + if (ret)
135447 + return ret;
135448 + if (val > MAX_FQID)
135449 + return -EINVAL;
135450 + query_fq_fields_data.fqid = (u32)val;
135451 + return count;
135452 +}
135453 +
135454 +static const struct file_operations query_fq_fields_fops = {
135455 + .owner = THIS_MODULE,
135456 + .open = query_fq_fields_open,
135457 + .read = seq_read,
135458 + .write = query_fq_fields_write,
135459 + .release = single_release,
135460 +};
135461 +
135462 +/*******************************************************************************
135463 + * Query WQ lengths
135464 + ******************************************************************************/
135465 +struct query_wq_lengths_data_s {
135466 + union {
135467 + u16 channel_wq; /* ignores wq (3 lsbits) */
135468 + struct {
135469 + u16 id:13; /* qm_channel */
135470 + u16 __reserved:3;
135471 + } __packed channel;
135472 + };
135473 +};
135474 +static struct query_wq_lengths_data_s query_wq_lengths_data;
135475 +static int query_wq_lengths_show(struct seq_file *file, void *offset)
135476 +{
135477 + int ret;
135478 + struct qm_mcr_querywq wq;
135479 + int i;
135480 +
135481 + memset(&wq, 0, sizeof(struct qm_mcr_querywq));
135482 + wq.channel.id = query_wq_lengths_data.channel.id;
135483 + ret = qman_query_wq(0, &wq);
135484 + if (ret)
135485 + return ret;
135486 + seq_printf(file, "Query Result For Channel: 0x%x\n", wq.channel.id);
135487 + for (i = 0; i < 8; i++)
135488 + /* mask out upper 4 bits since they are not part of length */
135489 + seq_printf(file, " wq%d_len : %u\n", i, wq.wq_len[i] & 0x0fff);
135490 + return 0;
135491 +}
135492 +
135493 +static int query_wq_lengths_open(struct inode *inode,
135494 + struct file *file)
135495 +{
135496 + return single_open(file, query_wq_lengths_show, NULL);
135497 +}
135498 +
135499 +static ssize_t query_wq_lengths_write(struct file *f,
135500 + const char __user *buf, size_t count, loff_t *off)
135501 +{
135502 + int ret;
135503 + unsigned long val;
135504 +
135505 + ret = user_input_convert(buf, count, &val);
135506 + if (ret)
135507 + return ret;
135508 + if (val > 0xfff8)
135509 + return -EINVAL;
135510 + query_wq_lengths_data.channel.id = (u16)val;
135511 + return count;
135512 +}
135513 +
135514 +static const struct file_operations query_wq_lengths_fops = {
135515 + .owner = THIS_MODULE,
135516 + .open = query_wq_lengths_open,
135517 + .read = seq_read,
135518 + .write = query_wq_lengths_write,
135519 + .release = single_release,
135520 +};
135521 +
135522 +/*******************************************************************************
135523 + * Query CGR
135524 + ******************************************************************************/
135525 +struct query_cgr_s {
135526 + u8 cgid;
135527 +};
135528 +static struct query_cgr_s query_cgr_data;
135529 +
135530 +static int query_cgr_show(struct seq_file *file, void *offset)
135531 +{
135532 + int ret;
135533 + struct qm_mcr_querycgr cgrd;
135534 + struct qman_cgr cgr;
135535 + int i, j;
135536 + u32 mask;
135537 +
135538 + memset(&cgr, 0, sizeof(cgr));
135539 + memset(&cgrd, 0, sizeof(cgrd));
135540 + cgr.cgrid = query_cgr_data.cgid;
135541 + ret = qman_query_cgr(&cgr, &cgrd);
135542 + if (ret)
135543 + return ret;
135544 + seq_printf(file, "Query CGR id 0x%x\n", cgr.cgrid);
135545 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135546 + cgrd.cgr.wr_parm_g.MA, cgrd.cgr.wr_parm_g.Mn,
135547 + cgrd.cgr.wr_parm_g.SA, cgrd.cgr.wr_parm_g.Sn,
135548 + cgrd.cgr.wr_parm_g.Pn);
135549 +
135550 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135551 + cgrd.cgr.wr_parm_y.MA, cgrd.cgr.wr_parm_y.Mn,
135552 + cgrd.cgr.wr_parm_y.SA, cgrd.cgr.wr_parm_y.Sn,
135553 + cgrd.cgr.wr_parm_y.Pn);
135554 +
135555 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135556 + cgrd.cgr.wr_parm_r.MA, cgrd.cgr.wr_parm_r.Mn,
135557 + cgrd.cgr.wr_parm_r.SA, cgrd.cgr.wr_parm_r.Sn,
135558 + cgrd.cgr.wr_parm_r.Pn);
135559 +
135560 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
135561 + cgrd.cgr.wr_en_g, cgrd.cgr.wr_en_y, cgrd.cgr.wr_en_r);
135562 +
135563 + seq_printf(file, " cscn_en: %u\n", cgrd.cgr.cscn_en);
135564 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30) {
135565 + seq_puts(file, " cscn_targ_dcp:\n");
135566 + mask = 0x80000000;
135567 + for (i = 0; i < 32; i++) {
135568 + if (cgrd.cgr.cscn_targ & mask)
135569 + seq_printf(file, " send CSCN to dcp %u\n",
135570 + (31 - i));
135571 + mask >>= 1;
135572 + }
135573 +
135574 + seq_puts(file, " cscn_targ_swp:\n");
135575 + for (i = 0; i < 4; i++) {
135576 + mask = 0x80000000;
135577 + for (j = 0; j < 32; j++) {
135578 + if (cgrd.cscn_targ_swp[i] & mask)
135579 + seq_printf(file, " send CSCN to swp"
135580 + " %u\n", (127 - (i * 32) - j));
135581 + mask >>= 1;
135582 + }
135583 + }
135584 + } else {
135585 + seq_printf(file, " cscn_targ: %u\n", cgrd.cgr.cscn_targ);
135586 + }
135587 + seq_printf(file, " cstd_en: %u\n", cgrd.cgr.cstd_en);
135588 + seq_printf(file, " cs: %u\n", cgrd.cgr.cs);
135589 +
135590 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
135591 + cgrd.cgr.cs_thres.TA, cgrd.cgr.cs_thres.Tn);
135592 +
135593 + seq_printf(file, " mode: %s\n",
135594 + (cgrd.cgr.mode & QMAN_CGR_MODE_FRAME) ?
135595 + "frame count" : "byte count");
135596 + seq_printf(file, " i_bcnt: %llu\n", qm_mcr_querycgr_i_get64(&cgrd));
135597 + seq_printf(file, " a_bcnt: %llu\n", qm_mcr_querycgr_a_get64(&cgrd));
135598 +
135599 + return 0;
135600 +}
135601 +
135602 +static int query_cgr_open(struct inode *inode, struct file *file)
135603 +{
135604 + return single_open(file, query_cgr_show, NULL);
135605 +}
135606 +
135607 +static ssize_t query_cgr_write(struct file *f, const char __user *buf,
135608 + size_t count, loff_t *off)
135609 +{
135610 + int ret;
135611 + unsigned long val;
135612 +
135613 + ret = user_input_convert(buf, count, &val);
135614 + if (ret)
135615 + return ret;
135616 + if (val > 0xff)
135617 + return -EINVAL;
135618 + query_cgr_data.cgid = (u8)val;
135619 + return count;
135620 +}
135621 +
135622 +static const struct file_operations query_cgr_fops = {
135623 + .owner = THIS_MODULE,
135624 + .open = query_cgr_open,
135625 + .read = seq_read,
135626 + .write = query_cgr_write,
135627 + .release = single_release,
135628 +};
135629 +
135630 +/*******************************************************************************
135631 + * Test Write CGR
135632 + ******************************************************************************/
135633 +struct test_write_cgr_s {
135634 + u64 i_bcnt;
135635 + u8 cgid;
135636 +};
135637 +static struct test_write_cgr_s test_write_cgr_data;
135638 +
135639 +static int testwrite_cgr_show(struct seq_file *file, void *offset)
135640 +{
135641 + int ret;
135642 + struct qm_mcr_cgrtestwrite result;
135643 + struct qman_cgr cgr;
135644 + u64 i_bcnt;
135645 +
135646 + memset(&cgr, 0, sizeof(struct qman_cgr));
135647 + memset(&result, 0, sizeof(struct qm_mcr_cgrtestwrite));
135648 + cgr.cgrid = test_write_cgr_data.cgid;
135649 + i_bcnt = test_write_cgr_data.i_bcnt;
135650 + ret = qman_testwrite_cgr(&cgr, i_bcnt, &result);
135651 + if (ret)
135652 + return ret;
135653 + seq_printf(file, "CGR Test Write CGR id 0x%x\n", cgr.cgrid);
135654 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135655 + result.cgr.wr_parm_g.MA, result.cgr.wr_parm_g.Mn,
135656 + result.cgr.wr_parm_g.SA, result.cgr.wr_parm_g.Sn,
135657 + result.cgr.wr_parm_g.Pn);
135658 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135659 + result.cgr.wr_parm_y.MA, result.cgr.wr_parm_y.Mn,
135660 + result.cgr.wr_parm_y.SA, result.cgr.wr_parm_y.Sn,
135661 + result.cgr.wr_parm_y.Pn);
135662 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135663 + result.cgr.wr_parm_r.MA, result.cgr.wr_parm_r.Mn,
135664 + result.cgr.wr_parm_r.SA, result.cgr.wr_parm_r.Sn,
135665 + result.cgr.wr_parm_r.Pn);
135666 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
135667 + result.cgr.wr_en_g, result.cgr.wr_en_y, result.cgr.wr_en_r);
135668 + seq_printf(file, " cscn_en: %u\n", result.cgr.cscn_en);
135669 + seq_printf(file, " cscn_targ: %u\n", result.cgr.cscn_targ);
135670 + seq_printf(file, " cstd_en: %u\n", result.cgr.cstd_en);
135671 + seq_printf(file, " cs: %u\n", result.cgr.cs);
135672 + seq_printf(file, " cs_thresh_TA: %u, cs_thresh_Tn: %u\n",
135673 + result.cgr.cs_thres.TA, result.cgr.cs_thres.Tn);
135674 +
135675 + /* Add Mode for Si 2 */
135676 + seq_printf(file, " mode: %s\n",
135677 + (result.cgr.mode & QMAN_CGR_MODE_FRAME) ?
135678 + "frame count" : "byte count");
135679 +
135680 + seq_printf(file, " i_bcnt: %llu\n",
135681 + qm_mcr_cgrtestwrite_i_get64(&result));
135682 + seq_printf(file, " a_bcnt: %llu\n",
135683 + qm_mcr_cgrtestwrite_a_get64(&result));
135684 + seq_printf(file, " wr_prob_g: %u\n", result.wr_prob_g);
135685 + seq_printf(file, " wr_prob_y: %u\n", result.wr_prob_y);
135686 + seq_printf(file, " wr_prob_r: %u\n", result.wr_prob_r);
135687 + return 0;
135688 +}
135689 +
135690 +static int testwrite_cgr_open(struct inode *inode, struct file *file)
135691 +{
135692 + return single_open(file, testwrite_cgr_show, NULL);
135693 +}
135694 +
135695 +static const struct file_operations testwrite_cgr_fops = {
135696 + .owner = THIS_MODULE,
135697 + .open = testwrite_cgr_open,
135698 + .read = seq_read,
135699 + .release = single_release,
135700 +};
135701 +
135702 +
135703 +static int testwrite_cgr_ibcnt_show(struct seq_file *file, void *offset)
135704 +{
135705 + seq_printf(file, "i_bcnt: %llu\n", test_write_cgr_data.i_bcnt);
135706 + return 0;
135707 +}
135708 +static int testwrite_cgr_ibcnt_open(struct inode *inode, struct file *file)
135709 +{
135710 + return single_open(file, testwrite_cgr_ibcnt_show, NULL);
135711 +}
135712 +
135713 +static ssize_t testwrite_cgr_ibcnt_write(struct file *f, const char __user *buf,
135714 + size_t count, loff_t *off)
135715 +{
135716 + int ret;
135717 + unsigned long val;
135718 +
135719 + ret = user_input_convert(buf, count, &val);
135720 + if (ret)
135721 + return ret;
135722 + test_write_cgr_data.i_bcnt = val;
135723 + return count;
135724 +}
135725 +
135726 +static const struct file_operations teswrite_cgr_ibcnt_fops = {
135727 + .owner = THIS_MODULE,
135728 + .open = testwrite_cgr_ibcnt_open,
135729 + .read = seq_read,
135730 + .write = testwrite_cgr_ibcnt_write,
135731 + .release = single_release,
135732 +};
135733 +
135734 +static int testwrite_cgr_cgrid_show(struct seq_file *file, void *offset)
135735 +{
135736 + seq_printf(file, "cgrid: %u\n", (u32)test_write_cgr_data.cgid);
135737 + return 0;
135738 +}
135739 +static int testwrite_cgr_cgrid_open(struct inode *inode, struct file *file)
135740 +{
135741 + return single_open(file, testwrite_cgr_cgrid_show, NULL);
135742 +}
135743 +
135744 +static ssize_t testwrite_cgr_cgrid_write(struct file *f, const char __user *buf,
135745 + size_t count, loff_t *off)
135746 +{
135747 + int ret;
135748 + unsigned long val;
135749 +
135750 + ret = user_input_convert(buf, count, &val);
135751 + if (ret)
135752 + return ret;
135753 + if (val > 0xff)
135754 + return -EINVAL;
135755 + test_write_cgr_data.cgid = (u8)val;
135756 + return count;
135757 +}
135758 +
135759 +static const struct file_operations teswrite_cgr_cgrid_fops = {
135760 + .owner = THIS_MODULE,
135761 + .open = testwrite_cgr_cgrid_open,
135762 + .read = seq_read,
135763 + .write = testwrite_cgr_cgrid_write,
135764 + .release = single_release,
135765 +};
135766 +
135767 +/*******************************************************************************
135768 + * Query Congestion State
135769 + ******************************************************************************/
135770 +static int query_congestion_show(struct seq_file *file, void *offset)
135771 +{
135772 + int ret;
135773 + struct qm_mcr_querycongestion cs;
135774 + int i, j, in_cong = 0;
135775 + u32 mask;
135776 +
135777 + memset(&cs, 0, sizeof(struct qm_mcr_querycongestion));
135778 + ret = qman_query_congestion(&cs);
135779 + if (ret)
135780 + return ret;
135781 + seq_puts(file, "Query Congestion Result\n");
135782 + for (i = 0; i < 8; i++) {
135783 + mask = 0x80000000;
135784 + for (j = 0; j < 32; j++) {
135785 + if (cs.state.__state[i] & mask) {
135786 + in_cong = 1;
135787 + seq_printf(file, " cg %u: %s\n", (i*32)+j,
135788 + "in congestion");
135789 + }
135790 + mask >>= 1;
135791 + }
135792 + }
135793 + if (!in_cong)
135794 + seq_puts(file, " All congestion groups not congested.\n");
135795 + return 0;
135796 +}
135797 +
135798 +static int query_congestion_open(struct inode *inode, struct file *file)
135799 +{
135800 + return single_open(file, query_congestion_show, NULL);
135801 +}
135802 +
135803 +static const struct file_operations query_congestion_fops = {
135804 + .owner = THIS_MODULE,
135805 + .open = query_congestion_open,
135806 + .read = seq_read,
135807 + .release = single_release,
135808 +};
135809 +
135810 +/*******************************************************************************
135811 + * Query CCGR
135812 + ******************************************************************************/
135813 +struct query_ccgr_s {
135814 + u32 ccgid;
135815 +};
135816 +static struct query_ccgr_s query_ccgr_data;
135817 +
135818 +static int query_ccgr_show(struct seq_file *file, void *offset)
135819 +{
135820 + int ret;
135821 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
135822 + struct qm_mcc_ceetm_ccgr_query query_opts;
135823 + int i, j;
135824 + u32 mask;
135825 +
135826 + memset(&ccgr_query, 0, sizeof(struct qm_mcr_ceetm_ccgr_query));
135827 + memset(&query_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_query));
135828 +
135829 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
135830 + return -EINVAL;
135831 +
135832 + seq_printf(file, "Query CCGID %x\n", query_ccgr_data.ccgid);
135833 + query_opts.dcpid = ((query_ccgr_data.ccgid & 0xFF000000) >> 24);
135834 + query_opts.ccgrid = query_ccgr_data.ccgid & 0x000001FF;
135835 + ret = qman_ceetm_query_ccgr(&query_opts, &ccgr_query);
135836 + if (ret)
135837 + return ret;
135838 + seq_printf(file, "Query CCGR id %x in DCP %d\n", query_opts.ccgrid,
135839 + query_opts.dcpid);
135840 + seq_printf(file, " wr_parm_g MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135841 + ccgr_query.cm_query.wr_parm_g.MA,
135842 + ccgr_query.cm_query.wr_parm_g.Mn,
135843 + ccgr_query.cm_query.wr_parm_g.SA,
135844 + ccgr_query.cm_query.wr_parm_g.Sn,
135845 + ccgr_query.cm_query.wr_parm_g.Pn);
135846 +
135847 + seq_printf(file, " wr_parm_y MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135848 + ccgr_query.cm_query.wr_parm_y.MA,
135849 + ccgr_query.cm_query.wr_parm_y.Mn,
135850 + ccgr_query.cm_query.wr_parm_y.SA,
135851 + ccgr_query.cm_query.wr_parm_y.Sn,
135852 + ccgr_query.cm_query.wr_parm_y.Pn);
135853 +
135854 + seq_printf(file, " wr_parm_r MA: %u, Mn: %u, SA: %u, Sn: %u, Pn: %u\n",
135855 + ccgr_query.cm_query.wr_parm_r.MA,
135856 + ccgr_query.cm_query.wr_parm_r.Mn,
135857 + ccgr_query.cm_query.wr_parm_r.SA,
135858 + ccgr_query.cm_query.wr_parm_r.Sn,
135859 + ccgr_query.cm_query.wr_parm_r.Pn);
135860 +
135861 + seq_printf(file, " wr_en_g: %u, wr_en_y: %u, we_en_r: %u\n",
135862 + ccgr_query.cm_query.ctl_wr_en_g,
135863 + ccgr_query.cm_query.ctl_wr_en_y,
135864 + ccgr_query.cm_query.ctl_wr_en_r);
135865 +
135866 + seq_printf(file, " cscn_en: %u\n", ccgr_query.cm_query.ctl_cscn_en);
135867 + seq_puts(file, " cscn_targ_dcp:\n");
135868 + mask = 0x80000000;
135869 + for (i = 0; i < 32; i++) {
135870 + if (ccgr_query.cm_query.cscn_targ_dcp & mask)
135871 + seq_printf(file, " send CSCN to dcp %u\n", (31 - i));
135872 + mask >>= 1;
135873 + }
135874 +
135875 + seq_puts(file, " cscn_targ_swp:\n");
135876 + for (i = 0; i < 4; i++) {
135877 + mask = 0x80000000;
135878 + for (j = 0; j < 32; j++) {
135879 + if (ccgr_query.cm_query.cscn_targ_swp[i] & mask)
135880 + seq_printf(file, " send CSCN to swp"
135881 + "%u\n", (127 - (i * 32) - j));
135882 + mask >>= 1;
135883 + }
135884 + }
135885 +
135886 + seq_printf(file, " td_en: %u\n", ccgr_query.cm_query.ctl_td_en);
135887 +
135888 + seq_printf(file, " cs_thresh_in_TA: %u, cs_thresh_in_Tn: %u\n",
135889 + ccgr_query.cm_query.cs_thres.TA,
135890 + ccgr_query.cm_query.cs_thres.Tn);
135891 +
135892 + seq_printf(file, " cs_thresh_out_TA: %u, cs_thresh_out_Tn: %u\n",
135893 + ccgr_query.cm_query.cs_thres_x.TA,
135894 + ccgr_query.cm_query.cs_thres_x.Tn);
135895 +
135896 + seq_printf(file, " td_thresh_TA: %u, td_thresh_Tn: %u\n",
135897 + ccgr_query.cm_query.td_thres.TA,
135898 + ccgr_query.cm_query.td_thres.Tn);
135899 +
135900 + seq_printf(file, " mode: %s\n",
135901 + (ccgr_query.cm_query.ctl_mode &
135902 + QMAN_CGR_MODE_FRAME) ?
135903 + "frame count" : "byte count");
135904 + seq_printf(file, " i_cnt: %llu\n", (u64)ccgr_query.cm_query.i_cnt);
135905 + seq_printf(file, " a_cnt: %llu\n", (u64)ccgr_query.cm_query.a_cnt);
135906 +
135907 + return 0;
135908 +}
135909 +
135910 +static int query_ccgr_open(struct inode *inode, struct file *file)
135911 +{
135912 + return single_open(file, query_ccgr_show, NULL);
135913 +}
135914 +
135915 +static ssize_t query_ccgr_write(struct file *f, const char __user *buf,
135916 + size_t count, loff_t *off)
135917 +{
135918 + int ret;
135919 + unsigned long val;
135920 +
135921 + ret = user_input_convert(buf, count, &val);
135922 + if (ret)
135923 + return ret;
135924 + query_ccgr_data.ccgid = val;
135925 + return count;
135926 +}
135927 +
135928 +static const struct file_operations query_ccgr_fops = {
135929 + .owner = THIS_MODULE,
135930 + .open = query_ccgr_open,
135931 + .read = seq_read,
135932 + .write = query_ccgr_write,
135933 + .release = single_release,
135934 +};
135935 +/*******************************************************************************
135936 + * QMan register
135937 + ******************************************************************************/
135938 +struct qman_register_s {
135939 + u32 val;
135940 +};
135941 +static struct qman_register_s qman_register_data;
135942 +
135943 +static void init_ccsrmempeek(void)
135944 +{
135945 + struct device_node *dn;
135946 + const u32 *regaddr_p;
135947 +
135948 + dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
135949 + if (!dn) {
135950 + pr_info("No fsl,qman node\n");
135951 + return;
135952 + }
135953 + regaddr_p = of_get_address(dn, 0, &qman_ccsr_size, NULL);
135954 + if (!regaddr_p) {
135955 + of_node_put(dn);
135956 + return;
135957 + }
135958 + qman_ccsr_start = of_translate_address(dn, regaddr_p);
135959 + of_node_put(dn);
135960 +}
135961 +/* This function provides access to QMan ccsr memory map */
135962 +static int qman_ccsrmempeek(u32 *val, u32 offset)
135963 +{
135964 + void __iomem *addr;
135965 + u64 phys_addr;
135966 +
135967 + if (!qman_ccsr_start)
135968 + return -EINVAL;
135969 +
135970 + if (offset > (qman_ccsr_size - sizeof(u32)))
135971 + return -EINVAL;
135972 +
135973 + phys_addr = qman_ccsr_start + offset;
135974 + addr = ioremap(phys_addr, sizeof(u32));
135975 + if (!addr) {
135976 + pr_err("ccsrmempeek, ioremap failed\n");
135977 + return -EINVAL;
135978 + }
135979 + *val = in_be32(addr);
135980 + iounmap(addr);
135981 + return 0;
135982 +}
135983 +
135984 +static int qman_ccsrmempeek_show(struct seq_file *file, void *offset)
135985 +{
135986 + u32 b;
135987 +
135988 + qman_ccsrmempeek(&b, qman_register_data.val);
135989 + seq_printf(file, "QMan register offset = 0x%x\n",
135990 + qman_register_data.val);
135991 + seq_printf(file, "value = 0x%08x\n", b);
135992 +
135993 + return 0;
135994 +}
135995 +
135996 +static int qman_ccsrmempeek_open(struct inode *inode, struct file *file)
135997 +{
135998 + return single_open(file, qman_ccsrmempeek_show, NULL);
135999 +}
136000 +
136001 +static ssize_t qman_ccsrmempeek_write(struct file *f, const char __user *buf,
136002 + size_t count, loff_t *off)
136003 +{
136004 + int ret;
136005 + unsigned long val;
136006 +
136007 + ret = user_input_convert(buf, count, &val);
136008 + if (ret)
136009 + return ret;
136010 + /* multiple of 4 */
136011 + if (val > (qman_ccsr_size - sizeof(u32))) {
136012 + pr_info("Input 0x%lx > 0x%llx\n",
136013 + val, (qman_ccsr_size - sizeof(u32)));
136014 + return -EINVAL;
136015 + }
136016 + if (val & 0x3) {
136017 + pr_info("Input 0x%lx not multiple of 4\n", val);
136018 + return -EINVAL;
136019 + }
136020 + qman_register_data.val = val;
136021 + return count;
136022 +}
136023 +
136024 +static const struct file_operations qman_ccsrmempeek_fops = {
136025 + .owner = THIS_MODULE,
136026 + .open = qman_ccsrmempeek_open,
136027 + .read = seq_read,
136028 + .write = qman_ccsrmempeek_write,
136029 +};
136030 +
136031 +/*******************************************************************************
136032 + * QMan state
136033 + ******************************************************************************/
136034 +static int qman_fqd_state_show(struct seq_file *file, void *offset)
136035 +{
136036 + struct qm_mcr_queryfq_np np;
136037 + struct qman_fq fq;
136038 + struct line_buffer_fq line_buf;
136039 + int ret, i;
136040 + u8 *state = file->private;
136041 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
136042 +
136043 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
136044 + memset(&line_buf, 0, sizeof(line_buf));
136045 +
136046 + seq_printf(file, "List of fq ids in state: %s\n", state_txt[*state]);
136047 +
136048 + for (i = 1; i < fqid_max; i++) {
136049 + fq.fqid = i;
136050 + ret = qman_query_fq_np(&fq, &np);
136051 + if (ret)
136052 + return ret;
136053 + if (*state == (np.state & QM_MCR_NP_STATE_MASK))
136054 + add_to_line_buffer(&line_buf, fq.fqid, file);
136055 + /* Keep a summary count of all states */
136056 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
136057 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
136058 + }
136059 + flush_line_buffer(&line_buf, file);
136060 +
136061 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
136062 + seq_printf(file, "%s count = %u\n", state_txt[i],
136063 + qm_fq_state_cnt[i]);
136064 + }
136065 + return 0;
136066 +}
136067 +
136068 +static int qman_fqd_state_open(struct inode *inode, struct file *file)
136069 +{
136070 + return single_open(file, qman_fqd_state_show, inode->i_private);
136071 +}
136072 +
136073 +static const struct file_operations qman_fqd_state_fops = {
136074 + .owner = THIS_MODULE,
136075 + .open = qman_fqd_state_open,
136076 + .read = seq_read,
136077 +};
136078 +
136079 +static int qman_fqd_ctrl_show(struct seq_file *file, void *offset)
136080 +{
136081 + struct qm_fqd fqd;
136082 + struct qman_fq fq;
136083 + u32 fq_en_cnt = 0, fq_di_cnt = 0;
136084 + int ret, i;
136085 + struct mask_filter_s *data = file->private;
136086 + const char *ctrl_txt = get_fqd_ctrl_text(data->mask);
136087 + struct line_buffer_fq line_buf;
136088 +
136089 + memset(&line_buf, 0, sizeof(line_buf));
136090 + seq_printf(file, "List of fq ids with: %s :%s\n",
136091 + ctrl_txt, (data->filter) ? "enabled" : "disabled");
136092 + for (i = 1; i < fqid_max; i++) {
136093 + fq.fqid = i;
136094 + memset(&fqd, 0, sizeof(struct qm_fqd));
136095 + ret = qman_query_fq(&fq, &fqd);
136096 + if (ret)
136097 + return ret;
136098 + if (data->filter) {
136099 + if (fqd.fq_ctrl & data->mask)
136100 + add_to_line_buffer(&line_buf, fq.fqid, file);
136101 + } else {
136102 + if (!(fqd.fq_ctrl & data->mask))
136103 + add_to_line_buffer(&line_buf, fq.fqid, file);
136104 + }
136105 + if (fqd.fq_ctrl & data->mask)
136106 + fq_en_cnt++;
136107 + else
136108 + fq_di_cnt++;
136109 + }
136110 + flush_line_buffer(&line_buf, file);
136111 +
136112 + seq_printf(file, "Total FQD with: %s : enabled = %u\n",
136113 + ctrl_txt, fq_en_cnt);
136114 + seq_printf(file, "Total FQD with: %s : disabled = %u\n",
136115 + ctrl_txt, fq_di_cnt);
136116 + return 0;
136117 +}
136118 +
136119 +/*******************************************************************************
136120 + * QMan ctrl CGE, TDE, ORP, CTX, CPC, SFDR, BLOCK, HOLD, CACHE
136121 + ******************************************************************************/
136122 +static int qman_fqd_ctrl_open(struct inode *inode, struct file *file)
136123 +{
136124 + return single_open(file, qman_fqd_ctrl_show, inode->i_private);
136125 +}
136126 +
136127 +static const struct file_operations qman_fqd_ctrl_fops = {
136128 + .owner = THIS_MODULE,
136129 + .open = qman_fqd_ctrl_open,
136130 + .read = seq_read,
136131 +};
136132 +
136133 +/*******************************************************************************
136134 + * QMan ctrl summary
136135 + ******************************************************************************/
136136 +/*******************************************************************************
136137 + * QMan summary state
136138 + ******************************************************************************/
136139 +static int qman_fqd_non_prog_summary_show(struct seq_file *file, void *offset)
136140 +{
136141 + struct qm_mcr_queryfq_np np;
136142 + struct qman_fq fq;
136143 + int ret, i;
136144 + u32 qm_fq_state_cnt[ARRAY_SIZE(fqd_states)];
136145 +
136146 + memset(qm_fq_state_cnt, 0, sizeof(qm_fq_state_cnt));
136147 +
136148 + for (i = 1; i < fqid_max; i++) {
136149 + fq.fqid = i;
136150 + ret = qman_query_fq_np(&fq, &np);
136151 + if (ret)
136152 + return ret;
136153 + /* Keep a summary count of all states */
136154 + if ((np.state & QM_MCR_NP_STATE_MASK) < ARRAY_SIZE(fqd_states))
136155 + qm_fq_state_cnt[(np.state & QM_MCR_NP_STATE_MASK)]++;
136156 + }
136157 +
136158 + for (i = 0; i < ARRAY_SIZE(fqd_states); i++) {
136159 + seq_printf(file, "%s count = %u\n", state_txt[i],
136160 + qm_fq_state_cnt[i]);
136161 + }
136162 + return 0;
136163 +}
136164 +
136165 +static int qman_fqd_prog_summary_show(struct seq_file *file, void *offset)
136166 +{
136167 + struct qm_fqd fqd;
136168 + struct qman_fq fq;
136169 + int ret, i , j;
136170 + u32 qm_prog_cnt[ARRAY_SIZE(mask_filter)/2];
136171 +
136172 + memset(qm_prog_cnt, 0, sizeof(qm_prog_cnt));
136173 +
136174 + for (i = 1; i < fqid_max; i++) {
136175 + memset(&fqd, 0, sizeof(struct qm_fqd));
136176 + fq.fqid = i;
136177 + ret = qman_query_fq(&fq, &fqd);
136178 + if (ret)
136179 + return ret;
136180 + /* Keep a summary count of all states */
136181 + for (j = 0; j < ARRAY_SIZE(mask_filter); j += 2)
136182 + if ((fqd.fq_ctrl & QM_FQCTRL_MASK) &
136183 + mask_filter[j].mask)
136184 + qm_prog_cnt[j/2]++;
136185 + }
136186 + for (i = 0; i < ARRAY_SIZE(mask_filter) / 2; i++) {
136187 + seq_printf(file, "%s count = %u\n",
136188 + get_fqd_ctrl_text(mask_filter[i*2].mask),
136189 + qm_prog_cnt[i]);
136190 + }
136191 + return 0;
136192 +}
136193 +
136194 +static int qman_fqd_summary_show(struct seq_file *file, void *offset)
136195 +{
136196 + int ret;
136197 +
136198 + /* Display summary of non programmable fields */
136199 + ret = qman_fqd_non_prog_summary_show(file, offset);
136200 + if (ret)
136201 + return ret;
136202 + seq_puts(file, "-----------------------------------------\n");
136203 + /* Display programmable fields */
136204 + ret = qman_fqd_prog_summary_show(file, offset);
136205 + if (ret)
136206 + return ret;
136207 + return 0;
136208 +}
136209 +
136210 +static int qman_fqd_summary_open(struct inode *inode, struct file *file)
136211 +{
136212 + return single_open(file, qman_fqd_summary_show, NULL);
136213 +}
136214 +
136215 +static const struct file_operations qman_fqd_summary_fops = {
136216 + .owner = THIS_MODULE,
136217 + .open = qman_fqd_summary_open,
136218 + .read = seq_read,
136219 +};
136220 +
136221 +/*******************************************************************************
136222 + * QMan destination work queue
136223 + ******************************************************************************/
136224 +struct qman_dest_wq_s {
136225 + u16 wq_id;
136226 +};
136227 +static struct qman_dest_wq_s qman_dest_wq_data = {
136228 + .wq_id = 0,
136229 +};
136230 +
136231 +static int qman_fqd_dest_wq_show(struct seq_file *file, void *offset)
136232 +{
136233 + struct qm_fqd fqd;
136234 + struct qman_fq fq;
136235 + int ret, i;
136236 + u16 *wq, wq_id = qman_dest_wq_data.wq_id;
136237 + struct line_buffer_fq line_buf;
136238 +
136239 + memset(&line_buf, 0, sizeof(line_buf));
136240 + /* use vmalloc : need to allocate large memory region and don't
136241 + * require the memory to be physically contiguous. */
136242 + wq = vzalloc(sizeof(u16) * (0xFFFF+1));
136243 + if (!wq)
136244 + return -ENOMEM;
136245 +
136246 + seq_printf(file, "List of fq ids with destination work queue id"
136247 + " = 0x%x\n", wq_id);
136248 +
136249 + for (i = 1; i < fqid_max; i++) {
136250 + fq.fqid = i;
136251 + memset(&fqd, 0, sizeof(struct qm_fqd));
136252 + ret = qman_query_fq(&fq, &fqd);
136253 + if (ret) {
136254 + vfree(wq);
136255 + return ret;
136256 + }
136257 + if (wq_id == fqd.dest_wq)
136258 + add_to_line_buffer(&line_buf, fq.fqid, file);
136259 + wq[fqd.dest_wq]++;
136260 + }
136261 + flush_line_buffer(&line_buf, file);
136262 +
136263 + seq_puts(file, "Summary of all FQD destination work queue values\n");
136264 + for (i = 0; i < 0xFFFF; i++) {
136265 + if (wq[i])
136266 + seq_printf(file, "Channel: 0x%x WQ: 0x%x WQ_ID: 0x%x, "
136267 + "count = %u\n", i >> 3, i & 0x3, i, wq[i]);
136268 + }
136269 + vfree(wq);
136270 + return 0;
136271 +}
136272 +
136273 +static ssize_t qman_fqd_dest_wq_write(struct file *f, const char __user *buf,
136274 + size_t count, loff_t *off)
136275 +{
136276 + int ret;
136277 + unsigned long val;
136278 +
136279 + ret = user_input_convert(buf, count, &val);
136280 + if (ret)
136281 + return ret;
136282 + if (val > 0xFFFF)
136283 + return -EINVAL;
136284 + qman_dest_wq_data.wq_id = val;
136285 + return count;
136286 +}
136287 +
136288 +static int qman_fqd_dest_wq_open(struct inode *inode, struct file *file)
136289 +{
136290 + return single_open(file, qman_fqd_dest_wq_show, NULL);
136291 +}
136292 +
136293 +static const struct file_operations qman_fqd_dest_wq_fops = {
136294 + .owner = THIS_MODULE,
136295 + .open = qman_fqd_dest_wq_open,
136296 + .read = seq_read,
136297 + .write = qman_fqd_dest_wq_write,
136298 +};
136299 +
136300 +/*******************************************************************************
136301 + * QMan Intra-Class Scheduling Credit
136302 + ******************************************************************************/
136303 +static int qman_fqd_cred_show(struct seq_file *file, void *offset)
136304 +{
136305 + struct qm_fqd fqd;
136306 + struct qman_fq fq;
136307 + int ret, i;
136308 + u32 fq_cnt = 0;
136309 + struct line_buffer_fq line_buf;
136310 +
136311 + memset(&line_buf, 0, sizeof(line_buf));
136312 + seq_puts(file, "List of fq ids with Intra-Class Scheduling Credit > 0"
136313 + "\n");
136314 +
136315 + for (i = 1; i < fqid_max; i++) {
136316 + fq.fqid = i;
136317 + memset(&fqd, 0, sizeof(struct qm_fqd));
136318 + ret = qman_query_fq(&fq, &fqd);
136319 + if (ret)
136320 + return ret;
136321 + if (fqd.ics_cred > 0) {
136322 + add_to_line_buffer(&line_buf, fq.fqid, file);
136323 + fq_cnt++;
136324 + }
136325 + }
136326 + flush_line_buffer(&line_buf, file);
136327 +
136328 + seq_printf(file, "Total FQD with ics_cred > 0 = %d\n", fq_cnt);
136329 + return 0;
136330 +}
136331 +
136332 +static int qman_fqd_cred_open(struct inode *inode, struct file *file)
136333 +{
136334 + return single_open(file, qman_fqd_cred_show, NULL);
136335 +}
136336 +
136337 +static const struct file_operations qman_fqd_cred_fops = {
136338 + .owner = THIS_MODULE,
136339 + .open = qman_fqd_cred_open,
136340 + .read = seq_read,
136341 +};
136342 +
136343 +/*******************************************************************************
136344 + * Class Queue Fields
136345 + ******************************************************************************/
136346 +struct query_cq_fields_data_s {
136347 + u32 cqid;
136348 +};
136349 +
136350 +static struct query_cq_fields_data_s query_cq_fields_data = {
136351 + .cqid = 1,
136352 +};
136353 +
136354 +static int query_cq_fields_show(struct seq_file *file, void *offset)
136355 +{
136356 + int ret;
136357 + struct qm_mcr_ceetm_cq_query query_result;
136358 + unsigned int cqid;
136359 + unsigned int portal;
136360 +
136361 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30)
136362 + return -EINVAL;
136363 +
136364 + cqid = query_cq_fields_data.cqid & 0x00FFFFFF;
136365 + portal = query_cq_fields_data.cqid >> 24;
136366 + if (portal > qm_dc_portal_fman1)
136367 + return -EINVAL;
136368 +
136369 + ret = qman_ceetm_query_cq(cqid, portal, &query_result);
136370 + if (ret)
136371 + return ret;
136372 + seq_printf(file, "Query CQ Fields Result cqid 0x%x on DCP %d\n",
136373 + cqid, portal);
136374 + seq_printf(file, " ccgid: %u\n", query_result.ccgid);
136375 + seq_printf(file, " state: %u\n", query_result.state);
136376 + seq_printf(file, " pfdr_hptr: %u\n", query_result.pfdr_hptr);
136377 + seq_printf(file, " pfdr_tptr: %u\n", query_result.pfdr_tptr);
136378 + seq_printf(file, " od1_xsfdr: %u\n", query_result.od1_xsfdr);
136379 + seq_printf(file, " od2_xsfdr: %u\n", query_result.od2_xsfdr);
136380 + seq_printf(file, " od3_xsfdr: %u\n", query_result.od3_xsfdr);
136381 + seq_printf(file, " od4_xsfdr: %u\n", query_result.od4_xsfdr);
136382 + seq_printf(file, " od5_xsfdr: %u\n", query_result.od5_xsfdr);
136383 + seq_printf(file, " od6_xsfdr: %u\n", query_result.od6_xsfdr);
136384 + seq_printf(file, " ra1_xsfdr: %u\n", query_result.ra1_xsfdr);
136385 + seq_printf(file, " ra2_xsfdr: %u\n", query_result.ra2_xsfdr);
136386 + seq_printf(file, " frame_count: %u\n", query_result.frm_cnt);
136387 +
136388 + return 0;
136389 +}
136390 +
136391 +static int query_cq_fields_open(struct inode *inode,
136392 + struct file *file)
136393 +{
136394 + return single_open(file, query_cq_fields_show, NULL);
136395 +}
136396 +
136397 +static ssize_t query_cq_fields_write(struct file *f,
136398 + const char __user *buf, size_t count, loff_t *off)
136399 +{
136400 + int ret;
136401 + unsigned long val;
136402 +
136403 + ret = user_input_convert(buf, count, &val);
136404 + if (ret)
136405 + return ret;
136406 + query_cq_fields_data.cqid = (u32)val;
136407 + return count;
136408 +}
136409 +
136410 +static const struct file_operations query_cq_fields_fops = {
136411 + .owner = THIS_MODULE,
136412 + .open = query_cq_fields_open,
136413 + .read = seq_read,
136414 + .write = query_cq_fields_write,
136415 + .release = single_release,
136416 +};
136417 +
136418 +/*******************************************************************************
136419 + * READ CEETM_XSFDR_IN_USE
136420 + ******************************************************************************/
136421 +struct query_ceetm_xsfdr_data_s {
136422 + enum qm_dc_portal dcp_portal;
136423 +};
136424 +
136425 +static struct query_ceetm_xsfdr_data_s query_ceetm_xsfdr_data;
136426 +
136427 +static int query_ceetm_xsfdr_show(struct seq_file *file, void *offset)
136428 +{
136429 + int ret;
136430 + unsigned int xsfdr_in_use;
136431 + enum qm_dc_portal portal;
136432 +
136433 +
136434 + if (qman_ip_rev < QMAN_REV31)
136435 + return -EINVAL;
136436 +
136437 + portal = query_ceetm_xsfdr_data.dcp_portal;
136438 + ret = qman_ceetm_get_xsfdr(portal, &xsfdr_in_use);
136439 + if (ret) {
136440 + seq_printf(file, "Read CEETM_XSFDR_IN_USE on DCP %d failed\n",
136441 + portal);
136442 + return ret;
136443 + }
136444 +
136445 + seq_printf(file, "DCP%d: CEETM_XSFDR_IN_USE number is %u\n", portal,
136446 + (xsfdr_in_use & 0x1FFF));
136447 + return 0;
136448 +}
136449 +
136450 +static int query_ceetm_xsfdr_open(struct inode *inode,
136451 + struct file *file)
136452 +{
136453 + return single_open(file, query_ceetm_xsfdr_show, NULL);
136454 +}
136455 +
136456 +static ssize_t query_ceetm_xsfdr_write(struct file *f,
136457 + const char __user *buf, size_t count, loff_t *off)
136458 +{
136459 + int ret;
136460 + unsigned long val;
136461 +
136462 + ret = user_input_convert(buf, count, &val);
136463 + if (ret)
136464 + return ret;
136465 + if (val > qm_dc_portal_fman1)
136466 + return -EINVAL;
136467 + query_ceetm_xsfdr_data.dcp_portal = (u32)val;
136468 + return count;
136469 +}
136470 +
136471 +static const struct file_operations query_ceetm_xsfdr_fops = {
136472 + .owner = THIS_MODULE,
136473 + .open = query_ceetm_xsfdr_open,
136474 + .read = seq_read,
136475 + .write = query_ceetm_xsfdr_write,
136476 + .release = single_release,
136477 +};
136478 +
136479 +/* helper macros used in qman_debugfs_module_init */
136480 +#define QMAN_DBGFS_ENTRY(name, mode, parent, data, fops) \
136481 + do { \
136482 + d = debugfs_create_file(name, \
136483 + mode, parent, \
136484 + data, \
136485 + fops); \
136486 + if (d == NULL) { \
136487 + ret = -ENOMEM; \
136488 + goto _return; \
136489 + } \
136490 + } while (0)
136491 +
136492 +/* dfs_root as parent */
136493 +#define QMAN_DBGFS_ENTRY_ROOT(name, mode, data, fops) \
136494 + QMAN_DBGFS_ENTRY(name, mode, dfs_root, data, fops)
136495 +
136496 +/* fqd_root as parent */
136497 +#define QMAN_DBGFS_ENTRY_FQDROOT(name, mode, data, fops) \
136498 + QMAN_DBGFS_ENTRY(name, mode, fqd_root, data, fops)
136499 +
136500 +/* fqd state */
136501 +#define QMAN_DBGFS_ENTRY_FQDSTATE(name, index) \
136502 + QMAN_DBGFS_ENTRY_FQDROOT(name, S_IRUGO, \
136503 + (void *)&mask_filter[index], &qman_fqd_ctrl_fops)
136504 +
136505 +static int __init qman_debugfs_module_init(void)
136506 +{
136507 + int ret = 0;
136508 + struct dentry *d, *fqd_root;
136509 + u32 reg;
136510 +
136511 + fqid_max = 0;
136512 + init_ccsrmempeek();
136513 + if (qman_ccsr_start) {
136514 + if (!qman_ccsrmempeek(&reg, QM_FQD_AR)) {
136515 + /* extract the size of the FQD window */
136516 + reg = reg & 0x3f;
136517 + /* calculate valid frame queue descriptor range */
136518 + fqid_max = (1 << (reg + 1)) / QM_FQD_BLOCK_SIZE;
136519 + }
136520 + }
136521 + dfs_root = debugfs_create_dir("qman", NULL);
136522 + fqd_root = debugfs_create_dir("fqd", dfs_root);
136523 + if (dfs_root == NULL || fqd_root == NULL) {
136524 + ret = -ENOMEM;
136525 + pr_err("Cannot create qman/fqd debugfs dir\n");
136526 + goto _return;
136527 + }
136528 + if (fqid_max) {
136529 + QMAN_DBGFS_ENTRY_ROOT("ccsrmempeek", S_IRUGO | S_IWUGO,
136530 + NULL, &qman_ccsrmempeek_fops);
136531 + }
136532 + QMAN_DBGFS_ENTRY_ROOT("query_fq_np_fields", S_IRUGO | S_IWUGO,
136533 + &query_fq_np_fields_data, &query_fq_np_fields_fops);
136534 +
136535 + QMAN_DBGFS_ENTRY_ROOT("query_fq_fields", S_IRUGO | S_IWUGO,
136536 + &query_fq_fields_data, &query_fq_fields_fops);
136537 +
136538 + QMAN_DBGFS_ENTRY_ROOT("query_wq_lengths", S_IRUGO | S_IWUGO,
136539 + &query_wq_lengths_data, &query_wq_lengths_fops);
136540 +
136541 + QMAN_DBGFS_ENTRY_ROOT("query_cgr", S_IRUGO | S_IWUGO,
136542 + &query_cgr_data, &query_cgr_fops);
136543 +
136544 + QMAN_DBGFS_ENTRY_ROOT("query_congestion", S_IRUGO,
136545 + NULL, &query_congestion_fops);
136546 +
136547 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr", S_IRUGO,
136548 + NULL, &testwrite_cgr_fops);
136549 +
136550 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_cgrid", S_IRUGO | S_IWUGO,
136551 + NULL, &teswrite_cgr_cgrid_fops);
136552 +
136553 + QMAN_DBGFS_ENTRY_ROOT("testwrite_cgr_ibcnt", S_IRUGO | S_IWUGO,
136554 + NULL, &teswrite_cgr_ibcnt_fops);
136555 +
136556 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_ccgr", S_IRUGO | S_IWUGO,
136557 + &query_ccgr_data, &query_ccgr_fops);
136558 + /* Create files with fqd_root as parent */
136559 +
136560 + QMAN_DBGFS_ENTRY_FQDROOT("stateoos", S_IRUGO,
136561 + (void *)&fqd_states[QM_MCR_NP_STATE_OOS], &qman_fqd_state_fops);
136562 +
136563 + QMAN_DBGFS_ENTRY_FQDROOT("state_retired", S_IRUGO,
136564 + (void *)&fqd_states[QM_MCR_NP_STATE_RETIRED],
136565 + &qman_fqd_state_fops);
136566 +
136567 + QMAN_DBGFS_ENTRY_FQDROOT("state_tentatively_sched", S_IRUGO,
136568 + (void *)&fqd_states[QM_MCR_NP_STATE_TEN_SCHED],
136569 + &qman_fqd_state_fops);
136570 +
136571 + QMAN_DBGFS_ENTRY_FQDROOT("state_truly_sched", S_IRUGO,
136572 + (void *)&fqd_states[QM_MCR_NP_STATE_TRU_SCHED],
136573 + &qman_fqd_state_fops);
136574 +
136575 + QMAN_DBGFS_ENTRY_FQDROOT("state_parked", S_IRUGO,
136576 + (void *)&fqd_states[QM_MCR_NP_STATE_PARKED],
136577 + &qman_fqd_state_fops);
136578 +
136579 + QMAN_DBGFS_ENTRY_FQDROOT("state_active", S_IRUGO,
136580 + (void *)&fqd_states[QM_MCR_NP_STATE_ACTIVE],
136581 + &qman_fqd_state_fops);
136582 + QMAN_DBGFS_ENTRY_ROOT("query_cq_fields", S_IRUGO | S_IWUGO,
136583 + &query_cq_fields_data, &query_cq_fields_fops);
136584 + QMAN_DBGFS_ENTRY_ROOT("query_ceetm_xsfdr_in_use", S_IRUGO | S_IWUGO,
136585 + &query_ceetm_xsfdr_data, &query_ceetm_xsfdr_fops);
136586 +
136587 +
136588 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_enable", 17);
136589 +
136590 + QMAN_DBGFS_ENTRY_FQDSTATE("cge_disable", 16);
136591 +
136592 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_enable", 15);
136593 +
136594 + QMAN_DBGFS_ENTRY_FQDSTATE("tde_disable", 14);
136595 +
136596 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_enable", 13);
136597 +
136598 + QMAN_DBGFS_ENTRY_FQDSTATE("orp_disable", 12);
136599 +
136600 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_enable", 11);
136601 +
136602 + QMAN_DBGFS_ENTRY_FQDSTATE("ctx_a_stashing_disable", 10);
136603 +
136604 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_enable", 9);
136605 +
136606 + QMAN_DBGFS_ENTRY_FQDSTATE("cpc_disable", 8);
136607 +
136608 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_enable", 7);
136609 +
136610 + QMAN_DBGFS_ENTRY_FQDSTATE("sfdr_disable", 6);
136611 +
136612 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_enable", 5);
136613 +
136614 + QMAN_DBGFS_ENTRY_FQDSTATE("avoid_blocking_disable", 4);
136615 +
136616 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_enable", 3);
136617 +
136618 + QMAN_DBGFS_ENTRY_FQDSTATE("hold_active_disable", 2);
136619 +
136620 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_enable", 1);
136621 +
136622 + QMAN_DBGFS_ENTRY_FQDSTATE("prefer_in_cache_disable", 0);
136623 +
136624 + QMAN_DBGFS_ENTRY_FQDROOT("summary", S_IRUGO,
136625 + NULL, &qman_fqd_summary_fops);
136626 +
136627 + QMAN_DBGFS_ENTRY_FQDROOT("wq", S_IRUGO | S_IWUGO,
136628 + NULL, &qman_fqd_dest_wq_fops);
136629 +
136630 + QMAN_DBGFS_ENTRY_FQDROOT("cred", S_IRUGO,
136631 + NULL, &qman_fqd_cred_fops);
136632 +
136633 + return 0;
136634 +
136635 +_return:
136636 + debugfs_remove_recursive(dfs_root);
136637 + return ret;
136638 +}
136639 +
136640 +static void __exit qman_debugfs_module_exit(void)
136641 +{
136642 + debugfs_remove_recursive(dfs_root);
136643 +}
136644 +
136645 +module_init(qman_debugfs_module_init);
136646 +module_exit(qman_debugfs_module_exit);
136647 +MODULE_LICENSE("Dual BSD/GPL");
136648 --- /dev/null
136649 +++ b/drivers/staging/fsl_qbman/qman_driver.c
136650 @@ -0,0 +1,961 @@
136651 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
136652 + *
136653 + * Redistribution and use in source and binary forms, with or without
136654 + * modification, are permitted provided that the following conditions are met:
136655 + * * Redistributions of source code must retain the above copyright
136656 + * notice, this list of conditions and the following disclaimer.
136657 + * * Redistributions in binary form must reproduce the above copyright
136658 + * notice, this list of conditions and the following disclaimer in the
136659 + * documentation and/or other materials provided with the distribution.
136660 + * * Neither the name of Freescale Semiconductor nor the
136661 + * names of its contributors may be used to endorse or promote products
136662 + * derived from this software without specific prior written permission.
136663 + *
136664 + *
136665 + * ALTERNATIVELY, this software may be distributed under the terms of the
136666 + * GNU General Public License ("GPL") as published by the Free Software
136667 + * Foundation, either version 2 of that License or (at your option) any
136668 + * later version.
136669 + *
136670 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
136671 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
136672 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
136673 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
136674 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
136675 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
136676 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
136677 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
136678 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
136679 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
136680 + */
136681 +
136682 +#include "qman_private.h"
136683 +
136684 +#include <asm/smp.h> /* hard_smp_processor_id() if !CONFIG_SMP */
136685 +#ifdef CONFIG_HOTPLUG_CPU
136686 +#include <linux/cpu.h>
136687 +#endif
136688 +
136689 +/* Global variable containing revision id (even on non-control plane systems
136690 + * where CCSR isn't available) */
136691 +u16 qman_ip_rev;
136692 +EXPORT_SYMBOL(qman_ip_rev);
136693 +u8 qman_ip_cfg;
136694 +EXPORT_SYMBOL(qman_ip_cfg);
136695 +u16 qm_channel_pool1 = QMAN_CHANNEL_POOL1;
136696 +EXPORT_SYMBOL(qm_channel_pool1);
136697 +u16 qm_channel_caam = QMAN_CHANNEL_CAAM;
136698 +EXPORT_SYMBOL(qm_channel_caam);
136699 +u16 qm_channel_pme = QMAN_CHANNEL_PME;
136700 +EXPORT_SYMBOL(qm_channel_pme);
136701 +u16 qm_channel_dce = QMAN_CHANNEL_DCE;
136702 +EXPORT_SYMBOL(qm_channel_dce);
136703 +u16 qman_portal_max;
136704 +EXPORT_SYMBOL(qman_portal_max);
136705 +
136706 +u32 qman_clk;
136707 +struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
136708 +/* the qman ceetm instances on the given SoC */
136709 +u8 num_ceetms;
136710 +
136711 +/* For these variables, and the portal-initialisation logic, the
136712 + * comments in bman_driver.c apply here so won't be repeated. */
136713 +static struct qman_portal *shared_portals[NR_CPUS];
136714 +static int num_shared_portals;
136715 +static int shared_portals_idx;
136716 +static LIST_HEAD(unused_pcfgs);
136717 +static DEFINE_SPINLOCK(unused_pcfgs_lock);
136718 +
136719 +/* A SDQCR mask comprising all the available/visible pool channels */
136720 +static u32 pools_sdqcr;
136721 +
136722 +#define STR_ERR_NOPROP "No '%s' property in node %s\n"
136723 +#define STR_ERR_CELL "'%s' is not a %d-cell range in node %s\n"
136724 +#define STR_FQID_RANGE "fsl,fqid-range"
136725 +#define STR_POOL_CHAN_RANGE "fsl,pool-channel-range"
136726 +#define STR_CGRID_RANGE "fsl,cgrid-range"
136727 +
136728 +/* A "fsl,fqid-range" node; release the given range to the allocator */
136729 +static __init int fsl_fqid_range_init(struct device_node *node)
136730 +{
136731 + int ret;
136732 + const u32 *range = of_get_property(node, STR_FQID_RANGE, &ret);
136733 + if (!range) {
136734 + pr_err(STR_ERR_NOPROP, STR_FQID_RANGE, node->full_name);
136735 + return -EINVAL;
136736 + }
136737 + if (ret != 8) {
136738 + pr_err(STR_ERR_CELL, STR_FQID_RANGE, 2, node->full_name);
136739 + return -EINVAL;
136740 + }
136741 + qman_seed_fqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136742 + pr_info("Qman: FQID allocator includes range %d:%d\n",
136743 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136744 + return 0;
136745 +}
136746 +
136747 +/* A "fsl,pool-channel-range" node; add to the SDQCR mask only */
136748 +static __init int fsl_pool_channel_range_sdqcr(struct device_node *node)
136749 +{
136750 + int ret;
136751 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
136752 + if (!chanid) {
136753 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
136754 + return -EINVAL;
136755 + }
136756 + if (ret != 8) {
136757 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
136758 + return -EINVAL;
136759 + }
136760 + for (ret = 0; ret < be32_to_cpu(chanid[1]); ret++)
136761 + pools_sdqcr |= QM_SDQCR_CHANNELS_POOL_CONV(be32_to_cpu(chanid[0]) + ret);
136762 + return 0;
136763 +}
136764 +
136765 +/* A "fsl,pool-channel-range" node; release the given range to the allocator */
136766 +static __init int fsl_pool_channel_range_init(struct device_node *node)
136767 +{
136768 + int ret;
136769 + const u32 *chanid = of_get_property(node, STR_POOL_CHAN_RANGE, &ret);
136770 + if (!chanid) {
136771 + pr_err(STR_ERR_NOPROP, STR_POOL_CHAN_RANGE, node->full_name);
136772 + return -EINVAL;
136773 + }
136774 + if (ret != 8) {
136775 + pr_err(STR_ERR_CELL, STR_POOL_CHAN_RANGE, 1, node->full_name);
136776 + return -EINVAL;
136777 + }
136778 + qman_seed_pool_range(be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
136779 + pr_info("Qman: pool channel allocator includes range %d:%d\n",
136780 + be32_to_cpu(chanid[0]), be32_to_cpu(chanid[1]));
136781 + return 0;
136782 +}
136783 +
136784 +/* A "fsl,cgrid-range" node; release the given range to the allocator */
136785 +static __init int fsl_cgrid_range_init(struct device_node *node)
136786 +{
136787 + struct qman_cgr cgr;
136788 + int ret, errors = 0;
136789 + const u32 *range = of_get_property(node, STR_CGRID_RANGE, &ret);
136790 + if (!range) {
136791 + pr_err(STR_ERR_NOPROP, STR_CGRID_RANGE, node->full_name);
136792 + return -EINVAL;
136793 + }
136794 + if (ret != 8) {
136795 + pr_err(STR_ERR_CELL, STR_CGRID_RANGE, 2, node->full_name);
136796 + return -EINVAL;
136797 + }
136798 + qman_seed_cgrid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136799 + pr_info("Qman: CGRID allocator includes range %d:%d\n",
136800 + be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136801 + for (cgr.cgrid = 0; cgr.cgrid < __CGR_NUM; cgr.cgrid++) {
136802 + ret = qman_modify_cgr(&cgr, QMAN_CGR_FLAG_USE_INIT, NULL);
136803 + if (ret)
136804 + errors++;
136805 + }
136806 + if (errors)
136807 + pr_err("Warning: %d error%s while initialising CGRs %d:%d\n",
136808 + errors, (errors > 1) ? "s" : "", range[0], range[1]);
136809 + return 0;
136810 +}
136811 +
136812 +static __init int fsl_ceetm_init(struct device_node *node)
136813 +{
136814 + enum qm_dc_portal dcp_portal;
136815 + struct qm_ceetm_sp *sp;
136816 + struct qm_ceetm_lni *lni;
136817 + int ret, i;
136818 + const u32 *range;
136819 +
136820 + /* Find LFQID range */
136821 + range = of_get_property(node, "fsl,ceetm-lfqid-range", &ret);
136822 + if (!range) {
136823 + pr_err("No fsl,ceetm-lfqid-range in node %s\n",
136824 + node->full_name);
136825 + return -EINVAL;
136826 + }
136827 + if (ret != 8) {
136828 + pr_err("fsl,ceetm-lfqid-range is not a 2-cell range in node"
136829 + " %s\n", node->full_name);
136830 + return -EINVAL;
136831 + }
136832 +
136833 + dcp_portal = (be32_to_cpu(range[0]) & 0x0F0000) >> 16;
136834 + if (dcp_portal > qm_dc_portal_fman1) {
136835 + pr_err("The DCP portal %d doesn't support CEETM\n", dcp_portal);
136836 + return -EINVAL;
136837 + }
136838 +
136839 + if (dcp_portal == qm_dc_portal_fman0)
136840 + qman_seed_ceetm0_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136841 + if (dcp_portal == qm_dc_portal_fman1)
136842 + qman_seed_ceetm1_lfqid_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136843 + pr_debug("Qman: The lfqid allocator of CEETM %d includes range"
136844 + " 0x%x:0x%x\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136845 +
136846 + qman_ceetms[dcp_portal].idx = dcp_portal;
136847 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].sub_portals);
136848 + INIT_LIST_HEAD(&qman_ceetms[dcp_portal].lnis);
136849 +
136850 + /* Find Sub-portal range */
136851 + range = of_get_property(node, "fsl,ceetm-sp-range", &ret);
136852 + if (!range) {
136853 + pr_err("No fsl,ceetm-sp-range in node %s\n", node->full_name);
136854 + return -EINVAL;
136855 + }
136856 + if (ret != 8) {
136857 + pr_err("fsl,ceetm-sp-range is not a 2-cell range in node %s\n",
136858 + node->full_name);
136859 + return -EINVAL;
136860 + }
136861 +
136862 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
136863 + sp = kzalloc(sizeof(*sp), GFP_KERNEL);
136864 + if (!sp) {
136865 + pr_err("Can't alloc memory for sub-portal %d\n",
136866 + range[0] + i);
136867 + return -ENOMEM;
136868 + }
136869 + sp->idx = be32_to_cpu(range[0]) + i;
136870 + sp->dcp_idx = dcp_portal;
136871 + sp->is_claimed = 0;
136872 + list_add_tail(&sp->node, &qman_ceetms[dcp_portal].sub_portals);
136873 + sp++;
136874 + }
136875 + pr_debug("Qman: Reserve sub-portal %d:%d for CEETM %d\n",
136876 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
136877 + qman_ceetms[dcp_portal].sp_range[0] = be32_to_cpu(range[0]);
136878 + qman_ceetms[dcp_portal].sp_range[1] = be32_to_cpu(range[1]);
136879 +
136880 + /* Find LNI range */
136881 + range = of_get_property(node, "fsl,ceetm-lni-range", &ret);
136882 + if (!range) {
136883 + pr_err("No fsl,ceetm-lni-range in node %s\n", node->full_name);
136884 + return -EINVAL;
136885 + }
136886 + if (ret != 8) {
136887 + pr_err("fsl,ceetm-lni-range is not a 2-cell range in node %s\n",
136888 + node->full_name);
136889 + return -EINVAL;
136890 + }
136891 +
136892 + for (i = 0; i < be32_to_cpu(range[1]); i++) {
136893 + lni = kzalloc(sizeof(*lni), GFP_KERNEL);
136894 + if (!lni) {
136895 + pr_err("Can't alloc memory for LNI %d\n",
136896 + range[0] + i);
136897 + return -ENOMEM;
136898 + }
136899 + lni->idx = be32_to_cpu(range[0]) + i;
136900 + lni->dcp_idx = dcp_portal;
136901 + lni->is_claimed = 0;
136902 + INIT_LIST_HEAD(&lni->channels);
136903 + list_add_tail(&lni->node, &qman_ceetms[dcp_portal].lnis);
136904 + lni++;
136905 + }
136906 + pr_debug("Qman: Reserve LNI %d:%d for CEETM %d\n",
136907 + be32_to_cpu(range[0]), be32_to_cpu(range[1]), dcp_portal);
136908 + qman_ceetms[dcp_portal].lni_range[0] = be32_to_cpu(range[0]);
136909 + qman_ceetms[dcp_portal].lni_range[1] = be32_to_cpu(range[1]);
136910 +
136911 + /* Find CEETM channel range */
136912 + range = of_get_property(node, "fsl,ceetm-channel-range", &ret);
136913 + if (!range) {
136914 + pr_err("No fsl,ceetm-channel-range in node %s\n",
136915 + node->full_name);
136916 + return -EINVAL;
136917 + }
136918 + if (ret != 8) {
136919 + pr_err("fsl,ceetm-channel-range is not a 2-cell range in node"
136920 + "%s\n", node->full_name);
136921 + return -EINVAL;
136922 + }
136923 +
136924 + if (dcp_portal == qm_dc_portal_fman0)
136925 + qman_seed_ceetm0_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136926 + if (dcp_portal == qm_dc_portal_fman1)
136927 + qman_seed_ceetm1_channel_range(be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136928 + pr_debug("Qman: The channel allocator of CEETM %d includes"
136929 + " range %d:%d\n", dcp_portal, be32_to_cpu(range[0]), be32_to_cpu(range[1]));
136930 +
136931 + /* Set CEETM PRES register */
136932 + ret = qman_ceetm_set_prescaler(dcp_portal);
136933 + if (ret)
136934 + return ret;
136935 + return 0;
136936 +}
136937 +
136938 +static void qman_get_ip_revision(struct device_node *dn)
136939 +{
136940 + u16 ip_rev = 0;
136941 + u8 ip_cfg = QMAN_REV_CFG_0;
136942 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
136943 + if (!of_device_is_available(dn))
136944 + continue;
136945 + if (of_device_is_compatible(dn, "fsl,qman-portal-1.0") ||
136946 + of_device_is_compatible(dn, "fsl,qman-portal-1.0.0")) {
136947 + pr_err("QMAN rev1.0 on P4080 rev1 is not supported!\n");
136948 + BUG_ON(1);
136949 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.1") ||
136950 + of_device_is_compatible(dn, "fsl,qman-portal-1.1.0")) {
136951 + ip_rev = QMAN_REV11;
136952 + qman_portal_max = 10;
136953 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-1.2") ||
136954 + of_device_is_compatible(dn, "fsl,qman-portal-1.2.0")) {
136955 + ip_rev = QMAN_REV12;
136956 + qman_portal_max = 10;
136957 + } else if (of_device_is_compatible(dn, "fsl,qman-portal-2.0") ||
136958 + of_device_is_compatible(dn, "fsl,qman-portal-2.0.0")) {
136959 + ip_rev = QMAN_REV20;
136960 + qman_portal_max = 3;
136961 + } else if (of_device_is_compatible(dn,
136962 + "fsl,qman-portal-3.0.0")) {
136963 + ip_rev = QMAN_REV30;
136964 + qman_portal_max = 50;
136965 + } else if (of_device_is_compatible(dn,
136966 + "fsl,qman-portal-3.0.1")) {
136967 + ip_rev = QMAN_REV30;
136968 + qman_portal_max = 25;
136969 + ip_cfg = QMAN_REV_CFG_1;
136970 + } else if (of_device_is_compatible(dn,
136971 + "fsl,qman-portal-3.1.0")) {
136972 + ip_rev = QMAN_REV31;
136973 + qman_portal_max = 50;
136974 + } else if (of_device_is_compatible(dn,
136975 + "fsl,qman-portal-3.1.1")) {
136976 + ip_rev = QMAN_REV31;
136977 + qman_portal_max = 25;
136978 + ip_cfg = QMAN_REV_CFG_1;
136979 + } else if (of_device_is_compatible(dn,
136980 + "fsl,qman-portal-3.1.2")) {
136981 + ip_rev = QMAN_REV31;
136982 + qman_portal_max = 18;
136983 + ip_cfg = QMAN_REV_CFG_2;
136984 + } else if (of_device_is_compatible(dn,
136985 + "fsl,qman-portal-3.1.3")) {
136986 + ip_rev = QMAN_REV31;
136987 + qman_portal_max = 10;
136988 + ip_cfg = QMAN_REV_CFG_3;
136989 + } else if (of_device_is_compatible(dn,
136990 + "fsl,qman-portal-3.2.0")) {
136991 + ip_rev = QMAN_REV32;
136992 + qman_portal_max = 10;
136993 + ip_cfg = QMAN_REV_CFG_3; // TODO: Verify for ls1043
136994 + } else if (of_device_is_compatible(dn,
136995 + "fsl,qman-portal-3.2.1")) {
136996 + ip_rev = QMAN_REV32;
136997 + qman_portal_max = 10;
136998 + ip_cfg = QMAN_REV_CFG_3;
136999 + } else {
137000 + pr_warn("unknown QMan version in portal node,"
137001 + "default to rev1.1\n");
137002 + ip_rev = QMAN_REV11;
137003 + qman_portal_max = 10;
137004 + }
137005 +
137006 + if (!qman_ip_rev) {
137007 + if (ip_rev) {
137008 + qman_ip_rev = ip_rev;
137009 + qman_ip_cfg = ip_cfg;
137010 + } else {
137011 + pr_warn("unknown Qman version,"
137012 + " default to rev1.1\n");
137013 + qman_ip_rev = QMAN_REV11;
137014 + qman_ip_cfg = QMAN_REV_CFG_0;
137015 + }
137016 + } else if (ip_rev && (qman_ip_rev != ip_rev))
137017 + pr_warn("Revision=0x%04x, but portal '%s' has"
137018 + " 0x%04x\n",
137019 + qman_ip_rev, dn->full_name, ip_rev);
137020 + if (qman_ip_rev == ip_rev)
137021 + break;
137022 + }
137023 +}
137024 +
137025 +/* Parse a portal node, perform generic mapping duties and return the config. It
137026 + * is not known at this stage for what purpose (or even if) the portal will be
137027 + * used. */
137028 +static struct qm_portal_config * __init parse_pcfg(struct device_node *node)
137029 +{
137030 + struct qm_portal_config *pcfg;
137031 + const u32 *index_p;
137032 + u32 index, channel;
137033 + int irq, ret;
137034 + resource_size_t len;
137035 +
137036 + pcfg = kmalloc(sizeof(*pcfg), GFP_KERNEL);
137037 + if (!pcfg) {
137038 + pr_err("can't allocate portal config");
137039 + return NULL;
137040 + }
137041 +
137042 + /*
137043 + * This is a *horrible hack*, but the IOMMU/PAMU driver needs a
137044 + * 'struct device' in order to get the PAMU stashing setup and the QMan
137045 + * portal [driver] won't function at all without ring stashing
137046 + *
137047 + * Making the QMan portal driver nice and proper is part of the
137048 + * upstreaming effort
137049 + */
137050 + pcfg->dev.bus = &platform_bus_type;
137051 + pcfg->dev.of_node = node;
137052 +#ifdef CONFIG_FSL_PAMU
137053 + pcfg->dev.archdata.iommu_domain = NULL;
137054 +#endif
137055 +
137056 + ret = of_address_to_resource(node, DPA_PORTAL_CE,
137057 + &pcfg->addr_phys[DPA_PORTAL_CE]);
137058 + if (ret) {
137059 + pr_err("Can't get %s property '%s'\n", node->full_name,
137060 + "reg::CE");
137061 + goto err;
137062 + }
137063 + ret = of_address_to_resource(node, DPA_PORTAL_CI,
137064 + &pcfg->addr_phys[DPA_PORTAL_CI]);
137065 + if (ret) {
137066 + pr_err("Can't get %s property '%s'\n", node->full_name,
137067 + "reg::CI");
137068 + goto err;
137069 + }
137070 + index_p = of_get_property(node, "cell-index", &ret);
137071 + if (!index_p || (ret != 4)) {
137072 + pr_err("Can't get %s property '%s'\n", node->full_name,
137073 + "cell-index");
137074 + goto err;
137075 + }
137076 + index = be32_to_cpu(*index_p);
137077 + if (index >= qman_portal_max) {
137078 + pr_err("QMan portal index %d is beyond max (%d)\n",
137079 + index, qman_portal_max);
137080 + goto err;
137081 + }
137082 +
137083 + channel = index + QM_CHANNEL_SWPORTAL0;
137084 + pcfg->public_cfg.channel = channel;
137085 + pcfg->public_cfg.cpu = -1;
137086 + irq = irq_of_parse_and_map(node, 0);
137087 + if (irq == 0) {
137088 + pr_err("Can't get %s property '%s'\n", node->full_name,
137089 + "interrupts");
137090 + goto err;
137091 + }
137092 + pcfg->public_cfg.irq = irq;
137093 + pcfg->public_cfg.index = index;
137094 +#ifdef CONFIG_FSL_QMAN_CONFIG
137095 + /* We need the same LIODN offset for all portals */
137096 + qman_liodn_fixup(pcfg->public_cfg.channel);
137097 +#endif
137098 +
137099 + len = resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]);
137100 + if (len != (unsigned long)len)
137101 + goto err;
137102 +
137103 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
137104 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_cache_ns(
137105 + pcfg->addr_phys[DPA_PORTAL_CE].start,
137106 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CE]));
137107 +
137108 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap(
137109 + pcfg->addr_phys[DPA_PORTAL_CI].start,
137110 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]));
137111 +#else
137112 + pcfg->addr_virt[DPA_PORTAL_CE] = ioremap_prot(
137113 + pcfg->addr_phys[DPA_PORTAL_CE].start,
137114 + (unsigned long)len,
137115 + 0);
137116 + pcfg->addr_virt[DPA_PORTAL_CI] = ioremap_prot(
137117 + pcfg->addr_phys[DPA_PORTAL_CI].start,
137118 + resource_size(&pcfg->addr_phys[DPA_PORTAL_CI]),
137119 + _PAGE_GUARDED | _PAGE_NO_CACHE);
137120 +#endif
137121 + return pcfg;
137122 +err:
137123 + kfree(pcfg);
137124 + return NULL;
137125 +}
137126 +
137127 +static struct qm_portal_config *get_pcfg(struct list_head *list)
137128 +{
137129 + struct qm_portal_config *pcfg;
137130 + if (list_empty(list))
137131 + return NULL;
137132 + pcfg = list_entry(list->prev, struct qm_portal_config, list);
137133 + list_del(&pcfg->list);
137134 + return pcfg;
137135 +}
137136 +
137137 +static struct qm_portal_config *get_pcfg_idx(struct list_head *list, u32 idx)
137138 +{
137139 + struct qm_portal_config *pcfg;
137140 + if (list_empty(list))
137141 + return NULL;
137142 + list_for_each_entry(pcfg, list, list) {
137143 + if (pcfg->public_cfg.index == idx) {
137144 + list_del(&pcfg->list);
137145 + return pcfg;
137146 + }
137147 + }
137148 + return NULL;
137149 +}
137150 +
137151 +static void portal_set_cpu(struct qm_portal_config *pcfg, int cpu)
137152 +{
137153 +#ifdef CONFIG_FSL_PAMU
137154 + int ret;
137155 + int window_count = 1;
137156 + struct iommu_domain_geometry geom_attr;
137157 + struct pamu_stash_attribute stash_attr;
137158 +
137159 + pcfg->iommu_domain = iommu_domain_alloc(&platform_bus_type);
137160 + if (!pcfg->iommu_domain) {
137161 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_alloc() failed",
137162 + __func__);
137163 + goto _no_iommu;
137164 + }
137165 + geom_attr.aperture_start = 0;
137166 + geom_attr.aperture_end =
137167 + ((dma_addr_t)1 << min(8 * sizeof(dma_addr_t), (size_t)36)) - 1;
137168 + geom_attr.force_aperture = true;
137169 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_GEOMETRY,
137170 + &geom_attr);
137171 + if (ret < 0) {
137172 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
137173 + __func__, ret);
137174 + goto _iommu_domain_free;
137175 + }
137176 + ret = iommu_domain_set_attr(pcfg->iommu_domain, DOMAIN_ATTR_WINDOWS,
137177 + &window_count);
137178 + if (ret < 0) {
137179 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
137180 + __func__, ret);
137181 + goto _iommu_domain_free;
137182 + }
137183 + stash_attr.cpu = cpu;
137184 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
137185 + /* set stash information for the window */
137186 + stash_attr.window = 0;
137187 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
137188 + DOMAIN_ATTR_FSL_PAMU_STASH,
137189 + &stash_attr);
137190 + if (ret < 0) {
137191 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
137192 + __func__, ret);
137193 + goto _iommu_domain_free;
137194 + }
137195 + ret = iommu_domain_window_enable(pcfg->iommu_domain, 0, 0, 1ULL << 36,
137196 + IOMMU_READ | IOMMU_WRITE);
137197 + if (ret < 0) {
137198 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_window_enable() = %d",
137199 + __func__, ret);
137200 + goto _iommu_domain_free;
137201 + }
137202 + ret = iommu_attach_device(pcfg->iommu_domain, &pcfg->dev);
137203 + if (ret < 0) {
137204 + pr_err(KBUILD_MODNAME ":%s(): iommu_device_attach() = %d",
137205 + __func__, ret);
137206 + goto _iommu_domain_free;
137207 + }
137208 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
137209 + DOMAIN_ATTR_FSL_PAMU_ENABLE,
137210 + &window_count);
137211 + if (ret < 0) {
137212 + pr_err(KBUILD_MODNAME ":%s(): iommu_domain_set_attr() = %d",
137213 + __func__, ret);
137214 + goto _iommu_detach_device;
137215 + }
137216 +
137217 +_no_iommu:
137218 +#endif
137219 +#ifdef CONFIG_FSL_QMAN_CONFIG
137220 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
137221 +#endif
137222 + pr_warn("Failed to set QMan portal's stash request queue\n");
137223 +
137224 + return;
137225 +
137226 +#ifdef CONFIG_FSL_PAMU
137227 +_iommu_detach_device:
137228 + iommu_detach_device(pcfg->iommu_domain, NULL);
137229 +_iommu_domain_free:
137230 + iommu_domain_free(pcfg->iommu_domain);
137231 +#endif
137232 +}
137233 +
137234 +struct qm_portal_config *qm_get_unused_portal_idx(u32 idx)
137235 +{
137236 + struct qm_portal_config *ret;
137237 + spin_lock(&unused_pcfgs_lock);
137238 + if (idx == QBMAN_ANY_PORTAL_IDX)
137239 + ret = get_pcfg(&unused_pcfgs);
137240 + else
137241 + ret = get_pcfg_idx(&unused_pcfgs, idx);
137242 + spin_unlock(&unused_pcfgs_lock);
137243 + /* Bind stashing LIODNs to the CPU we are currently executing on, and
137244 + * set the portal to use the stashing request queue corresonding to the
137245 + * cpu as well. The user-space driver assumption is that the pthread has
137246 + * to already be affine to one cpu only before opening a portal. If that
137247 + * check is circumvented, the only risk is a performance degradation -
137248 + * stashing will go to whatever cpu they happened to be running on when
137249 + * opening the device file, and if that isn't the cpu they subsequently
137250 + * bind to and do their polling on, tough. */
137251 + if (ret)
137252 + portal_set_cpu(ret, hard_smp_processor_id());
137253 + return ret;
137254 +}
137255 +
137256 +struct qm_portal_config *qm_get_unused_portal(void)
137257 +{
137258 + return qm_get_unused_portal_idx(QBMAN_ANY_PORTAL_IDX);
137259 +}
137260 +
137261 +void qm_put_unused_portal(struct qm_portal_config *pcfg)
137262 +{
137263 + spin_lock(&unused_pcfgs_lock);
137264 + list_add(&pcfg->list, &unused_pcfgs);
137265 + spin_unlock(&unused_pcfgs_lock);
137266 +}
137267 +
137268 +static struct qman_portal *init_pcfg(struct qm_portal_config *pcfg)
137269 +{
137270 + struct qman_portal *p;
137271 +
137272 + pcfg->iommu_domain = NULL;
137273 + portal_set_cpu(pcfg, pcfg->public_cfg.cpu);
137274 + p = qman_create_affine_portal(pcfg, NULL);
137275 + if (p) {
137276 + u32 irq_sources = 0;
137277 + /* Determine what should be interrupt-vs-poll driven */
137278 +#ifdef CONFIG_FSL_DPA_PIRQ_SLOW
137279 + irq_sources |= QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI |
137280 + QM_PIRQ_CSCI | QM_PIRQ_CCSCI;
137281 +#endif
137282 +#ifdef CONFIG_FSL_DPA_PIRQ_FAST
137283 + irq_sources |= QM_PIRQ_DQRI;
137284 +#endif
137285 + qman_p_irqsource_add(p, irq_sources);
137286 + pr_info("Qman portal %sinitialised, cpu %d\n",
137287 + pcfg->public_cfg.is_shared ? "(shared) " : "",
137288 + pcfg->public_cfg.cpu);
137289 + } else
137290 + pr_crit("Qman portal failure on cpu %d\n",
137291 + pcfg->public_cfg.cpu);
137292 + return p;
137293 +}
137294 +
137295 +static void init_slave(int cpu)
137296 +{
137297 + struct qman_portal *p;
137298 + struct cpumask oldmask = current->cpus_allowed;
137299 + set_cpus_allowed_ptr(current, get_cpu_mask(cpu));
137300 + p = qman_create_affine_slave(shared_portals[shared_portals_idx++], cpu);
137301 + if (!p)
137302 + pr_err("Qman slave portal failure on cpu %d\n", cpu);
137303 + else
137304 + pr_info("Qman portal %sinitialised, cpu %d\n", "(slave) ", cpu);
137305 + set_cpus_allowed_ptr(current, &oldmask);
137306 + if (shared_portals_idx >= num_shared_portals)
137307 + shared_portals_idx = 0;
137308 +}
137309 +
137310 +static struct cpumask want_unshared __initdata;
137311 +static struct cpumask want_shared __initdata;
137312 +
137313 +static int __init parse_qportals(char *str)
137314 +{
137315 + return parse_portals_bootarg(str, &want_shared, &want_unshared,
137316 + "qportals");
137317 +}
137318 +__setup("qportals=", parse_qportals);
137319 +
137320 +static void qman_portal_update_sdest(const struct qm_portal_config *pcfg,
137321 + unsigned int cpu)
137322 +{
137323 +#ifdef CONFIG_FSL_PAMU
137324 + struct pamu_stash_attribute stash_attr;
137325 + int ret;
137326 +
137327 + if (pcfg->iommu_domain) {
137328 + stash_attr.cpu = cpu;
137329 + stash_attr.cache = PAMU_ATTR_CACHE_L1;
137330 + /* set stash information for the window */
137331 + stash_attr.window = 0;
137332 + ret = iommu_domain_set_attr(pcfg->iommu_domain,
137333 + DOMAIN_ATTR_FSL_PAMU_STASH, &stash_attr);
137334 + if (ret < 0) {
137335 + pr_err("Failed to update pamu stash setting\n");
137336 + return;
137337 + }
137338 + }
137339 +#endif
137340 +#ifdef CONFIG_FSL_QMAN_CONFIG
137341 + if (qman_set_sdest(pcfg->public_cfg.channel, cpu))
137342 + pr_warn("Failed to update portal's stash request queue\n");
137343 +#endif
137344 +}
137345 +
137346 +static int qman_offline_cpu(unsigned int cpu)
137347 +{
137348 + struct qman_portal *p;
137349 + const struct qm_portal_config *pcfg;
137350 + p = (struct qman_portal *)affine_portals[cpu];
137351 + if (p) {
137352 + pcfg = qman_get_qm_portal_config(p);
137353 + if (pcfg) {
137354 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(0));
137355 + qman_portal_update_sdest(pcfg, 0);
137356 + }
137357 + }
137358 + return 0;
137359 +}
137360 +
137361 +#ifdef CONFIG_HOTPLUG_CPU
137362 +static int qman_online_cpu(unsigned int cpu)
137363 +{
137364 + struct qman_portal *p;
137365 + const struct qm_portal_config *pcfg;
137366 + p = (struct qman_portal *)affine_portals[cpu];
137367 + if (p) {
137368 + pcfg = qman_get_qm_portal_config(p);
137369 + if (pcfg) {
137370 + irq_set_affinity(pcfg->public_cfg.irq, cpumask_of(cpu));
137371 + qman_portal_update_sdest(pcfg, cpu);
137372 + }
137373 + }
137374 + return 0;
137375 +}
137376 +
137377 +#endif /* CONFIG_HOTPLUG_CPU */
137378 +
137379 +__init int qman_init(void)
137380 +{
137381 + struct cpumask slave_cpus;
137382 + struct cpumask unshared_cpus = *cpu_none_mask;
137383 + struct cpumask shared_cpus = *cpu_none_mask;
137384 + LIST_HEAD(unshared_pcfgs);
137385 + LIST_HEAD(shared_pcfgs);
137386 + struct device_node *dn;
137387 + struct qm_portal_config *pcfg;
137388 + struct qman_portal *p;
137389 + int cpu, ret;
137390 + const u32 *clk;
137391 + struct cpumask offline_cpus;
137392 +
137393 + /* Initialise the Qman (CCSR) device */
137394 + for_each_compatible_node(dn, NULL, "fsl,qman") {
137395 + if (!qman_init_ccsr(dn))
137396 + pr_info("Qman err interrupt handler present\n");
137397 + else
137398 + pr_err("Qman CCSR setup failed\n");
137399 +
137400 + clk = of_get_property(dn, "clock-frequency", NULL);
137401 + if (!clk)
137402 + pr_warn("Can't find Qman clock frequency\n");
137403 + else
137404 + qman_clk = be32_to_cpu(*clk);
137405 + }
137406 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137407 + /* Setup lookup table for FQ demux */
137408 + ret = qman_setup_fq_lookup_table(get_qman_fqd_size()/64);
137409 + if (ret)
137410 + return ret;
137411 +#endif
137412 +
137413 + /* Get qman ip revision */
137414 + qman_get_ip_revision(dn);
137415 + if ((qman_ip_rev & 0xff00) >= QMAN_REV30) {
137416 + qm_channel_pool1 = QMAN_CHANNEL_POOL1_REV3;
137417 + qm_channel_caam = QMAN_CHANNEL_CAAM_REV3;
137418 + qm_channel_pme = QMAN_CHANNEL_PME_REV3;
137419 + }
137420 +
137421 + if ((qman_ip_rev == QMAN_REV31) && (qman_ip_cfg == QMAN_REV_CFG_2))
137422 + qm_channel_dce = QMAN_CHANNEL_DCE_QMANREV312;
137423 +
137424 + /*
137425 + * Parse the ceetm node to get how many ceetm instances are supported
137426 + * on the current silicon. num_ceetms must be confirmed before portals
137427 + * are intiailized.
137428 + */
137429 + num_ceetms = 0;
137430 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm")
137431 + num_ceetms++;
137432 +
137433 + /* Parse pool channels into the SDQCR mask. (Must happen before portals
137434 + * are initialised.) */
137435 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
137436 + ret = fsl_pool_channel_range_sdqcr(dn);
137437 + if (ret)
137438 + return ret;
137439 + }
137440 +
137441 + memset(affine_portals, 0, sizeof(void *) * num_possible_cpus());
137442 + /* Initialise portals. See bman_driver.c for comments */
137443 + for_each_compatible_node(dn, NULL, "fsl,qman-portal") {
137444 + if (!of_device_is_available(dn))
137445 + continue;
137446 + pcfg = parse_pcfg(dn);
137447 + if (pcfg) {
137448 + pcfg->public_cfg.pools = pools_sdqcr;
137449 + list_add_tail(&pcfg->list, &unused_pcfgs);
137450 + }
137451 + }
137452 + for_each_possible_cpu(cpu) {
137453 + if (cpumask_test_cpu(cpu, &want_shared)) {
137454 + pcfg = get_pcfg(&unused_pcfgs);
137455 + if (!pcfg)
137456 + break;
137457 + pcfg->public_cfg.cpu = cpu;
137458 + list_add_tail(&pcfg->list, &shared_pcfgs);
137459 + cpumask_set_cpu(cpu, &shared_cpus);
137460 + }
137461 + if (cpumask_test_cpu(cpu, &want_unshared)) {
137462 + if (cpumask_test_cpu(cpu, &shared_cpus))
137463 + continue;
137464 + pcfg = get_pcfg(&unused_pcfgs);
137465 + if (!pcfg)
137466 + break;
137467 + pcfg->public_cfg.cpu = cpu;
137468 + list_add_tail(&pcfg->list, &unshared_pcfgs);
137469 + cpumask_set_cpu(cpu, &unshared_cpus);
137470 + }
137471 + }
137472 + if (list_empty(&shared_pcfgs) && list_empty(&unshared_pcfgs)) {
137473 + for_each_online_cpu(cpu) {
137474 + pcfg = get_pcfg(&unused_pcfgs);
137475 + if (!pcfg)
137476 + break;
137477 + pcfg->public_cfg.cpu = cpu;
137478 + list_add_tail(&pcfg->list, &unshared_pcfgs);
137479 + cpumask_set_cpu(cpu, &unshared_cpus);
137480 + }
137481 + }
137482 + cpumask_andnot(&slave_cpus, cpu_possible_mask, &shared_cpus);
137483 + cpumask_andnot(&slave_cpus, &slave_cpus, &unshared_cpus);
137484 + if (cpumask_empty(&slave_cpus)) {
137485 + if (!list_empty(&shared_pcfgs)) {
137486 + cpumask_or(&unshared_cpus, &unshared_cpus,
137487 + &shared_cpus);
137488 + cpumask_clear(&shared_cpus);
137489 + list_splice_tail(&shared_pcfgs, &unshared_pcfgs);
137490 + INIT_LIST_HEAD(&shared_pcfgs);
137491 + }
137492 + } else {
137493 + if (list_empty(&shared_pcfgs)) {
137494 + pcfg = get_pcfg(&unshared_pcfgs);
137495 + if (!pcfg) {
137496 + pr_crit("No QMan portals available!\n");
137497 + return 0;
137498 + }
137499 + cpumask_clear_cpu(pcfg->public_cfg.cpu, &unshared_cpus);
137500 + cpumask_set_cpu(pcfg->public_cfg.cpu, &shared_cpus);
137501 + list_add_tail(&pcfg->list, &shared_pcfgs);
137502 + }
137503 + }
137504 + list_for_each_entry(pcfg, &unshared_pcfgs, list) {
137505 + pcfg->public_cfg.is_shared = 0;
137506 + p = init_pcfg(pcfg);
137507 + if (!p) {
137508 + pr_crit("Unable to configure portals\n");
137509 + return 0;
137510 + }
137511 + }
137512 + list_for_each_entry(pcfg, &shared_pcfgs, list) {
137513 + pcfg->public_cfg.is_shared = 1;
137514 + p = init_pcfg(pcfg);
137515 + if (p)
137516 + shared_portals[num_shared_portals++] = p;
137517 + }
137518 + if (!cpumask_empty(&slave_cpus))
137519 + for_each_cpu(cpu, &slave_cpus)
137520 + init_slave(cpu);
137521 + pr_info("Qman portals initialised\n");
137522 + cpumask_andnot(&offline_cpus, cpu_possible_mask, cpu_online_mask);
137523 + for_each_cpu(cpu, &offline_cpus)
137524 + qman_offline_cpu(cpu);
137525 +#ifdef CONFIG_HOTPLUG_CPU
137526 + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
137527 + "soc/qman_portal:online",
137528 + qman_online_cpu, qman_offline_cpu);
137529 + if (ret < 0) {
137530 + pr_err("qman: failed to register hotplug callbacks.\n");
137531 + return ret;
137532 + }
137533 +#endif
137534 + return 0;
137535 +}
137536 +
137537 +__init int qman_resource_init(void)
137538 +{
137539 + struct device_node *dn;
137540 + int ret;
137541 +
137542 + /* Initialise FQID allocation ranges */
137543 + for_each_compatible_node(dn, NULL, "fsl,fqid-range") {
137544 + ret = fsl_fqid_range_init(dn);
137545 + if (ret)
137546 + return ret;
137547 + }
137548 + /* Initialise CGRID allocation ranges */
137549 + for_each_compatible_node(dn, NULL, "fsl,cgrid-range") {
137550 + ret = fsl_cgrid_range_init(dn);
137551 + if (ret)
137552 + return ret;
137553 + }
137554 + /* Parse pool channels into the allocator. (Must happen after portals
137555 + * are initialised.) */
137556 + for_each_compatible_node(dn, NULL, "fsl,pool-channel-range") {
137557 + ret = fsl_pool_channel_range_init(dn);
137558 + if (ret)
137559 + return ret;
137560 + }
137561 +
137562 + /* Parse CEETM */
137563 + for_each_compatible_node(dn, NULL, "fsl,qman-ceetm") {
137564 + ret = fsl_ceetm_init(dn);
137565 + if (ret)
137566 + return ret;
137567 + }
137568 + return 0;
137569 +}
137570 +
137571 +#ifdef CONFIG_SUSPEND
137572 +void suspend_unused_qportal(void)
137573 +{
137574 + struct qm_portal_config *pcfg;
137575 +
137576 + if (list_empty(&unused_pcfgs))
137577 + return;
137578 +
137579 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
137580 +#ifdef CONFIG_PM_DEBUG
137581 + pr_info("Need to save qportal %d\n", pcfg->public_cfg.index);
137582 +#endif
137583 + /* save isdr, disable all via isdr, clear isr */
137584 + pcfg->saved_isdr =
137585 + __raw_readl(pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
137586 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
137587 + 0xe08);
137588 + __raw_writel(0xffffffff, pcfg->addr_virt[DPA_PORTAL_CI] +
137589 + 0xe00);
137590 + }
137591 + return;
137592 +}
137593 +
137594 +void resume_unused_qportal(void)
137595 +{
137596 + struct qm_portal_config *pcfg;
137597 +
137598 + if (list_empty(&unused_pcfgs))
137599 + return;
137600 +
137601 + list_for_each_entry(pcfg, &unused_pcfgs, list) {
137602 +#ifdef CONFIG_PM_DEBUG
137603 + pr_info("Need to resume qportal %d\n", pcfg->public_cfg.index);
137604 +#endif
137605 + /* restore isdr */
137606 + __raw_writel(pcfg->saved_isdr,
137607 + pcfg->addr_virt[DPA_PORTAL_CI] + 0xe08);
137608 + }
137609 + return;
137610 +}
137611 +#endif
137612 --- /dev/null
137613 +++ b/drivers/staging/fsl_qbman/qman_high.c
137614 @@ -0,0 +1,5655 @@
137615 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
137616 + *
137617 + * Redistribution and use in source and binary forms, with or without
137618 + * modification, are permitted provided that the following conditions are met:
137619 + * * Redistributions of source code must retain the above copyright
137620 + * notice, this list of conditions and the following disclaimer.
137621 + * * Redistributions in binary form must reproduce the above copyright
137622 + * notice, this list of conditions and the following disclaimer in the
137623 + * documentation and/or other materials provided with the distribution.
137624 + * * Neither the name of Freescale Semiconductor nor the
137625 + * names of its contributors may be used to endorse or promote products
137626 + * derived from this software without specific prior written permission.
137627 + *
137628 + *
137629 + * ALTERNATIVELY, this software may be distributed under the terms of the
137630 + * GNU General Public License ("GPL") as published by the Free Software
137631 + * Foundation, either version 2 of that License or (at your option) any
137632 + * later version.
137633 + *
137634 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
137635 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
137636 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
137637 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
137638 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
137639 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
137640 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
137641 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
137642 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
137643 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
137644 + */
137645 +
137646 +#include "qman_low.h"
137647 +
137648 +/* Compilation constants */
137649 +#define DQRR_MAXFILL 15
137650 +#define EQCR_ITHRESH 4 /* if EQCR congests, interrupt threshold */
137651 +#define IRQNAME "QMan portal %d"
137652 +#define MAX_IRQNAME 16 /* big enough for "QMan portal %d" */
137653 +
137654 +/* Divide 'n' by 'd', rounding down if 'r' is negative, rounding up if it's
137655 + * positive, and rounding to the closest value if it's zero. NB, this macro
137656 + * implicitly upgrades parameters to unsigned 64-bit, so feed it with types
137657 + * that are compatible with this. NB, these arguments should not be expressions
137658 + * unless it is safe for them to be evaluated multiple times. Eg. do not pass
137659 + * in "some_value++" as a parameter to the macro! */
137660 +#define ROUNDING(n, d, r) \
137661 + (((r) < 0) ? div64_u64((n), (d)) : \
137662 + (((r) > 0) ? div64_u64(((n) + (d) - 1), (d)) : \
137663 + div64_u64(((n) + ((d) / 2)), (d))))
137664 +
137665 +/* Lock/unlock frame queues, subject to the "LOCKED" flag. This is about
137666 + * inter-processor locking only. Note, FQLOCK() is always called either under a
137667 + * local_irq_save() or from interrupt context - hence there's no need for irq
137668 + * protection (and indeed, attempting to nest irq-protection doesn't work, as
137669 + * the "irq en/disable" machinery isn't recursive...). */
137670 +#define FQLOCK(fq) \
137671 + do { \
137672 + struct qman_fq *__fq478 = (fq); \
137673 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
137674 + spin_lock(&__fq478->fqlock); \
137675 + } while (0)
137676 +#define FQUNLOCK(fq) \
137677 + do { \
137678 + struct qman_fq *__fq478 = (fq); \
137679 + if (fq_isset(__fq478, QMAN_FQ_FLAG_LOCKED)) \
137680 + spin_unlock(&__fq478->fqlock); \
137681 + } while (0)
137682 +
137683 +static inline void fq_set(struct qman_fq *fq, u32 mask)
137684 +{
137685 + set_bits(mask, &fq->flags);
137686 +}
137687 +static inline void fq_clear(struct qman_fq *fq, u32 mask)
137688 +{
137689 + clear_bits(mask, &fq->flags);
137690 +}
137691 +static inline int fq_isset(struct qman_fq *fq, u32 mask)
137692 +{
137693 + return fq->flags & mask;
137694 +}
137695 +static inline int fq_isclear(struct qman_fq *fq, u32 mask)
137696 +{
137697 + return !(fq->flags & mask);
137698 +}
137699 +
137700 +struct qman_portal {
137701 + struct qm_portal p;
137702 + unsigned long bits; /* PORTAL_BITS_*** - dynamic, strictly internal */
137703 + unsigned long irq_sources;
137704 + u32 use_eqcr_ci_stashing;
137705 + u32 slowpoll; /* only used when interrupts are off */
137706 + struct qman_fq *vdqcr_owned; /* only 1 volatile dequeue at a time */
137707 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
137708 + struct qman_fq *eqci_owned; /* only 1 enqueue WAIT_SYNC at a time */
137709 +#endif
137710 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137711 + raw_spinlock_t sharing_lock; /* only used if is_shared */
137712 + int is_shared;
137713 + struct qman_portal *sharing_redirect;
137714 +#endif
137715 + u32 sdqcr;
137716 + int dqrr_disable_ref;
137717 + /* A portal-specific handler for DCP ERNs. If this is NULL, the global
137718 + * handler is called instead. */
137719 + qman_cb_dc_ern cb_dc_ern;
137720 + /* When the cpu-affine portal is activated, this is non-NULL */
137721 + const struct qm_portal_config *config;
137722 + /* This is needed for providing a non-NULL device to dma_map_***() */
137723 + struct platform_device *pdev;
137724 + struct dpa_rbtree retire_table;
137725 + char irqname[MAX_IRQNAME];
137726 + /* 2-element array. cgrs[0] is mask, cgrs[1] is snapshot. */
137727 + struct qman_cgrs *cgrs;
137728 + /* linked-list of CSCN handlers. */
137729 + struct list_head cgr_cbs;
137730 + /* list lock */
137731 + spinlock_t cgr_lock;
137732 + /* 2-element array. ccgrs[0] is mask, ccgrs[1] is snapshot. */
137733 + struct qman_ccgrs *ccgrs[QMAN_CEETM_MAX];
137734 + /* 256-element array, each is a linked-list of CCSCN handlers. */
137735 + struct list_head ccgr_cbs[QMAN_CEETM_MAX];
137736 + /* list lock */
137737 + spinlock_t ccgr_lock;
137738 + /* track if memory was allocated by the driver */
137739 + u8 alloced;
137740 + /* power management data */
137741 + u32 save_isdr;
137742 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
137743 + /* Keep a shadow copy of the DQRR on LE systems as the SW needs to
137744 + * do byte swaps of DQRR read only memory. First entry must be aligned
137745 + * to 2 ** 10 to ensure DQRR index calculations based shadow copy
137746 + * address (6 bits for address shift + 4 bits for the DQRR size).
137747 + */
137748 + struct qm_dqrr_entry shadow_dqrr[QM_DQRR_SIZE] __aligned(1024);
137749 +#endif
137750 +};
137751 +
137752 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137753 +#define PORTAL_IRQ_LOCK(p, irqflags) \
137754 + do { \
137755 + if ((p)->is_shared) \
137756 + raw_spin_lock_irqsave(&(p)->sharing_lock, irqflags); \
137757 + else \
137758 + local_irq_save(irqflags); \
137759 + } while (0)
137760 +#define PORTAL_IRQ_UNLOCK(p, irqflags) \
137761 + do { \
137762 + if ((p)->is_shared) \
137763 + raw_spin_unlock_irqrestore(&(p)->sharing_lock, \
137764 + irqflags); \
137765 + else \
137766 + local_irq_restore(irqflags); \
137767 + } while (0)
137768 +#else
137769 +#define PORTAL_IRQ_LOCK(p, irqflags) local_irq_save(irqflags)
137770 +#define PORTAL_IRQ_UNLOCK(p, irqflags) local_irq_restore(irqflags)
137771 +#endif
137772 +
137773 +/* Global handler for DCP ERNs. Used when the portal receiving the message does
137774 + * not have a portal-specific handler. */
137775 +static qman_cb_dc_ern cb_dc_ern;
137776 +
137777 +static cpumask_t affine_mask;
137778 +static DEFINE_SPINLOCK(affine_mask_lock);
137779 +static u16 affine_channels[NR_CPUS];
137780 +static DEFINE_PER_CPU(struct qman_portal, qman_affine_portal);
137781 +void *affine_portals[NR_CPUS];
137782 +
137783 +/* "raw" gets the cpu-local struct whether it's a redirect or not. */
137784 +static inline struct qman_portal *get_raw_affine_portal(void)
137785 +{
137786 + return &get_cpu_var(qman_affine_portal);
137787 +}
137788 +/* For ops that can redirect, this obtains the portal to use */
137789 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
137790 +static inline struct qman_portal *get_affine_portal(void)
137791 +{
137792 + struct qman_portal *p = get_raw_affine_portal();
137793 + if (p->sharing_redirect)
137794 + return p->sharing_redirect;
137795 + return p;
137796 +}
137797 +#else
137798 +#define get_affine_portal() get_raw_affine_portal()
137799 +#endif
137800 +/* For every "get", there must be a "put" */
137801 +static inline void put_affine_portal(void)
137802 +{
137803 + put_cpu_var(qman_affine_portal);
137804 +}
137805 +/* Exception: poll functions assume the caller is cpu-affine and in no risk of
137806 + * re-entrance, which are the two reasons we usually use the get/put_cpu_var()
137807 + * semantic - ie. to disable pre-emption. Some use-cases expect the execution
137808 + * context to remain as non-atomic during poll-triggered callbacks as it was
137809 + * when the poll API was first called (eg. NAPI), so we go out of our way in
137810 + * this case to not disable pre-emption. */
137811 +static inline struct qman_portal *get_poll_portal(void)
137812 +{
137813 + return &get_cpu_var(qman_affine_portal);
137814 +}
137815 +#define put_poll_portal()
137816 +
137817 +/* This gives a FQID->FQ lookup to cover the fact that we can't directly demux
137818 + * retirement notifications (the fact they are sometimes h/w-consumed means that
137819 + * contextB isn't always a s/w demux - and as we can't know which case it is
137820 + * when looking at the notification, we have to use the slow lookup for all of
137821 + * them). NB, it's possible to have multiple FQ objects refer to the same FQID
137822 + * (though at most one of them should be the consumer), so this table isn't for
137823 + * all FQs - FQs are added when retirement commands are issued, and removed when
137824 + * they complete, which also massively reduces the size of this table. */
137825 +IMPLEMENT_DPA_RBTREE(fqtree, struct qman_fq, node, fqid);
137826 +
137827 +/* This is what everything can wait on, even if it migrates to a different cpu
137828 + * to the one whose affine portal it is waiting on. */
137829 +static DECLARE_WAIT_QUEUE_HEAD(affine_queue);
137830 +
137831 +static inline int table_push_fq(struct qman_portal *p, struct qman_fq *fq)
137832 +{
137833 + int ret = fqtree_push(&p->retire_table, fq);
137834 + if (ret)
137835 + pr_err("ERROR: double FQ-retirement %d\n", fq->fqid);
137836 + return ret;
137837 +}
137838 +
137839 +static inline void table_del_fq(struct qman_portal *p, struct qman_fq *fq)
137840 +{
137841 + fqtree_del(&p->retire_table, fq);
137842 +}
137843 +
137844 +static inline struct qman_fq *table_find_fq(struct qman_portal *p, u32 fqid)
137845 +{
137846 + return fqtree_find(&p->retire_table, fqid);
137847 +}
137848 +
137849 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
137850 +static void **qman_fq_lookup_table;
137851 +static size_t qman_fq_lookup_table_size;
137852 +
137853 +int qman_setup_fq_lookup_table(size_t num_entries)
137854 +{
137855 + num_entries++;
137856 + /* Allocate 1 more entry since the first entry is not used */
137857 + qman_fq_lookup_table = vzalloc((num_entries * sizeof(void *)));
137858 + if (!qman_fq_lookup_table) {
137859 + pr_err("QMan: Could not allocate fq lookup table\n");
137860 + return -ENOMEM;
137861 + }
137862 + qman_fq_lookup_table_size = num_entries;
137863 + pr_info("QMan: Allocated lookup table at %p, entry count %lu\n",
137864 + qman_fq_lookup_table,
137865 + (unsigned long)qman_fq_lookup_table_size);
137866 + return 0;
137867 +}
137868 +
137869 +/* global structure that maintains fq object mapping */
137870 +static DEFINE_SPINLOCK(fq_hash_table_lock);
137871 +
137872 +static int find_empty_fq_table_entry(u32 *entry, struct qman_fq *fq)
137873 +{
137874 + u32 i;
137875 +
137876 + spin_lock(&fq_hash_table_lock);
137877 + /* Can't use index zero because this has special meaning
137878 + * in context_b field. */
137879 + for (i = 1; i < qman_fq_lookup_table_size; i++) {
137880 + if (qman_fq_lookup_table[i] == NULL) {
137881 + *entry = i;
137882 + qman_fq_lookup_table[i] = fq;
137883 + spin_unlock(&fq_hash_table_lock);
137884 + return 0;
137885 + }
137886 + }
137887 + spin_unlock(&fq_hash_table_lock);
137888 + return -ENOMEM;
137889 +}
137890 +
137891 +static void clear_fq_table_entry(u32 entry)
137892 +{
137893 + spin_lock(&fq_hash_table_lock);
137894 + BUG_ON(entry >= qman_fq_lookup_table_size);
137895 + qman_fq_lookup_table[entry] = NULL;
137896 + spin_unlock(&fq_hash_table_lock);
137897 +}
137898 +
137899 +static inline struct qman_fq *get_fq_table_entry(u32 entry)
137900 +{
137901 + BUG_ON(entry >= qman_fq_lookup_table_size);
137902 + return qman_fq_lookup_table[entry];
137903 +}
137904 +#endif
137905 +
137906 +static inline void cpu_to_hw_fqd(struct qm_fqd *fqd)
137907 +{
137908 + /* Byteswap the FQD to HW format */
137909 + fqd->fq_ctrl = cpu_to_be16(fqd->fq_ctrl);
137910 + fqd->dest_wq = cpu_to_be16(fqd->dest_wq);
137911 + fqd->ics_cred = cpu_to_be16(fqd->ics_cred);
137912 + fqd->context_b = cpu_to_be32(fqd->context_b);
137913 + fqd->context_a.opaque = cpu_to_be64(fqd->context_a.opaque);
137914 +}
137915 +
137916 +static inline void hw_fqd_to_cpu(struct qm_fqd *fqd)
137917 +{
137918 + /* Byteswap the FQD to CPU format */
137919 + fqd->fq_ctrl = be16_to_cpu(fqd->fq_ctrl);
137920 + fqd->dest_wq = be16_to_cpu(fqd->dest_wq);
137921 + fqd->ics_cred = be16_to_cpu(fqd->ics_cred);
137922 + fqd->context_b = be32_to_cpu(fqd->context_b);
137923 + fqd->context_a.opaque = be64_to_cpu(fqd->context_a.opaque);
137924 +}
137925 +
137926 +/* Swap a 40 bit address */
137927 +static inline u64 cpu_to_be40(u64 in)
137928 +{
137929 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137930 + return in;
137931 +#else
137932 + u64 out = 0;
137933 + u8 *p = (u8 *) &out;
137934 + p[0] = in >> 32;
137935 + p[1] = in >> 24;
137936 + p[2] = in >> 16;
137937 + p[3] = in >> 8;
137938 + p[4] = in >> 0;
137939 + return out;
137940 +#endif
137941 +}
137942 +static inline u64 be40_to_cpu(u64 in)
137943 +{
137944 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137945 + return in;
137946 +#else
137947 + u64 out = 0;
137948 + u8 *pout = (u8 *) &out;
137949 + u8 *pin = (u8 *) &in;
137950 + pout[0] = pin[4];
137951 + pout[1] = pin[3];
137952 + pout[2] = pin[2];
137953 + pout[3] = pin[1];
137954 + pout[4] = pin[0];
137955 + return out;
137956 +#endif
137957 +}
137958 +
137959 +/* Swap a 24 bit value */
137960 +static inline u32 cpu_to_be24(u32 in)
137961 +{
137962 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137963 + return in;
137964 +#else
137965 + u32 out = 0;
137966 + u8 *p = (u8 *) &out;
137967 + p[0] = in >> 16;
137968 + p[1] = in >> 8;
137969 + p[2] = in >> 0;
137970 + return out;
137971 +#endif
137972 +}
137973 +
137974 +static inline u32 be24_to_cpu(u32 in)
137975 +{
137976 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137977 + return in;
137978 +#else
137979 + u32 out = 0;
137980 + u8 *pout = (u8 *) &out;
137981 + u8 *pin = (u8 *) &in;
137982 + pout[0] = pin[2];
137983 + pout[1] = pin[1];
137984 + pout[2] = pin[0];
137985 + return out;
137986 +#endif
137987 +}
137988 +
137989 +static inline u64 be48_to_cpu(u64 in)
137990 +{
137991 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
137992 + return in;
137993 +#else
137994 + u64 out = 0;
137995 + u8 *pout = (u8 *) &out;
137996 + u8 *pin = (u8 *) &in;
137997 +
137998 + pout[0] = pin[5];
137999 + pout[1] = pin[4];
138000 + pout[2] = pin[3];
138001 + pout[3] = pin[2];
138002 + pout[4] = pin[1];
138003 + pout[5] = pin[0];
138004 + return out;
138005 +#endif
138006 +}
138007 +static inline void cpu_to_hw_fd(struct qm_fd *fd)
138008 +{
138009 + fd->opaque_addr = cpu_to_be64(fd->opaque_addr);
138010 + fd->status = cpu_to_be32(fd->status);
138011 + fd->opaque = cpu_to_be32(fd->opaque);
138012 +}
138013 +
138014 +static inline void hw_fd_to_cpu(struct qm_fd *fd)
138015 +{
138016 + fd->opaque_addr = be64_to_cpu(fd->opaque_addr);
138017 + fd->status = be32_to_cpu(fd->status);
138018 + fd->opaque = be32_to_cpu(fd->opaque);
138019 +}
138020 +
138021 +static inline void hw_cq_query_to_cpu(struct qm_mcr_ceetm_cq_query *cq_query)
138022 +{
138023 + cq_query->ccgid = be16_to_cpu(cq_query->ccgid);
138024 + cq_query->state = be16_to_cpu(cq_query->state);
138025 + cq_query->pfdr_hptr = be24_to_cpu(cq_query->pfdr_hptr);
138026 + cq_query->pfdr_tptr = be24_to_cpu(cq_query->pfdr_tptr);
138027 + cq_query->od1_xsfdr = be16_to_cpu(cq_query->od1_xsfdr);
138028 + cq_query->od2_xsfdr = be16_to_cpu(cq_query->od2_xsfdr);
138029 + cq_query->od3_xsfdr = be16_to_cpu(cq_query->od3_xsfdr);
138030 + cq_query->od4_xsfdr = be16_to_cpu(cq_query->od4_xsfdr);
138031 + cq_query->od5_xsfdr = be16_to_cpu(cq_query->od5_xsfdr);
138032 + cq_query->od6_xsfdr = be16_to_cpu(cq_query->od6_xsfdr);
138033 + cq_query->ra1_xsfdr = be16_to_cpu(cq_query->ra1_xsfdr);
138034 + cq_query->ra2_xsfdr = be16_to_cpu(cq_query->ra2_xsfdr);
138035 + cq_query->frm_cnt = be24_to_cpu(cq_query->frm_cnt);
138036 +}
138037 +
138038 +static inline void hw_ccgr_query_to_cpu(struct qm_mcr_ceetm_ccgr_query *ccgr_q)
138039 +{
138040 + int i;
138041 +
138042 + ccgr_q->cm_query.cs_thres.hword =
138043 + be16_to_cpu(ccgr_q->cm_query.cs_thres.hword);
138044 + ccgr_q->cm_query.cs_thres_x.hword =
138045 + be16_to_cpu(ccgr_q->cm_query.cs_thres_x.hword);
138046 + ccgr_q->cm_query.td_thres.hword =
138047 + be16_to_cpu(ccgr_q->cm_query.td_thres.hword);
138048 + ccgr_q->cm_query.wr_parm_g.word =
138049 + be32_to_cpu(ccgr_q->cm_query.wr_parm_g.word);
138050 + ccgr_q->cm_query.wr_parm_y.word =
138051 + be32_to_cpu(ccgr_q->cm_query.wr_parm_y.word);
138052 + ccgr_q->cm_query.wr_parm_r.word =
138053 + be32_to_cpu(ccgr_q->cm_query.wr_parm_r.word);
138054 + ccgr_q->cm_query.cscn_targ_dcp =
138055 + be16_to_cpu(ccgr_q->cm_query.cscn_targ_dcp);
138056 + ccgr_q->cm_query.i_cnt = be40_to_cpu(ccgr_q->cm_query.i_cnt);
138057 + ccgr_q->cm_query.a_cnt = be40_to_cpu(ccgr_q->cm_query.a_cnt);
138058 + for (i = 0; i < ARRAY_SIZE(ccgr_q->cm_query.cscn_targ_swp); i++)
138059 + ccgr_q->cm_query.cscn_targ_swp[i] =
138060 + be32_to_cpu(ccgr_q->cm_query.cscn_targ_swp[i]);
138061 +}
138062 +
138063 +/* In the case that slow- and fast-path handling are both done by qman_poll()
138064 + * (ie. because there is no interrupt handling), we ought to balance how often
138065 + * we do the fast-path poll versus the slow-path poll. We'll use two decrementer
138066 + * sources, so we call the fast poll 'n' times before calling the slow poll
138067 + * once. The idle decrementer constant is used when the last slow-poll detected
138068 + * no work to do, and the busy decrementer constant when the last slow-poll had
138069 + * work to do. */
138070 +#define SLOW_POLL_IDLE 1000
138071 +#define SLOW_POLL_BUSY 10
138072 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is);
138073 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
138074 + unsigned int poll_limit);
138075 +
138076 +/* Portal interrupt handler */
138077 +static irqreturn_t portal_isr(__always_unused int irq, void *ptr)
138078 +{
138079 + struct qman_portal *p = ptr;
138080 + /*
138081 + * The CSCI/CCSCI source is cleared inside __poll_portal_slow(), because
138082 + * it could race against a Query Congestion State command also given
138083 + * as part of the handling of this interrupt source. We mustn't
138084 + * clear it a second time in this top-level function.
138085 + */
138086 + u32 clear = QM_DQAVAIL_MASK | (p->irq_sources &
138087 + ~(QM_PIRQ_CSCI | QM_PIRQ_CCSCI));
138088 + u32 is = qm_isr_status_read(&p->p) & p->irq_sources;
138089 + /* DQRR-handling if it's interrupt-driven */
138090 + if (is & QM_PIRQ_DQRI)
138091 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
138092 + /* Handling of anything else that's interrupt-driven */
138093 + clear |= __poll_portal_slow(p, is);
138094 + qm_isr_status_clear(&p->p, clear);
138095 + return IRQ_HANDLED;
138096 +}
138097 +
138098 +/* This inner version is used privately by qman_create_affine_portal(), as well
138099 + * as by the exported qman_stop_dequeues(). */
138100 +static inline void qman_stop_dequeues_ex(struct qman_portal *p)
138101 +{
138102 + unsigned long irqflags __maybe_unused;
138103 + PORTAL_IRQ_LOCK(p, irqflags);
138104 + if (!(p->dqrr_disable_ref++))
138105 + qm_dqrr_set_maxfill(&p->p, 0);
138106 + PORTAL_IRQ_UNLOCK(p, irqflags);
138107 +}
138108 +
138109 +static int drain_mr_fqrni(struct qm_portal *p)
138110 +{
138111 + const struct qm_mr_entry *msg;
138112 +loop:
138113 + msg = qm_mr_current(p);
138114 + if (!msg) {
138115 + /* if MR was full and h/w had other FQRNI entries to produce, we
138116 + * need to allow it time to produce those entries once the
138117 + * existing entries are consumed. A worst-case situation
138118 + * (fully-loaded system) means h/w sequencers may have to do 3-4
138119 + * other things before servicing the portal's MR pump, each of
138120 + * which (if slow) may take ~50 qman cycles (which is ~200
138121 + * processor cycles). So rounding up and then multiplying this
138122 + * worst-case estimate by a factor of 10, just to be
138123 + * ultra-paranoid, goes as high as 10,000 cycles. NB, we consume
138124 + * one entry at a time, so h/w has an opportunity to produce new
138125 + * entries well before the ring has been fully consumed, so
138126 + * we're being *really* paranoid here. */
138127 + u64 now, then = mfatb();
138128 + do {
138129 + now = mfatb();
138130 + } while ((then + 10000) > now);
138131 + msg = qm_mr_current(p);
138132 + if (!msg)
138133 + return 0;
138134 + }
138135 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) != QM_MR_VERB_FQRNI) {
138136 + /* We aren't draining anything but FQRNIs */
138137 + pr_err("QMan found verb 0x%x in MR\n", msg->verb);
138138 + return -1;
138139 + }
138140 + qm_mr_next(p);
138141 + qm_mr_cci_consume(p, 1);
138142 + goto loop;
138143 +}
138144 +
138145 +#ifdef CONFIG_SUSPEND
138146 +static int _qman_portal_suspend_noirq(struct device *dev)
138147 +{
138148 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
138149 +#ifdef CONFIG_PM_DEBUG
138150 + struct platform_device *pdev = to_platform_device(dev);
138151 +#endif
138152 +
138153 + p->save_isdr = qm_isr_disable_read(&p->p);
138154 + qm_isr_disable_write(&p->p, 0xffffffff);
138155 + qm_isr_status_clear(&p->p, 0xffffffff);
138156 +#ifdef CONFIG_PM_DEBUG
138157 + pr_info("Suspend for %s\n", pdev->name);
138158 +#endif
138159 + return 0;
138160 +}
138161 +
138162 +static int _qman_portal_resume_noirq(struct device *dev)
138163 +{
138164 + struct qman_portal *p = (struct qman_portal *)dev->platform_data;
138165 +
138166 + /* restore isdr */
138167 + qm_isr_disable_write(&p->p, p->save_isdr);
138168 + return 0;
138169 +}
138170 +#else
138171 +#define _qman_portal_suspend_noirq NULL
138172 +#define _qman_portal_resume_noirq NULL
138173 +#endif
138174 +
138175 +struct dev_pm_domain qman_portal_device_pm_domain = {
138176 + .ops = {
138177 + USE_PLATFORM_PM_SLEEP_OPS
138178 + .suspend_noirq = _qman_portal_suspend_noirq,
138179 + .resume_noirq = _qman_portal_resume_noirq,
138180 + }
138181 +};
138182 +
138183 +struct qman_portal *qman_create_portal(
138184 + struct qman_portal *portal,
138185 + const struct qm_portal_config *config,
138186 + const struct qman_cgrs *cgrs)
138187 +{
138188 + struct qm_portal *__p;
138189 + char buf[16];
138190 + int ret;
138191 + u32 isdr;
138192 + struct platform_device_info pdev_info;
138193 +
138194 + if (!portal) {
138195 + portal = kmalloc(sizeof(*portal), GFP_KERNEL);
138196 + if (!portal)
138197 + return portal;
138198 + portal->alloced = 1;
138199 + } else
138200 + portal->alloced = 0;
138201 +
138202 + __p = &portal->p;
138203 +
138204 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && defined CONFIG_FSL_PAMU
138205 + /* PAMU is required for stashing */
138206 + portal->use_eqcr_ci_stashing = ((qman_ip_rev >= QMAN_REV30) ?
138207 + 1 : 0);
138208 +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
138209 + portal->use_eqcr_ci_stashing = 1;
138210 +#else
138211 + portal->use_eqcr_ci_stashing = 0;
138212 +#endif
138213 +
138214 + /* prep the low-level portal struct with the mapped addresses from the
138215 + * config, everything that follows depends on it and "config" is more
138216 + * for (de)reference... */
138217 + __p->addr.addr_ce = config->addr_virt[DPA_PORTAL_CE];
138218 + __p->addr.addr_ci = config->addr_virt[DPA_PORTAL_CI];
138219 + /*
138220 + * If CI-stashing is used, the current defaults use a threshold of 3,
138221 + * and stash with high-than-DQRR priority.
138222 + */
138223 + if (qm_eqcr_init(__p, qm_eqcr_pvb,
138224 + portal->use_eqcr_ci_stashing ? 3 : 0, 1)) {
138225 + pr_err("Qman EQCR initialisation failed\n");
138226 + goto fail_eqcr;
138227 + }
138228 + if (qm_dqrr_init(__p, config, qm_dqrr_dpush, qm_dqrr_pvb,
138229 + qm_dqrr_cdc, DQRR_MAXFILL)) {
138230 + pr_err("Qman DQRR initialisation failed\n");
138231 + goto fail_dqrr;
138232 + }
138233 + if (qm_mr_init(__p, qm_mr_pvb, qm_mr_cci)) {
138234 + pr_err("Qman MR initialisation failed\n");
138235 + goto fail_mr;
138236 + }
138237 + if (qm_mc_init(__p)) {
138238 + pr_err("Qman MC initialisation failed\n");
138239 + goto fail_mc;
138240 + }
138241 + if (qm_isr_init(__p)) {
138242 + pr_err("Qman ISR initialisation failed\n");
138243 + goto fail_isr;
138244 + }
138245 + /* static interrupt-gating controls */
138246 + qm_dqrr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_DQRR_ITHRESH);
138247 + qm_mr_set_ithresh(__p, CONFIG_FSL_QMAN_PIRQ_MR_ITHRESH);
138248 + qm_isr_set_iperiod(__p, CONFIG_FSL_QMAN_PIRQ_IPERIOD);
138249 + portal->cgrs = kmalloc(2 * sizeof(*cgrs), GFP_KERNEL);
138250 + if (!portal->cgrs)
138251 + goto fail_cgrs;
138252 + /* initial snapshot is no-depletion */
138253 + qman_cgrs_init(&portal->cgrs[1]);
138254 + if (cgrs)
138255 + portal->cgrs[0] = *cgrs;
138256 + else
138257 + /* if the given mask is NULL, assume all CGRs can be seen */
138258 + qman_cgrs_fill(&portal->cgrs[0]);
138259 + INIT_LIST_HEAD(&portal->cgr_cbs);
138260 + spin_lock_init(&portal->cgr_lock);
138261 + if (num_ceetms) {
138262 + for (ret = 0; ret < num_ceetms; ret++) {
138263 + portal->ccgrs[ret] = kmalloc(2 *
138264 + sizeof(struct qman_ccgrs), GFP_KERNEL);
138265 + if (!portal->ccgrs[ret])
138266 + goto fail_ccgrs;
138267 + qman_ccgrs_init(&portal->ccgrs[ret][1]);
138268 + qman_ccgrs_fill(&portal->ccgrs[ret][0]);
138269 + INIT_LIST_HEAD(&portal->ccgr_cbs[ret]);
138270 + }
138271 + }
138272 + spin_lock_init(&portal->ccgr_lock);
138273 + portal->bits = 0;
138274 + portal->slowpoll = 0;
138275 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138276 + portal->eqci_owned = NULL;
138277 +#endif
138278 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138279 + raw_spin_lock_init(&portal->sharing_lock);
138280 + portal->is_shared = config->public_cfg.is_shared;
138281 + portal->sharing_redirect = NULL;
138282 +#endif
138283 + portal->sdqcr = QM_SDQCR_SOURCE_CHANNELS | QM_SDQCR_COUNT_UPTO3 |
138284 + QM_SDQCR_DEDICATED_PRECEDENCE | QM_SDQCR_TYPE_PRIO_QOS |
138285 + QM_SDQCR_TOKEN_SET(0xab) | QM_SDQCR_CHANNELS_DEDICATED;
138286 + portal->dqrr_disable_ref = 0;
138287 + portal->cb_dc_ern = NULL;
138288 + sprintf(buf, "qportal-%d", config->public_cfg.channel);
138289 +
138290 + memset(&pdev_info, 0, sizeof(pdev_info));
138291 + pdev_info.name = buf;
138292 + pdev_info.id = PLATFORM_DEVID_NONE;
138293 + pdev_info.dma_mask = DMA_BIT_MASK(40);
138294 +
138295 + portal->pdev = platform_device_register_full(&pdev_info);
138296 + if (!portal->pdev) {
138297 + pr_err("qman_portal - platform_device_alloc() failed\n");
138298 + goto fail_devregister;
138299 + }
138300 +
138301 + arch_setup_dma_ops(&portal->pdev->dev, 0, 0, NULL, true);
138302 +
138303 + portal->pdev->dev.pm_domain = &qman_portal_device_pm_domain;
138304 + portal->pdev->dev.platform_data = portal;
138305 + dpa_rbtree_init(&portal->retire_table);
138306 + isdr = 0xffffffff;
138307 + qm_isr_disable_write(__p, isdr);
138308 + portal->irq_sources = 0;
138309 + qm_isr_enable_write(__p, portal->irq_sources);
138310 + qm_isr_status_clear(__p, 0xffffffff);
138311 + snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, config->public_cfg.cpu);
138312 + if (request_irq(config->public_cfg.irq, portal_isr, 0, portal->irqname,
138313 + portal)) {
138314 + pr_err("request_irq() failed\n");
138315 + goto fail_irq;
138316 + }
138317 + if ((config->public_cfg.cpu != -1) &&
138318 + irq_can_set_affinity(config->public_cfg.irq) &&
138319 + irq_set_affinity(config->public_cfg.irq,
138320 + cpumask_of(config->public_cfg.cpu))) {
138321 + pr_err("irq_set_affinity() failed\n");
138322 + goto fail_affinity;
138323 + }
138324 +
138325 + /* Need EQCR to be empty before continuing */
138326 + isdr ^= QM_PIRQ_EQCI;
138327 + qm_isr_disable_write(__p, isdr);
138328 + ret = qm_eqcr_get_fill(__p);
138329 + if (ret) {
138330 + pr_err("Qman EQCR unclean\n");
138331 + goto fail_eqcr_empty;
138332 + }
138333 + isdr ^= (QM_PIRQ_DQRI | QM_PIRQ_MRI);
138334 + qm_isr_disable_write(__p, isdr);
138335 + if (qm_dqrr_current(__p) != NULL) {
138336 + pr_err("Qman DQRR unclean\n");
138337 + qm_dqrr_cdc_consume_n(__p, 0xffff);
138338 + }
138339 + if (qm_mr_current(__p) != NULL) {
138340 + /* special handling, drain just in case it's a few FQRNIs */
138341 + if (drain_mr_fqrni(__p)) {
138342 + const struct qm_mr_entry *e = qm_mr_current(__p);
138343 + /*
138344 + * Message ring cannot be empty no need to check
138345 + * qm_mr_current returned successfully
138346 + */
138347 + pr_err("Qman MR unclean, MR VERB 0x%x, rc 0x%x\n, addr 0x%x",
138348 + e->verb, e->ern.rc, e->ern.fd.addr_lo);
138349 + goto fail_dqrr_mr_empty;
138350 + }
138351 + }
138352 + /* Success */
138353 + portal->config = config;
138354 + qm_isr_disable_write(__p, 0);
138355 + qm_isr_uninhibit(__p);
138356 + /* Write a sane SDQCR */
138357 + qm_dqrr_sdqcr_set(__p, portal->sdqcr);
138358 + return portal;
138359 +fail_dqrr_mr_empty:
138360 +fail_eqcr_empty:
138361 +fail_affinity:
138362 + free_irq(config->public_cfg.irq, portal);
138363 +fail_irq:
138364 + platform_device_unregister(portal->pdev);
138365 +fail_devregister:
138366 + if (num_ceetms)
138367 + for (ret = 0; ret < num_ceetms; ret++)
138368 + kfree(portal->ccgrs[ret]);
138369 +fail_ccgrs:
138370 + kfree(portal->cgrs);
138371 +fail_cgrs:
138372 + qm_isr_finish(__p);
138373 +fail_isr:
138374 + qm_mc_finish(__p);
138375 +fail_mc:
138376 + qm_mr_finish(__p);
138377 +fail_mr:
138378 + qm_dqrr_finish(__p);
138379 +fail_dqrr:
138380 + qm_eqcr_finish(__p);
138381 +fail_eqcr:
138382 + if (portal->alloced)
138383 + kfree(portal);
138384 + return NULL;
138385 +}
138386 +
138387 +struct qman_portal *qman_create_affine_portal(
138388 + const struct qm_portal_config *config,
138389 + const struct qman_cgrs *cgrs)
138390 +{
138391 + struct qman_portal *res;
138392 + struct qman_portal *portal;
138393 +
138394 + portal = &per_cpu(qman_affine_portal, config->public_cfg.cpu);
138395 + res = qman_create_portal(portal, config, cgrs);
138396 + if (res) {
138397 + spin_lock(&affine_mask_lock);
138398 + cpumask_set_cpu(config->public_cfg.cpu, &affine_mask);
138399 + affine_channels[config->public_cfg.cpu] =
138400 + config->public_cfg.channel;
138401 + affine_portals[config->public_cfg.cpu] = portal;
138402 + spin_unlock(&affine_mask_lock);
138403 + }
138404 + return res;
138405 +}
138406 +
138407 +/* These checks are BUG_ON()s because the driver is already supposed to avoid
138408 + * these cases. */
138409 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
138410 + int cpu)
138411 +{
138412 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138413 + struct qman_portal *p;
138414 + p = &per_cpu(qman_affine_portal, cpu);
138415 + /* Check that we don't already have our own portal */
138416 + BUG_ON(p->config);
138417 + /* Check that we aren't already slaving to another portal */
138418 + BUG_ON(p->is_shared);
138419 + /* Check that 'redirect' is prepared to have us */
138420 + BUG_ON(!redirect->config->public_cfg.is_shared);
138421 + /* These are the only elements to initialise when redirecting */
138422 + p->irq_sources = 0;
138423 + p->sharing_redirect = redirect;
138424 + affine_portals[cpu] = p;
138425 + return p;
138426 +#else
138427 + BUG();
138428 + return NULL;
138429 +#endif
138430 +}
138431 +
138432 +void qman_destroy_portal(struct qman_portal *qm)
138433 +{
138434 + const struct qm_portal_config *pcfg;
138435 + int i;
138436 +
138437 + /* Stop dequeues on the portal */
138438 + qm_dqrr_sdqcr_set(&qm->p, 0);
138439 +
138440 + /* NB we do this to "quiesce" EQCR. If we add enqueue-completions or
138441 + * something related to QM_PIRQ_EQCI, this may need fixing.
138442 + * Also, due to the prefetching model used for CI updates in the enqueue
138443 + * path, this update will only invalidate the CI cacheline *after*
138444 + * working on it, so we need to call this twice to ensure a full update
138445 + * irrespective of where the enqueue processing was at when the teardown
138446 + * began. */
138447 + qm_eqcr_cce_update(&qm->p);
138448 + qm_eqcr_cce_update(&qm->p);
138449 + pcfg = qm->config;
138450 +
138451 + free_irq(pcfg->public_cfg.irq, qm);
138452 +
138453 + kfree(qm->cgrs);
138454 + if (num_ceetms)
138455 + for (i = 0; i < num_ceetms; i++)
138456 + kfree(qm->ccgrs[i]);
138457 + qm_isr_finish(&qm->p);
138458 + qm_mc_finish(&qm->p);
138459 + qm_mr_finish(&qm->p);
138460 + qm_dqrr_finish(&qm->p);
138461 + qm_eqcr_finish(&qm->p);
138462 +
138463 + platform_device_unregister(qm->pdev);
138464 +
138465 + qm->config = NULL;
138466 + if (qm->alloced)
138467 + kfree(qm);
138468 +}
138469 +
138470 +const struct qm_portal_config *qman_destroy_affine_portal(void)
138471 +{
138472 + /* We don't want to redirect if we're a slave, use "raw" */
138473 + struct qman_portal *qm = get_raw_affine_portal();
138474 + const struct qm_portal_config *pcfg;
138475 + int cpu;
138476 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138477 + if (qm->sharing_redirect) {
138478 + qm->sharing_redirect = NULL;
138479 + put_affine_portal();
138480 + return NULL;
138481 + }
138482 + qm->is_shared = 0;
138483 +#endif
138484 + pcfg = qm->config;
138485 + cpu = pcfg->public_cfg.cpu;
138486 +
138487 + qman_destroy_portal(qm);
138488 +
138489 + spin_lock(&affine_mask_lock);
138490 + cpumask_clear_cpu(cpu, &affine_mask);
138491 + spin_unlock(&affine_mask_lock);
138492 + put_affine_portal();
138493 + return pcfg;
138494 +}
138495 +
138496 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal *p)
138497 +{
138498 + return &p->config->public_cfg;
138499 +}
138500 +EXPORT_SYMBOL(qman_p_get_portal_config);
138501 +
138502 +const struct qman_portal_config *qman_get_portal_config(void)
138503 +{
138504 + struct qman_portal *p = get_affine_portal();
138505 + const struct qman_portal_config *ret = qman_p_get_portal_config(p);
138506 + put_affine_portal();
138507 + return ret;
138508 +}
138509 +EXPORT_SYMBOL(qman_get_portal_config);
138510 +
138511 +/* Inline helper to reduce nesting in __poll_portal_slow() */
138512 +static inline void fq_state_change(struct qman_portal *p, struct qman_fq *fq,
138513 + const struct qm_mr_entry *msg, u8 verb)
138514 +{
138515 + FQLOCK(fq);
138516 + switch (verb) {
138517 + case QM_MR_VERB_FQRL:
138518 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_ORL));
138519 + fq_clear(fq, QMAN_FQ_STATE_ORL);
138520 + table_del_fq(p, fq);
138521 + break;
138522 + case QM_MR_VERB_FQRN:
138523 + DPA_ASSERT((fq->state == qman_fq_state_parked) ||
138524 + (fq->state == qman_fq_state_sched));
138525 + DPA_ASSERT(fq_isset(fq, QMAN_FQ_STATE_CHANGING));
138526 + fq_clear(fq, QMAN_FQ_STATE_CHANGING);
138527 + if (msg->fq.fqs & QM_MR_FQS_NOTEMPTY)
138528 + fq_set(fq, QMAN_FQ_STATE_NE);
138529 + if (msg->fq.fqs & QM_MR_FQS_ORLPRESENT)
138530 + fq_set(fq, QMAN_FQ_STATE_ORL);
138531 + else
138532 + table_del_fq(p, fq);
138533 + fq->state = qman_fq_state_retired;
138534 + break;
138535 + case QM_MR_VERB_FQPN:
138536 + DPA_ASSERT(fq->state == qman_fq_state_sched);
138537 + DPA_ASSERT(fq_isclear(fq, QMAN_FQ_STATE_CHANGING));
138538 + fq->state = qman_fq_state_parked;
138539 + }
138540 + FQUNLOCK(fq);
138541 +}
138542 +
138543 +static u32 __poll_portal_slow(struct qman_portal *p, u32 is)
138544 +{
138545 + const struct qm_mr_entry *msg;
138546 + struct qm_mr_entry swapped_msg;
138547 + int k;
138548 +
138549 + if (is & QM_PIRQ_CSCI) {
138550 + struct qman_cgrs rr, c;
138551 + struct qm_mc_result *mcr;
138552 + struct qman_cgr *cgr;
138553 + unsigned long irqflags __maybe_unused;
138554 +
138555 + spin_lock_irqsave(&p->cgr_lock, irqflags);
138556 + /*
138557 + * The CSCI bit must be cleared _before_ issuing the
138558 + * Query Congestion State command, to ensure that a long
138559 + * CGR State Change callback cannot miss an intervening
138560 + * state change.
138561 + */
138562 + qm_isr_status_clear(&p->p, QM_PIRQ_CSCI);
138563 + qm_mc_start(&p->p);
138564 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
138565 + while (!(mcr = qm_mc_result(&p->p)))
138566 + cpu_relax();
138567 + for (k = 0; k < 8; k++)
138568 + mcr->querycongestion.state.__state[k] = be32_to_cpu(
138569 + mcr->querycongestion.state.__state[k]);
138570 + /* mask out the ones I'm not interested in */
138571 + qman_cgrs_and(&rr, (const struct qman_cgrs *)
138572 + &mcr->querycongestion.state, &p->cgrs[0]);
138573 + /* check previous snapshot for delta, enter/exit congestion */
138574 + qman_cgrs_xor(&c, &rr, &p->cgrs[1]);
138575 + /* update snapshot */
138576 + qman_cgrs_cp(&p->cgrs[1], &rr);
138577 + /* Invoke callback */
138578 + list_for_each_entry(cgr, &p->cgr_cbs, node)
138579 + if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid))
138580 + cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid));
138581 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
138582 + }
138583 + if (is & QM_PIRQ_CCSCI) {
138584 + struct qman_ccgrs rr, c, congestion_result;
138585 + struct qm_mc_result *mcr;
138586 + struct qm_mc_command *mcc;
138587 + struct qm_ceetm_ccg *ccg;
138588 + unsigned long irqflags __maybe_unused;
138589 + int i, j;
138590 +
138591 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
138592 + /*
138593 + * The CCSCI bit must be cleared _before_ issuing the
138594 + * Query Congestion State command, to ensure that a long
138595 + * CCGR State Change callback cannot miss an intervening
138596 + * state change.
138597 + */
138598 + qm_isr_status_clear(&p->p, QM_PIRQ_CCSCI);
138599 +
138600 + for (i = 0; i < num_ceetms; i++) {
138601 + for (j = 0; j < 2; j++) {
138602 + mcc = qm_mc_start(&p->p);
138603 + mcc->ccgr_query.ccgrid = cpu_to_be16(
138604 + CEETM_QUERY_CONGESTION_STATE | j);
138605 + mcc->ccgr_query.dcpid = i;
138606 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
138607 + while (!(mcr = qm_mc_result(&p->p)))
138608 + cpu_relax();
138609 + for (k = 0; k < 8; k++)
138610 + mcr->ccgr_query.congestion_state.state.
138611 + __state[k] = be32_to_cpu(
138612 + mcr->ccgr_query.
138613 + congestion_state.state.
138614 + __state[k]);
138615 + congestion_result.q[j] =
138616 + mcr->ccgr_query.congestion_state.state;
138617 + }
138618 + /* mask out the ones I'm not interested in */
138619 + qman_ccgrs_and(&rr, &congestion_result,
138620 + &p->ccgrs[i][0]);
138621 + /*
138622 + * check previous snapshot for delta, enter/exit
138623 + * congestion.
138624 + */
138625 + qman_ccgrs_xor(&c, &rr, &p->ccgrs[i][1]);
138626 + /* update snapshot */
138627 + qman_ccgrs_cp(&p->ccgrs[i][1], &rr);
138628 + /* Invoke callback */
138629 + list_for_each_entry(ccg, &p->ccgr_cbs[i], cb_node)
138630 + if (ccg->cb && qman_ccgrs_get(&c,
138631 + (ccg->parent->idx << 4) | ccg->idx))
138632 + ccg->cb(ccg, ccg->cb_ctx,
138633 + qman_ccgrs_get(&rr,
138634 + (ccg->parent->idx << 4)
138635 + | ccg->idx));
138636 + }
138637 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
138638 + }
138639 +
138640 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
138641 + if (is & QM_PIRQ_EQCI) {
138642 + unsigned long irqflags;
138643 + PORTAL_IRQ_LOCK(p, irqflags);
138644 + p->eqci_owned = NULL;
138645 + PORTAL_IRQ_UNLOCK(p, irqflags);
138646 + wake_up(&affine_queue);
138647 + }
138648 +#endif
138649 +
138650 + if (is & QM_PIRQ_EQRI) {
138651 + unsigned long irqflags __maybe_unused;
138652 + PORTAL_IRQ_LOCK(p, irqflags);
138653 + qm_eqcr_cce_update(&p->p);
138654 + qm_eqcr_set_ithresh(&p->p, 0);
138655 + PORTAL_IRQ_UNLOCK(p, irqflags);
138656 + wake_up(&affine_queue);
138657 + }
138658 +
138659 + if (is & QM_PIRQ_MRI) {
138660 + struct qman_fq *fq;
138661 + u8 verb, num = 0;
138662 +mr_loop:
138663 + qm_mr_pvb_update(&p->p);
138664 + msg = qm_mr_current(&p->p);
138665 + if (!msg)
138666 + goto mr_done;
138667 + swapped_msg = *msg;
138668 + hw_fd_to_cpu(&swapped_msg.ern.fd);
138669 + verb = msg->verb & QM_MR_VERB_TYPE_MASK;
138670 + /* The message is a software ERN iff the 0x20 bit is set */
138671 + if (verb & 0x20) {
138672 + switch (verb) {
138673 + case QM_MR_VERB_FQRNI:
138674 + /* nada, we drop FQRNIs on the floor */
138675 + break;
138676 + case QM_MR_VERB_FQRN:
138677 + case QM_MR_VERB_FQRL:
138678 + /* Lookup in the retirement table */
138679 + fq = table_find_fq(p, be32_to_cpu(msg->fq.fqid));
138680 + BUG_ON(!fq);
138681 + fq_state_change(p, fq, &swapped_msg, verb);
138682 + if (fq->cb.fqs)
138683 + fq->cb.fqs(p, fq, &swapped_msg);
138684 + break;
138685 + case QM_MR_VERB_FQPN:
138686 + /* Parked */
138687 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138688 + fq = get_fq_table_entry(
138689 + be32_to_cpu(msg->fq.contextB));
138690 +#else
138691 + fq = (void *)(uintptr_t)
138692 + be32_to_cpu(msg->fq.contextB);
138693 +#endif
138694 + fq_state_change(p, fq, msg, verb);
138695 + if (fq->cb.fqs)
138696 + fq->cb.fqs(p, fq, &swapped_msg);
138697 + break;
138698 + case QM_MR_VERB_DC_ERN:
138699 + /* DCP ERN */
138700 + if (p->cb_dc_ern)
138701 + p->cb_dc_ern(p, msg);
138702 + else if (cb_dc_ern)
138703 + cb_dc_ern(p, msg);
138704 + else {
138705 + static int warn_once;
138706 + if (!warn_once) {
138707 + pr_crit("Leaking DCP ERNs!\n");
138708 + warn_once = 1;
138709 + }
138710 + }
138711 + break;
138712 + default:
138713 + pr_crit("Invalid MR verb 0x%02x\n", verb);
138714 + }
138715 + } else {
138716 + /* Its a software ERN */
138717 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138718 + fq = get_fq_table_entry(be32_to_cpu(msg->ern.tag));
138719 +#else
138720 + fq = (void *)(uintptr_t)be32_to_cpu(msg->ern.tag);
138721 +#endif
138722 + fq->cb.ern(p, fq, &swapped_msg);
138723 + }
138724 + num++;
138725 + qm_mr_next(&p->p);
138726 + goto mr_loop;
138727 +mr_done:
138728 + qm_mr_cci_consume(&p->p, num);
138729 + }
138730 + /*
138731 + * QM_PIRQ_CSCI/CCSCI has already been cleared, as part of its specific
138732 + * processing. If that interrupt source has meanwhile been re-asserted,
138733 + * we mustn't clear it here (or in the top-level interrupt handler).
138734 + */
138735 + return is & (QM_PIRQ_EQCI | QM_PIRQ_EQRI | QM_PIRQ_MRI);
138736 +}
138737 +
138738 +/* remove some slowish-path stuff from the "fast path" and make sure it isn't
138739 + * inlined. */
138740 +static noinline void clear_vdqcr(struct qman_portal *p, struct qman_fq *fq)
138741 +{
138742 + p->vdqcr_owned = NULL;
138743 + FQLOCK(fq);
138744 + fq_clear(fq, QMAN_FQ_STATE_VDQCR);
138745 + FQUNLOCK(fq);
138746 + wake_up(&affine_queue);
138747 +}
138748 +
138749 +/* Copy a DQRR entry ensuring reads reach QBMan in order */
138750 +static inline void safe_copy_dqrr(struct qm_dqrr_entry *dst,
138751 + const struct qm_dqrr_entry *src)
138752 +{
138753 + int i = 0;
138754 + const u64 *s64 = (u64*)src;
138755 + u64 *d64 = (u64*)dst;
138756 +
138757 + /* DQRR only has 32 bytes of valid data so only need to
138758 + * copy 4 - 64 bit values */
138759 + *d64 = *s64;
138760 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
138761 + {
138762 + u32 res, zero = 0;
138763 + /* Create a dependancy after copying first bytes ensures no wrap
138764 + transaction generated to QBMan */
138765 + /* Logical AND the value pointed to by s64 with 0x0 and
138766 + store the result in res */
138767 + asm volatile("and %[result], %[in1], %[in2]"
138768 + : [result] "=r" (res)
138769 + : [in1] "r" (zero), [in2] "r" (*s64)
138770 + : "memory");
138771 + /* Add res to s64 - this creates a dependancy on the result of
138772 + reading the value of s64 before the next read. The side
138773 + effect of this is that the core must stall until the first
138774 + aligned read is complete therefore preventing a WRAP
138775 + transaction to be seen by the QBMan */
138776 + asm volatile("add %[result], %[in1], %[in2]"
138777 + : [result] "=r" (s64)
138778 + : [in1] "r" (res), [in2] "r" (s64)
138779 + : "memory");
138780 + }
138781 +#endif
138782 + /* Copy the last 3 64 bit parts */
138783 + d64++; s64++;
138784 + for (;i<3; i++)
138785 + *d64++ = *s64++;
138786 +}
138787 +
138788 +/* Look: no locks, no irq_save()s, no preempt_disable()s! :-) The only states
138789 + * that would conflict with other things if they ran at the same time on the
138790 + * same cpu are;
138791 + *
138792 + * (i) setting/clearing vdqcr_owned, and
138793 + * (ii) clearing the NE (Not Empty) flag.
138794 + *
138795 + * Both are safe. Because;
138796 + *
138797 + * (i) this clearing can only occur after qman_volatile_dequeue() has set the
138798 + * vdqcr_owned field (which it does before setting VDQCR), and
138799 + * qman_volatile_dequeue() blocks interrupts and preemption while this is
138800 + * done so that we can't interfere.
138801 + * (ii) the NE flag is only cleared after qman_retire_fq() has set it, and as
138802 + * with (i) that API prevents us from interfering until it's safe.
138803 + *
138804 + * The good thing is that qman_volatile_dequeue() and qman_retire_fq() run far
138805 + * less frequently (ie. per-FQ) than __poll_portal_fast() does, so the nett
138806 + * advantage comes from this function not having to "lock" anything at all.
138807 + *
138808 + * Note also that the callbacks are invoked at points which are safe against the
138809 + * above potential conflicts, but that this function itself is not re-entrant
138810 + * (this is because the function tracks one end of each FIFO in the portal and
138811 + * we do *not* want to lock that). So the consequence is that it is safe for
138812 + * user callbacks to call into any Qman API *except* qman_poll() (as that's the
138813 + * sole API that could be invoking the callback through this function).
138814 + */
138815 +static inline unsigned int __poll_portal_fast(struct qman_portal *p,
138816 + unsigned int poll_limit)
138817 +{
138818 + const struct qm_dqrr_entry *dq;
138819 + struct qman_fq *fq;
138820 + enum qman_cb_dqrr_result res;
138821 + unsigned int limit = 0;
138822 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
138823 + struct qm_dqrr_entry *shadow;
138824 + const struct qm_dqrr_entry *orig_dq;
138825 +#endif
138826 +loop:
138827 + qm_dqrr_pvb_update(&p->p);
138828 + dq = qm_dqrr_current(&p->p);
138829 + if (!dq)
138830 + goto done;
138831 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
138832 + /* If running on an LE system the fields of the
138833 + dequeue entry must be swapped. Because the
138834 + QMan HW will ignore writes the DQRR entry is
138835 + copied and the index stored within the copy */
138836 + shadow = &p->shadow_dqrr[DQRR_PTR2IDX(dq)];
138837 + /* Use safe copy here to avoid WRAP transaction */
138838 + safe_copy_dqrr(shadow, dq);
138839 + orig_dq = dq;
138840 + dq = shadow;
138841 + shadow->fqid = be32_to_cpu(shadow->fqid);
138842 + shadow->contextB = be32_to_cpu(shadow->contextB);
138843 + shadow->seqnum = be16_to_cpu(shadow->seqnum);
138844 + hw_fd_to_cpu(&shadow->fd);
138845 +#endif
138846 + if (dq->stat & QM_DQRR_STAT_UNSCHEDULED) {
138847 + /* VDQCR: don't trust contextB as the FQ may have been
138848 + * configured for h/w consumption and we're draining it
138849 + * post-retirement. */
138850 + fq = p->vdqcr_owned;
138851 + /* We only set QMAN_FQ_STATE_NE when retiring, so we only need
138852 + * to check for clearing it when doing volatile dequeues. It's
138853 + * one less thing to check in the critical path (SDQCR). */
138854 + if (dq->stat & QM_DQRR_STAT_FQ_EMPTY)
138855 + fq_clear(fq, QMAN_FQ_STATE_NE);
138856 + /* this is duplicated from the SDQCR code, but we have stuff to
138857 + * do before *and* after this callback, and we don't want
138858 + * multiple if()s in the critical path (SDQCR). */
138859 + res = fq->cb.dqrr(p, fq, dq);
138860 + if (res == qman_cb_dqrr_stop)
138861 + goto done;
138862 + /* Check for VDQCR completion */
138863 + if (dq->stat & QM_DQRR_STAT_DQCR_EXPIRED)
138864 + clear_vdqcr(p, fq);
138865 + } else {
138866 + /* SDQCR: contextB points to the FQ */
138867 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
138868 + fq = get_fq_table_entry(dq->contextB);
138869 +#else
138870 + fq = (void *)(uintptr_t)dq->contextB;
138871 +#endif
138872 + /* Now let the callback do its stuff */
138873 + res = fq->cb.dqrr(p, fq, dq);
138874 +
138875 + /* The callback can request that we exit without consuming this
138876 + * entry nor advancing; */
138877 + if (res == qman_cb_dqrr_stop)
138878 + goto done;
138879 + }
138880 + /* Interpret 'dq' from a driver perspective. */
138881 + /* Parking isn't possible unless HELDACTIVE was set. NB,
138882 + * FORCEELIGIBLE implies HELDACTIVE, so we only need to
138883 + * check for HELDACTIVE to cover both. */
138884 + DPA_ASSERT((dq->stat & QM_DQRR_STAT_FQ_HELDACTIVE) ||
138885 + (res != qman_cb_dqrr_park));
138886 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
138887 + if (res != qman_cb_dqrr_defer)
138888 + qm_dqrr_cdc_consume_1ptr(&p->p, orig_dq,
138889 + (res == qman_cb_dqrr_park));
138890 +#else
138891 + /* Defer just means "skip it, I'll consume it myself later on" */
138892 + if (res != qman_cb_dqrr_defer)
138893 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, (res == qman_cb_dqrr_park));
138894 +#endif
138895 + /* Move forward */
138896 + qm_dqrr_next(&p->p);
138897 + /* Entry processed and consumed, increment our counter. The callback can
138898 + * request that we exit after consuming the entry, and we also exit if
138899 + * we reach our processing limit, so loop back only if neither of these
138900 + * conditions is met. */
138901 + if ((++limit < poll_limit) && (res != qman_cb_dqrr_consume_stop))
138902 + goto loop;
138903 +done:
138904 + return limit;
138905 +}
138906 +
138907 +u32 qman_irqsource_get(void)
138908 +{
138909 + /* "irqsource" and "poll" APIs mustn't redirect when sharing, they
138910 + * should shut the user out if they are not the primary CPU hosting the
138911 + * portal. That's why we use the "raw" interface. */
138912 + struct qman_portal *p = get_raw_affine_portal();
138913 + u32 ret = p->irq_sources & QM_PIRQ_VISIBLE;
138914 + put_affine_portal();
138915 + return ret;
138916 +}
138917 +EXPORT_SYMBOL(qman_irqsource_get);
138918 +
138919 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits __maybe_unused)
138920 +{
138921 + __maybe_unused unsigned long irqflags;
138922 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138923 + if (p->sharing_redirect)
138924 + return -EINVAL;
138925 + else
138926 +#endif
138927 + {
138928 + bits = bits & QM_PIRQ_VISIBLE;
138929 + PORTAL_IRQ_LOCK(p, irqflags);
138930 +
138931 + /* Clear any previously remaining interrupt conditions in
138932 + * QCSP_ISR. This prevents raising a false interrupt when
138933 + * interrupt conditions are enabled in QCSP_IER.
138934 + */
138935 + qm_isr_status_clear(&p->p, bits);
138936 + set_bits(bits, &p->irq_sources);
138937 + qm_isr_enable_write(&p->p, p->irq_sources);
138938 + PORTAL_IRQ_UNLOCK(p, irqflags);
138939 + }
138940 + return 0;
138941 +}
138942 +EXPORT_SYMBOL(qman_p_irqsource_add);
138943 +
138944 +int qman_irqsource_add(u32 bits __maybe_unused)
138945 +{
138946 + struct qman_portal *p = get_raw_affine_portal();
138947 + int ret;
138948 + ret = qman_p_irqsource_add(p, bits);
138949 + put_affine_portal();
138950 + return ret;
138951 +}
138952 +EXPORT_SYMBOL(qman_irqsource_add);
138953 +
138954 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits)
138955 +{
138956 + __maybe_unused unsigned long irqflags;
138957 + u32 ier;
138958 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
138959 + if (p->sharing_redirect) {
138960 + put_affine_portal();
138961 + return -EINVAL;
138962 + }
138963 +#endif
138964 + /* Our interrupt handler only processes+clears status register bits that
138965 + * are in p->irq_sources. As we're trimming that mask, if one of them
138966 + * were to assert in the status register just before we remove it from
138967 + * the enable register, there would be an interrupt-storm when we
138968 + * release the IRQ lock. So we wait for the enable register update to
138969 + * take effect in h/w (by reading it back) and then clear all other bits
138970 + * in the status register. Ie. we clear them from ISR once it's certain
138971 + * IER won't allow them to reassert. */
138972 + PORTAL_IRQ_LOCK(p, irqflags);
138973 + bits &= QM_PIRQ_VISIBLE;
138974 + clear_bits(bits, &p->irq_sources);
138975 + qm_isr_enable_write(&p->p, p->irq_sources);
138976 +
138977 + ier = qm_isr_enable_read(&p->p);
138978 + /* Using "~ier" (rather than "bits" or "~p->irq_sources") creates a
138979 + * data-dependency, ie. to protect against re-ordering. */
138980 + qm_isr_status_clear(&p->p, ~ier);
138981 + PORTAL_IRQ_UNLOCK(p, irqflags);
138982 + return 0;
138983 +}
138984 +EXPORT_SYMBOL(qman_p_irqsource_remove);
138985 +
138986 +int qman_irqsource_remove(u32 bits)
138987 +{
138988 + struct qman_portal *p = get_raw_affine_portal();
138989 + int ret;
138990 + ret = qman_p_irqsource_remove(p, bits);
138991 + put_affine_portal();
138992 + return ret;
138993 +}
138994 +EXPORT_SYMBOL(qman_irqsource_remove);
138995 +
138996 +const cpumask_t *qman_affine_cpus(void)
138997 +{
138998 + return &affine_mask;
138999 +}
139000 +EXPORT_SYMBOL(qman_affine_cpus);
139001 +
139002 +u16 qman_affine_channel(int cpu)
139003 +{
139004 + if (cpu < 0) {
139005 + struct qman_portal *portal = get_raw_affine_portal();
139006 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
139007 + BUG_ON(portal->sharing_redirect);
139008 +#endif
139009 + cpu = portal->config->public_cfg.cpu;
139010 + put_affine_portal();
139011 + }
139012 + BUG_ON(!cpumask_test_cpu(cpu, &affine_mask));
139013 + return affine_channels[cpu];
139014 +}
139015 +EXPORT_SYMBOL(qman_affine_channel);
139016 +
139017 +void *qman_get_affine_portal(int cpu)
139018 +{
139019 + return affine_portals[cpu];
139020 +}
139021 +EXPORT_SYMBOL(qman_get_affine_portal);
139022 +
139023 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit)
139024 +{
139025 + int ret;
139026 +
139027 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
139028 + if (unlikely(p->sharing_redirect))
139029 + ret = -EINVAL;
139030 + else
139031 +#endif
139032 + {
139033 + BUG_ON(p->irq_sources & QM_PIRQ_DQRI);
139034 + ret = __poll_portal_fast(p, limit);
139035 + }
139036 + return ret;
139037 +}
139038 +EXPORT_SYMBOL(qman_p_poll_dqrr);
139039 +
139040 +int qman_poll_dqrr(unsigned int limit)
139041 +{
139042 + struct qman_portal *p = get_poll_portal();
139043 + int ret;
139044 + ret = qman_p_poll_dqrr(p, limit);
139045 + put_poll_portal();
139046 + return ret;
139047 +}
139048 +EXPORT_SYMBOL(qman_poll_dqrr);
139049 +
139050 +u32 qman_p_poll_slow(struct qman_portal *p)
139051 +{
139052 + u32 ret;
139053 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
139054 + if (unlikely(p->sharing_redirect))
139055 + ret = (u32)-1;
139056 + else
139057 +#endif
139058 + {
139059 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
139060 + ret = __poll_portal_slow(p, is);
139061 + qm_isr_status_clear(&p->p, ret);
139062 + }
139063 + return ret;
139064 +}
139065 +EXPORT_SYMBOL(qman_p_poll_slow);
139066 +
139067 +u32 qman_poll_slow(void)
139068 +{
139069 + struct qman_portal *p = get_poll_portal();
139070 + u32 ret;
139071 + ret = qman_p_poll_slow(p);
139072 + put_poll_portal();
139073 + return ret;
139074 +}
139075 +EXPORT_SYMBOL(qman_poll_slow);
139076 +
139077 +/* Legacy wrapper */
139078 +void qman_p_poll(struct qman_portal *p)
139079 +{
139080 +#ifdef CONFIG_FSL_DPA_PORTAL_SHARE
139081 + if (unlikely(p->sharing_redirect))
139082 + return;
139083 +#endif
139084 + if ((~p->irq_sources) & QM_PIRQ_SLOW) {
139085 + if (!(p->slowpoll--)) {
139086 + u32 is = qm_isr_status_read(&p->p) & ~p->irq_sources;
139087 + u32 active = __poll_portal_slow(p, is);
139088 + if (active) {
139089 + qm_isr_status_clear(&p->p, active);
139090 + p->slowpoll = SLOW_POLL_BUSY;
139091 + } else
139092 + p->slowpoll = SLOW_POLL_IDLE;
139093 + }
139094 + }
139095 + if ((~p->irq_sources) & QM_PIRQ_DQRI)
139096 + __poll_portal_fast(p, CONFIG_FSL_QMAN_POLL_LIMIT);
139097 +}
139098 +EXPORT_SYMBOL(qman_p_poll);
139099 +
139100 +void qman_poll(void)
139101 +{
139102 + struct qman_portal *p = get_poll_portal();
139103 + qman_p_poll(p);
139104 + put_poll_portal();
139105 +}
139106 +EXPORT_SYMBOL(qman_poll);
139107 +
139108 +void qman_p_stop_dequeues(struct qman_portal *p)
139109 +{
139110 + qman_stop_dequeues_ex(p);
139111 +}
139112 +EXPORT_SYMBOL(qman_p_stop_dequeues);
139113 +
139114 +void qman_stop_dequeues(void)
139115 +{
139116 + struct qman_portal *p = get_affine_portal();
139117 + qman_p_stop_dequeues(p);
139118 + put_affine_portal();
139119 +}
139120 +EXPORT_SYMBOL(qman_stop_dequeues);
139121 +
139122 +void qman_p_start_dequeues(struct qman_portal *p)
139123 +{
139124 + unsigned long irqflags __maybe_unused;
139125 + PORTAL_IRQ_LOCK(p, irqflags);
139126 + DPA_ASSERT(p->dqrr_disable_ref > 0);
139127 + if (!(--p->dqrr_disable_ref))
139128 + qm_dqrr_set_maxfill(&p->p, DQRR_MAXFILL);
139129 + PORTAL_IRQ_UNLOCK(p, irqflags);
139130 +}
139131 +EXPORT_SYMBOL(qman_p_start_dequeues);
139132 +
139133 +void qman_start_dequeues(void)
139134 +{
139135 + struct qman_portal *p = get_affine_portal();
139136 + qman_p_start_dequeues(p);
139137 + put_affine_portal();
139138 +}
139139 +EXPORT_SYMBOL(qman_start_dequeues);
139140 +
139141 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools)
139142 +{
139143 + unsigned long irqflags __maybe_unused;
139144 + PORTAL_IRQ_LOCK(p, irqflags);
139145 + pools &= p->config->public_cfg.pools;
139146 + p->sdqcr |= pools;
139147 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
139148 + PORTAL_IRQ_UNLOCK(p, irqflags);
139149 +}
139150 +EXPORT_SYMBOL(qman_p_static_dequeue_add);
139151 +
139152 +void qman_static_dequeue_add(u32 pools)
139153 +{
139154 + struct qman_portal *p = get_affine_portal();
139155 + qman_p_static_dequeue_add(p, pools);
139156 + put_affine_portal();
139157 +}
139158 +EXPORT_SYMBOL(qman_static_dequeue_add);
139159 +
139160 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools)
139161 +{
139162 + unsigned long irqflags __maybe_unused;
139163 + PORTAL_IRQ_LOCK(p, irqflags);
139164 + pools &= p->config->public_cfg.pools;
139165 + p->sdqcr &= ~pools;
139166 + qm_dqrr_sdqcr_set(&p->p, p->sdqcr);
139167 + PORTAL_IRQ_UNLOCK(p, irqflags);
139168 +}
139169 +EXPORT_SYMBOL(qman_p_static_dequeue_del);
139170 +
139171 +void qman_static_dequeue_del(u32 pools)
139172 +{
139173 + struct qman_portal *p = get_affine_portal();
139174 + qman_p_static_dequeue_del(p, pools);
139175 + put_affine_portal();
139176 +}
139177 +EXPORT_SYMBOL(qman_static_dequeue_del);
139178 +
139179 +u32 qman_p_static_dequeue_get(struct qman_portal *p)
139180 +{
139181 + return p->sdqcr;
139182 +}
139183 +EXPORT_SYMBOL(qman_p_static_dequeue_get);
139184 +
139185 +u32 qman_static_dequeue_get(void)
139186 +{
139187 + struct qman_portal *p = get_affine_portal();
139188 + u32 ret = qman_p_static_dequeue_get(p);
139189 + put_affine_portal();
139190 + return ret;
139191 +}
139192 +EXPORT_SYMBOL(qman_static_dequeue_get);
139193 +
139194 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
139195 + int park_request)
139196 +{
139197 + qm_dqrr_cdc_consume_1ptr(&p->p, dq, park_request);
139198 +}
139199 +EXPORT_SYMBOL(qman_p_dca);
139200 +
139201 +void qman_dca(struct qm_dqrr_entry *dq, int park_request)
139202 +{
139203 + struct qman_portal *p = get_affine_portal();
139204 + qman_p_dca(p, dq, park_request);
139205 + put_affine_portal();
139206 +}
139207 +EXPORT_SYMBOL(qman_dca);
139208 +
139209 +/*******************/
139210 +/* Frame queue API */
139211 +/*******************/
139212 +
139213 +static const char *mcr_result_str(u8 result)
139214 +{
139215 + switch (result) {
139216 + case QM_MCR_RESULT_NULL:
139217 + return "QM_MCR_RESULT_NULL";
139218 + case QM_MCR_RESULT_OK:
139219 + return "QM_MCR_RESULT_OK";
139220 + case QM_MCR_RESULT_ERR_FQID:
139221 + return "QM_MCR_RESULT_ERR_FQID";
139222 + case QM_MCR_RESULT_ERR_FQSTATE:
139223 + return "QM_MCR_RESULT_ERR_FQSTATE";
139224 + case QM_MCR_RESULT_ERR_NOTEMPTY:
139225 + return "QM_MCR_RESULT_ERR_NOTEMPTY";
139226 + case QM_MCR_RESULT_PENDING:
139227 + return "QM_MCR_RESULT_PENDING";
139228 + case QM_MCR_RESULT_ERR_BADCOMMAND:
139229 + return "QM_MCR_RESULT_ERR_BADCOMMAND";
139230 + }
139231 + return "<unknown MCR result>";
139232 +}
139233 +
139234 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq)
139235 +{
139236 + struct qm_fqd fqd;
139237 + struct qm_mcr_queryfq_np np;
139238 + struct qm_mc_command *mcc;
139239 + struct qm_mc_result *mcr;
139240 + struct qman_portal *p;
139241 + unsigned long irqflags __maybe_unused;
139242 +
139243 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID) {
139244 + int ret = qman_alloc_fqid(&fqid);
139245 + if (ret)
139246 + return ret;
139247 + }
139248 + spin_lock_init(&fq->fqlock);
139249 + fq->fqid = fqid;
139250 + fq->flags = flags;
139251 + fq->state = qman_fq_state_oos;
139252 + fq->cgr_groupid = 0;
139253 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
139254 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
139255 + return -ENOMEM;
139256 +#endif
139257 + if (!(flags & QMAN_FQ_FLAG_AS_IS) || (flags & QMAN_FQ_FLAG_NO_MODIFY))
139258 + return 0;
139259 + /* Everything else is AS_IS support */
139260 + p = get_affine_portal();
139261 + PORTAL_IRQ_LOCK(p, irqflags);
139262 + mcc = qm_mc_start(&p->p);
139263 + mcc->queryfq.fqid = cpu_to_be32(fqid);
139264 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
139265 + while (!(mcr = qm_mc_result(&p->p)))
139266 + cpu_relax();
139267 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ);
139268 + if (mcr->result != QM_MCR_RESULT_OK) {
139269 + pr_err("QUERYFQ failed: %s\n", mcr_result_str(mcr->result));
139270 + goto err;
139271 + }
139272 + fqd = mcr->queryfq.fqd;
139273 + hw_fqd_to_cpu(&fqd);
139274 + mcc = qm_mc_start(&p->p);
139275 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
139276 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
139277 + while (!(mcr = qm_mc_result(&p->p)))
139278 + cpu_relax();
139279 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYFQ_NP);
139280 + if (mcr->result != QM_MCR_RESULT_OK) {
139281 + pr_err("QUERYFQ_NP failed: %s\n", mcr_result_str(mcr->result));
139282 + goto err;
139283 + }
139284 + np = mcr->queryfq_np;
139285 + /* Phew, have queryfq and queryfq_np results, stitch together
139286 + * the FQ object from those. */
139287 + fq->cgr_groupid = fqd.cgid;
139288 + switch (np.state & QM_MCR_NP_STATE_MASK) {
139289 + case QM_MCR_NP_STATE_OOS:
139290 + break;
139291 + case QM_MCR_NP_STATE_RETIRED:
139292 + fq->state = qman_fq_state_retired;
139293 + if (np.frm_cnt)
139294 + fq_set(fq, QMAN_FQ_STATE_NE);
139295 + break;
139296 + case QM_MCR_NP_STATE_TEN_SCHED:
139297 + case QM_MCR_NP_STATE_TRU_SCHED:
139298 + case QM_MCR_NP_STATE_ACTIVE:
139299 + fq->state = qman_fq_state_sched;
139300 + if (np.state & QM_MCR_NP_STATE_R)
139301 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
139302 + break;
139303 + case QM_MCR_NP_STATE_PARKED:
139304 + fq->state = qman_fq_state_parked;
139305 + break;
139306 + default:
139307 + DPA_ASSERT(NULL == "invalid FQ state");
139308 + }
139309 + if (fqd.fq_ctrl & QM_FQCTRL_CGE)
139310 + fq->state |= QMAN_FQ_STATE_CGR_EN;
139311 + PORTAL_IRQ_UNLOCK(p, irqflags);
139312 + put_affine_portal();
139313 + return 0;
139314 +err:
139315 + PORTAL_IRQ_UNLOCK(p, irqflags);
139316 + put_affine_portal();
139317 + if (flags & QMAN_FQ_FLAG_DYNAMIC_FQID)
139318 + qman_release_fqid(fqid);
139319 + return -EIO;
139320 +}
139321 +EXPORT_SYMBOL(qman_create_fq);
139322 +
139323 +void qman_destroy_fq(struct qman_fq *fq, u32 flags __maybe_unused)
139324 +{
139325 +
139326 + /* We don't need to lock the FQ as it is a pre-condition that the FQ be
139327 + * quiesced. Instead, run some checks. */
139328 + switch (fq->state) {
139329 + case qman_fq_state_parked:
139330 + DPA_ASSERT(flags & QMAN_FQ_DESTROY_PARKED);
139331 + case qman_fq_state_oos:
139332 + if (fq_isset(fq, QMAN_FQ_FLAG_DYNAMIC_FQID))
139333 + qman_release_fqid(fq->fqid);
139334 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
139335 + clear_fq_table_entry(fq->key);
139336 +#endif
139337 + return;
139338 + default:
139339 + break;
139340 + }
139341 + DPA_ASSERT(NULL == "qman_free_fq() on unquiesced FQ!");
139342 +}
139343 +EXPORT_SYMBOL(qman_destroy_fq);
139344 +
139345 +u32 qman_fq_fqid(struct qman_fq *fq)
139346 +{
139347 + return fq->fqid;
139348 +}
139349 +EXPORT_SYMBOL(qman_fq_fqid);
139350 +
139351 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags)
139352 +{
139353 + if (state)
139354 + *state = fq->state;
139355 + if (flags)
139356 + *flags = fq->flags;
139357 +}
139358 +EXPORT_SYMBOL(qman_fq_state);
139359 +
139360 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts)
139361 +{
139362 + struct qm_mc_command *mcc;
139363 + struct qm_mc_result *mcr;
139364 + struct qman_portal *p;
139365 + unsigned long irqflags __maybe_unused;
139366 + u8 res, myverb = (flags & QMAN_INITFQ_FLAG_SCHED) ?
139367 + QM_MCC_VERB_INITFQ_SCHED : QM_MCC_VERB_INITFQ_PARKED;
139368 +
139369 + if ((fq->state != qman_fq_state_oos) &&
139370 + (fq->state != qman_fq_state_parked))
139371 + return -EINVAL;
139372 +#ifdef CONFIG_FSL_DPA_CHECKING
139373 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139374 + return -EINVAL;
139375 +#endif
139376 + if (opts && (opts->we_mask & QM_INITFQ_WE_OAC)) {
139377 + /* And can't be set at the same time as TDTHRESH */
139378 + if (opts->we_mask & QM_INITFQ_WE_TDTHRESH)
139379 + return -EINVAL;
139380 + }
139381 + /* Issue an INITFQ_[PARKED|SCHED] management command */
139382 + p = get_affine_portal();
139383 + PORTAL_IRQ_LOCK(p, irqflags);
139384 + FQLOCK(fq);
139385 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
139386 + ((fq->state != qman_fq_state_oos) &&
139387 + (fq->state != qman_fq_state_parked)))) {
139388 + FQUNLOCK(fq);
139389 + PORTAL_IRQ_UNLOCK(p, irqflags);
139390 + put_affine_portal();
139391 + return -EBUSY;
139392 + }
139393 + mcc = qm_mc_start(&p->p);
139394 + if (opts)
139395 + mcc->initfq = *opts;
139396 + mcc->initfq.fqid = cpu_to_be32(fq->fqid);
139397 + mcc->initfq.count = 0;
139398 +
139399 + /* If the FQ does *not* have the TO_DCPORTAL flag, contextB is set as a
139400 + * demux pointer. Otherwise, the caller-provided value is allowed to
139401 + * stand, don't overwrite it. */
139402 + if (fq_isclear(fq, QMAN_FQ_FLAG_TO_DCPORTAL)) {
139403 + dma_addr_t phys_fq;
139404 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTB;
139405 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
139406 + mcc->initfq.fqd.context_b = fq->key;
139407 +#else
139408 + mcc->initfq.fqd.context_b = (u32)(uintptr_t)fq;
139409 +#endif
139410 + /* and the physical address - NB, if the user wasn't trying to
139411 + * set CONTEXTA, clear the stashing settings. */
139412 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_CONTEXTA)) {
139413 + mcc->initfq.we_mask |= QM_INITFQ_WE_CONTEXTA;
139414 + memset(&mcc->initfq.fqd.context_a, 0,
139415 + sizeof(mcc->initfq.fqd.context_a));
139416 + } else {
139417 + phys_fq = dma_map_single(&p->pdev->dev, fq, sizeof(*fq),
139418 + DMA_TO_DEVICE);
139419 + if (dma_mapping_error(&p->pdev->dev, phys_fq)) {
139420 + dev_err(&p->pdev->dev,
139421 + "dma_map_single failed for fqid: %u\n",
139422 + fq->fqid);
139423 + FQUNLOCK(fq);
139424 + PORTAL_IRQ_UNLOCK(p, irqflags);
139425 + put_affine_portal();
139426 + return -EIO;
139427 + }
139428 +
139429 + qm_fqd_stashing_set64(&mcc->initfq.fqd, phys_fq);
139430 + }
139431 + }
139432 + if (flags & QMAN_INITFQ_FLAG_LOCAL) {
139433 + mcc->initfq.fqd.dest.channel = p->config->public_cfg.channel;
139434 + if (!(mcc->initfq.we_mask & QM_INITFQ_WE_DESTWQ)) {
139435 + mcc->initfq.we_mask |= QM_INITFQ_WE_DESTWQ;
139436 + mcc->initfq.fqd.dest.wq = 4;
139437 + }
139438 + }
139439 + mcc->initfq.we_mask = cpu_to_be16(mcc->initfq.we_mask);
139440 + cpu_to_hw_fqd(&mcc->initfq.fqd);
139441 + qm_mc_commit(&p->p, myverb);
139442 + while (!(mcr = qm_mc_result(&p->p)))
139443 + cpu_relax();
139444 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
139445 + res = mcr->result;
139446 + if (res != QM_MCR_RESULT_OK) {
139447 + FQUNLOCK(fq);
139448 + PORTAL_IRQ_UNLOCK(p, irqflags);
139449 + put_affine_portal();
139450 + return -EIO;
139451 + }
139452 + if (opts) {
139453 + if (opts->we_mask & QM_INITFQ_WE_FQCTRL) {
139454 + if (opts->fqd.fq_ctrl & QM_FQCTRL_CGE)
139455 + fq_set(fq, QMAN_FQ_STATE_CGR_EN);
139456 + else
139457 + fq_clear(fq, QMAN_FQ_STATE_CGR_EN);
139458 + }
139459 + if (opts->we_mask & QM_INITFQ_WE_CGID)
139460 + fq->cgr_groupid = opts->fqd.cgid;
139461 + }
139462 + fq->state = (flags & QMAN_INITFQ_FLAG_SCHED) ?
139463 + qman_fq_state_sched : qman_fq_state_parked;
139464 + FQUNLOCK(fq);
139465 + PORTAL_IRQ_UNLOCK(p, irqflags);
139466 + put_affine_portal();
139467 + return 0;
139468 +}
139469 +EXPORT_SYMBOL(qman_init_fq);
139470 +
139471 +int qman_schedule_fq(struct qman_fq *fq)
139472 +{
139473 + struct qm_mc_command *mcc;
139474 + struct qm_mc_result *mcr;
139475 + struct qman_portal *p;
139476 + unsigned long irqflags __maybe_unused;
139477 + int ret = 0;
139478 + u8 res;
139479 +
139480 + if (fq->state != qman_fq_state_parked)
139481 + return -EINVAL;
139482 +#ifdef CONFIG_FSL_DPA_CHECKING
139483 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139484 + return -EINVAL;
139485 +#endif
139486 + /* Issue a ALTERFQ_SCHED management command */
139487 + p = get_affine_portal();
139488 + PORTAL_IRQ_LOCK(p, irqflags);
139489 + FQLOCK(fq);
139490 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
139491 + (fq->state != qman_fq_state_parked))) {
139492 + ret = -EBUSY;
139493 + goto out;
139494 + }
139495 + mcc = qm_mc_start(&p->p);
139496 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
139497 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_SCHED);
139498 + while (!(mcr = qm_mc_result(&p->p)))
139499 + cpu_relax();
139500 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_SCHED);
139501 + res = mcr->result;
139502 + if (res != QM_MCR_RESULT_OK) {
139503 + ret = -EIO;
139504 + goto out;
139505 + }
139506 + fq->state = qman_fq_state_sched;
139507 +out:
139508 + FQUNLOCK(fq);
139509 + PORTAL_IRQ_UNLOCK(p, irqflags);
139510 + put_affine_portal();
139511 + return ret;
139512 +}
139513 +EXPORT_SYMBOL(qman_schedule_fq);
139514 +
139515 +int qman_retire_fq(struct qman_fq *fq, u32 *flags)
139516 +{
139517 + struct qm_mc_command *mcc;
139518 + struct qm_mc_result *mcr;
139519 + struct qman_portal *p;
139520 + unsigned long irqflags __maybe_unused;
139521 + int rval;
139522 + u8 res;
139523 +
139524 + if ((fq->state != qman_fq_state_parked) &&
139525 + (fq->state != qman_fq_state_sched))
139526 + return -EINVAL;
139527 +#ifdef CONFIG_FSL_DPA_CHECKING
139528 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139529 + return -EINVAL;
139530 +#endif
139531 + p = get_affine_portal();
139532 + PORTAL_IRQ_LOCK(p, irqflags);
139533 + FQLOCK(fq);
139534 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
139535 + (fq->state == qman_fq_state_retired) ||
139536 + (fq->state == qman_fq_state_oos))) {
139537 + rval = -EBUSY;
139538 + goto out;
139539 + }
139540 + rval = table_push_fq(p, fq);
139541 + if (rval)
139542 + goto out;
139543 + mcc = qm_mc_start(&p->p);
139544 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
139545 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
139546 + while (!(mcr = qm_mc_result(&p->p)))
139547 + cpu_relax();
139548 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_RETIRE);
139549 + res = mcr->result;
139550 + /* "Elegant" would be to treat OK/PENDING the same way; set CHANGING,
139551 + * and defer the flags until FQRNI or FQRN (respectively) show up. But
139552 + * "Friendly" is to process OK immediately, and not set CHANGING. We do
139553 + * friendly, otherwise the caller doesn't necessarily have a fully
139554 + * "retired" FQ on return even if the retirement was immediate. However
139555 + * this does mean some code duplication between here and
139556 + * fq_state_change(). */
139557 + if (likely(res == QM_MCR_RESULT_OK)) {
139558 + rval = 0;
139559 + /* Process 'fq' right away, we'll ignore FQRNI */
139560 + if (mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY)
139561 + fq_set(fq, QMAN_FQ_STATE_NE);
139562 + if (mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)
139563 + fq_set(fq, QMAN_FQ_STATE_ORL);
139564 + else
139565 + table_del_fq(p, fq);
139566 + if (flags)
139567 + *flags = fq->flags;
139568 + fq->state = qman_fq_state_retired;
139569 + if (fq->cb.fqs) {
139570 + /* Another issue with supporting "immediate" retirement
139571 + * is that we're forced to drop FQRNIs, because by the
139572 + * time they're seen it may already be "too late" (the
139573 + * fq may have been OOS'd and free()'d already). But if
139574 + * the upper layer wants a callback whether it's
139575 + * immediate or not, we have to fake a "MR" entry to
139576 + * look like an FQRNI... */
139577 + struct qm_mr_entry msg;
139578 + msg.verb = QM_MR_VERB_FQRNI;
139579 + msg.fq.fqs = mcr->alterfq.fqs;
139580 + msg.fq.fqid = fq->fqid;
139581 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
139582 + msg.fq.contextB = fq->key;
139583 +#else
139584 + msg.fq.contextB = (u32)(uintptr_t)fq;
139585 +#endif
139586 + fq->cb.fqs(p, fq, &msg);
139587 + }
139588 + } else if (res == QM_MCR_RESULT_PENDING) {
139589 + rval = 1;
139590 + fq_set(fq, QMAN_FQ_STATE_CHANGING);
139591 + } else {
139592 + rval = -EIO;
139593 + table_del_fq(p, fq);
139594 + }
139595 +out:
139596 + FQUNLOCK(fq);
139597 + PORTAL_IRQ_UNLOCK(p, irqflags);
139598 + put_affine_portal();
139599 + return rval;
139600 +}
139601 +EXPORT_SYMBOL(qman_retire_fq);
139602 +
139603 +int qman_oos_fq(struct qman_fq *fq)
139604 +{
139605 + struct qm_mc_command *mcc;
139606 + struct qm_mc_result *mcr;
139607 + struct qman_portal *p;
139608 + unsigned long irqflags __maybe_unused;
139609 + int ret = 0;
139610 + u8 res;
139611 +
139612 + if (fq->state != qman_fq_state_retired)
139613 + return -EINVAL;
139614 +#ifdef CONFIG_FSL_DPA_CHECKING
139615 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139616 + return -EINVAL;
139617 +#endif
139618 + p = get_affine_portal();
139619 + PORTAL_IRQ_LOCK(p, irqflags);
139620 + FQLOCK(fq);
139621 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_BLOCKOOS)) ||
139622 + (fq->state != qman_fq_state_retired))) {
139623 + ret = -EBUSY;
139624 + goto out;
139625 + }
139626 + mcc = qm_mc_start(&p->p);
139627 + mcc->alterfq.fqid = cpu_to_be32(fq->fqid);
139628 + qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_OOS);
139629 + while (!(mcr = qm_mc_result(&p->p)))
139630 + cpu_relax();
139631 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_ALTER_OOS);
139632 + res = mcr->result;
139633 + if (res != QM_MCR_RESULT_OK) {
139634 + ret = -EIO;
139635 + goto out;
139636 + }
139637 + fq->state = qman_fq_state_oos;
139638 +out:
139639 + FQUNLOCK(fq);
139640 + PORTAL_IRQ_UNLOCK(p, irqflags);
139641 + put_affine_portal();
139642 + return ret;
139643 +}
139644 +EXPORT_SYMBOL(qman_oos_fq);
139645 +
139646 +int qman_fq_flow_control(struct qman_fq *fq, int xon)
139647 +{
139648 + struct qm_mc_command *mcc;
139649 + struct qm_mc_result *mcr;
139650 + struct qman_portal *p;
139651 + unsigned long irqflags __maybe_unused;
139652 + int ret = 0;
139653 + u8 res;
139654 + u8 myverb;
139655 +
139656 + if ((fq->state == qman_fq_state_oos) ||
139657 + (fq->state == qman_fq_state_retired) ||
139658 + (fq->state == qman_fq_state_parked))
139659 + return -EINVAL;
139660 +
139661 +#ifdef CONFIG_FSL_DPA_CHECKING
139662 + if (unlikely(fq_isset(fq, QMAN_FQ_FLAG_NO_MODIFY)))
139663 + return -EINVAL;
139664 +#endif
139665 + /* Issue a ALTER_FQXON or ALTER_FQXOFF management command */
139666 + p = get_affine_portal();
139667 + PORTAL_IRQ_LOCK(p, irqflags);
139668 + FQLOCK(fq);
139669 + if (unlikely((fq_isset(fq, QMAN_FQ_STATE_CHANGING)) ||
139670 + (fq->state == qman_fq_state_parked) ||
139671 + (fq->state == qman_fq_state_oos) ||
139672 + (fq->state == qman_fq_state_retired))) {
139673 + ret = -EBUSY;
139674 + goto out;
139675 + }
139676 + mcc = qm_mc_start(&p->p);
139677 + mcc->alterfq.fqid = fq->fqid;
139678 + mcc->alterfq.count = 0;
139679 + myverb = xon ? QM_MCC_VERB_ALTER_FQXON : QM_MCC_VERB_ALTER_FQXOFF;
139680 +
139681 + qm_mc_commit(&p->p, myverb);
139682 + while (!(mcr = qm_mc_result(&p->p)))
139683 + cpu_relax();
139684 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
139685 +
139686 + res = mcr->result;
139687 + if (res != QM_MCR_RESULT_OK) {
139688 + ret = -EIO;
139689 + goto out;
139690 + }
139691 +out:
139692 + FQUNLOCK(fq);
139693 + PORTAL_IRQ_UNLOCK(p, irqflags);
139694 + put_affine_portal();
139695 + return ret;
139696 +}
139697 +EXPORT_SYMBOL(qman_fq_flow_control);
139698 +
139699 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd)
139700 +{
139701 + struct qm_mc_command *mcc;
139702 + struct qm_mc_result *mcr;
139703 + struct qman_portal *p = get_affine_portal();
139704 + unsigned long irqflags __maybe_unused;
139705 + u8 res;
139706 +
139707 + PORTAL_IRQ_LOCK(p, irqflags);
139708 + mcc = qm_mc_start(&p->p);
139709 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
139710 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ);
139711 + while (!(mcr = qm_mc_result(&p->p)))
139712 + cpu_relax();
139713 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
139714 + res = mcr->result;
139715 + if (res == QM_MCR_RESULT_OK)
139716 + *fqd = mcr->queryfq.fqd;
139717 + hw_fqd_to_cpu(fqd);
139718 + PORTAL_IRQ_UNLOCK(p, irqflags);
139719 + put_affine_portal();
139720 + if (res != QM_MCR_RESULT_OK)
139721 + return -EIO;
139722 + return 0;
139723 +}
139724 +EXPORT_SYMBOL(qman_query_fq);
139725 +
139726 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np)
139727 +{
139728 + struct qm_mc_command *mcc;
139729 + struct qm_mc_result *mcr;
139730 + struct qman_portal *p = get_affine_portal();
139731 + unsigned long irqflags __maybe_unused;
139732 + u8 res;
139733 +
139734 + PORTAL_IRQ_LOCK(p, irqflags);
139735 + mcc = qm_mc_start(&p->p);
139736 + mcc->queryfq.fqid = cpu_to_be32(fq->fqid);
139737 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYFQ_NP);
139738 + while (!(mcr = qm_mc_result(&p->p)))
139739 + cpu_relax();
139740 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
139741 + res = mcr->result;
139742 + if (res == QM_MCR_RESULT_OK) {
139743 + *np = mcr->queryfq_np;
139744 + np->fqd_link = be24_to_cpu(np->fqd_link);
139745 + np->odp_seq = be16_to_cpu(np->odp_seq);
139746 + np->orp_nesn = be16_to_cpu(np->orp_nesn);
139747 + np->orp_ea_hseq = be16_to_cpu(np->orp_ea_hseq);
139748 + np->orp_ea_tseq = be16_to_cpu(np->orp_ea_tseq);
139749 + np->orp_ea_hptr = be24_to_cpu(np->orp_ea_hptr);
139750 + np->orp_ea_tptr = be24_to_cpu(np->orp_ea_tptr);
139751 + np->pfdr_hptr = be24_to_cpu(np->pfdr_hptr);
139752 + np->pfdr_tptr = be24_to_cpu(np->pfdr_tptr);
139753 + np->ics_surp = be16_to_cpu(np->ics_surp);
139754 + np->byte_cnt = be32_to_cpu(np->byte_cnt);
139755 + np->frm_cnt = be24_to_cpu(np->frm_cnt);
139756 + np->ra1_sfdr = be16_to_cpu(np->ra1_sfdr);
139757 + np->ra2_sfdr = be16_to_cpu(np->ra2_sfdr);
139758 + np->od1_sfdr = be16_to_cpu(np->od1_sfdr);
139759 + np->od2_sfdr = be16_to_cpu(np->od2_sfdr);
139760 + np->od3_sfdr = be16_to_cpu(np->od3_sfdr);
139761 + }
139762 + PORTAL_IRQ_UNLOCK(p, irqflags);
139763 + put_affine_portal();
139764 + if (res == QM_MCR_RESULT_ERR_FQID)
139765 + return -ERANGE;
139766 + else if (res != QM_MCR_RESULT_OK)
139767 + return -EIO;
139768 + return 0;
139769 +}
139770 +EXPORT_SYMBOL(qman_query_fq_np);
139771 +
139772 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq)
139773 +{
139774 + struct qm_mc_command *mcc;
139775 + struct qm_mc_result *mcr;
139776 + struct qman_portal *p = get_affine_portal();
139777 + unsigned long irqflags __maybe_unused;
139778 + u8 res, myverb;
139779 +
139780 + PORTAL_IRQ_LOCK(p, irqflags);
139781 + myverb = (query_dedicated) ? QM_MCR_VERB_QUERYWQ_DEDICATED :
139782 + QM_MCR_VERB_QUERYWQ;
139783 + mcc = qm_mc_start(&p->p);
139784 + mcc->querywq.channel.id = cpu_to_be16(wq->channel.id);
139785 + qm_mc_commit(&p->p, myverb);
139786 + while (!(mcr = qm_mc_result(&p->p)))
139787 + cpu_relax();
139788 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == myverb);
139789 + res = mcr->result;
139790 + if (res == QM_MCR_RESULT_OK) {
139791 + int i, array_len;
139792 + wq->channel.id = be16_to_cpu(mcr->querywq.channel.id);
139793 + array_len = ARRAY_SIZE(mcr->querywq.wq_len);
139794 + for (i = 0; i < array_len; i++)
139795 + wq->wq_len[i] = be32_to_cpu(mcr->querywq.wq_len[i]);
139796 + }
139797 + PORTAL_IRQ_UNLOCK(p, irqflags);
139798 + put_affine_portal();
139799 + if (res != QM_MCR_RESULT_OK) {
139800 + pr_err("QUERYWQ failed: %s\n", mcr_result_str(res));
139801 + return -EIO;
139802 + }
139803 + return 0;
139804 +}
139805 +EXPORT_SYMBOL(qman_query_wq);
139806 +
139807 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
139808 + struct qm_mcr_cgrtestwrite *result)
139809 +{
139810 + struct qm_mc_command *mcc;
139811 + struct qm_mc_result *mcr;
139812 + struct qman_portal *p = get_affine_portal();
139813 + unsigned long irqflags __maybe_unused;
139814 + u8 res;
139815 +
139816 + PORTAL_IRQ_LOCK(p, irqflags);
139817 + mcc = qm_mc_start(&p->p);
139818 + mcc->cgrtestwrite.cgid = cgr->cgrid;
139819 + mcc->cgrtestwrite.i_bcnt_hi = (u8)(i_bcnt >> 32);
139820 + mcc->cgrtestwrite.i_bcnt_lo = (u32)i_bcnt;
139821 + qm_mc_commit(&p->p, QM_MCC_VERB_CGRTESTWRITE);
139822 + while (!(mcr = qm_mc_result(&p->p)))
139823 + cpu_relax();
139824 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_CGRTESTWRITE);
139825 + res = mcr->result;
139826 + if (res == QM_MCR_RESULT_OK)
139827 + *result = mcr->cgrtestwrite;
139828 + PORTAL_IRQ_UNLOCK(p, irqflags);
139829 + put_affine_portal();
139830 + if (res != QM_MCR_RESULT_OK) {
139831 + pr_err("CGR TEST WRITE failed: %s\n", mcr_result_str(res));
139832 + return -EIO;
139833 + }
139834 + return 0;
139835 +}
139836 +EXPORT_SYMBOL(qman_testwrite_cgr);
139837 +
139838 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *cgrd)
139839 +{
139840 + struct qm_mc_command *mcc;
139841 + struct qm_mc_result *mcr;
139842 + struct qman_portal *p = get_affine_portal();
139843 + unsigned long irqflags __maybe_unused;
139844 + u8 res;
139845 + int i;
139846 +
139847 + PORTAL_IRQ_LOCK(p, irqflags);
139848 + mcc = qm_mc_start(&p->p);
139849 + mcc->querycgr.cgid = cgr->cgrid;
139850 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCGR);
139851 + while (!(mcr = qm_mc_result(&p->p)))
139852 + cpu_relax();
139853 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCC_VERB_QUERYCGR);
139854 + res = mcr->result;
139855 + if (res == QM_MCR_RESULT_OK)
139856 + *cgrd = mcr->querycgr;
139857 + PORTAL_IRQ_UNLOCK(p, irqflags);
139858 + put_affine_portal();
139859 + if (res != QM_MCR_RESULT_OK) {
139860 + pr_err("QUERY_CGR failed: %s\n", mcr_result_str(res));
139861 + return -EIO;
139862 + }
139863 + cgrd->cgr.wr_parm_g.word =
139864 + be32_to_cpu(cgrd->cgr.wr_parm_g.word);
139865 + cgrd->cgr.wr_parm_y.word =
139866 + be32_to_cpu(cgrd->cgr.wr_parm_y.word);
139867 + cgrd->cgr.wr_parm_r.word =
139868 + be32_to_cpu(cgrd->cgr.wr_parm_r.word);
139869 + cgrd->cgr.cscn_targ = be32_to_cpu(cgrd->cgr.cscn_targ);
139870 + cgrd->cgr.__cs_thres = be16_to_cpu(cgrd->cgr.__cs_thres);
139871 + for (i = 0; i < ARRAY_SIZE(cgrd->cscn_targ_swp); i++)
139872 + be32_to_cpus(&cgrd->cscn_targ_swp[i]);
139873 + return 0;
139874 +}
139875 +EXPORT_SYMBOL(qman_query_cgr);
139876 +
139877 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion)
139878 +{
139879 + struct qm_mc_result *mcr;
139880 + struct qman_portal *p = get_affine_portal();
139881 + unsigned long irqflags __maybe_unused;
139882 + u8 res;
139883 + int i;
139884 +
139885 + PORTAL_IRQ_LOCK(p, irqflags);
139886 + qm_mc_start(&p->p);
139887 + qm_mc_commit(&p->p, QM_MCC_VERB_QUERYCONGESTION);
139888 + while (!(mcr = qm_mc_result(&p->p)))
139889 + cpu_relax();
139890 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
139891 + QM_MCC_VERB_QUERYCONGESTION);
139892 + res = mcr->result;
139893 + if (res == QM_MCR_RESULT_OK)
139894 + memcpy_fromio(congestion, &mcr->querycongestion,
139895 + sizeof(*congestion));
139896 + PORTAL_IRQ_UNLOCK(p, irqflags);
139897 + put_affine_portal();
139898 + if (res != QM_MCR_RESULT_OK) {
139899 + pr_err("QUERY_CONGESTION failed: %s\n", mcr_result_str(res));
139900 + return -EIO;
139901 + }
139902 +
139903 + for (i = 0; i < ARRAY_SIZE(congestion->state.__state); i++)
139904 + be32_to_cpus(&congestion->state.__state[i]);
139905 + return 0;
139906 +}
139907 +EXPORT_SYMBOL(qman_query_congestion);
139908 +
139909 +/* internal function used as a wait_event() expression */
139910 +static int set_p_vdqcr(struct qman_portal *p, struct qman_fq *fq, u32 vdqcr)
139911 +{
139912 + unsigned long irqflags __maybe_unused;
139913 + int ret = -EBUSY;
139914 + PORTAL_IRQ_LOCK(p, irqflags);
139915 + if (!p->vdqcr_owned) {
139916 + FQLOCK(fq);
139917 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
139918 + goto escape;
139919 + fq_set(fq, QMAN_FQ_STATE_VDQCR);
139920 + FQUNLOCK(fq);
139921 + p->vdqcr_owned = fq;
139922 + ret = 0;
139923 + }
139924 +escape:
139925 + PORTAL_IRQ_UNLOCK(p, irqflags);
139926 + if (!ret)
139927 + qm_dqrr_vdqcr_set(&p->p, vdqcr);
139928 + return ret;
139929 +}
139930 +
139931 +static int set_vdqcr(struct qman_portal **p, struct qman_fq *fq, u32 vdqcr)
139932 +{
139933 + int ret;
139934 + *p = get_affine_portal();
139935 + ret = set_p_vdqcr(*p, fq, vdqcr);
139936 + put_affine_portal();
139937 + return ret;
139938 +}
139939 +
139940 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139941 +static int wait_p_vdqcr_start(struct qman_portal *p, struct qman_fq *fq,
139942 + u32 vdqcr, u32 flags)
139943 +{
139944 + int ret = 0;
139945 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
139946 + ret = wait_event_interruptible(affine_queue,
139947 + !(ret = set_p_vdqcr(p, fq, vdqcr)));
139948 + else
139949 + wait_event(affine_queue, !(ret = set_p_vdqcr(p, fq, vdqcr)));
139950 + return ret;
139951 +}
139952 +
139953 +static int wait_vdqcr_start(struct qman_portal **p, struct qman_fq *fq,
139954 + u32 vdqcr, u32 flags)
139955 +{
139956 + int ret = 0;
139957 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
139958 + ret = wait_event_interruptible(affine_queue,
139959 + !(ret = set_vdqcr(p, fq, vdqcr)));
139960 + else
139961 + wait_event(affine_queue, !(ret = set_vdqcr(p, fq, vdqcr)));
139962 + return ret;
139963 +}
139964 +#endif
139965 +
139966 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
139967 + u32 flags __maybe_unused, u32 vdqcr)
139968 +{
139969 + int ret;
139970 +
139971 + if ((fq->state != qman_fq_state_parked) &&
139972 + (fq->state != qman_fq_state_retired))
139973 + return -EINVAL;
139974 + if (vdqcr & QM_VDQCR_FQID_MASK)
139975 + return -EINVAL;
139976 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
139977 + return -EBUSY;
139978 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
139979 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139980 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
139981 + ret = wait_p_vdqcr_start(p, fq, vdqcr, flags);
139982 + else
139983 +#endif
139984 + ret = set_p_vdqcr(p, fq, vdqcr);
139985 + if (ret)
139986 + return ret;
139987 + /* VDQCR is set */
139988 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
139989 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
139990 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
139991 + /* NB: don't propagate any error - the caller wouldn't
139992 + * know whether the VDQCR was issued or not. A signal
139993 + * could arrive after returning anyway, so the caller
139994 + * can check signal_pending() if that's an issue. */
139995 + wait_event_interruptible(affine_queue,
139996 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
139997 + else
139998 + wait_event(affine_queue,
139999 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
140000 + }
140001 +#endif
140002 + return 0;
140003 +}
140004 +EXPORT_SYMBOL(qman_p_volatile_dequeue);
140005 +
140006 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags __maybe_unused,
140007 + u32 vdqcr)
140008 +{
140009 + struct qman_portal *p;
140010 + int ret;
140011 +
140012 + if ((fq->state != qman_fq_state_parked) &&
140013 + (fq->state != qman_fq_state_retired))
140014 + return -EINVAL;
140015 + if (vdqcr & QM_VDQCR_FQID_MASK)
140016 + return -EINVAL;
140017 + if (fq_isset(fq, QMAN_FQ_STATE_VDQCR))
140018 + return -EBUSY;
140019 + vdqcr = (vdqcr & ~QM_VDQCR_FQID_MASK) | fq->fqid;
140020 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140021 + if (flags & QMAN_VOLATILE_FLAG_WAIT)
140022 + ret = wait_vdqcr_start(&p, fq, vdqcr, flags);
140023 + else
140024 +#endif
140025 + ret = set_vdqcr(&p, fq, vdqcr);
140026 + if (ret)
140027 + return ret;
140028 + /* VDQCR is set */
140029 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140030 + if (flags & QMAN_VOLATILE_FLAG_FINISH) {
140031 + if (flags & QMAN_VOLATILE_FLAG_WAIT_INT)
140032 + /* NB: don't propagate any error - the caller wouldn't
140033 + * know whether the VDQCR was issued or not. A signal
140034 + * could arrive after returning anyway, so the caller
140035 + * can check signal_pending() if that's an issue. */
140036 + wait_event_interruptible(affine_queue,
140037 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
140038 + else
140039 + wait_event(affine_queue,
140040 + !fq_isset(fq, QMAN_FQ_STATE_VDQCR));
140041 + }
140042 +#endif
140043 + return 0;
140044 +}
140045 +EXPORT_SYMBOL(qman_volatile_dequeue);
140046 +
140047 +static noinline void update_eqcr_ci(struct qman_portal *p, u8 avail)
140048 +{
140049 + if (avail)
140050 + qm_eqcr_cce_prefetch(&p->p);
140051 + else
140052 + qm_eqcr_cce_update(&p->p);
140053 +}
140054 +
140055 +int qman_eqcr_is_empty(void)
140056 +{
140057 + unsigned long irqflags __maybe_unused;
140058 + struct qman_portal *p = get_affine_portal();
140059 + u8 avail;
140060 +
140061 + PORTAL_IRQ_LOCK(p, irqflags);
140062 + update_eqcr_ci(p, 0);
140063 + avail = qm_eqcr_get_fill(&p->p);
140064 + PORTAL_IRQ_UNLOCK(p, irqflags);
140065 + put_affine_portal();
140066 + return avail == 0;
140067 +}
140068 +EXPORT_SYMBOL(qman_eqcr_is_empty);
140069 +
140070 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine)
140071 +{
140072 + if (affine) {
140073 + unsigned long irqflags __maybe_unused;
140074 + struct qman_portal *p = get_affine_portal();
140075 + PORTAL_IRQ_LOCK(p, irqflags);
140076 + p->cb_dc_ern = handler;
140077 + PORTAL_IRQ_UNLOCK(p, irqflags);
140078 + put_affine_portal();
140079 + } else
140080 + cb_dc_ern = handler;
140081 +}
140082 +EXPORT_SYMBOL(qman_set_dc_ern);
140083 +
140084 +static inline struct qm_eqcr_entry *try_p_eq_start(struct qman_portal *p,
140085 + unsigned long *irqflags __maybe_unused,
140086 + struct qman_fq *fq,
140087 + const struct qm_fd *fd,
140088 + u32 flags)
140089 +{
140090 + struct qm_eqcr_entry *eq;
140091 + u8 avail;
140092 + PORTAL_IRQ_LOCK(p, (*irqflags));
140093 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140094 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140095 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140096 + if (p->eqci_owned) {
140097 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
140098 + return NULL;
140099 + }
140100 + p->eqci_owned = fq;
140101 + }
140102 +#endif
140103 + if (p->use_eqcr_ci_stashing) {
140104 + /*
140105 + * The stashing case is easy, only update if we need to in
140106 + * order to try and liberate ring entries.
140107 + */
140108 + eq = qm_eqcr_start_stash(&p->p);
140109 + } else {
140110 + /*
140111 + * The non-stashing case is harder, need to prefetch ahead of
140112 + * time.
140113 + */
140114 + avail = qm_eqcr_get_avail(&p->p);
140115 + if (avail < 2)
140116 + update_eqcr_ci(p, avail);
140117 + eq = qm_eqcr_start_no_stash(&p->p);
140118 + }
140119 +
140120 + if (unlikely(!eq)) {
140121 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140122 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140123 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC)))
140124 + p->eqci_owned = NULL;
140125 +#endif
140126 + PORTAL_IRQ_UNLOCK(p, (*irqflags));
140127 + return NULL;
140128 + }
140129 + if (flags & QMAN_ENQUEUE_FLAG_DCA)
140130 + eq->dca = QM_EQCR_DCA_ENABLE |
140131 + ((flags & QMAN_ENQUEUE_FLAG_DCA_PARK) ?
140132 + QM_EQCR_DCA_PARK : 0) |
140133 + ((flags >> 8) & QM_EQCR_DCA_IDXMASK);
140134 + eq->fqid = cpu_to_be32(fq->fqid);
140135 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
140136 + eq->tag = cpu_to_be32(fq->key);
140137 +#else
140138 + eq->tag = cpu_to_be32((u32)(uintptr_t)fq);
140139 +#endif
140140 + eq->fd = *fd;
140141 + cpu_to_hw_fd(&eq->fd);
140142 + return eq;
140143 +}
140144 +
140145 +static inline struct qm_eqcr_entry *try_eq_start(struct qman_portal **p,
140146 + unsigned long *irqflags __maybe_unused,
140147 + struct qman_fq *fq,
140148 + const struct qm_fd *fd,
140149 + u32 flags)
140150 +{
140151 + struct qm_eqcr_entry *eq;
140152 + *p = get_affine_portal();
140153 + eq = try_p_eq_start(*p, irqflags, fq, fd, flags);
140154 + if (!eq)
140155 + put_affine_portal();
140156 + return eq;
140157 +}
140158 +
140159 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140160 +static noinline struct qm_eqcr_entry *__wait_eq_start(struct qman_portal **p,
140161 + unsigned long *irqflags __maybe_unused,
140162 + struct qman_fq *fq,
140163 + const struct qm_fd *fd,
140164 + u32 flags)
140165 +{
140166 + struct qm_eqcr_entry *eq = try_eq_start(p, irqflags, fq, fd, flags);
140167 + if (!eq)
140168 + qm_eqcr_set_ithresh(&(*p)->p, EQCR_ITHRESH);
140169 + return eq;
140170 +}
140171 +static noinline struct qm_eqcr_entry *wait_eq_start(struct qman_portal **p,
140172 + unsigned long *irqflags __maybe_unused,
140173 + struct qman_fq *fq,
140174 + const struct qm_fd *fd,
140175 + u32 flags)
140176 +{
140177 + struct qm_eqcr_entry *eq;
140178 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140179 + /* NB: return NULL if signal occurs before completion. Signal
140180 + * can occur during return. Caller must check for signal */
140181 + wait_event_interruptible(affine_queue,
140182 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
140183 + else
140184 + wait_event(affine_queue,
140185 + (eq = __wait_eq_start(p, irqflags, fq, fd, flags)));
140186 + return eq;
140187 +}
140188 +static noinline struct qm_eqcr_entry *__wait_p_eq_start(struct qman_portal *p,
140189 + unsigned long *irqflags __maybe_unused,
140190 + struct qman_fq *fq,
140191 + const struct qm_fd *fd,
140192 + u32 flags)
140193 +{
140194 + struct qm_eqcr_entry *eq = try_p_eq_start(p, irqflags, fq, fd, flags);
140195 + if (!eq)
140196 + qm_eqcr_set_ithresh(&p->p, EQCR_ITHRESH);
140197 + return eq;
140198 +}
140199 +static noinline struct qm_eqcr_entry *wait_p_eq_start(struct qman_portal *p,
140200 + unsigned long *irqflags __maybe_unused,
140201 + struct qman_fq *fq,
140202 + const struct qm_fd *fd,
140203 + u32 flags)
140204 +{
140205 + struct qm_eqcr_entry *eq;
140206 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140207 + /* NB: return NULL if signal occurs before completion. Signal
140208 + * can occur during return. Caller must check for signal */
140209 + wait_event_interruptible(affine_queue,
140210 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
140211 + else
140212 + wait_event(affine_queue,
140213 + (eq = __wait_p_eq_start(p, irqflags, fq, fd, flags)));
140214 + return eq;
140215 +}
140216 +#endif
140217 +
140218 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
140219 + const struct qm_fd *fd, u32 flags)
140220 +{
140221 + struct qm_eqcr_entry *eq;
140222 + unsigned long irqflags __maybe_unused;
140223 +
140224 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140225 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
140226 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
140227 + else
140228 +#endif
140229 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
140230 + if (!eq)
140231 + return -EBUSY;
140232 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
140233 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
140234 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140235 + /* Factor the below out, it's used from qman_enqueue_orp() too */
140236 + PORTAL_IRQ_UNLOCK(p, irqflags);
140237 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140238 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140239 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140240 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140241 + /* NB: return success even if signal occurs before
140242 + * condition is true. pvb_commit guarantees success */
140243 + wait_event_interruptible(affine_queue,
140244 + (p->eqci_owned != fq));
140245 + else
140246 + wait_event(affine_queue, (p->eqci_owned != fq));
140247 + }
140248 +#endif
140249 + return 0;
140250 +}
140251 +EXPORT_SYMBOL(qman_p_enqueue);
140252 +
140253 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags)
140254 +{
140255 + struct qman_portal *p;
140256 + struct qm_eqcr_entry *eq;
140257 + unsigned long irqflags __maybe_unused;
140258 +
140259 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140260 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
140261 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
140262 + else
140263 +#endif
140264 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
140265 + if (!eq)
140266 + return -EBUSY;
140267 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
140268 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
140269 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140270 + /* Factor the below out, it's used from qman_enqueue_orp() too */
140271 + PORTAL_IRQ_UNLOCK(p, irqflags);
140272 + put_affine_portal();
140273 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140274 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140275 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140276 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140277 + /* NB: return success even if signal occurs before
140278 + * condition is true. pvb_commit guarantees success */
140279 + wait_event_interruptible(affine_queue,
140280 + (p->eqci_owned != fq));
140281 + else
140282 + wait_event(affine_queue, (p->eqci_owned != fq));
140283 + }
140284 +#endif
140285 + return 0;
140286 +}
140287 +EXPORT_SYMBOL(qman_enqueue);
140288 +
140289 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
140290 + const struct qm_fd *fd, u32 flags,
140291 + struct qman_fq *orp, u16 orp_seqnum)
140292 +{
140293 + struct qm_eqcr_entry *eq;
140294 + unsigned long irqflags __maybe_unused;
140295 +
140296 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140297 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
140298 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
140299 + else
140300 +#endif
140301 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
140302 + if (!eq)
140303 + return -EBUSY;
140304 + /* Process ORP-specifics here */
140305 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
140306 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
140307 + else {
140308 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
140309 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
140310 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
140311 + else
140312 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
140313 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
140314 + }
140315 + eq->seqnum = cpu_to_be16(orp_seqnum);
140316 + eq->orp = cpu_to_be32(orp->fqid);
140317 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
140318 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
140319 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
140320 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
140321 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140322 + PORTAL_IRQ_UNLOCK(p, irqflags);
140323 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140324 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140325 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140326 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140327 + /* NB: return success even if signal occurs before
140328 + * condition is true. pvb_commit guarantees success */
140329 + wait_event_interruptible(affine_queue,
140330 + (p->eqci_owned != fq));
140331 + else
140332 + wait_event(affine_queue, (p->eqci_owned != fq));
140333 + }
140334 +#endif
140335 + return 0;
140336 +}
140337 +EXPORT_SYMBOL(qman_p_enqueue_orp);
140338 +
140339 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
140340 + struct qman_fq *orp, u16 orp_seqnum)
140341 +{
140342 + struct qman_portal *p;
140343 + struct qm_eqcr_entry *eq;
140344 + unsigned long irqflags __maybe_unused;
140345 +
140346 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140347 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
140348 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
140349 + else
140350 +#endif
140351 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
140352 + if (!eq)
140353 + return -EBUSY;
140354 + /* Process ORP-specifics here */
140355 + if (flags & QMAN_ENQUEUE_FLAG_NLIS)
140356 + orp_seqnum |= QM_EQCR_SEQNUM_NLIS;
140357 + else {
140358 + orp_seqnum &= ~QM_EQCR_SEQNUM_NLIS;
140359 + if (flags & QMAN_ENQUEUE_FLAG_NESN)
140360 + orp_seqnum |= QM_EQCR_SEQNUM_NESN;
140361 + else
140362 + /* No need to check 4 QMAN_ENQUEUE_FLAG_HOLE */
140363 + orp_seqnum &= ~QM_EQCR_SEQNUM_NESN;
140364 + }
140365 + eq->seqnum = cpu_to_be16(orp_seqnum);
140366 + eq->orp = cpu_to_be32(orp->fqid);
140367 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
140368 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_ORP |
140369 + ((flags & (QMAN_ENQUEUE_FLAG_HOLE | QMAN_ENQUEUE_FLAG_NESN)) ?
140370 + 0 : QM_EQCR_VERB_CMD_ENQUEUE) |
140371 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140372 + PORTAL_IRQ_UNLOCK(p, irqflags);
140373 + put_affine_portal();
140374 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140375 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140376 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140377 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140378 + /* NB: return success even if signal occurs before
140379 + * condition is true. pvb_commit guarantees success */
140380 + wait_event_interruptible(affine_queue,
140381 + (p->eqci_owned != fq));
140382 + else
140383 + wait_event(affine_queue, (p->eqci_owned != fq));
140384 + }
140385 +#endif
140386 + return 0;
140387 +}
140388 +EXPORT_SYMBOL(qman_enqueue_orp);
140389 +
140390 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
140391 + const struct qm_fd *fd, u32 flags,
140392 + qman_cb_precommit cb, void *cb_arg)
140393 +{
140394 + struct qm_eqcr_entry *eq;
140395 + unsigned long irqflags __maybe_unused;
140396 +
140397 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140398 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
140399 + eq = wait_p_eq_start(p, &irqflags, fq, fd, flags);
140400 + else
140401 +#endif
140402 + eq = try_p_eq_start(p, &irqflags, fq, fd, flags);
140403 + if (!eq)
140404 + return -EBUSY;
140405 + /* invoke user supplied callback function before writing commit verb */
140406 + if (cb(cb_arg)) {
140407 + PORTAL_IRQ_UNLOCK(p, irqflags);
140408 + return -EINVAL;
140409 + }
140410 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
140411 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
140412 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140413 + /* Factor the below out, it's used from qman_enqueue_orp() too */
140414 + PORTAL_IRQ_UNLOCK(p, irqflags);
140415 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140416 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140417 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140418 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140419 + /* NB: return success even if signal occurs before
140420 + * condition is true. pvb_commit guarantees success */
140421 + wait_event_interruptible(affine_queue,
140422 + (p->eqci_owned != fq));
140423 + else
140424 + wait_event(affine_queue, (p->eqci_owned != fq));
140425 + }
140426 +#endif
140427 + return 0;
140428 +}
140429 +EXPORT_SYMBOL(qman_p_enqueue_precommit);
140430 +
140431 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
140432 + u32 flags, qman_cb_precommit cb, void *cb_arg)
140433 +{
140434 + struct qman_portal *p;
140435 + struct qm_eqcr_entry *eq;
140436 + unsigned long irqflags __maybe_unused;
140437 +
140438 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
140439 + if (flags & QMAN_ENQUEUE_FLAG_WAIT)
140440 + eq = wait_eq_start(&p, &irqflags, fq, fd, flags);
140441 + else
140442 +#endif
140443 + eq = try_eq_start(&p, &irqflags, fq, fd, flags);
140444 + if (!eq)
140445 + return -EBUSY;
140446 + /* invoke user supplied callback function before writing commit verb */
140447 + if (cb(cb_arg)) {
140448 + PORTAL_IRQ_UNLOCK(p, irqflags);
140449 + put_affine_portal();
140450 + return -EINVAL;
140451 + }
140452 + /* Note: QM_EQCR_VERB_INTERRUPT == QMAN_ENQUEUE_FLAG_WAIT_SYNC */
140453 + qm_eqcr_pvb_commit(&p->p, QM_EQCR_VERB_CMD_ENQUEUE |
140454 + (flags & (QM_EQCR_VERB_COLOUR_MASK | QM_EQCR_VERB_INTERRUPT)));
140455 + /* Factor the below out, it's used from qman_enqueue_orp() too */
140456 + PORTAL_IRQ_UNLOCK(p, irqflags);
140457 + put_affine_portal();
140458 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
140459 + if (unlikely((flags & QMAN_ENQUEUE_FLAG_WAIT) &&
140460 + (flags & QMAN_ENQUEUE_FLAG_WAIT_SYNC))) {
140461 + if (flags & QMAN_ENQUEUE_FLAG_WAIT_INT)
140462 + /* NB: return success even if signal occurs before
140463 + * condition is true. pvb_commit guarantees success */
140464 + wait_event_interruptible(affine_queue,
140465 + (p->eqci_owned != fq));
140466 + else
140467 + wait_event(affine_queue, (p->eqci_owned != fq));
140468 + }
140469 +#endif
140470 + return 0;
140471 +}
140472 +EXPORT_SYMBOL(qman_enqueue_precommit);
140473 +
140474 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
140475 + struct qm_mcc_initcgr *opts)
140476 +{
140477 + struct qm_mc_command *mcc;
140478 + struct qm_mc_result *mcr;
140479 + struct qman_portal *p = get_affine_portal();
140480 + unsigned long irqflags __maybe_unused;
140481 + u8 res;
140482 + u8 verb = QM_MCC_VERB_MODIFYCGR;
140483 +
140484 + PORTAL_IRQ_LOCK(p, irqflags);
140485 + mcc = qm_mc_start(&p->p);
140486 + if (opts)
140487 + mcc->initcgr = *opts;
140488 + mcc->initcgr.we_mask = cpu_to_be16(mcc->initcgr.we_mask);
140489 + mcc->initcgr.cgr.wr_parm_g.word =
140490 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_g.word);
140491 + mcc->initcgr.cgr.wr_parm_y.word =
140492 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_y.word);
140493 + mcc->initcgr.cgr.wr_parm_r.word =
140494 + cpu_to_be32(mcc->initcgr.cgr.wr_parm_r.word);
140495 + mcc->initcgr.cgr.cscn_targ = cpu_to_be32(mcc->initcgr.cgr.cscn_targ);
140496 + mcc->initcgr.cgr.__cs_thres = cpu_to_be16(mcc->initcgr.cgr.__cs_thres);
140497 +
140498 + mcc->initcgr.cgid = cgr->cgrid;
140499 + if (flags & QMAN_CGR_FLAG_USE_INIT)
140500 + verb = QM_MCC_VERB_INITCGR;
140501 + qm_mc_commit(&p->p, verb);
140502 + while (!(mcr = qm_mc_result(&p->p)))
140503 + cpu_relax();
140504 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == verb);
140505 + res = mcr->result;
140506 + PORTAL_IRQ_UNLOCK(p, irqflags);
140507 + put_affine_portal();
140508 + return (res == QM_MCR_RESULT_OK) ? 0 : -EIO;
140509 +}
140510 +EXPORT_SYMBOL(qman_modify_cgr);
140511 +
140512 +#define TARG_MASK(n) (0x80000000 >> (n->config->public_cfg.channel - \
140513 + QM_CHANNEL_SWPORTAL0))
140514 +#define TARG_DCP_MASK(n) (0x80000000 >> (10 + n))
140515 +#define PORTAL_IDX(n) (n->config->public_cfg.channel - QM_CHANNEL_SWPORTAL0)
140516 +
140517 +static u8 qman_cgr_cpus[__CGR_NUM];
140518 +
140519 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
140520 + struct qm_mcc_initcgr *opts)
140521 +{
140522 + unsigned long irqflags __maybe_unused;
140523 + struct qm_mcr_querycgr cgr_state;
140524 + struct qm_mcc_initcgr local_opts;
140525 + int ret;
140526 + struct qman_portal *p;
140527 +
140528 + /* We have to check that the provided CGRID is within the limits of the
140529 + * data-structures, for obvious reasons. However we'll let h/w take
140530 + * care of determining whether it's within the limits of what exists on
140531 + * the SoC. */
140532 + if (cgr->cgrid >= __CGR_NUM)
140533 + return -EINVAL;
140534 +
140535 + preempt_disable();
140536 + p = get_affine_portal();
140537 + qman_cgr_cpus[cgr->cgrid] = smp_processor_id();
140538 + preempt_enable();
140539 +
140540 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
140541 + cgr->chan = p->config->public_cfg.channel;
140542 + spin_lock_irqsave(&p->cgr_lock, irqflags);
140543 +
140544 + /* if no opts specified, just add it to the list */
140545 + if (!opts)
140546 + goto add_list;
140547 +
140548 + ret = qman_query_cgr(cgr, &cgr_state);
140549 + if (ret)
140550 + goto release_lock;
140551 + if (opts)
140552 + local_opts = *opts;
140553 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
140554 + local_opts.cgr.cscn_targ_upd_ctrl =
140555 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p);
140556 + else
140557 + /* Overwrite TARG */
140558 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
140559 + TARG_MASK(p);
140560 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
140561 +
140562 + /* send init if flags indicate so */
140563 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
140564 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT, &local_opts);
140565 + else
140566 + ret = qman_modify_cgr(cgr, 0, &local_opts);
140567 + if (ret)
140568 + goto release_lock;
140569 +add_list:
140570 + list_add(&cgr->node, &p->cgr_cbs);
140571 +
140572 + /* Determine if newly added object requires its callback to be called */
140573 + ret = qman_query_cgr(cgr, &cgr_state);
140574 + if (ret) {
140575 + /* we can't go back, so proceed and return success, but screen
140576 + * and wail to the log file */
140577 + pr_crit("CGR HW state partially modified\n");
140578 + ret = 0;
140579 + goto release_lock;
140580 + }
140581 + if (cgr->cb && cgr_state.cgr.cscn_en && qman_cgrs_get(&p->cgrs[1],
140582 + cgr->cgrid))
140583 + cgr->cb(p, cgr, 1);
140584 +release_lock:
140585 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
140586 + put_affine_portal();
140587 + return ret;
140588 +}
140589 +EXPORT_SYMBOL(qman_create_cgr);
140590 +
140591 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
140592 + struct qm_mcc_initcgr *opts)
140593 +{
140594 + unsigned long irqflags __maybe_unused;
140595 + struct qm_mcc_initcgr local_opts;
140596 + struct qm_mcr_querycgr cgr_state;
140597 + int ret;
140598 +
140599 + if ((qman_ip_rev & 0xFF00) < QMAN_REV30) {
140600 + pr_warn("This QMan version doesn't support to send CSCN to DCP portal\n");
140601 + return -EINVAL;
140602 + }
140603 + /* We have to check that the provided CGRID is within the limits of the
140604 + * data-structures, for obvious reasons. However we'll let h/w take
140605 + * care of determining whether it's within the limits of what exists on
140606 + * the SoC.
140607 + */
140608 + if (cgr->cgrid >= __CGR_NUM)
140609 + return -EINVAL;
140610 +
140611 + ret = qman_query_cgr(cgr, &cgr_state);
140612 + if (ret)
140613 + return ret;
140614 +
140615 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
140616 + if (opts)
140617 + local_opts = *opts;
140618 +
140619 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
140620 + local_opts.cgr.cscn_targ_upd_ctrl =
140621 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT |
140622 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_portal;
140623 + else
140624 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ |
140625 + TARG_DCP_MASK(dcp_portal);
140626 + local_opts.we_mask |= QM_CGR_WE_CSCN_TARG;
140627 +
140628 + /* send init if flags indicate so */
140629 + if (opts && (flags & QMAN_CGR_FLAG_USE_INIT))
140630 + ret = qman_modify_cgr(cgr, QMAN_CGR_FLAG_USE_INIT,
140631 + &local_opts);
140632 + else
140633 + ret = qman_modify_cgr(cgr, 0, &local_opts);
140634 +
140635 + return ret;
140636 +}
140637 +EXPORT_SYMBOL(qman_create_cgr_to_dcp);
140638 +
140639 +int qman_delete_cgr(struct qman_cgr *cgr)
140640 +{
140641 + unsigned long irqflags __maybe_unused;
140642 + struct qm_mcr_querycgr cgr_state;
140643 + struct qm_mcc_initcgr local_opts;
140644 + int ret = 0;
140645 + struct qman_cgr *i;
140646 + struct qman_portal *p = get_affine_portal();
140647 +
140648 + if (cgr->chan != p->config->public_cfg.channel) {
140649 + pr_crit("Attempting to delete cgr from different portal "
140650 + "than it was create: create 0x%x, delete 0x%x\n",
140651 + cgr->chan, p->config->public_cfg.channel);
140652 + ret = -EINVAL;
140653 + goto put_portal;
140654 + }
140655 + memset(&local_opts, 0, sizeof(struct qm_mcc_initcgr));
140656 + spin_lock_irqsave(&p->cgr_lock, irqflags);
140657 + list_del(&cgr->node);
140658 + /*
140659 + * If there are no other CGR objects for this CGRID in the list, update
140660 + * CSCN_TARG accordingly
140661 + */
140662 + list_for_each_entry(i, &p->cgr_cbs, node)
140663 + if ((i->cgrid == cgr->cgrid) && i->cb)
140664 + goto release_lock;
140665 + ret = qman_query_cgr(cgr, &cgr_state);
140666 + if (ret) {
140667 + /* add back to the list */
140668 + list_add(&cgr->node, &p->cgr_cbs);
140669 + goto release_lock;
140670 + }
140671 + /* Overwrite TARG */
140672 + local_opts.we_mask = QM_CGR_WE_CSCN_TARG;
140673 + if ((qman_ip_rev & 0xFF00) >= QMAN_REV30)
140674 + local_opts.cgr.cscn_targ_upd_ctrl = PORTAL_IDX(p);
140675 + else
140676 + local_opts.cgr.cscn_targ = cgr_state.cgr.cscn_targ &
140677 + ~(TARG_MASK(p));
140678 + ret = qman_modify_cgr(cgr, 0, &local_opts);
140679 + if (ret)
140680 + /* add back to the list */
140681 + list_add(&cgr->node, &p->cgr_cbs);
140682 +release_lock:
140683 + spin_unlock_irqrestore(&p->cgr_lock, irqflags);
140684 +put_portal:
140685 + put_affine_portal();
140686 + return ret;
140687 +}
140688 +EXPORT_SYMBOL(qman_delete_cgr);
140689 +
140690 +struct cgr_comp {
140691 + struct qman_cgr *cgr;
140692 + struct completion completion;
140693 +};
140694 +
140695 +static void qman_delete_cgr_smp_call(void *p)
140696 +{
140697 + qman_delete_cgr((struct qman_cgr *)p);
140698 +}
140699 +
140700 +void qman_delete_cgr_safe(struct qman_cgr *cgr)
140701 +{
140702 + preempt_disable();
140703 + if (qman_cgr_cpus[cgr->cgrid] != smp_processor_id()) {
140704 + smp_call_function_single(qman_cgr_cpus[cgr->cgrid],
140705 + qman_delete_cgr_smp_call, cgr, true);
140706 + preempt_enable();
140707 + return;
140708 + }
140709 + qman_delete_cgr(cgr);
140710 + preempt_enable();
140711 +}
140712 +EXPORT_SYMBOL(qman_delete_cgr_safe);
140713 +
140714 +int qm_get_clock(u64 *clock_hz)
140715 +{
140716 + if (!qman_clk) {
140717 + pr_warn("Qman clock speed is unknown\n");
140718 + return -EINVAL;
140719 + }
140720 + *clock_hz = (u64)qman_clk;
140721 + return 0;
140722 +}
140723 +EXPORT_SYMBOL(qm_get_clock);
140724 +
140725 +int qm_set_clock(u64 clock_hz)
140726 +{
140727 + if (qman_clk)
140728 + return -1;
140729 + qman_clk = (u32)clock_hz;
140730 + return 0;
140731 +}
140732 +EXPORT_SYMBOL(qm_set_clock);
140733 +
140734 +/* CEETM management command */
140735 +static int qman_ceetm_configure_lfqmt(struct qm_mcc_ceetm_lfqmt_config *opts)
140736 +{
140737 + struct qm_mc_command *mcc;
140738 + struct qm_mc_result *mcr;
140739 + struct qman_portal *p;
140740 + unsigned long irqflags __maybe_unused;
140741 + u8 res;
140742 +
140743 + p = get_affine_portal();
140744 + PORTAL_IRQ_LOCK(p, irqflags);
140745 +
140746 + mcc = qm_mc_start(&p->p);
140747 + mcc->lfqmt_config = *opts;
140748 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_CONFIG);
140749 + while (!(mcr = qm_mc_result(&p->p)))
140750 + cpu_relax();
140751 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140752 + QM_CEETM_VERB_LFQMT_CONFIG);
140753 + PORTAL_IRQ_UNLOCK(p, irqflags);
140754 + put_affine_portal();
140755 +
140756 + res = mcr->result;
140757 + if (res != QM_MCR_RESULT_OK) {
140758 + pr_err("CEETM: CONFIGURE LFQMT failed\n");
140759 + return -EIO;
140760 + }
140761 + return 0;
140762 +}
140763 +
140764 +int qman_ceetm_query_lfqmt(int lfqid,
140765 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query)
140766 +{
140767 + struct qm_mc_command *mcc;
140768 + struct qm_mc_result *mcr;
140769 + struct qman_portal *p;
140770 + unsigned long irqflags __maybe_unused;
140771 + u8 res;
140772 +
140773 + p = get_affine_portal();
140774 + PORTAL_IRQ_LOCK(p, irqflags);
140775 +
140776 + mcc = qm_mc_start(&p->p);
140777 + mcc->lfqmt_query.lfqid = lfqid;
140778 + qm_mc_commit(&p->p, QM_CEETM_VERB_LFQMT_QUERY);
140779 + while (!(mcr = qm_mc_result(&p->p)))
140780 + cpu_relax();
140781 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_LFQMT_QUERY);
140782 + res = mcr->result;
140783 + if (res == QM_MCR_RESULT_OK)
140784 + *lfqmt_query = mcr->lfqmt_query;
140785 +
140786 + PORTAL_IRQ_UNLOCK(p, irqflags);
140787 + put_affine_portal();
140788 + if (res != QM_MCR_RESULT_OK) {
140789 + pr_err("CEETM: QUERY LFQMT failed\n");
140790 + return -EIO;
140791 + }
140792 + return 0;
140793 +}
140794 +EXPORT_SYMBOL(qman_ceetm_query_lfqmt);
140795 +
140796 +static int qman_ceetm_configure_cq(struct qm_mcc_ceetm_cq_config *opts)
140797 +{
140798 + struct qm_mc_command *mcc;
140799 + struct qm_mc_result *mcr;
140800 + struct qman_portal *p;
140801 + unsigned long irqflags __maybe_unused;
140802 + u8 res;
140803 +
140804 + p = get_affine_portal();
140805 + PORTAL_IRQ_LOCK(p, irqflags);
140806 +
140807 + mcc = qm_mc_start(&p->p);
140808 + mcc->cq_config = *opts;
140809 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_CONFIG);
140810 + while (!(mcr = qm_mc_result(&p->p)))
140811 + cpu_relax();
140812 + res = mcr->result;
140813 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_CONFIG);
140814 +
140815 + PORTAL_IRQ_UNLOCK(p, irqflags);
140816 + put_affine_portal();
140817 +
140818 + if (res != QM_MCR_RESULT_OK) {
140819 + pr_err("CEETM: CONFIGURE CQ failed\n");
140820 + return -EIO;
140821 + }
140822 + return 0;
140823 +}
140824 +
140825 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
140826 + struct qm_mcr_ceetm_cq_query *cq_query)
140827 +{
140828 + struct qm_mc_command *mcc;
140829 + struct qm_mc_result *mcr;
140830 + struct qman_portal *p;
140831 + unsigned long irqflags __maybe_unused;
140832 + u8 res;
140833 +
140834 + p = get_affine_portal();
140835 + PORTAL_IRQ_LOCK(p, irqflags);
140836 +
140837 + mcc = qm_mc_start(&p->p);
140838 + mcc->cq_query.cqid = cpu_to_be16(cqid);
140839 + mcc->cq_query.dcpid = dcpid;
140840 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_QUERY);
140841 + while (!(mcr = qm_mc_result(&p->p)))
140842 + cpu_relax();
140843 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CQ_QUERY);
140844 + res = mcr->result;
140845 + if (res == QM_MCR_RESULT_OK) {
140846 + *cq_query = mcr->cq_query;
140847 + hw_cq_query_to_cpu(cq_query);
140848 + }
140849 +
140850 + PORTAL_IRQ_UNLOCK(p, irqflags);
140851 + put_affine_portal();
140852 +
140853 + if (res != QM_MCR_RESULT_OK) {
140854 + pr_err("CEETM: QUERY CQ failed\n");
140855 + return -EIO;
140856 + }
140857 +
140858 + return 0;
140859 +}
140860 +EXPORT_SYMBOL(qman_ceetm_query_cq);
140861 +
140862 +static int qman_ceetm_configure_dct(struct qm_mcc_ceetm_dct_config *opts)
140863 +{
140864 + struct qm_mc_command *mcc;
140865 + struct qm_mc_result *mcr;
140866 + struct qman_portal *p;
140867 + unsigned long irqflags __maybe_unused;
140868 + u8 res;
140869 +
140870 + p = get_affine_portal();
140871 + PORTAL_IRQ_LOCK(p, irqflags);
140872 +
140873 + mcc = qm_mc_start(&p->p);
140874 + mcc->dct_config = *opts;
140875 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_CONFIG);
140876 + while (!(mcr = qm_mc_result(&p->p)))
140877 + cpu_relax();
140878 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_CONFIG);
140879 + res = mcr->result;
140880 +
140881 + PORTAL_IRQ_UNLOCK(p, irqflags);
140882 + put_affine_portal();
140883 +
140884 + if (res != QM_MCR_RESULT_OK) {
140885 + pr_err("CEETM: CONFIGURE DCT failed\n");
140886 + return -EIO;
140887 + }
140888 + return 0;
140889 +}
140890 +
140891 +static int qman_ceetm_query_dct(struct qm_mcc_ceetm_dct_query *opts,
140892 + struct qm_mcr_ceetm_dct_query *dct_query)
140893 +{
140894 + struct qm_mc_command *mcc;
140895 + struct qm_mc_result *mcr;
140896 + struct qman_portal *p = get_affine_portal();
140897 + unsigned long irqflags __maybe_unused;
140898 + u8 res;
140899 +
140900 + PORTAL_IRQ_LOCK(p, irqflags);
140901 +
140902 + mcc = qm_mc_start(&p->p);
140903 + mcc->dct_query = *opts;
140904 + qm_mc_commit(&p->p, QM_CEETM_VERB_DCT_QUERY);
140905 + while (!(mcr = qm_mc_result(&p->p)))
140906 + cpu_relax();
140907 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_DCT_QUERY);
140908 + res = mcr->result;
140909 +
140910 + PORTAL_IRQ_UNLOCK(p, irqflags);
140911 + put_affine_portal();
140912 +
140913 + if (res != QM_MCR_RESULT_OK) {
140914 + pr_err("CEETM: QUERY DCT failed\n");
140915 + return -EIO;
140916 + }
140917 +
140918 + *dct_query = mcr->dct_query;
140919 + return 0;
140920 +}
140921 +
140922 +static int qman_ceetm_configure_class_scheduler(
140923 + struct qm_mcc_ceetm_class_scheduler_config *opts)
140924 +{
140925 + struct qm_mc_command *mcc;
140926 + struct qm_mc_result *mcr;
140927 + struct qman_portal *p;
140928 + unsigned long irqflags __maybe_unused;
140929 + u8 res;
140930 +
140931 + p = get_affine_portal();
140932 + PORTAL_IRQ_LOCK(p, irqflags);
140933 +
140934 + mcc = qm_mc_start(&p->p);
140935 + mcc->csch_config = *opts;
140936 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
140937 + while (!(mcr = qm_mc_result(&p->p)))
140938 + cpu_relax();
140939 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140940 + QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG);
140941 + res = mcr->result;
140942 +
140943 + PORTAL_IRQ_UNLOCK(p, irqflags);
140944 + put_affine_portal();
140945 +
140946 + if (res != QM_MCR_RESULT_OK) {
140947 + pr_err("CEETM: CONFIGURE CLASS SCHEDULER failed\n");
140948 + return -EIO;
140949 + }
140950 + return 0;
140951 +}
140952 +
140953 +static int qman_ceetm_query_class_scheduler(struct qm_ceetm_channel *channel,
140954 + struct qm_mcr_ceetm_class_scheduler_query *query)
140955 +{
140956 + struct qm_mc_command *mcc;
140957 + struct qm_mc_result *mcr;
140958 + struct qman_portal *p;
140959 + unsigned long irqflags __maybe_unused;
140960 + u8 res;
140961 +
140962 + p = get_affine_portal();
140963 + PORTAL_IRQ_LOCK(p, irqflags);
140964 +
140965 + mcc = qm_mc_start(&p->p);
140966 + mcc->csch_query.cqcid = cpu_to_be16(channel->idx);
140967 + mcc->csch_query.dcpid = channel->dcp_idx;
140968 + qm_mc_commit(&p->p, QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
140969 + while (!(mcr = qm_mc_result(&p->p)))
140970 + cpu_relax();
140971 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
140972 + QM_CEETM_VERB_CLASS_SCHEDULER_QUERY);
140973 + res = mcr->result;
140974 +
140975 + PORTAL_IRQ_UNLOCK(p, irqflags);
140976 + put_affine_portal();
140977 +
140978 + if (res != QM_MCR_RESULT_OK) {
140979 + pr_err("CEETM: QUERY CLASS SCHEDULER failed\n");
140980 + return -EIO;
140981 + }
140982 + *query = mcr->csch_query;
140983 + return 0;
140984 +}
140985 +
140986 +static int qman_ceetm_configure_mapping_shaper_tcfc(
140987 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config *opts)
140988 +{
140989 + struct qm_mc_command *mcc;
140990 + struct qm_mc_result *mcr;
140991 + struct qman_portal *p;
140992 + unsigned long irqflags __maybe_unused;
140993 + u8 res;
140994 +
140995 + p = get_affine_portal();
140996 + PORTAL_IRQ_LOCK(p, irqflags);
140997 +
140998 + mcc = qm_mc_start(&p->p);
140999 + mcc->mst_config = *opts;
141000 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
141001 + while (!(mcr = qm_mc_result(&p->p)))
141002 + cpu_relax();
141003 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141004 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG);
141005 + res = mcr->result;
141006 +
141007 + PORTAL_IRQ_UNLOCK(p, irqflags);
141008 + put_affine_portal();
141009 +
141010 + if (res != QM_MCR_RESULT_OK) {
141011 + pr_err("CEETM: CONFIGURE CHANNEL MAPPING failed\n");
141012 + return -EIO;
141013 + }
141014 + return 0;
141015 +}
141016 +
141017 +static int qman_ceetm_query_mapping_shaper_tcfc(
141018 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query *opts,
141019 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query *response)
141020 +{
141021 + struct qm_mc_command *mcc;
141022 + struct qm_mc_result *mcr;
141023 + struct qman_portal *p;
141024 + unsigned long irqflags __maybe_unused;
141025 + u8 res;
141026 +
141027 + p = get_affine_portal();
141028 + PORTAL_IRQ_LOCK(p, irqflags);
141029 +
141030 + mcc = qm_mc_start(&p->p);
141031 + mcc->mst_query = *opts;
141032 + qm_mc_commit(&p->p, QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
141033 + while (!(mcr = qm_mc_result(&p->p)))
141034 + cpu_relax();
141035 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141036 + QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY);
141037 + res = mcr->result;
141038 +
141039 + PORTAL_IRQ_UNLOCK(p, irqflags);
141040 + put_affine_portal();
141041 +
141042 + if (res != QM_MCR_RESULT_OK) {
141043 + pr_err("CEETM: QUERY CHANNEL MAPPING failed\n");
141044 + return -EIO;
141045 + }
141046 +
141047 + *response = mcr->mst_query;
141048 + return 0;
141049 +}
141050 +
141051 +static int qman_ceetm_configure_ccgr(struct qm_mcc_ceetm_ccgr_config *opts)
141052 +{
141053 + struct qm_mc_command *mcc;
141054 + struct qm_mc_result *mcr;
141055 + struct qman_portal *p;
141056 + unsigned long irqflags __maybe_unused;
141057 + u8 res;
141058 +
141059 + p = get_affine_portal();
141060 + PORTAL_IRQ_LOCK(p, irqflags);
141061 +
141062 + mcc = qm_mc_start(&p->p);
141063 + mcc->ccgr_config = *opts;
141064 +
141065 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_CONFIG);
141066 + while (!(mcr = qm_mc_result(&p->p)))
141067 + cpu_relax();
141068 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_CONFIG);
141069 +
141070 + PORTAL_IRQ_UNLOCK(p, irqflags);
141071 + put_affine_portal();
141072 +
141073 + res = mcr->result;
141074 + if (res != QM_MCR_RESULT_OK) {
141075 + pr_err("CEETM: CONFIGURE CCGR failed\n");
141076 + return -EIO;
141077 + }
141078 + return 0;
141079 +}
141080 +
141081 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
141082 + struct qm_mcr_ceetm_ccgr_query *response)
141083 +{
141084 + struct qm_mc_command *mcc;
141085 + struct qm_mc_result *mcr;
141086 + struct qman_portal *p;
141087 + unsigned long irqflags __maybe_unused;
141088 + u8 res;
141089 +
141090 + p = get_affine_portal();
141091 + PORTAL_IRQ_LOCK(p, irqflags);
141092 +
141093 + mcc = qm_mc_start(&p->p);
141094 + mcc->ccgr_query.ccgrid = cpu_to_be16(ccgr_query->ccgrid);
141095 + mcc->ccgr_query.dcpid = ccgr_query->dcpid;
141096 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
141097 +
141098 + while (!(mcr = qm_mc_result(&p->p)))
141099 + cpu_relax();
141100 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_CEETM_VERB_CCGR_QUERY);
141101 + res = mcr->result;
141102 + if (res == QM_MCR_RESULT_OK) {
141103 + *response = mcr->ccgr_query;
141104 + hw_ccgr_query_to_cpu(response);
141105 + }
141106 +
141107 + PORTAL_IRQ_UNLOCK(p, irqflags);
141108 + put_affine_portal();
141109 + if (res != QM_MCR_RESULT_OK) {
141110 + pr_err("CEETM: QUERY CCGR failed\n");
141111 + return -EIO;
141112 + }
141113 + return 0;
141114 +}
141115 +EXPORT_SYMBOL(qman_ceetm_query_ccgr);
141116 +
141117 +static int qman_ceetm_cq_peek_pop_xsfdrread(struct qm_ceetm_cq *cq,
141118 + u8 command_type, u16 xsfdr,
141119 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread *cq_ppxr)
141120 +{
141121 + struct qm_mc_command *mcc;
141122 + struct qm_mc_result *mcr;
141123 + struct qman_portal *p;
141124 + unsigned long irqflags __maybe_unused;
141125 + u8 res;
141126 +
141127 + p = get_affine_portal();
141128 + PORTAL_IRQ_LOCK(p, irqflags);
141129 +
141130 + mcc = qm_mc_start(&p->p);
141131 + switch (command_type) {
141132 + case 0:
141133 + case 1:
141134 + mcc->cq_ppxr.cqid = (cq->parent->idx << 4) | cq->idx;
141135 + break;
141136 + case 2:
141137 + mcc->cq_ppxr.xsfdr = xsfdr;
141138 + break;
141139 + default:
141140 + break;
141141 + }
141142 + mcc->cq_ppxr.ct = command_type;
141143 + mcc->cq_ppxr.dcpid = cq->parent->dcp_idx;
141144 + qm_mc_commit(&p->p, QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
141145 + while (!(mcr = qm_mc_result(&p->p)))
141146 + cpu_relax();
141147 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141148 + QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD);
141149 +
141150 + PORTAL_IRQ_UNLOCK(p, irqflags);
141151 + put_affine_portal();
141152 +
141153 + res = mcr->result;
141154 + if (res != QM_MCR_RESULT_OK) {
141155 + pr_err("CEETM: CQ PEEK/POP/XSFDR READ failed\n");
141156 + return -EIO;
141157 + }
141158 + *cq_ppxr = mcr->cq_ppxr;
141159 + return 0;
141160 +}
141161 +
141162 +static int qman_ceetm_query_statistics(u16 cid,
141163 + enum qm_dc_portal dcp_idx,
141164 + u16 command_type,
141165 + struct qm_mcr_ceetm_statistics_query *query_result)
141166 +{
141167 + struct qm_mc_command *mcc;
141168 + struct qm_mc_result *mcr;
141169 + struct qman_portal *p;
141170 + unsigned long irqflags __maybe_unused;
141171 + u8 res;
141172 +
141173 + p = get_affine_portal();
141174 + PORTAL_IRQ_LOCK(p, irqflags);
141175 +
141176 + mcc = qm_mc_start(&p->p);
141177 + mcc->stats_query_write.cid = cid;
141178 + mcc->stats_query_write.dcpid = dcp_idx;
141179 + mcc->stats_query_write.ct = command_type;
141180 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
141181 +
141182 + while (!(mcr = qm_mc_result(&p->p)))
141183 + cpu_relax();
141184 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141185 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
141186 +
141187 + PORTAL_IRQ_UNLOCK(p, irqflags);
141188 + put_affine_portal();
141189 +
141190 + res = mcr->result;
141191 + if (res != QM_MCR_RESULT_OK) {
141192 + pr_err("CEETM: STATISTICS QUERY failed\n");
141193 + return -EIO;
141194 + }
141195 + *query_result = mcr->stats_query;
141196 + return 0;
141197 +}
141198 +
141199 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
141200 + u16 command_type, u64 frame_count,
141201 + u64 byte_count)
141202 +{
141203 + struct qm_mc_command *mcc;
141204 + struct qm_mc_result *mcr;
141205 + struct qman_portal *p;
141206 + unsigned long irqflags __maybe_unused;
141207 + u8 res;
141208 +
141209 + p = get_affine_portal();
141210 + PORTAL_IRQ_LOCK(p, irqflags);
141211 +
141212 + mcc = qm_mc_start(&p->p);
141213 + mcc->stats_query_write.cid = cid;
141214 + mcc->stats_query_write.dcpid = dcp_idx;
141215 + mcc->stats_query_write.ct = command_type;
141216 + mcc->stats_query_write.frm_cnt = frame_count;
141217 + mcc->stats_query_write.byte_cnt = byte_count;
141218 + qm_mc_commit(&p->p, QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
141219 +
141220 + while (!(mcr = qm_mc_result(&p->p)))
141221 + cpu_relax();
141222 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
141223 + QM_CEETM_VERB_STATISTICS_QUERY_WRITE);
141224 +
141225 + PORTAL_IRQ_UNLOCK(p, irqflags);
141226 + put_affine_portal();
141227 +
141228 + res = mcr->result;
141229 + if (res != QM_MCR_RESULT_OK) {
141230 + pr_err("CEETM: STATISTICS WRITE failed\n");
141231 + return -EIO;
141232 + }
141233 + return 0;
141234 +}
141235 +EXPORT_SYMBOL(qman_ceetm_query_write_statistics);
141236 +
141237 +int qman_ceetm_bps2tokenrate(u64 bps, struct qm_ceetm_rate *token_rate,
141238 + int rounding)
141239 +{
141240 + u16 pres;
141241 + u64 temp;
141242 + u64 qman_freq;
141243 + int ret;
141244 +
141245 + /* Read PRES from CEET_CFG_PRES register */
141246 + ret = qman_ceetm_get_prescaler(&pres);
141247 + if (ret)
141248 + return -EINVAL;
141249 +
141250 + ret = qm_get_clock(&qman_freq);
141251 + if (ret)
141252 + return -EINVAL;
141253 +
141254 + /* token-rate = bytes-per-second * update-reference-period
141255 + *
141256 + * Where token-rate is N/8192 for a integer N, and
141257 + * update-reference-period is (2^22)/(PRES*QHz), where PRES
141258 + * is the prescalar value and QHz is the QMan clock frequency.
141259 + * So:
141260 + *
141261 + * token-rate = (byte-per-second*2^22)/PRES*QHZ)
141262 + *
141263 + * Converting to bits-per-second gives;
141264 + *
141265 + * token-rate = (bps*2^19) / (PRES*QHZ)
141266 + * N = (bps*2^32) / (PRES*QHz)
141267 + *
141268 + * And to avoid 64-bit overflow if 'bps' is larger than 4Gbps
141269 + * (yet minimise rounding error if 'bps' is small), we reorganise
141270 + * the formula to use two 16-bit shifts rather than 1 32-bit shift.
141271 + * N = (((bps*2^16)/PRES)*2^16)/QHz
141272 + */
141273 + temp = ROUNDING((bps << 16), pres, rounding);
141274 + temp = ROUNDING((temp << 16), qman_freq, rounding);
141275 + token_rate->whole = temp >> 13;
141276 + token_rate->fraction = temp & (((u64)1 << 13) - 1);
141277 + return 0;
141278 +}
141279 +EXPORT_SYMBOL(qman_ceetm_bps2tokenrate);
141280 +
141281 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate, u64 *bps,
141282 + int rounding)
141283 +{
141284 + u16 pres;
141285 + u64 temp;
141286 + u64 qman_freq;
141287 + int ret;
141288 +
141289 + /* Read PRES from CEET_CFG_PRES register */
141290 + ret = qman_ceetm_get_prescaler(&pres);
141291 + if (ret)
141292 + return -EINVAL;
141293 +
141294 + ret = qm_get_clock(&qman_freq);
141295 + if (ret)
141296 + return -EINVAL;
141297 +
141298 + /* bytes-per-second = token-rate / update-reference-period
141299 + *
141300 + * where "token-rate" is N/8192 for an integer N, and
141301 + * "update-reference-period" is (2^22)/(PRES*QHz), where PRES is
141302 + * the prescalar value and QHz is the QMan clock frequency. So;
141303 + *
141304 + * bytes-per-second = (N/8192) / (4194304/PRES*QHz)
141305 + * = N*PRES*QHz / (4194304*8192)
141306 + * = N*PRES*QHz / (2^35)
141307 + *
141308 + * Converting to bits-per-second gives;
141309 + *
141310 + * bps = N*PRES*QHZ / (2^32)
141311 + *
141312 + * Note, the numerator has a maximum width of 72 bits! So to
141313 + * avoid 64-bit overflow errors, we calculate PRES*QHZ (maximum
141314 + * width 48 bits) divided by 2^9 (reducing to maximum 39 bits), before
141315 + * multiplying by N (goes to maximum of 63 bits).
141316 + *
141317 + * temp = PRES*QHZ / (2^16)
141318 + * kbps = temp*N / (2^16)
141319 + */
141320 + temp = ROUNDING(qman_freq * pres, (u64)1 << 16 , rounding);
141321 + temp *= ((token_rate->whole << 13) + token_rate->fraction);
141322 + *bps = ROUNDING(temp, (u64)(1) << 16, rounding);
141323 + return 0;
141324 +}
141325 +EXPORT_SYMBOL(qman_ceetm_tokenrate2bps);
141326 +
141327 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp, enum qm_dc_portal dcp_idx,
141328 + unsigned int sp_idx)
141329 +{
141330 + struct qm_ceetm_sp *p;
141331 +
141332 + DPA_ASSERT((dcp_idx == qm_dc_portal_fman0) ||
141333 + (dcp_idx == qm_dc_portal_fman1));
141334 +
141335 + if ((sp_idx < qman_ceetms[dcp_idx].sp_range[0]) ||
141336 + (sp_idx >= (qman_ceetms[dcp_idx].sp_range[0] +
141337 + qman_ceetms[dcp_idx].sp_range[1]))) {
141338 + pr_err("Sub-portal index doesn't exist\n");
141339 + return -EINVAL;
141340 + }
141341 +
141342 + list_for_each_entry(p, &qman_ceetms[dcp_idx].sub_portals, node) {
141343 + if ((p->idx == sp_idx) && (p->is_claimed == 0)) {
141344 + p->is_claimed = 1;
141345 + *sp = p;
141346 + return 0;
141347 + }
141348 + }
141349 + pr_err("The sub-portal#%d is not available!\n", sp_idx);
141350 + return -ENODEV;
141351 +}
141352 +EXPORT_SYMBOL(qman_ceetm_sp_claim);
141353 +
141354 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp)
141355 +{
141356 + struct qm_ceetm_sp *p;
141357 +
141358 + if (sp->lni && sp->lni->is_claimed == 1) {
141359 + pr_err("The dependency of sub-portal has not been released!\n");
141360 + return -EBUSY;
141361 + }
141362 +
141363 + list_for_each_entry(p, &qman_ceetms[sp->dcp_idx].sub_portals, node) {
141364 + if (p->idx == sp->idx) {
141365 + p->is_claimed = 0;
141366 + p->lni = NULL;
141367 + }
141368 + }
141369 + /* Disable CEETM mode of this sub-portal */
141370 + qman_sp_disable_ceetm_mode(sp->dcp_idx, sp->idx);
141371 +
141372 + return 0;
141373 +}
141374 +EXPORT_SYMBOL(qman_ceetm_sp_release);
141375 +
141376 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni, enum qm_dc_portal dcp_idx,
141377 + unsigned int lni_idx)
141378 +{
141379 + struct qm_ceetm_lni *p;
141380 +
141381 + if ((lni_idx < qman_ceetms[dcp_idx].lni_range[0]) ||
141382 + (lni_idx >= (qman_ceetms[dcp_idx].lni_range[0] +
141383 + qman_ceetms[dcp_idx].lni_range[1]))) {
141384 + pr_err("The lni index is out of range\n");
141385 + return -EINVAL;
141386 + }
141387 +
141388 + list_for_each_entry(p, &qman_ceetms[dcp_idx].lnis, node) {
141389 + if ((p->idx == lni_idx) && (p->is_claimed == 0)) {
141390 + *lni = p;
141391 + p->is_claimed = 1;
141392 + return 0;
141393 + }
141394 + }
141395 +
141396 + pr_err("The LNI#%d is not available!\n", lni_idx);
141397 + return -EINVAL;
141398 +}
141399 +EXPORT_SYMBOL(qman_ceetm_lni_claim);
141400 +
141401 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni)
141402 +{
141403 + struct qm_ceetm_lni *p;
141404 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141405 +
141406 + if (!list_empty(&lni->channels)) {
141407 + pr_err("The LNI dependencies are not released!\n");
141408 + return -EBUSY;
141409 + }
141410 +
141411 + list_for_each_entry(p, &qman_ceetms[lni->dcp_idx].lnis, node) {
141412 + if (p->idx == lni->idx) {
141413 + p->shaper_enable = 0;
141414 + p->shaper_couple = 0;
141415 + p->cr_token_rate.whole = 0;
141416 + p->cr_token_rate.fraction = 0;
141417 + p->er_token_rate.whole = 0;
141418 + p->er_token_rate.fraction = 0;
141419 + p->cr_token_bucket_limit = 0;
141420 + p->er_token_bucket_limit = 0;
141421 + p->is_claimed = 0;
141422 + }
141423 + }
141424 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141425 + config_opts.dcpid = lni->dcp_idx;
141426 + memset(&config_opts.shaper_config, 0,
141427 + sizeof(config_opts.shaper_config));
141428 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141429 +}
141430 +EXPORT_SYMBOL(qman_ceetm_lni_release);
141431 +
141432 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp, struct qm_ceetm_lni *lni)
141433 +{
141434 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141435 +
141436 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
141437 + config_opts.dcpid = sp->dcp_idx;
141438 + config_opts.sp_mapping.map_lni_id = lni->idx;
141439 + sp->lni = lni;
141440 +
141441 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts))
141442 + return -EINVAL;
141443 +
141444 + /* Enable CEETM mode for this sub-portal */
141445 + return qman_sp_enable_ceetm_mode(sp->dcp_idx, sp->idx);
141446 +}
141447 +EXPORT_SYMBOL(qman_ceetm_sp_set_lni);
141448 +
141449 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp, unsigned int *lni_idx)
141450 +{
141451 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141452 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141453 +
141454 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_SP_MAPPING | sp->idx);
141455 + query_opts.dcpid = sp->dcp_idx;
141456 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141457 + pr_err("Can't get SP <-> LNI mapping\n");
141458 + return -EINVAL;
141459 + }
141460 + *lni_idx = query_result.sp_mapping_query.map_lni_id;
141461 + sp->lni->idx = query_result.sp_mapping_query.map_lni_id;
141462 + return 0;
141463 +}
141464 +EXPORT_SYMBOL(qman_ceetm_sp_get_lni);
141465 +
141466 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
141467 + int oal)
141468 +{
141469 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141470 +
141471 + if (lni->shaper_enable) {
141472 + pr_err("The shaper has already been enabled\n");
141473 + return -EINVAL;
141474 + }
141475 + lni->shaper_enable = 1;
141476 + lni->shaper_couple = coupled;
141477 + lni->oal = oal;
141478 +
141479 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141480 + config_opts.dcpid = lni->dcp_idx;
141481 + config_opts.shaper_config.cpl = coupled;
141482 + config_opts.shaper_config.oal = oal;
141483 + config_opts.shaper_config.crtcr = cpu_to_be24((lni->cr_token_rate.whole
141484 + << 13) | lni->cr_token_rate.fraction);
141485 + config_opts.shaper_config.ertcr = cpu_to_be24((lni->er_token_rate.whole
141486 + << 13) | lni->er_token_rate.fraction);
141487 + config_opts.shaper_config.crtbl =
141488 + cpu_to_be16(lni->cr_token_bucket_limit);
141489 + config_opts.shaper_config.ertbl =
141490 + cpu_to_be16(lni->er_token_bucket_limit);
141491 + config_opts.shaper_config.mps = 60;
141492 +
141493 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141494 +}
141495 +EXPORT_SYMBOL(qman_ceetm_lni_enable_shaper);
141496 +
141497 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni)
141498 +{
141499 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141500 +
141501 + if (!lni->shaper_enable) {
141502 + pr_err("The shaper has been disabled\n");
141503 + return -EINVAL;
141504 + }
141505 +
141506 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141507 + config_opts.dcpid = lni->dcp_idx;
141508 + config_opts.shaper_config.cpl = lni->shaper_couple;
141509 + config_opts.shaper_config.oal = lni->oal;
141510 + config_opts.shaper_config.crtbl =
141511 + cpu_to_be16(lni->cr_token_bucket_limit);
141512 + config_opts.shaper_config.ertbl =
141513 + cpu_to_be16(lni->er_token_bucket_limit);
141514 + /* Set CR/ER rate with all 1's to configure an infinite rate, thus
141515 + * disable the shaping.
141516 + */
141517 + config_opts.shaper_config.crtcr = 0xFFFFFF;
141518 + config_opts.shaper_config.ertcr = 0xFFFFFF;
141519 + config_opts.shaper_config.mps = 60;
141520 + lni->shaper_enable = 0;
141521 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141522 +}
141523 +EXPORT_SYMBOL(qman_ceetm_lni_disable_shaper);
141524 +
141525 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni)
141526 +{
141527 + return lni->shaper_enable;
141528 +}
141529 +EXPORT_SYMBOL(qman_ceetm_lni_is_shaper_enabled);
141530 +
141531 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
141532 + const struct qm_ceetm_rate *token_rate,
141533 + u16 token_limit)
141534 +{
141535 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141536 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141537 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141538 + int ret;
141539 +
141540 + lni->cr_token_rate.whole = token_rate->whole;
141541 + lni->cr_token_rate.fraction = token_rate->fraction;
141542 + lni->cr_token_bucket_limit = token_limit;
141543 + if (!lni->shaper_enable)
141544 + return 0;
141545 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141546 + query_opts.dcpid = lni->dcp_idx;
141547 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
141548 + &query_result);
141549 + if (ret) {
141550 + pr_err("Fail to get current LNI shaper setting\n");
141551 + return -EINVAL;
141552 + }
141553 +
141554 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141555 + config_opts.dcpid = lni->dcp_idx;
141556 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole << 13)
141557 + | (token_rate->fraction));
141558 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
141559 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
141560 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
141561 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
141562 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
141563 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
141564 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141565 +}
141566 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate);
141567 +
141568 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
141569 + u64 bps,
141570 + u16 token_limit)
141571 +{
141572 + struct qm_ceetm_rate token_rate;
141573 + int ret;
141574 +
141575 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
141576 + if (ret) {
141577 + pr_err("Can not convert bps to token rate\n");
141578 + return -EINVAL;
141579 + }
141580 +
141581 + return qman_ceetm_lni_set_commit_rate(lni, &token_rate, token_limit);
141582 +}
141583 +EXPORT_SYMBOL(qman_ceetm_lni_set_commit_rate_bps);
141584 +
141585 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
141586 + struct qm_ceetm_rate *token_rate,
141587 + u16 *token_limit)
141588 +{
141589 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141590 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141591 + int ret;
141592 +
141593 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141594 + query_opts.dcpid = lni->dcp_idx;
141595 +
141596 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141597 + if (ret) {
141598 + pr_err("The LNI CR rate or limit is not set\n");
141599 + return -EINVAL;
141600 + }
141601 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
141602 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
141603 + 0x1FFF;
141604 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
141605 + return 0;
141606 +}
141607 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate);
141608 +
141609 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
141610 + u64 *bps, u16 *token_limit)
141611 +{
141612 + struct qm_ceetm_rate token_rate;
141613 + int ret;
141614 +
141615 + ret = qman_ceetm_lni_get_commit_rate(lni, &token_rate, token_limit);
141616 + if (ret) {
141617 + pr_err("The LNI CR rate or limit is not available\n");
141618 + return -EINVAL;
141619 + }
141620 +
141621 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
141622 +}
141623 +EXPORT_SYMBOL(qman_ceetm_lni_get_commit_rate_bps);
141624 +
141625 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
141626 + const struct qm_ceetm_rate *token_rate,
141627 + u16 token_limit)
141628 +{
141629 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141630 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141631 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141632 + int ret;
141633 +
141634 + lni->er_token_rate.whole = token_rate->whole;
141635 + lni->er_token_rate.fraction = token_rate->fraction;
141636 + lni->er_token_bucket_limit = token_limit;
141637 + if (!lni->shaper_enable)
141638 + return 0;
141639 +
141640 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141641 + query_opts.dcpid = lni->dcp_idx;
141642 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts,
141643 + &query_result);
141644 + if (ret) {
141645 + pr_err("Fail to get current LNI shaper setting\n");
141646 + return -EINVAL;
141647 + }
141648 +
141649 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141650 + config_opts.dcpid = lni->dcp_idx;
141651 + config_opts.shaper_config.ertcr = cpu_to_be24(
141652 + (token_rate->whole << 13) | (token_rate->fraction));
141653 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
141654 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
141655 + config_opts.shaper_config.oal = query_result.shaper_query.oal;
141656 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
141657 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
141658 + config_opts.shaper_config.mps = query_result.shaper_query.mps;
141659 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141660 +}
141661 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate);
141662 +
141663 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
141664 + u64 bps,
141665 + u16 token_limit)
141666 +{
141667 + struct qm_ceetm_rate token_rate;
141668 + int ret;
141669 +
141670 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
141671 + if (ret) {
141672 + pr_err("Can not convert bps to token rate\n");
141673 + return -EINVAL;
141674 + }
141675 + return qman_ceetm_lni_set_excess_rate(lni, &token_rate, token_limit);
141676 +}
141677 +EXPORT_SYMBOL(qman_ceetm_lni_set_excess_rate_bps);
141678 +
141679 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
141680 + struct qm_ceetm_rate *token_rate,
141681 + u16 *token_limit)
141682 +{
141683 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141684 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141685 + int ret;
141686 +
141687 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_LNI_SHAPER | lni->idx);
141688 + query_opts.dcpid = lni->dcp_idx;
141689 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141690 + if (ret) {
141691 + pr_err("The LNI ER rate or limit is not set\n");
141692 + return -EINVAL;
141693 + }
141694 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
141695 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
141696 + 0x1FFF;
141697 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
141698 + return 0;
141699 +}
141700 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate);
141701 +
141702 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
141703 + u64 *bps, u16 *token_limit)
141704 +{
141705 + struct qm_ceetm_rate token_rate;
141706 + int ret;
141707 +
141708 + ret = qman_ceetm_lni_get_excess_rate(lni, &token_rate, token_limit);
141709 + if (ret) {
141710 + pr_err("The LNI ER rate or limit is not available\n");
141711 + return -EINVAL;
141712 + }
141713 +
141714 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
141715 +}
141716 +EXPORT_SYMBOL(qman_ceetm_lni_get_excess_rate_bps);
141717 +
141718 +#define QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(n) ((15 - n) * 4)
141719 +#define QMAN_CEETM_LNITCFCC_ENABLE 0x8
141720 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
141721 + unsigned int cq_level,
141722 + int traffic_class)
141723 +{
141724 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141725 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141726 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141727 + u64 lnitcfcc;
141728 +
141729 + if ((cq_level > 15) | (traffic_class > 7)) {
141730 + pr_err("The CQ or traffic class id is out of range\n");
141731 + return -EINVAL;
141732 + }
141733 +
141734 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
141735 + query_opts.dcpid = lni->dcp_idx;
141736 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141737 + pr_err("Fail to query tcfcc\n");
141738 + return -EINVAL;
141739 + }
141740 +
141741 + lnitcfcc = be64_to_cpu(query_result.tcfc_query.lnitcfcc);
141742 + if (traffic_class == -1) {
141743 + /* disable tcfc for this CQ */
141744 + lnitcfcc &= ~((u64)QMAN_CEETM_LNITCFCC_ENABLE <<
141745 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
141746 + } else {
141747 + lnitcfcc &= ~((u64)0xF <<
141748 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
141749 + lnitcfcc |= ((u64)(QMAN_CEETM_LNITCFCC_ENABLE |
141750 + traffic_class)) <<
141751 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level);
141752 + }
141753 + config_opts.tcfc_config.lnitcfcc = cpu_to_be64(lnitcfcc);
141754 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
141755 + config_opts.dcpid = lni->dcp_idx;
141756 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141757 +}
141758 +EXPORT_SYMBOL(qman_ceetm_lni_set_tcfcc);
141759 +
141760 +#define QMAN_CEETM_LNITCFCC_TC_MASK 0x7
141761 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni, unsigned int cq_level,
141762 + int *traffic_class)
141763 +{
141764 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141765 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141766 + int ret;
141767 + u8 lnitcfcc;
141768 +
141769 + if (cq_level > 15) {
141770 + pr_err("the CQ level is out of range\n");
141771 + return -EINVAL;
141772 + }
141773 +
141774 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_TCFC | lni->idx);
141775 + query_opts.dcpid = lni->dcp_idx;
141776 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141777 + if (ret)
141778 + return ret;
141779 + lnitcfcc = (u8)be64_to_cpu((query_result.tcfc_query.lnitcfcc) >>
141780 + QMAN_CEETM_LNITCFCC_CQ_LEVEL_SHIFT(cq_level));
141781 + if (lnitcfcc & QMAN_CEETM_LNITCFCC_ENABLE)
141782 + *traffic_class = lnitcfcc & QMAN_CEETM_LNITCFCC_TC_MASK;
141783 + else
141784 + *traffic_class = -1;
141785 + return 0;
141786 +}
141787 +EXPORT_SYMBOL(qman_ceetm_lni_get_tcfcc);
141788 +
141789 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
141790 + struct qm_ceetm_lni *lni)
141791 +{
141792 + struct qm_ceetm_channel *p;
141793 + u32 channel_idx;
141794 + int ret = 0;
141795 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141796 +
141797 + if (lni->dcp_idx == qm_dc_portal_fman0) {
141798 + ret = qman_alloc_ceetm0_channel(&channel_idx);
141799 + } else if (lni->dcp_idx == qm_dc_portal_fman1) {
141800 + ret = qman_alloc_ceetm1_channel(&channel_idx);
141801 + } else {
141802 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141803 + lni->dcp_idx);
141804 + return -EINVAL;
141805 + }
141806 +
141807 + if (ret) {
141808 + pr_err("The is no channel available for LNI#%d\n", lni->idx);
141809 + return -ENODEV;
141810 + }
141811 +
141812 + p = kzalloc(sizeof(*p), GFP_KERNEL);
141813 + if (!p)
141814 + return -ENOMEM;
141815 + p->idx = channel_idx;
141816 + p->dcp_idx = lni->dcp_idx;
141817 + p->lni_idx = lni->idx;
141818 + list_add_tail(&p->node, &lni->channels);
141819 + INIT_LIST_HEAD(&p->class_queues);
141820 + INIT_LIST_HEAD(&p->ccgs);
141821 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141822 + channel_idx);
141823 + config_opts.dcpid = lni->dcp_idx;
141824 + config_opts.channel_mapping.map_lni_id = lni->idx;
141825 + config_opts.channel_mapping.map_shaped = 0;
141826 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
141827 + pr_err("Can't map channel#%d for LNI#%d\n",
141828 + channel_idx, lni->idx);
141829 + return -EINVAL;
141830 + }
141831 + *channel = p;
141832 + return 0;
141833 +}
141834 +EXPORT_SYMBOL(qman_ceetm_channel_claim);
141835 +
141836 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel)
141837 +{
141838 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141839 + if (!list_empty(&channel->class_queues)) {
141840 + pr_err("CEETM channel#%d has class queue unreleased!\n",
141841 + channel->idx);
141842 + return -EBUSY;
141843 + }
141844 + if (!list_empty(&channel->ccgs)) {
141845 + pr_err("CEETM channel#%d has ccg unreleased!\n",
141846 + channel->idx);
141847 + return -EBUSY;
141848 + }
141849 +
141850 + /* channel->dcp_idx corresponds to known fman validation */
141851 + if ((channel->dcp_idx != qm_dc_portal_fman0) &&
141852 + (channel->dcp_idx != qm_dc_portal_fman1)) {
141853 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141854 + channel->dcp_idx);
141855 + return -EINVAL;
141856 + }
141857 +
141858 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141859 + channel->idx);
141860 + config_opts.dcpid = channel->dcp_idx;
141861 + memset(&config_opts.shaper_config, 0,
141862 + sizeof(config_opts.shaper_config));
141863 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
141864 + pr_err("Can't reset channel shapping parameters\n");
141865 + return -EINVAL;
141866 + }
141867 +
141868 + if (channel->dcp_idx == qm_dc_portal_fman0) {
141869 + qman_release_ceetm0_channelid(channel->idx);
141870 + } else if (channel->dcp_idx == qm_dc_portal_fman1) {
141871 + qman_release_ceetm1_channelid(channel->idx);
141872 + } else {
141873 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
141874 + channel->dcp_idx);
141875 + return -EINVAL;
141876 + }
141877 + list_del(&channel->node);
141878 + kfree(channel);
141879 +
141880 + return 0;
141881 +}
141882 +EXPORT_SYMBOL(qman_ceetm_channel_release);
141883 +
141884 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
141885 + int coupled)
141886 +{
141887 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141888 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141889 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141890 +
141891 + if (channel->shaper_enable == 1) {
141892 + pr_err("This channel shaper has been enabled!\n");
141893 + return -EINVAL;
141894 + }
141895 +
141896 + channel->shaper_enable = 1;
141897 + channel->shaper_couple = coupled;
141898 +
141899 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141900 + channel->idx);
141901 + query_opts.dcpid = channel->dcp_idx;
141902 +
141903 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141904 + pr_err("Can't query channel mapping\n");
141905 + return -EINVAL;
141906 + }
141907 +
141908 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141909 + channel->idx);
141910 + config_opts.dcpid = channel->dcp_idx;
141911 + config_opts.channel_mapping.map_lni_id =
141912 + query_result.channel_mapping_query.map_lni_id;
141913 + config_opts.channel_mapping.map_shaped = 1;
141914 + if (qman_ceetm_configure_mapping_shaper_tcfc(&config_opts)) {
141915 + pr_err("Can't enable shaper for channel #%d\n", channel->idx);
141916 + return -EINVAL;
141917 + }
141918 +
141919 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141920 + channel->idx);
141921 + config_opts.shaper_config.cpl = coupled;
141922 + config_opts.shaper_config.crtcr =
141923 + cpu_to_be24((channel->cr_token_rate.whole
141924 + << 13) |
141925 + channel->cr_token_rate.fraction);
141926 + config_opts.shaper_config.ertcr =
141927 + cpu_to_be24(channel->er_token_rate.whole
141928 + << 13 |
141929 + channel->er_token_rate.fraction);
141930 + config_opts.shaper_config.crtbl =
141931 + cpu_to_be16(channel->cr_token_bucket_limit);
141932 + config_opts.shaper_config.ertbl =
141933 + cpu_to_be16(channel->er_token_bucket_limit);
141934 +
141935 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141936 +}
141937 +EXPORT_SYMBOL(qman_ceetm_channel_enable_shaper);
141938 +
141939 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel)
141940 +{
141941 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141942 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141943 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141944 +
141945 +
141946 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141947 + channel->idx);
141948 + query_opts.dcpid = channel->dcp_idx;
141949 +
141950 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141951 + pr_err("Can't query channel mapping\n");
141952 + return -EINVAL;
141953 + }
141954 +
141955 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141956 + channel->idx);
141957 + config_opts.dcpid = channel->dcp_idx;
141958 + config_opts.channel_mapping.map_shaped = 0;
141959 + config_opts.channel_mapping.map_lni_id =
141960 + query_result.channel_mapping_query.map_lni_id;
141961 +
141962 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
141963 +}
141964 +EXPORT_SYMBOL(qman_ceetm_channel_disable_shaper);
141965 +
141966 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel)
141967 +{
141968 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141969 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141970 +
141971 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_MAPPING |
141972 + channel->idx);
141973 + query_opts.dcpid = channel->dcp_idx;
141974 +
141975 + if (qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result)) {
141976 + pr_err("Can't query channel mapping\n");
141977 + return -EINVAL;
141978 + }
141979 +
141980 + return query_result.channel_mapping_query.map_shaped;
141981 +}
141982 +EXPORT_SYMBOL(qman_ceetm_channel_is_shaper_enabled);
141983 +
141984 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
141985 + const struct qm_ceetm_rate *token_rate,
141986 + u16 token_limit)
141987 +{
141988 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
141989 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
141990 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
141991 + int ret;
141992 +
141993 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
141994 + channel->idx);
141995 + query_opts.dcpid = channel->dcp_idx;
141996 +
141997 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
141998 + if (ret) {
141999 + pr_err("Fail to get the current channel shaper setting\n");
142000 + return -EINVAL;
142001 + }
142002 +
142003 + channel->cr_token_rate.whole = token_rate->whole;
142004 + channel->cr_token_rate.fraction = token_rate->fraction;
142005 + channel->cr_token_bucket_limit = token_limit;
142006 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
142007 + channel->idx);
142008 + config_opts.dcpid = channel->dcp_idx;
142009 + config_opts.shaper_config.crtcr = cpu_to_be24((token_rate->whole
142010 + << 13) | (token_rate->fraction));
142011 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
142012 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
142013 + config_opts.shaper_config.ertcr = query_result.shaper_query.ertcr;
142014 + config_opts.shaper_config.ertbl = query_result.shaper_query.ertbl;
142015 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
142016 +}
142017 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate);
142018 +
142019 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
142020 + u64 bps, u16 token_limit)
142021 +{
142022 + struct qm_ceetm_rate token_rate;
142023 + int ret;
142024 +
142025 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
142026 + if (ret) {
142027 + pr_err("Can not convert bps to token rate\n");
142028 + return -EINVAL;
142029 + }
142030 + return qman_ceetm_channel_set_commit_rate(channel, &token_rate,
142031 + token_limit);
142032 +}
142033 +EXPORT_SYMBOL(qman_ceetm_channel_set_commit_rate_bps);
142034 +
142035 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
142036 + struct qm_ceetm_rate *token_rate,
142037 + u16 *token_limit)
142038 +{
142039 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
142040 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
142041 + int ret;
142042 +
142043 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
142044 + channel->idx);
142045 + query_opts.dcpid = channel->dcp_idx;
142046 +
142047 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
142048 + if (ret | !query_result.shaper_query.crtcr |
142049 + !query_result.shaper_query.crtbl) {
142050 + pr_err("The channel commit rate or limit is not set\n");
142051 + return -EINVAL;
142052 + }
142053 + token_rate->whole = be24_to_cpu(query_result.shaper_query.crtcr) >> 13;
142054 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.crtcr) &
142055 + 0x1FFF;
142056 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
142057 + return 0;
142058 +}
142059 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate);
142060 +
142061 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
142062 + u64 *bps, u16 *token_limit)
142063 +{
142064 + struct qm_ceetm_rate token_rate;
142065 + int ret;
142066 +
142067 + ret = qman_ceetm_channel_get_commit_rate(channel, &token_rate,
142068 + token_limit);
142069 + if (ret) {
142070 + pr_err("The channel CR rate or limit is not available\n");
142071 + return -EINVAL;
142072 + }
142073 +
142074 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
142075 +}
142076 +EXPORT_SYMBOL(qman_ceetm_channel_get_commit_rate_bps);
142077 +
142078 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
142079 + const struct qm_ceetm_rate *token_rate,
142080 + u16 token_limit)
142081 +{
142082 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
142083 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
142084 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
142085 + int ret;
142086 +
142087 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
142088 + channel->idx);
142089 + query_opts.dcpid = channel->dcp_idx;
142090 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
142091 + if (ret) {
142092 + pr_err("Fail to get the current channel shaper setting\n");
142093 + return -EINVAL;
142094 + }
142095 +
142096 + channel->er_token_rate.whole = token_rate->whole;
142097 + channel->er_token_rate.fraction = token_rate->fraction;
142098 + channel->er_token_bucket_limit = token_limit;
142099 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
142100 + channel->idx);
142101 + config_opts.dcpid = channel->dcp_idx;
142102 + config_opts.shaper_config.ertcr = cpu_to_be24(
142103 + (token_rate->whole << 13) | (token_rate->fraction));
142104 + config_opts.shaper_config.ertbl = cpu_to_be16(token_limit);
142105 + config_opts.shaper_config.cpl = query_result.shaper_query.cpl;
142106 + config_opts.shaper_config.crtcr = query_result.shaper_query.crtcr;
142107 + config_opts.shaper_config.crtbl = query_result.shaper_query.crtbl;
142108 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
142109 +}
142110 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate);
142111 +
142112 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
142113 + u64 bps, u16 token_limit)
142114 +{
142115 + struct qm_ceetm_rate token_rate;
142116 + int ret;
142117 +
142118 + ret = qman_ceetm_bps2tokenrate(bps, &token_rate, 0);
142119 + if (ret) {
142120 + pr_err("Can not convert bps to token rate\n");
142121 + return -EINVAL;
142122 + }
142123 + return qman_ceetm_channel_set_excess_rate(channel, &token_rate,
142124 + token_limit);
142125 +}
142126 +EXPORT_SYMBOL(qman_ceetm_channel_set_excess_rate_bps);
142127 +
142128 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
142129 + struct qm_ceetm_rate *token_rate,
142130 + u16 *token_limit)
142131 +{
142132 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
142133 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
142134 + int ret;
142135 +
142136 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
142137 + channel->idx);
142138 + query_opts.dcpid = channel->dcp_idx;
142139 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
142140 + if (ret | !query_result.shaper_query.ertcr |
142141 + !query_result.shaper_query.ertbl) {
142142 + pr_err("The channel excess rate or limit is not set\n");
142143 + return -EINVAL;
142144 + }
142145 + token_rate->whole = be24_to_cpu(query_result.shaper_query.ertcr) >> 13;
142146 + token_rate->fraction = be24_to_cpu(query_result.shaper_query.ertcr) &
142147 + 0x1FFF;
142148 + *token_limit = be16_to_cpu(query_result.shaper_query.ertbl);
142149 + return 0;
142150 +}
142151 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate);
142152 +
142153 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
142154 + u64 *bps, u16 *token_limit)
142155 +{
142156 + struct qm_ceetm_rate token_rate;
142157 + int ret;
142158 +
142159 + ret = qman_ceetm_channel_get_excess_rate(channel, &token_rate,
142160 + token_limit);
142161 + if (ret) {
142162 + pr_err("The channel ER rate or limit is not available\n");
142163 + return -EINVAL;
142164 + }
142165 +
142166 + return qman_ceetm_tokenrate2bps(&token_rate, bps, 0);
142167 +}
142168 +EXPORT_SYMBOL(qman_ceetm_channel_get_excess_rate_bps);
142169 +
142170 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
142171 + u16 token_limit)
142172 +{
142173 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config config_opts;
142174 +
142175 + if (channel->shaper_enable) {
142176 + pr_err("This channel is a shaped one\n");
142177 + return -EINVAL;
142178 + }
142179 +
142180 + channel->cr_token_bucket_limit = token_limit;
142181 + config_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
142182 + channel->idx);
142183 + config_opts.dcpid = channel->dcp_idx;
142184 + config_opts.shaper_config.crtbl = cpu_to_be16(token_limit);
142185 + return qman_ceetm_configure_mapping_shaper_tcfc(&config_opts);
142186 +}
142187 +EXPORT_SYMBOL(qman_ceetm_channel_set_weight);
142188 +
142189 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
142190 + u16 *token_limit)
142191 +{
142192 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query query_opts;
142193 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query query_result;
142194 + int ret;
142195 +
142196 + query_opts.cid = cpu_to_be16(CEETM_COMMAND_CHANNEL_SHAPER |
142197 + channel->idx);
142198 + query_opts.dcpid = channel->dcp_idx;
142199 + ret = qman_ceetm_query_mapping_shaper_tcfc(&query_opts, &query_result);
142200 + if (ret | !query_result.shaper_query.crtbl) {
142201 + pr_err("This unshaped channel's uFQ wight is unavailable\n");
142202 + return -EINVAL;
142203 + }
142204 + *token_limit = be16_to_cpu(query_result.shaper_query.crtbl);
142205 + return 0;
142206 +}
142207 +EXPORT_SYMBOL(qman_ceetm_channel_get_weight);
142208 +
142209 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel, int group_b,
142210 + unsigned int prio_a, unsigned int prio_b)
142211 +{
142212 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
142213 + struct qm_mcr_ceetm_class_scheduler_query query_result;
142214 + int i;
142215 +
142216 + if (prio_a > 7) {
142217 + pr_err("The priority of group A is out of range\n");
142218 + return -EINVAL;
142219 + }
142220 + if (group_b && (prio_b > 7)) {
142221 + pr_err("The priority of group B is out of range\n");
142222 + return -EINVAL;
142223 + }
142224 +
142225 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
142226 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
142227 + return -EINVAL;
142228 + }
142229 +
142230 + config_opts.cqcid = cpu_to_be16(channel->idx);
142231 + config_opts.dcpid = channel->dcp_idx;
142232 + config_opts.gpc_combine_flag = !group_b;
142233 + config_opts.gpc_prio_a = prio_a;
142234 + config_opts.gpc_prio_b = prio_b;
142235 +
142236 + for (i = 0; i < 8; i++)
142237 + config_opts.w[i] = query_result.w[i];
142238 + config_opts.crem = query_result.crem;
142239 + config_opts.erem = query_result.erem;
142240 +
142241 + return qman_ceetm_configure_class_scheduler(&config_opts);
142242 +}
142243 +EXPORT_SYMBOL(qman_ceetm_channel_set_group);
142244 +
142245 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel, int *group_b,
142246 + unsigned int *prio_a, unsigned int *prio_b)
142247 +{
142248 + struct qm_mcr_ceetm_class_scheduler_query query_result;
142249 +
142250 + if (qman_ceetm_query_class_scheduler(channel, &query_result)) {
142251 + pr_err("Can't query channel#%d's scheduler!\n", channel->idx);
142252 + return -EINVAL;
142253 + }
142254 + *group_b = !query_result.gpc_combine_flag;
142255 + *prio_a = query_result.gpc_prio_a;
142256 + *prio_b = query_result.gpc_prio_b;
142257 +
142258 + return 0;
142259 +}
142260 +EXPORT_SYMBOL(qman_ceetm_channel_get_group);
142261 +
142262 +#define GROUP_A_ELIGIBILITY_SET (1 << 8)
142263 +#define GROUP_B_ELIGIBILITY_SET (1 << 9)
142264 +#define CQ_ELIGIBILITY_SET(n) (1 << (7 - n))
142265 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
142266 + *channel, int group_b, int cre)
142267 +{
142268 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
142269 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
142270 + int i;
142271 +
142272 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
142273 + pr_err("Cannot get the channel %d scheduler setting.\n",
142274 + channel->idx);
142275 + return -EINVAL;
142276 + }
142277 + csch_config.cqcid = cpu_to_be16(channel->idx);
142278 + csch_config.dcpid = channel->dcp_idx;
142279 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
142280 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
142281 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
142282 +
142283 + for (i = 0; i < 8; i++)
142284 + csch_config.w[i] = csch_query.w[i];
142285 + csch_config.erem = csch_query.erem;
142286 + if (group_b)
142287 + csch_config.crem = (be16_to_cpu(csch_query.crem)
142288 + & ~GROUP_B_ELIGIBILITY_SET)
142289 + | (cre ? GROUP_B_ELIGIBILITY_SET : 0);
142290 + else
142291 + csch_config.crem = (be16_to_cpu(csch_query.crem)
142292 + & ~GROUP_A_ELIGIBILITY_SET)
142293 + | (cre ? GROUP_A_ELIGIBILITY_SET : 0);
142294 +
142295 + csch_config.crem = cpu_to_be16(csch_config.crem);
142296 +
142297 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
142298 + pr_err("Cannot config channel %d's scheduler with "
142299 + "group_%c's cr eligibility\n", channel->idx,
142300 + group_b ? 'b' : 'a');
142301 + return -EINVAL;
142302 + }
142303 +
142304 + return 0;
142305 +}
142306 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_cr_eligibility);
142307 +
142308 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
142309 + *channel, int group_b, int ere)
142310 +{
142311 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
142312 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
142313 + int i;
142314 +
142315 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
142316 + pr_err("Cannot get the channel %d scheduler setting.\n",
142317 + channel->idx);
142318 + return -EINVAL;
142319 + }
142320 + csch_config.cqcid = cpu_to_be16(channel->idx);
142321 + csch_config.dcpid = channel->dcp_idx;
142322 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
142323 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
142324 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
142325 +
142326 + for (i = 0; i < 8; i++)
142327 + csch_config.w[i] = csch_query.w[i];
142328 + csch_config.crem = csch_query.crem;
142329 + if (group_b)
142330 + csch_config.erem = (be16_to_cpu(csch_query.erem)
142331 + & ~GROUP_B_ELIGIBILITY_SET)
142332 + | (ere ? GROUP_B_ELIGIBILITY_SET : 0);
142333 + else
142334 + csch_config.erem = (be16_to_cpu(csch_query.erem)
142335 + & ~GROUP_A_ELIGIBILITY_SET)
142336 + | (ere ? GROUP_A_ELIGIBILITY_SET : 0);
142337 +
142338 + csch_config.erem = cpu_to_be16(csch_config.erem);
142339 +
142340 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
142341 + pr_err("Cannot config channel %d's scheduler with "
142342 + "group_%c's er eligibility\n", channel->idx,
142343 + group_b ? 'b' : 'a');
142344 + return -EINVAL;
142345 + }
142346 +
142347 + return 0;
142348 +}
142349 +EXPORT_SYMBOL(qman_ceetm_channel_set_group_er_eligibility);
142350 +
142351 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
142352 + unsigned int idx, int cre)
142353 +{
142354 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
142355 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
142356 + int i;
142357 +
142358 + if (idx > 7) {
142359 + pr_err("CQ index is out of range\n");
142360 + return -EINVAL;
142361 + }
142362 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
142363 + pr_err("Cannot get the channel %d scheduler setting.\n",
142364 + channel->idx);
142365 + return -EINVAL;
142366 + }
142367 + csch_config.cqcid = cpu_to_be16(channel->idx);
142368 + csch_config.dcpid = channel->dcp_idx;
142369 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
142370 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
142371 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
142372 + for (i = 0; i < 8; i++)
142373 + csch_config.w[i] = csch_query.w[i];
142374 + csch_config.erem = csch_query.erem;
142375 + csch_config.crem = (be16_to_cpu(csch_query.crem)
142376 + & ~CQ_ELIGIBILITY_SET(idx)) |
142377 + (cre ? CQ_ELIGIBILITY_SET(idx) : 0);
142378 + csch_config.crem = cpu_to_be16(csch_config.crem);
142379 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
142380 + pr_err("Cannot config channel scheduler to set "
142381 + "cr eligibility mask for CQ#%d\n", idx);
142382 + return -EINVAL;
142383 + }
142384 +
142385 + return 0;
142386 +}
142387 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_cr_eligibility);
142388 +
142389 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
142390 + unsigned int idx, int ere)
142391 +{
142392 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
142393 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
142394 + int i;
142395 +
142396 + if (idx > 7) {
142397 + pr_err("CQ index is out of range\n");
142398 + return -EINVAL;
142399 + }
142400 + if (qman_ceetm_query_class_scheduler(channel, &csch_query)) {
142401 + pr_err("Cannot get the channel %d scheduler setting.\n",
142402 + channel->idx);
142403 + return -EINVAL;
142404 + }
142405 + csch_config.cqcid = cpu_to_be16(channel->idx);
142406 + csch_config.dcpid = channel->dcp_idx;
142407 + csch_config.gpc_combine_flag = csch_query.gpc_combine_flag;
142408 + csch_config.gpc_prio_a = csch_query.gpc_prio_a;
142409 + csch_config.gpc_prio_b = csch_query.gpc_prio_b;
142410 + for (i = 0; i < 8; i++)
142411 + csch_config.w[i] = csch_query.w[i];
142412 + csch_config.crem = csch_query.crem;
142413 + csch_config.erem = (be16_to_cpu(csch_query.erem)
142414 + & ~CQ_ELIGIBILITY_SET(idx)) |
142415 + (ere ? CQ_ELIGIBILITY_SET(idx) : 0);
142416 + csch_config.erem = cpu_to_be16(csch_config.erem);
142417 + if (qman_ceetm_configure_class_scheduler(&csch_config)) {
142418 + pr_err("Cannot config channel scheduler to set "
142419 + "er eligibility mask for CQ#%d\n", idx);
142420 + return -EINVAL;
142421 + }
142422 + return 0;
142423 +}
142424 +EXPORT_SYMBOL(qman_ceetm_channel_set_cq_er_eligibility);
142425 +
142426 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
142427 + struct qm_ceetm_channel *channel, unsigned int idx,
142428 + struct qm_ceetm_ccg *ccg)
142429 +{
142430 + struct qm_ceetm_cq *p;
142431 + struct qm_mcc_ceetm_cq_config cq_config;
142432 +
142433 + if (idx > 7) {
142434 + pr_err("The independent class queue id is out of range\n");
142435 + return -EINVAL;
142436 + }
142437 +
142438 + list_for_each_entry(p, &channel->class_queues, node) {
142439 + if (p->idx == idx) {
142440 + pr_err("The CQ#%d has been claimed!\n", idx);
142441 + return -EINVAL;
142442 + }
142443 + }
142444 +
142445 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142446 + if (!p) {
142447 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
142448 + return -ENOMEM;
142449 + }
142450 +
142451 + list_add_tail(&p->node, &channel->class_queues);
142452 + p->idx = idx;
142453 + p->is_claimed = 1;
142454 + p->parent = channel;
142455 + INIT_LIST_HEAD(&p->bound_lfqids);
142456 +
142457 + if (ccg) {
142458 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
142459 + cq_config.dcpid = channel->dcp_idx;
142460 + cq_config.ccgid = cpu_to_be16(ccg->idx);
142461 + if (qman_ceetm_configure_cq(&cq_config)) {
142462 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
142463 + idx, ccg->idx);
142464 + list_del(&p->node);
142465 + kfree(p);
142466 + return -EINVAL;
142467 + }
142468 + }
142469 +
142470 + *cq = p;
142471 + return 0;
142472 +}
142473 +EXPORT_SYMBOL(qman_ceetm_cq_claim);
142474 +
142475 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
142476 + struct qm_ceetm_channel *channel, unsigned int idx,
142477 + struct qm_ceetm_ccg *ccg)
142478 +{
142479 + struct qm_ceetm_cq *p;
142480 + struct qm_mcc_ceetm_cq_config cq_config;
142481 +
142482 + if ((idx < 8) || (idx > 15)) {
142483 + pr_err("This grouped class queue id is out of range\n");
142484 + return -EINVAL;
142485 + }
142486 +
142487 + list_for_each_entry(p, &channel->class_queues, node) {
142488 + if (p->idx == idx) {
142489 + pr_err("The CQ#%d has been claimed!\n", idx);
142490 + return -EINVAL;
142491 + }
142492 + }
142493 +
142494 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142495 + if (!p) {
142496 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
142497 + return -ENOMEM;
142498 + }
142499 +
142500 + list_add_tail(&p->node, &channel->class_queues);
142501 + p->idx = idx;
142502 + p->is_claimed = 1;
142503 + p->parent = channel;
142504 + INIT_LIST_HEAD(&p->bound_lfqids);
142505 +
142506 + if (ccg) {
142507 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
142508 + cq_config.dcpid = channel->dcp_idx;
142509 + cq_config.ccgid = cpu_to_be16(ccg->idx);
142510 + if (qman_ceetm_configure_cq(&cq_config)) {
142511 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
142512 + idx, ccg->idx);
142513 + list_del(&p->node);
142514 + kfree(p);
142515 + return -EINVAL;
142516 + }
142517 + }
142518 + *cq = p;
142519 + return 0;
142520 +}
142521 +EXPORT_SYMBOL(qman_ceetm_cq_claim_A);
142522 +
142523 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
142524 + struct qm_ceetm_channel *channel, unsigned int idx,
142525 + struct qm_ceetm_ccg *ccg)
142526 +{
142527 + struct qm_ceetm_cq *p;
142528 + struct qm_mcc_ceetm_cq_config cq_config;
142529 +
142530 + if ((idx < 12) || (idx > 15)) {
142531 + pr_err("This grouped class queue id is out of range\n");
142532 + return -EINVAL;
142533 + }
142534 +
142535 + list_for_each_entry(p, &channel->class_queues, node) {
142536 + if (p->idx == idx) {
142537 + pr_err("The CQ#%d has been claimed!\n", idx);
142538 + return -EINVAL;
142539 + }
142540 + }
142541 +
142542 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142543 + if (!p) {
142544 + pr_err("Can't allocate memory for CQ#%d!\n", idx);
142545 + return -ENOMEM;
142546 + }
142547 +
142548 + list_add_tail(&p->node, &channel->class_queues);
142549 + p->idx = idx;
142550 + p->is_claimed = 1;
142551 + p->parent = channel;
142552 + INIT_LIST_HEAD(&p->bound_lfqids);
142553 +
142554 + if (ccg) {
142555 + cq_config.cqid = cpu_to_be16((channel->idx << 4) | idx);
142556 + cq_config.dcpid = channel->dcp_idx;
142557 + cq_config.ccgid = cpu_to_be16(ccg->idx);
142558 + if (qman_ceetm_configure_cq(&cq_config)) {
142559 + pr_err("Can't configure the CQ#%d with CCGRID#%d\n",
142560 + idx, ccg->idx);
142561 + list_del(&p->node);
142562 + kfree(p);
142563 + return -EINVAL;
142564 + }
142565 + }
142566 + *cq = p;
142567 + return 0;
142568 +}
142569 +EXPORT_SYMBOL(qman_ceetm_cq_claim_B);
142570 +
142571 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq)
142572 +{
142573 + if (!list_empty(&cq->bound_lfqids)) {
142574 + pr_err("The CQ#%d has unreleased LFQID\n", cq->idx);
142575 + return -EBUSY;
142576 + }
142577 + list_del(&cq->node);
142578 + qman_ceetm_drain_cq(cq);
142579 + kfree(cq);
142580 + return 0;
142581 +}
142582 +EXPORT_SYMBOL(qman_ceetm_cq_release);
142583 +
142584 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
142585 + struct qm_ceetm_weight_code *weight_code)
142586 +{
142587 + struct qm_mcc_ceetm_class_scheduler_config config_opts;
142588 + struct qm_mcr_ceetm_class_scheduler_query query_result;
142589 + int i;
142590 +
142591 + if (cq->idx < 8) {
142592 + pr_err("Can not set weight for ungrouped class queue\n");
142593 + return -EINVAL;
142594 + }
142595 +
142596 + if (qman_ceetm_query_class_scheduler(cq->parent, &query_result)) {
142597 + pr_err("Can't query channel#%d's scheduler!\n",
142598 + cq->parent->idx);
142599 + return -EINVAL;
142600 + }
142601 +
142602 + config_opts.cqcid = cpu_to_be16(cq->parent->idx);
142603 + config_opts.dcpid = cq->parent->dcp_idx;
142604 + config_opts.crem = query_result.crem;
142605 + config_opts.erem = query_result.erem;
142606 + config_opts.gpc_combine_flag = query_result.gpc_combine_flag;
142607 + config_opts.gpc_prio_a = query_result.gpc_prio_a;
142608 + config_opts.gpc_prio_b = query_result.gpc_prio_b;
142609 +
142610 + for (i = 0; i < 8; i++)
142611 + config_opts.w[i] = query_result.w[i];
142612 + config_opts.w[cq->idx - 8] = ((weight_code->y << 3) |
142613 + (weight_code->x & 0x7));
142614 + return qman_ceetm_configure_class_scheduler(&config_opts);
142615 +}
142616 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight);
142617 +
142618 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
142619 + struct qm_ceetm_weight_code *weight_code)
142620 +{
142621 + struct qm_mcr_ceetm_class_scheduler_query query_result;
142622 +
142623 + if (cq->idx < 8) {
142624 + pr_err("Can not get weight for ungrouped class queue\n");
142625 + return -EINVAL;
142626 + }
142627 +
142628 + if (qman_ceetm_query_class_scheduler(cq->parent,
142629 + &query_result)) {
142630 + pr_err("Can't get the weight code for CQ#%d!\n", cq->idx);
142631 + return -EINVAL;
142632 + }
142633 + weight_code->y = query_result.w[cq->idx - 8] >> 3;
142634 + weight_code->x = query_result.w[cq->idx - 8] & 0x7;
142635 +
142636 + return 0;
142637 +}
142638 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight);
142639 +
142640 +/* The WBFS code is represent as {x,y}, the effect wieght can be calculated as:
142641 + * effective weight = 2^x / (1 - (y/64))
142642 + * = 2^(x+6) / (64 - y)
142643 + */
142644 +static void reduce_fraction(u32 *n, u32 *d)
142645 +{
142646 + u32 factor = 2;
142647 + u32 lesser = (*n < *d) ? *n : *d;
142648 + /* If factor exceeds the square-root of the lesser of *n and *d,
142649 + * then there's no point continuing. Proof: if there was a factor
142650 + * bigger than the square root, that would imply there exists
142651 + * another factor smaller than the square-root with which it
142652 + * multiplies to give 'lesser' - but that's a contradiction
142653 + * because the other factor would have already been found and
142654 + * divided out.
142655 + */
142656 + while ((factor * factor) <= lesser) {
142657 + /* If 'factor' is a factor of *n and *d, divide them both
142658 + * by 'factor' as many times as possible.
142659 + */
142660 + while (!(*n % factor) && !(*d % factor)) {
142661 + *n /= factor;
142662 + *d /= factor;
142663 + lesser /= factor;
142664 + }
142665 + if (factor == 2)
142666 + factor = 3;
142667 + else
142668 + factor += 2;
142669 + }
142670 +}
142671 +
142672 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
142673 + u32 *numerator,
142674 + u32 *denominator)
142675 +{
142676 + *numerator = (u32) 1 << (weight_code->x + 6);
142677 + *denominator = 64 - weight_code->y;
142678 + reduce_fraction(numerator, denominator);
142679 + return 0;
142680 +}
142681 +EXPORT_SYMBOL(qman_ceetm_wbfs2ratio);
142682 +
142683 +/* For a given x, the weight is between 2^x (inclusive) and 2^(x+1) (exclusive).
142684 + * So find 'x' by range, and then estimate 'y' using:
142685 + * 64 - y = 2^(x + 6) / weight
142686 + * = 2^(x + 6) / (n/d)
142687 + * = d * 2^(x+6) / n
142688 + * y = 64 - (d * 2^(x+6) / n)
142689 + */
142690 +int qman_ceetm_ratio2wbfs(u32 numerator,
142691 + u32 denominator,
142692 + struct qm_ceetm_weight_code *weight_code,
142693 + int rounding)
142694 +{
142695 + unsigned int y, x = 0;
142696 + /* search incrementing 'x' until:
142697 + * weight < 2^(x+1)
142698 + * n/d < 2^(x+1)
142699 + * n < d * 2^(x+1)
142700 + */
142701 + while ((x < 8) && (numerator >= (denominator << (x + 1))))
142702 + x++;
142703 + if (x >= 8)
142704 + return -ERANGE;
142705 + /* because of the subtraction, use '-rounding' */
142706 + y = 64 - ROUNDING(denominator << (x + 6), numerator, -rounding);
142707 + if (y >= 32)
142708 + return -ERANGE;
142709 + weight_code->x = x;
142710 + weight_code->y = y;
142711 + return 0;
142712 +}
142713 +EXPORT_SYMBOL(qman_ceetm_ratio2wbfs);
142714 +
142715 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio)
142716 +{
142717 + struct qm_ceetm_weight_code weight_code;
142718 +
142719 + if (qman_ceetm_ratio2wbfs(ratio, 100, &weight_code, 0)) {
142720 + pr_err("Cannot get wbfs code for cq %x\n", cq->idx);
142721 + return -EINVAL;
142722 + }
142723 + return qman_ceetm_set_queue_weight(cq, &weight_code);
142724 +}
142725 +EXPORT_SYMBOL(qman_ceetm_set_queue_weight_in_ratio);
142726 +
142727 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio)
142728 +{
142729 + struct qm_ceetm_weight_code weight_code;
142730 + u32 n, d;
142731 +
142732 + if (qman_ceetm_get_queue_weight(cq, &weight_code)) {
142733 + pr_err("Cannot query the weight code for cq%x\n", cq->idx);
142734 + return -EINVAL;
142735 + }
142736 +
142737 + if (qman_ceetm_wbfs2ratio(&weight_code, &n, &d)) {
142738 + pr_err("Cannot get the ratio with wbfs code\n");
142739 + return -EINVAL;
142740 + }
142741 +
142742 + *ratio = (n * 100) / d;
142743 + return 0;
142744 +}
142745 +EXPORT_SYMBOL(qman_ceetm_get_queue_weight_in_ratio);
142746 +
142747 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
142748 + u64 *frame_count, u64 *byte_count)
142749 +{
142750 + struct qm_mcr_ceetm_statistics_query result;
142751 + u16 cid, command_type;
142752 + enum qm_dc_portal dcp_idx;
142753 + int ret;
142754 +
142755 + cid = cpu_to_be16((cq->parent->idx << 4) | cq->idx);
142756 + dcp_idx = cq->parent->dcp_idx;
142757 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
142758 + command_type = CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS;
142759 + else
142760 + command_type = CEETM_QUERY_DEQUEUE_STATISTICS;
142761 +
142762 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
142763 + if (ret) {
142764 + pr_err("Can't query the statistics of CQ#%d!\n", cq->idx);
142765 + return -EINVAL;
142766 + }
142767 +
142768 + *frame_count = be40_to_cpu(result.frm_cnt);
142769 + *byte_count = be48_to_cpu(result.byte_cnt);
142770 + return 0;
142771 +}
142772 +EXPORT_SYMBOL(qman_ceetm_cq_get_dequeue_statistics);
142773 +
142774 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq)
142775 +{
142776 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread ppxr;
142777 + int ret;
142778 +
142779 + do {
142780 + ret = qman_ceetm_cq_peek_pop_xsfdrread(cq, 1, 0, &ppxr);
142781 + if (ret) {
142782 + pr_err("Failed to pop frame from CQ\n");
142783 + return -EINVAL;
142784 + }
142785 + } while (!(ppxr.stat & 0x2));
142786 +
142787 + return 0;
142788 +}
142789 +EXPORT_SYMBOL(qman_ceetm_drain_cq);
142790 +
142791 +#define CEETM_LFQMT_LFQID_MSB 0xF00000
142792 +#define CEETM_LFQMT_LFQID_LSB 0x000FFF
142793 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
142794 + struct qm_ceetm_cq *cq)
142795 +{
142796 + struct qm_ceetm_lfq *p;
142797 + u32 lfqid;
142798 + int ret = 0;
142799 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
142800 +
142801 + if (cq->parent->dcp_idx == qm_dc_portal_fman0) {
142802 + ret = qman_alloc_ceetm0_lfqid(&lfqid);
142803 + } else if (cq->parent->dcp_idx == qm_dc_portal_fman1) {
142804 + ret = qman_alloc_ceetm1_lfqid(&lfqid);
142805 + } else {
142806 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
142807 + cq->parent->dcp_idx);
142808 + return -EINVAL;
142809 + }
142810 +
142811 + if (ret) {
142812 + pr_err("There is no lfqid avalaible for CQ#%d!\n", cq->idx);
142813 + return -ENODEV;
142814 + }
142815 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142816 + if (!p)
142817 + return -ENOMEM;
142818 + p->idx = lfqid;
142819 + p->dctidx = (u16)(lfqid & CEETM_LFQMT_LFQID_LSB);
142820 + p->parent = cq->parent;
142821 + list_add_tail(&p->node, &cq->bound_lfqids);
142822 +
142823 + lfqmt_config.lfqid = cpu_to_be24(CEETM_LFQMT_LFQID_MSB |
142824 + (cq->parent->dcp_idx << 16) |
142825 + (lfqid & CEETM_LFQMT_LFQID_LSB));
142826 + lfqmt_config.cqid = cpu_to_be16((cq->parent->idx << 4) | (cq->idx));
142827 + lfqmt_config.dctidx = cpu_to_be16(p->dctidx);
142828 + if (qman_ceetm_configure_lfqmt(&lfqmt_config)) {
142829 + pr_err("Can't configure LFQMT for LFQID#%d @ CQ#%d\n",
142830 + lfqid, cq->idx);
142831 + list_del(&p->node);
142832 + kfree(p);
142833 + return -EINVAL;
142834 + }
142835 + *lfq = p;
142836 + return 0;
142837 +}
142838 +EXPORT_SYMBOL(qman_ceetm_lfq_claim);
142839 +
142840 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq)
142841 +{
142842 + if (lfq->parent->dcp_idx == qm_dc_portal_fman0) {
142843 + qman_release_ceetm0_lfqid(lfq->idx);
142844 + } else if (lfq->parent->dcp_idx == qm_dc_portal_fman1) {
142845 + qman_release_ceetm1_lfqid(lfq->idx);
142846 + } else {
142847 + pr_err("dcp_idx %u does not correspond to a known fman in this driver\n",
142848 + lfq->parent->dcp_idx);
142849 + return -EINVAL;
142850 + }
142851 + list_del(&lfq->node);
142852 + kfree(lfq);
142853 + return 0;
142854 +}
142855 +EXPORT_SYMBOL(qman_ceetm_lfq_release);
142856 +
142857 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq, u64 context_a,
142858 + u32 context_b)
142859 +{
142860 + struct qm_mcc_ceetm_dct_config dct_config;
142861 + lfq->context_a = context_a;
142862 + lfq->context_b = context_b;
142863 + dct_config.dctidx = cpu_to_be16((u16)lfq->dctidx);
142864 + dct_config.dcpid = lfq->parent->dcp_idx;
142865 + dct_config.context_b = cpu_to_be32(context_b);
142866 + dct_config.context_a = cpu_to_be64(context_a);
142867 +
142868 + return qman_ceetm_configure_dct(&dct_config);
142869 +}
142870 +EXPORT_SYMBOL(qman_ceetm_lfq_set_context);
142871 +
142872 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq, u64 *context_a,
142873 + u32 *context_b)
142874 +{
142875 + struct qm_mcc_ceetm_dct_query dct_query;
142876 + struct qm_mcr_ceetm_dct_query query_result;
142877 +
142878 + dct_query.dctidx = cpu_to_be16(lfq->dctidx);
142879 + dct_query.dcpid = lfq->parent->dcp_idx;
142880 + if (qman_ceetm_query_dct(&dct_query, &query_result)) {
142881 + pr_err("Can't query LFQID#%d's context!\n", lfq->idx);
142882 + return -EINVAL;
142883 + }
142884 + *context_a = be64_to_cpu(query_result.context_a);
142885 + *context_b = be32_to_cpu(query_result.context_b);
142886 + return 0;
142887 +}
142888 +EXPORT_SYMBOL(qman_ceetm_lfq_get_context);
142889 +
142890 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq)
142891 +{
142892 + spin_lock_init(&fq->fqlock);
142893 + fq->fqid = lfq->idx;
142894 + fq->flags = QMAN_FQ_FLAG_NO_MODIFY;
142895 + if (lfq->ern)
142896 + fq->cb.ern = lfq->ern;
142897 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
142898 + if (unlikely(find_empty_fq_table_entry(&fq->key, fq)))
142899 + return -ENOMEM;
142900 +#endif
142901 + return 0;
142902 +}
142903 +EXPORT_SYMBOL(qman_ceetm_create_fq);
142904 +
142905 +#define MAX_CCG_IDX 0x000F
142906 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
142907 + struct qm_ceetm_channel *channel,
142908 + unsigned int idx,
142909 + void (*cscn)(struct qm_ceetm_ccg *,
142910 + void *cb_ctx,
142911 + int congested),
142912 + void *cb_ctx)
142913 +{
142914 + struct qm_ceetm_ccg *p;
142915 +
142916 + if (idx > MAX_CCG_IDX) {
142917 + pr_err("The given ccg index is out of range\n");
142918 + return -EINVAL;
142919 + }
142920 +
142921 + list_for_each_entry(p, &channel->ccgs, node) {
142922 + if (p->idx == idx) {
142923 + pr_err("The CCG#%d has been claimed\n", idx);
142924 + return -EINVAL;
142925 + }
142926 + }
142927 +
142928 + p = kmalloc(sizeof(*p), GFP_KERNEL);
142929 + if (!p) {
142930 + pr_err("Can't allocate memory for CCG#%d!\n", idx);
142931 + return -ENOMEM;
142932 + }
142933 +
142934 + list_add_tail(&p->node, &channel->ccgs);
142935 +
142936 + p->idx = idx;
142937 + p->parent = channel;
142938 + p->cb = cscn;
142939 + p->cb_ctx = cb_ctx;
142940 + INIT_LIST_HEAD(&p->cb_node);
142941 +
142942 + *ccg = p;
142943 + return 0;
142944 +}
142945 +EXPORT_SYMBOL(qman_ceetm_ccg_claim);
142946 +
142947 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg)
142948 +{
142949 + unsigned long irqflags __maybe_unused;
142950 + struct qm_mcc_ceetm_ccgr_config config_opts;
142951 + int ret = 0;
142952 + struct qman_portal *p = get_affine_portal();
142953 +
142954 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
142955 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
142956 + if (!list_empty(&ccg->cb_node))
142957 + list_del(&ccg->cb_node);
142958 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
142959 + (ccg->parent->idx << 4) | ccg->idx);
142960 + config_opts.dcpid = ccg->parent->dcp_idx;
142961 + config_opts.we_mask = cpu_to_be16(QM_CCGR_WE_CSCN_TUPD);
142962 + config_opts.cm_config.cscn_tupd = cpu_to_be16(PORTAL_IDX(p));
142963 + ret = qman_ceetm_configure_ccgr(&config_opts);
142964 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
142965 + put_affine_portal();
142966 +
142967 + list_del(&ccg->node);
142968 + kfree(ccg);
142969 + return ret;
142970 +}
142971 +EXPORT_SYMBOL(qman_ceetm_ccg_release);
142972 +
142973 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg, u16 we_mask,
142974 + const struct qm_ceetm_ccg_params *params)
142975 +{
142976 + struct qm_mcc_ceetm_ccgr_config config_opts;
142977 + unsigned long irqflags __maybe_unused;
142978 + int ret;
142979 + struct qman_portal *p;
142980 +
142981 + if (((ccg->parent->idx << 4) | ccg->idx) >= (2 * __CGR_NUM))
142982 + return -EINVAL;
142983 +
142984 + p = get_affine_portal();
142985 +
142986 + memset(&config_opts, 0, sizeof(struct qm_mcc_ceetm_ccgr_config));
142987 + spin_lock_irqsave(&p->ccgr_lock, irqflags);
142988 +
142989 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
142990 + (ccg->parent->idx << 4) | ccg->idx);
142991 + config_opts.dcpid = ccg->parent->dcp_idx;
142992 + config_opts.we_mask = we_mask;
142993 + if (we_mask & QM_CCGR_WE_CSCN_EN) {
142994 + config_opts.we_mask |= QM_CCGR_WE_CSCN_TUPD;
142995 + config_opts.cm_config.cscn_tupd = cpu_to_be16(
142996 + QM_CGR_TARG_UDP_CTRL_WRITE_BIT | PORTAL_IDX(p));
142997 + }
142998 + config_opts.we_mask = cpu_to_be16(config_opts.we_mask);
142999 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
143000 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
143001 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
143002 + config_opts.cm_config.ctl_td_en = params->td_en;
143003 + config_opts.cm_config.ctl_td_mode = params->td_mode;
143004 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
143005 + config_opts.cm_config.ctl_mode = params->mode;
143006 + config_opts.cm_config.oal = params->oal;
143007 + config_opts.cm_config.cs_thres.hword =
143008 + cpu_to_be16(params->cs_thres_in.hword);
143009 + config_opts.cm_config.cs_thres_x.hword =
143010 + cpu_to_be16(params->cs_thres_out.hword);
143011 + config_opts.cm_config.td_thres.hword =
143012 + cpu_to_be16(params->td_thres.hword);
143013 + config_opts.cm_config.wr_parm_g.word =
143014 + cpu_to_be32(params->wr_parm_g.word);
143015 + config_opts.cm_config.wr_parm_y.word =
143016 + cpu_to_be32(params->wr_parm_y.word);
143017 + config_opts.cm_config.wr_parm_r.word =
143018 + cpu_to_be32(params->wr_parm_r.word);
143019 + ret = qman_ceetm_configure_ccgr(&config_opts);
143020 + if (ret) {
143021 + pr_err("Configure CCGR CM failed!\n");
143022 + goto release_lock;
143023 + }
143024 +
143025 + if (we_mask & QM_CCGR_WE_CSCN_EN)
143026 + if (list_empty(&ccg->cb_node))
143027 + list_add(&ccg->cb_node,
143028 + &p->ccgr_cbs[ccg->parent->dcp_idx]);
143029 +release_lock:
143030 + spin_unlock_irqrestore(&p->ccgr_lock, irqflags);
143031 + put_affine_portal();
143032 + return ret;
143033 +}
143034 +EXPORT_SYMBOL(qman_ceetm_ccg_set);
143035 +
143036 +#define CEETM_CCGR_CTL_MASK 0x01
143037 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
143038 + struct qm_ceetm_ccg_params *params)
143039 +{
143040 + struct qm_mcc_ceetm_ccgr_query query_opts;
143041 + struct qm_mcr_ceetm_ccgr_query query_result;
143042 +
143043 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
143044 + (ccg->parent->idx << 4) | ccg->idx);
143045 + query_opts.dcpid = ccg->parent->dcp_idx;
143046 +
143047 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
143048 + pr_err("Can't query CCGR#%d\n", ccg->idx);
143049 + return -EINVAL;
143050 + }
143051 +
143052 + params->wr_parm_r.word = query_result.cm_query.wr_parm_r.word;
143053 + params->wr_parm_y.word = query_result.cm_query.wr_parm_y.word;
143054 + params->wr_parm_g.word = query_result.cm_query.wr_parm_g.word;
143055 + params->td_thres.hword = query_result.cm_query.td_thres.hword;
143056 + params->cs_thres_out.hword = query_result.cm_query.cs_thres_x.hword;
143057 + params->cs_thres_in.hword = query_result.cm_query.cs_thres.hword;
143058 + params->oal = query_result.cm_query.oal;
143059 + params->wr_en_g = query_result.cm_query.ctl_wr_en_g;
143060 + params->wr_en_y = query_result.cm_query.ctl_wr_en_y;
143061 + params->wr_en_r = query_result.cm_query.ctl_wr_en_r;
143062 + params->td_en = query_result.cm_query.ctl_td_en;
143063 + params->td_mode = query_result.cm_query.ctl_td_mode;
143064 + params->cscn_en = query_result.cm_query.ctl_cscn_en;
143065 + params->mode = query_result.cm_query.ctl_mode;
143066 +
143067 + return 0;
143068 +}
143069 +EXPORT_SYMBOL(qman_ceetm_ccg_get);
143070 +
143071 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
143072 + u64 *frame_count, u64 *byte_count)
143073 +{
143074 + struct qm_mcr_ceetm_statistics_query result;
143075 + u16 cid, command_type;
143076 + enum qm_dc_portal dcp_idx;
143077 + int ret;
143078 +
143079 + cid = cpu_to_be16((ccg->parent->idx << 4) | ccg->idx);
143080 + dcp_idx = ccg->parent->dcp_idx;
143081 + if (flags == QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER)
143082 + command_type = CEETM_QUERY_REJECT_CLEAR_STATISTICS;
143083 + else
143084 + command_type = CEETM_QUERY_REJECT_STATISTICS;
143085 +
143086 + ret = qman_ceetm_query_statistics(cid, dcp_idx, command_type, &result);
143087 + if (ret) {
143088 + pr_err("Can't query the statistics of CCG#%d!\n", ccg->idx);
143089 + return -EINVAL;
143090 + }
143091 +
143092 + *frame_count = be40_to_cpu(result.frm_cnt);
143093 + *byte_count = be48_to_cpu(result.byte_cnt);
143094 + return 0;
143095 +}
143096 +EXPORT_SYMBOL(qman_ceetm_ccg_get_reject_statistics);
143097 +
143098 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
143099 + u16 swp_idx,
143100 + unsigned int *cscn_enabled)
143101 +{
143102 + struct qm_mcc_ceetm_ccgr_query query_opts;
143103 + struct qm_mcr_ceetm_ccgr_query query_result;
143104 + int i;
143105 +
143106 + DPA_ASSERT(swp_idx < 127);
143107 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
143108 + (ccg->parent->idx << 4) | ccg->idx);
143109 + query_opts.dcpid = ccg->parent->dcp_idx;
143110 +
143111 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
143112 + pr_err("Can't query CCGR#%d\n", ccg->idx);
143113 + return -EINVAL;
143114 + }
143115 +
143116 + i = swp_idx / 32;
143117 + i = 3 - i;
143118 + *cscn_enabled = query_result.cm_query.cscn_targ_swp[i] >>
143119 + (31 - swp_idx % 32);
143120 +
143121 + return 0;
143122 +}
143123 +EXPORT_SYMBOL(qman_ceetm_cscn_swp_get);
143124 +
143125 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
143126 + u16 dcp_idx,
143127 + u8 vcgid,
143128 + unsigned int cscn_enabled,
143129 + u16 we_mask,
143130 + const struct qm_ceetm_ccg_params *params)
143131 +{
143132 + struct qm_mcc_ceetm_ccgr_config config_opts;
143133 + int ret;
143134 +
143135 + config_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_CONFIGURE |
143136 + (ccg->parent->idx << 4) | ccg->idx);
143137 + config_opts.dcpid = ccg->parent->dcp_idx;
143138 + config_opts.we_mask = cpu_to_be16(we_mask | QM_CCGR_WE_CSCN_TUPD |
143139 + QM_CCGR_WE_CDV);
143140 + config_opts.cm_config.cdv = vcgid;
143141 + config_opts.cm_config.cscn_tupd = cpu_to_be16((cscn_enabled << 15) |
143142 + QM_CGR_TARG_UDP_CTRL_DCP | dcp_idx);
143143 + config_opts.cm_config.ctl_wr_en_g = params->wr_en_g;
143144 + config_opts.cm_config.ctl_wr_en_y = params->wr_en_y;
143145 + config_opts.cm_config.ctl_wr_en_r = params->wr_en_r;
143146 + config_opts.cm_config.ctl_td_en = params->td_en;
143147 + config_opts.cm_config.ctl_td_mode = params->td_mode;
143148 + config_opts.cm_config.ctl_cscn_en = params->cscn_en;
143149 + config_opts.cm_config.ctl_mode = params->mode;
143150 + config_opts.cm_config.cs_thres.hword =
143151 + cpu_to_be16(params->cs_thres_in.hword);
143152 + config_opts.cm_config.cs_thres_x.hword =
143153 + cpu_to_be16(params->cs_thres_out.hword);
143154 + config_opts.cm_config.td_thres.hword =
143155 + cpu_to_be16(params->td_thres.hword);
143156 + config_opts.cm_config.wr_parm_g.word =
143157 + cpu_to_be32(params->wr_parm_g.word);
143158 + config_opts.cm_config.wr_parm_y.word =
143159 + cpu_to_be32(params->wr_parm_y.word);
143160 + config_opts.cm_config.wr_parm_r.word =
143161 + cpu_to_be32(params->wr_parm_r.word);
143162 +
143163 + ret = qman_ceetm_configure_ccgr(&config_opts);
143164 + if (ret) {
143165 + pr_err("Configure CSCN_TARG_DCP failed!\n");
143166 + return -EINVAL;
143167 + }
143168 + return 0;
143169 +}
143170 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_set);
143171 +
143172 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
143173 + u16 dcp_idx,
143174 + u8 *vcgid,
143175 + unsigned int *cscn_enabled)
143176 +{
143177 + struct qm_mcc_ceetm_ccgr_query query_opts;
143178 + struct qm_mcr_ceetm_ccgr_query query_result;
143179 +
143180 + query_opts.ccgrid = cpu_to_be16(CEETM_CCGR_CM_QUERY |
143181 + (ccg->parent->idx << 4) | ccg->idx);
143182 + query_opts.dcpid = ccg->parent->dcp_idx;
143183 +
143184 + if (qman_ceetm_query_ccgr(&query_opts, &query_result)) {
143185 + pr_err("Can't query CCGR#%d\n", ccg->idx);
143186 + return -EINVAL;
143187 + }
143188 +
143189 + *vcgid = query_result.cm_query.cdv;
143190 + *cscn_enabled = (query_result.cm_query.cscn_targ_dcp >> dcp_idx) & 0x1;
143191 + return 0;
143192 +}
143193 +EXPORT_SYMBOL(qman_ceetm_cscn_dcp_get);
143194 +
143195 +int qman_ceetm_querycongestion(struct __qm_mcr_querycongestion *ccg_state,
143196 + unsigned int dcp_idx)
143197 +{
143198 + struct qm_mc_command *mcc;
143199 + struct qm_mc_result *mcr;
143200 + struct qman_portal *p;
143201 + unsigned long irqflags __maybe_unused;
143202 + u8 res;
143203 + int i, j;
143204 +
143205 + p = get_affine_portal();
143206 + PORTAL_IRQ_LOCK(p, irqflags);
143207 +
143208 + mcc = qm_mc_start(&p->p);
143209 + for (i = 0; i < 2; i++) {
143210 + mcc->ccgr_query.ccgrid =
143211 + cpu_to_be16(CEETM_QUERY_CONGESTION_STATE | i);
143212 + mcc->ccgr_query.dcpid = dcp_idx;
143213 + qm_mc_commit(&p->p, QM_CEETM_VERB_CCGR_QUERY);
143214 +
143215 + while (!(mcr = qm_mc_result(&p->p)))
143216 + cpu_relax();
143217 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
143218 + QM_CEETM_VERB_CCGR_QUERY);
143219 + res = mcr->result;
143220 + if (res == QM_MCR_RESULT_OK) {
143221 + for (j = 0; j < 8; j++)
143222 + mcr->ccgr_query.congestion_state.state.
143223 + __state[j] = be32_to_cpu(mcr->ccgr_query.
143224 + congestion_state.state.__state[j]);
143225 + *(ccg_state + i) =
143226 + mcr->ccgr_query.congestion_state.state;
143227 + } else {
143228 + pr_err("QUERY CEETM CONGESTION STATE failed\n");
143229 + PORTAL_IRQ_UNLOCK(p, irqflags);
143230 + return -EIO;
143231 + }
143232 + }
143233 + PORTAL_IRQ_UNLOCK(p, irqflags);
143234 + put_affine_portal();
143235 + return 0;
143236 +}
143237 +
143238 +int qman_set_wpm(int wpm_enable)
143239 +{
143240 + return qm_set_wpm(wpm_enable);
143241 +}
143242 +EXPORT_SYMBOL(qman_set_wpm);
143243 +
143244 +int qman_get_wpm(int *wpm_enable)
143245 +{
143246 + return qm_get_wpm(wpm_enable);
143247 +}
143248 +EXPORT_SYMBOL(qman_get_wpm);
143249 +
143250 +int qman_shutdown_fq(u32 fqid)
143251 +{
143252 + struct qman_portal *p;
143253 + unsigned long irqflags __maybe_unused;
143254 + int ret;
143255 + struct qm_portal *low_p;
143256 + p = get_affine_portal();
143257 + PORTAL_IRQ_LOCK(p, irqflags);
143258 + low_p = &p->p;
143259 + ret = qm_shutdown_fq(&low_p, 1, fqid);
143260 + PORTAL_IRQ_UNLOCK(p, irqflags);
143261 + put_affine_portal();
143262 + return ret;
143263 +}
143264 +
143265 +const struct qm_portal_config *qman_get_qm_portal_config(
143266 + struct qman_portal *portal)
143267 +{
143268 + return portal->sharing_redirect ? NULL : portal->config;
143269 +}
143270 --- /dev/null
143271 +++ b/drivers/staging/fsl_qbman/qman_low.h
143272 @@ -0,0 +1,1445 @@
143273 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
143274 + *
143275 + * Redistribution and use in source and binary forms, with or without
143276 + * modification, are permitted provided that the following conditions are met:
143277 + * * Redistributions of source code must retain the above copyright
143278 + * notice, this list of conditions and the following disclaimer.
143279 + * * Redistributions in binary form must reproduce the above copyright
143280 + * notice, this list of conditions and the following disclaimer in the
143281 + * documentation and/or other materials provided with the distribution.
143282 + * * Neither the name of Freescale Semiconductor nor the
143283 + * names of its contributors may be used to endorse or promote products
143284 + * derived from this software without specific prior written permission.
143285 + *
143286 + *
143287 + * ALTERNATIVELY, this software may be distributed under the terms of the
143288 + * GNU General Public License ("GPL") as published by the Free Software
143289 + * Foundation, either version 2 of that License or (at your option) any
143290 + * later version.
143291 + *
143292 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
143293 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
143294 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
143295 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
143296 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
143297 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
143298 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
143299 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143300 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
143301 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
143302 + */
143303 +
143304 +#include "qman_private.h"
143305 +
143306 +/***************************/
143307 +/* Portal register assists */
143308 +/***************************/
143309 +
143310 +/* Cache-inhibited register offsets */
143311 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
143312 +
143313 +#define QM_REG_EQCR_PI_CINH 0x0000
143314 +#define QM_REG_EQCR_CI_CINH 0x0004
143315 +#define QM_REG_EQCR_ITR 0x0008
143316 +#define QM_REG_DQRR_PI_CINH 0x0040
143317 +#define QM_REG_DQRR_CI_CINH 0x0044
143318 +#define QM_REG_DQRR_ITR 0x0048
143319 +#define QM_REG_DQRR_DCAP 0x0050
143320 +#define QM_REG_DQRR_SDQCR 0x0054
143321 +#define QM_REG_DQRR_VDQCR 0x0058
143322 +#define QM_REG_DQRR_PDQCR 0x005c
143323 +#define QM_REG_MR_PI_CINH 0x0080
143324 +#define QM_REG_MR_CI_CINH 0x0084
143325 +#define QM_REG_MR_ITR 0x0088
143326 +#define QM_REG_CFG 0x0100
143327 +#define QM_REG_ISR 0x0e00
143328 +#define QM_REG_IIR 0x0e0c
143329 +#define QM_REG_ITPR 0x0e14
143330 +
143331 +/* Cache-enabled register offsets */
143332 +#define QM_CL_EQCR 0x0000
143333 +#define QM_CL_DQRR 0x1000
143334 +#define QM_CL_MR 0x2000
143335 +#define QM_CL_EQCR_PI_CENA 0x3000
143336 +#define QM_CL_EQCR_CI_CENA 0x3100
143337 +#define QM_CL_DQRR_PI_CENA 0x3200
143338 +#define QM_CL_DQRR_CI_CENA 0x3300
143339 +#define QM_CL_MR_PI_CENA 0x3400
143340 +#define QM_CL_MR_CI_CENA 0x3500
143341 +#define QM_CL_CR 0x3800
143342 +#define QM_CL_RR0 0x3900
143343 +#define QM_CL_RR1 0x3940
143344 +
143345 +#endif
143346 +
143347 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
143348 +
143349 +#define QM_REG_EQCR_PI_CINH 0x3000
143350 +#define QM_REG_EQCR_CI_CINH 0x3040
143351 +#define QM_REG_EQCR_ITR 0x3080
143352 +#define QM_REG_DQRR_PI_CINH 0x3100
143353 +#define QM_REG_DQRR_CI_CINH 0x3140
143354 +#define QM_REG_DQRR_ITR 0x3180
143355 +#define QM_REG_DQRR_DCAP 0x31C0
143356 +#define QM_REG_DQRR_SDQCR 0x3200
143357 +#define QM_REG_DQRR_VDQCR 0x3240
143358 +#define QM_REG_DQRR_PDQCR 0x3280
143359 +#define QM_REG_MR_PI_CINH 0x3300
143360 +#define QM_REG_MR_CI_CINH 0x3340
143361 +#define QM_REG_MR_ITR 0x3380
143362 +#define QM_REG_CFG 0x3500
143363 +#define QM_REG_ISR 0x3600
143364 +#define QM_REG_IIR 0x36C0
143365 +#define QM_REG_ITPR 0x3740
143366 +
143367 +/* Cache-enabled register offsets */
143368 +#define QM_CL_EQCR 0x0000
143369 +#define QM_CL_DQRR 0x1000
143370 +#define QM_CL_MR 0x2000
143371 +#define QM_CL_EQCR_PI_CENA 0x3000
143372 +#define QM_CL_EQCR_CI_CENA 0x3040
143373 +#define QM_CL_DQRR_PI_CENA 0x3100
143374 +#define QM_CL_DQRR_CI_CENA 0x3140
143375 +#define QM_CL_MR_PI_CENA 0x3300
143376 +#define QM_CL_MR_CI_CENA 0x3340
143377 +#define QM_CL_CR 0x3800
143378 +#define QM_CL_RR0 0x3900
143379 +#define QM_CL_RR1 0x3940
143380 +
143381 +#endif
143382 +
143383 +
143384 +/* BTW, the drivers (and h/w programming model) already obtain the required
143385 + * synchronisation for portal accesses via lwsync(), hwsync(), and
143386 + * data-dependencies. Use of barrier()s or other order-preserving primitives
143387 + * simply degrade performance. Hence the use of the __raw_*() interfaces, which
143388 + * simply ensure that the compiler treats the portal registers as volatile (ie.
143389 + * non-coherent). */
143390 +
143391 +/* Cache-inhibited register access. */
143392 +#define __qm_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ci + (o)))
143393 +#define __qm_out(qm, o, val) __raw_writel((cpu_to_be32(val)), \
143394 + (qm)->addr_ci + (o));
143395 +#define qm_in(reg) __qm_in(&portal->addr, QM_REG_##reg)
143396 +#define qm_out(reg, val) __qm_out(&portal->addr, QM_REG_##reg, val)
143397 +
143398 +/* Cache-enabled (index) register access */
143399 +#define __qm_cl_touch_ro(qm, o) dcbt_ro((qm)->addr_ce + (o))
143400 +#define __qm_cl_touch_rw(qm, o) dcbt_rw((qm)->addr_ce + (o))
143401 +#define __qm_cl_in(qm, o) be32_to_cpu(__raw_readl((qm)->addr_ce + (o)))
143402 +#define __qm_cl_out(qm, o, val) \
143403 + do { \
143404 + u32 *__tmpclout = (qm)->addr_ce + (o); \
143405 + __raw_writel(cpu_to_be32(val), __tmpclout); \
143406 + dcbf(__tmpclout); \
143407 + } while (0)
143408 +#define __qm_cl_invalidate(qm, o) dcbi((qm)->addr_ce + (o))
143409 +#define qm_cl_touch_ro(reg) __qm_cl_touch_ro(&portal->addr, QM_CL_##reg##_CENA)
143410 +#define qm_cl_touch_rw(reg) __qm_cl_touch_rw(&portal->addr, QM_CL_##reg##_CENA)
143411 +#define qm_cl_in(reg) __qm_cl_in(&portal->addr, QM_CL_##reg##_CENA)
143412 +#define qm_cl_out(reg, val) __qm_cl_out(&portal->addr, QM_CL_##reg##_CENA, val)
143413 +#define qm_cl_invalidate(reg)\
143414 + __qm_cl_invalidate(&portal->addr, QM_CL_##reg##_CENA)
143415 +
143416 +/* Cache-enabled ring access */
143417 +#define qm_cl(base, idx) ((void *)base + ((idx) << 6))
143418 +
143419 +/* Cyclic helper for rings. FIXME: once we are able to do fine-grain perf
143420 + * analysis, look at using the "extra" bit in the ring index registers to avoid
143421 + * cyclic issues. */
143422 +static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last)
143423 +{
143424 + /* 'first' is included, 'last' is excluded */
143425 + if (first <= last)
143426 + return last - first;
143427 + return ringsize + last - first;
143428 +}
143429 +
143430 +/* Portal modes.
143431 + * Enum types;
143432 + * pmode == production mode
143433 + * cmode == consumption mode,
143434 + * dmode == h/w dequeue mode.
143435 + * Enum values use 3 letter codes. First letter matches the portal mode,
143436 + * remaining two letters indicate;
143437 + * ci == cache-inhibited portal register
143438 + * ce == cache-enabled portal register
143439 + * vb == in-band valid-bit (cache-enabled)
143440 + * dc == DCA (Discrete Consumption Acknowledgement), DQRR-only
143441 + * As for "enum qm_dqrr_dmode", it should be self-explanatory.
143442 + */
143443 +enum qm_eqcr_pmode { /* matches QCSP_CFG::EPM */
143444 + qm_eqcr_pci = 0, /* PI index, cache-inhibited */
143445 + qm_eqcr_pce = 1, /* PI index, cache-enabled */
143446 + qm_eqcr_pvb = 2 /* valid-bit */
143447 +};
143448 +enum qm_dqrr_dmode { /* matches QCSP_CFG::DP */
143449 + qm_dqrr_dpush = 0, /* SDQCR + VDQCR */
143450 + qm_dqrr_dpull = 1 /* PDQCR */
143451 +};
143452 +enum qm_dqrr_pmode { /* s/w-only */
143453 + qm_dqrr_pci, /* reads DQRR_PI_CINH */
143454 + qm_dqrr_pce, /* reads DQRR_PI_CENA */
143455 + qm_dqrr_pvb /* reads valid-bit */
143456 +};
143457 +enum qm_dqrr_cmode { /* matches QCSP_CFG::DCM */
143458 + qm_dqrr_cci = 0, /* CI index, cache-inhibited */
143459 + qm_dqrr_cce = 1, /* CI index, cache-enabled */
143460 + qm_dqrr_cdc = 2 /* Discrete Consumption Acknowledgement */
143461 +};
143462 +enum qm_mr_pmode { /* s/w-only */
143463 + qm_mr_pci, /* reads MR_PI_CINH */
143464 + qm_mr_pce, /* reads MR_PI_CENA */
143465 + qm_mr_pvb /* reads valid-bit */
143466 +};
143467 +enum qm_mr_cmode { /* matches QCSP_CFG::MM */
143468 + qm_mr_cci = 0, /* CI index, cache-inhibited */
143469 + qm_mr_cce = 1 /* CI index, cache-enabled */
143470 +};
143471 +
143472 +
143473 +/* ------------------------- */
143474 +/* --- Portal structures --- */
143475 +
143476 +#define QM_EQCR_SIZE 8
143477 +#define QM_DQRR_SIZE 16
143478 +#define QM_MR_SIZE 8
143479 +
143480 +struct qm_eqcr {
143481 + struct qm_eqcr_entry *ring, *cursor;
143482 + u8 ci, available, ithresh, vbit;
143483 +#ifdef CONFIG_FSL_DPA_CHECKING
143484 + u32 busy;
143485 + enum qm_eqcr_pmode pmode;
143486 +#endif
143487 +};
143488 +
143489 +struct qm_dqrr {
143490 + const struct qm_dqrr_entry *ring, *cursor;
143491 + u8 pi, ci, fill, ithresh, vbit;
143492 +#ifdef CONFIG_FSL_DPA_CHECKING
143493 + enum qm_dqrr_dmode dmode;
143494 + enum qm_dqrr_pmode pmode;
143495 + enum qm_dqrr_cmode cmode;
143496 +#endif
143497 +};
143498 +
143499 +struct qm_mr {
143500 + const struct qm_mr_entry *ring, *cursor;
143501 + u8 pi, ci, fill, ithresh, vbit;
143502 +#ifdef CONFIG_FSL_DPA_CHECKING
143503 + enum qm_mr_pmode pmode;
143504 + enum qm_mr_cmode cmode;
143505 +#endif
143506 +};
143507 +
143508 +struct qm_mc {
143509 + struct qm_mc_command *cr;
143510 + struct qm_mc_result *rr;
143511 + u8 rridx, vbit;
143512 +#ifdef CONFIG_FSL_DPA_CHECKING
143513 + enum {
143514 + /* Can be _mc_start()ed */
143515 + qman_mc_idle,
143516 + /* Can be _mc_commit()ed or _mc_abort()ed */
143517 + qman_mc_user,
143518 + /* Can only be _mc_retry()ed */
143519 + qman_mc_hw
143520 + } state;
143521 +#endif
143522 +};
143523 +
143524 +#define QM_PORTAL_ALIGNMENT ____cacheline_aligned
143525 +
143526 +struct qm_addr {
143527 + void __iomem *addr_ce; /* cache-enabled */
143528 + void __iomem *addr_ci; /* cache-inhibited */
143529 +};
143530 +
143531 +struct qm_portal {
143532 + /* In the non-CONFIG_FSL_DPA_CHECKING case, the following stuff up to
143533 + * and including 'mc' fits within a cacheline (yay!). The 'config' part
143534 + * is setup-only, so isn't a cause for a concern. In other words, don't
143535 + * rearrange this structure on a whim, there be dragons ... */
143536 + struct qm_addr addr;
143537 + struct qm_eqcr eqcr;
143538 + struct qm_dqrr dqrr;
143539 + struct qm_mr mr;
143540 + struct qm_mc mc;
143541 +} QM_PORTAL_ALIGNMENT;
143542 +
143543 +
143544 +/* ---------------- */
143545 +/* --- EQCR API --- */
143546 +
143547 +/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
143548 +#define EQCR_CARRYCLEAR(p) \
143549 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_EQCR_SIZE << 6)))
143550 +
143551 +/* Bit-wise logic to convert a ring pointer to a ring index */
143552 +static inline u8 EQCR_PTR2IDX(struct qm_eqcr_entry *e)
143553 +{
143554 + return ((uintptr_t)e >> 6) & (QM_EQCR_SIZE - 1);
143555 +}
143556 +
143557 +/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
143558 +static inline void EQCR_INC(struct qm_eqcr *eqcr)
143559 +{
143560 + /* NB: this is odd-looking, but experiments show that it generates fast
143561 + * code with essentially no branching overheads. We increment to the
143562 + * next EQCR pointer and handle overflow and 'vbit'. */
143563 + struct qm_eqcr_entry *partial = eqcr->cursor + 1;
143564 + eqcr->cursor = EQCR_CARRYCLEAR(partial);
143565 + if (partial != eqcr->cursor)
143566 + eqcr->vbit ^= QM_EQCR_VERB_VBIT;
143567 +}
143568 +
143569 +static inline int qm_eqcr_init(struct qm_portal *portal,
143570 + enum qm_eqcr_pmode pmode,
143571 + unsigned int eq_stash_thresh,
143572 + int eq_stash_prio)
143573 +{
143574 + /* This use of 'register', as well as all other occurrences, is because
143575 + * it has been observed to generate much faster code with gcc than is
143576 + * otherwise the case. */
143577 + register struct qm_eqcr *eqcr = &portal->eqcr;
143578 + u32 cfg;
143579 + u8 pi;
143580 +
143581 + eqcr->ring = portal->addr.addr_ce + QM_CL_EQCR;
143582 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
143583 + qm_cl_invalidate(EQCR_CI);
143584 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
143585 + eqcr->cursor = eqcr->ring + pi;
143586 + eqcr->vbit = (qm_in(EQCR_PI_CINH) & QM_EQCR_SIZE) ?
143587 + QM_EQCR_VERB_VBIT : 0;
143588 + eqcr->available = QM_EQCR_SIZE - 1 -
143589 + qm_cyc_diff(QM_EQCR_SIZE, eqcr->ci, pi);
143590 + eqcr->ithresh = qm_in(EQCR_ITR);
143591 +#ifdef CONFIG_FSL_DPA_CHECKING
143592 + eqcr->busy = 0;
143593 + eqcr->pmode = pmode;
143594 +#endif
143595 + cfg = (qm_in(CFG) & 0x00ffffff) |
143596 + (eq_stash_thresh << 28) | /* QCSP_CFG: EST */
143597 + (eq_stash_prio << 26) | /* QCSP_CFG: EP */
143598 + ((pmode & 0x3) << 24); /* QCSP_CFG::EPM */
143599 + qm_out(CFG, cfg);
143600 + return 0;
143601 +}
143602 +
143603 +static inline unsigned int qm_eqcr_get_ci_stashing(struct qm_portal *portal)
143604 +{
143605 + return (qm_in(CFG) >> 28) & 0x7;
143606 +}
143607 +
143608 +static inline void qm_eqcr_finish(struct qm_portal *portal)
143609 +{
143610 + register struct qm_eqcr *eqcr = &portal->eqcr;
143611 + u8 pi, ci;
143612 + u32 cfg;
143613 +
143614 + /*
143615 + * Disable EQCI stashing because the QMan only
143616 + * presents the value it previously stashed to
143617 + * maintain coherency. Setting the stash threshold
143618 + * to 1 then 0 ensures that QMan has resyncronized
143619 + * its internal copy so that the portal is clean
143620 + * when it is reinitialized in the future
143621 + */
143622 + cfg = (qm_in(CFG) & 0x0fffffff) |
143623 + (1 << 28); /* QCSP_CFG: EST */
143624 + qm_out(CFG, cfg);
143625 + cfg &= 0x0fffffff; /* stash threshold = 0 */
143626 + qm_out(CFG, cfg);
143627 +
143628 + pi = qm_in(EQCR_PI_CINH) & (QM_EQCR_SIZE - 1);
143629 + ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
143630 +
143631 + /* Refresh EQCR CI cache value */
143632 + qm_cl_invalidate(EQCR_CI);
143633 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
143634 +
143635 + DPA_ASSERT(!eqcr->busy);
143636 + if (pi != EQCR_PTR2IDX(eqcr->cursor))
143637 + pr_crit("losing uncommited EQCR entries\n");
143638 + if (ci != eqcr->ci)
143639 + pr_crit("missing existing EQCR completions\n");
143640 + if (eqcr->ci != EQCR_PTR2IDX(eqcr->cursor))
143641 + pr_crit("EQCR destroyed unquiesced\n");
143642 +}
143643 +
143644 +static inline struct qm_eqcr_entry *qm_eqcr_start_no_stash(struct qm_portal
143645 + *portal)
143646 +{
143647 + register struct qm_eqcr *eqcr = &portal->eqcr;
143648 + DPA_ASSERT(!eqcr->busy);
143649 + if (!eqcr->available)
143650 + return NULL;
143651 +
143652 +
143653 +#ifdef CONFIG_FSL_DPA_CHECKING
143654 + eqcr->busy = 1;
143655 +#endif
143656 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
143657 + dcbz_64(eqcr->cursor);
143658 +#endif
143659 + return eqcr->cursor;
143660 +}
143661 +
143662 +static inline struct qm_eqcr_entry *qm_eqcr_start_stash(struct qm_portal
143663 + *portal)
143664 +{
143665 + register struct qm_eqcr *eqcr = &portal->eqcr;
143666 + u8 diff, old_ci;
143667 +
143668 + DPA_ASSERT(!eqcr->busy);
143669 + if (!eqcr->available) {
143670 + old_ci = eqcr->ci;
143671 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
143672 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
143673 + eqcr->available += diff;
143674 + if (!diff)
143675 + return NULL;
143676 + }
143677 +#ifdef CONFIG_FSL_DPA_CHECKING
143678 + eqcr->busy = 1;
143679 +#endif
143680 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
143681 + dcbz_64(eqcr->cursor);
143682 +#endif
143683 + return eqcr->cursor;
143684 +}
143685 +
143686 +static inline void qm_eqcr_abort(struct qm_portal *portal)
143687 +{
143688 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
143689 + DPA_ASSERT(eqcr->busy);
143690 +#ifdef CONFIG_FSL_DPA_CHECKING
143691 + eqcr->busy = 0;
143692 +#endif
143693 +}
143694 +
143695 +static inline struct qm_eqcr_entry *qm_eqcr_pend_and_next(
143696 + struct qm_portal *portal, u8 myverb)
143697 +{
143698 + register struct qm_eqcr *eqcr = &portal->eqcr;
143699 + DPA_ASSERT(eqcr->busy);
143700 + DPA_ASSERT(eqcr->pmode != qm_eqcr_pvb);
143701 + if (eqcr->available == 1)
143702 + return NULL;
143703 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
143704 + dcbf(eqcr->cursor);
143705 + EQCR_INC(eqcr);
143706 + eqcr->available--;
143707 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
143708 + dcbz_64(eqcr->cursor);
143709 +#endif
143710 + return eqcr->cursor;
143711 +}
143712 +
143713 +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
143714 +#define EQCR_COMMIT_CHECKS(eqcr) \
143715 +do { \
143716 + DPA_ASSERT(eqcr->busy); \
143717 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & 0xffffff00)); \
143718 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & 0xffffff00)); \
143719 +} while (0)
143720 +#else
143721 +#define EQCR_COMMIT_CHECKS(eqcr) \
143722 +do { \
143723 + DPA_ASSERT(eqcr->busy); \
143724 + DPA_ASSERT(eqcr->cursor->orp == (eqcr->cursor->orp & \
143725 + cpu_to_be32(0x00ffffff))); \
143726 + DPA_ASSERT(eqcr->cursor->fqid == (eqcr->cursor->fqid & \
143727 + cpu_to_be32(0x00ffffff))); \
143728 +} while (0)
143729 +#endif
143730 +
143731 +static inline void qm_eqcr_pci_commit(struct qm_portal *portal, u8 myverb)
143732 +{
143733 + register struct qm_eqcr *eqcr = &portal->eqcr;
143734 + EQCR_COMMIT_CHECKS(eqcr);
143735 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pci);
143736 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
143737 + EQCR_INC(eqcr);
143738 + eqcr->available--;
143739 + dcbf(eqcr->cursor);
143740 + hwsync();
143741 + qm_out(EQCR_PI_CINH, EQCR_PTR2IDX(eqcr->cursor));
143742 +#ifdef CONFIG_FSL_DPA_CHECKING
143743 + eqcr->busy = 0;
143744 +#endif
143745 +}
143746 +
143747 +static inline void qm_eqcr_pce_prefetch(struct qm_portal *portal)
143748 +{
143749 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
143750 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
143751 + qm_cl_invalidate(EQCR_PI);
143752 + qm_cl_touch_rw(EQCR_PI);
143753 +}
143754 +
143755 +static inline void qm_eqcr_pce_commit(struct qm_portal *portal, u8 myverb)
143756 +{
143757 + register struct qm_eqcr *eqcr = &portal->eqcr;
143758 + EQCR_COMMIT_CHECKS(eqcr);
143759 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pce);
143760 + eqcr->cursor->__dont_write_directly__verb = myverb | eqcr->vbit;
143761 + EQCR_INC(eqcr);
143762 + eqcr->available--;
143763 + dcbf(eqcr->cursor);
143764 + lwsync();
143765 + qm_cl_out(EQCR_PI, EQCR_PTR2IDX(eqcr->cursor));
143766 +#ifdef CONFIG_FSL_DPA_CHECKING
143767 + eqcr->busy = 0;
143768 +#endif
143769 +}
143770 +
143771 +static inline void qm_eqcr_pvb_commit(struct qm_portal *portal, u8 myverb)
143772 +{
143773 + register struct qm_eqcr *eqcr = &portal->eqcr;
143774 + struct qm_eqcr_entry *eqcursor;
143775 + EQCR_COMMIT_CHECKS(eqcr);
143776 + DPA_ASSERT(eqcr->pmode == qm_eqcr_pvb);
143777 + lwsync();
143778 + eqcursor = eqcr->cursor;
143779 + eqcursor->__dont_write_directly__verb = myverb | eqcr->vbit;
143780 + dcbf(eqcursor);
143781 + EQCR_INC(eqcr);
143782 + eqcr->available--;
143783 +#ifdef CONFIG_FSL_DPA_CHECKING
143784 + eqcr->busy = 0;
143785 +#endif
143786 +}
143787 +
143788 +static inline u8 qm_eqcr_cci_update(struct qm_portal *portal)
143789 +{
143790 + register struct qm_eqcr *eqcr = &portal->eqcr;
143791 + u8 diff, old_ci = eqcr->ci;
143792 + eqcr->ci = qm_in(EQCR_CI_CINH) & (QM_EQCR_SIZE - 1);
143793 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
143794 + eqcr->available += diff;
143795 + return diff;
143796 +}
143797 +
143798 +static inline void qm_eqcr_cce_prefetch(struct qm_portal *portal)
143799 +{
143800 + __maybe_unused register struct qm_eqcr *eqcr = &portal->eqcr;
143801 + qm_cl_touch_ro(EQCR_CI);
143802 +}
143803 +
143804 +static inline u8 qm_eqcr_cce_update(struct qm_portal *portal)
143805 +{
143806 + register struct qm_eqcr *eqcr = &portal->eqcr;
143807 + u8 diff, old_ci = eqcr->ci;
143808 + eqcr->ci = qm_cl_in(EQCR_CI) & (QM_EQCR_SIZE - 1);
143809 + qm_cl_invalidate(EQCR_CI);
143810 + diff = qm_cyc_diff(QM_EQCR_SIZE, old_ci, eqcr->ci);
143811 + eqcr->available += diff;
143812 + return diff;
143813 +}
143814 +
143815 +static inline u8 qm_eqcr_get_ithresh(struct qm_portal *portal)
143816 +{
143817 + register struct qm_eqcr *eqcr = &portal->eqcr;
143818 + return eqcr->ithresh;
143819 +}
143820 +
143821 +static inline void qm_eqcr_set_ithresh(struct qm_portal *portal, u8 ithresh)
143822 +{
143823 + register struct qm_eqcr *eqcr = &portal->eqcr;
143824 + eqcr->ithresh = ithresh;
143825 + qm_out(EQCR_ITR, ithresh);
143826 +}
143827 +
143828 +static inline u8 qm_eqcr_get_avail(struct qm_portal *portal)
143829 +{
143830 + register struct qm_eqcr *eqcr = &portal->eqcr;
143831 + return eqcr->available;
143832 +}
143833 +
143834 +static inline u8 qm_eqcr_get_fill(struct qm_portal *portal)
143835 +{
143836 + register struct qm_eqcr *eqcr = &portal->eqcr;
143837 + return QM_EQCR_SIZE - 1 - eqcr->available;
143838 +}
143839 +
143840 +
143841 +/* ---------------- */
143842 +/* --- DQRR API --- */
143843 +
143844 +/* FIXME: many possible improvements;
143845 + * - look at changing the API to use pointer rather than index parameters now
143846 + * that 'cursor' is a pointer,
143847 + * - consider moving other parameters to pointer if it could help (ci)
143848 + */
143849 +
143850 +#define DQRR_CARRYCLEAR(p) \
143851 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_DQRR_SIZE << 6)))
143852 +
143853 +static inline u8 DQRR_PTR2IDX(const struct qm_dqrr_entry *e)
143854 +{
143855 + return ((uintptr_t)e >> 6) & (QM_DQRR_SIZE - 1);
143856 +}
143857 +
143858 +static inline const struct qm_dqrr_entry *DQRR_INC(
143859 + const struct qm_dqrr_entry *e)
143860 +{
143861 + return DQRR_CARRYCLEAR(e + 1);
143862 +}
143863 +
143864 +static inline void qm_dqrr_set_maxfill(struct qm_portal *portal, u8 mf)
143865 +{
143866 + qm_out(CFG, (qm_in(CFG) & 0xff0fffff) |
143867 + ((mf & (QM_DQRR_SIZE - 1)) << 20));
143868 +}
143869 +
143870 +static inline void qm_dqrr_cci_consume(struct qm_portal *portal, u8 num)
143871 +{
143872 + register struct qm_dqrr *dqrr = &portal->dqrr;
143873 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
143874 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
143875 + qm_out(DQRR_CI_CINH, dqrr->ci);
143876 +}
143877 +
143878 +static inline void qm_dqrr_cce_consume(struct qm_portal *portal, u8 num)
143879 +{
143880 + register struct qm_dqrr *dqrr = &portal->dqrr;
143881 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
143882 + dqrr->ci = (dqrr->ci + num) & (QM_DQRR_SIZE - 1);
143883 + qm_cl_out(DQRR_CI, dqrr->ci);
143884 +}
143885 +
143886 +static inline void qm_dqrr_cdc_consume_n(struct qm_portal *portal, u16 bitmask)
143887 +{
143888 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143889 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
143890 + qm_out(DQRR_DCAP, (1 << 8) | /* DQRR_DCAP::S */
143891 + ((u32)bitmask << 16)); /* DQRR_DCAP::DCAP_CI */
143892 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
143893 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
143894 +}
143895 +
143896 +static inline int qm_dqrr_init(struct qm_portal *portal,
143897 + const struct qm_portal_config *config,
143898 + enum qm_dqrr_dmode dmode,
143899 + __maybe_unused enum qm_dqrr_pmode pmode,
143900 + enum qm_dqrr_cmode cmode, u8 max_fill)
143901 +{
143902 + register struct qm_dqrr *dqrr = &portal->dqrr;
143903 + u32 cfg;
143904 +
143905 + /* Make sure the DQRR will be idle when we enable */
143906 + qm_out(DQRR_SDQCR, 0);
143907 + qm_out(DQRR_VDQCR, 0);
143908 + qm_out(DQRR_PDQCR, 0);
143909 + dqrr->ring = portal->addr.addr_ce + QM_CL_DQRR;
143910 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
143911 + dqrr->ci = qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
143912 + dqrr->cursor = dqrr->ring + dqrr->ci;
143913 + dqrr->fill = qm_cyc_diff(QM_DQRR_SIZE, dqrr->ci, dqrr->pi);
143914 + dqrr->vbit = (qm_in(DQRR_PI_CINH) & QM_DQRR_SIZE) ?
143915 + QM_DQRR_VERB_VBIT : 0;
143916 + dqrr->ithresh = qm_in(DQRR_ITR);
143917 +
143918 + /* Free up pending DQRR entries if any as per current DCM */
143919 + if (dqrr->fill) {
143920 + enum qm_dqrr_cmode dcm = (qm_in(CFG) >> 16) & 3;
143921 +
143922 +#ifdef CONFIG_FSL_DPA_CHECKING
143923 + dqrr->cmode = dcm;
143924 +#endif
143925 + switch (dcm) {
143926 + case qm_dqrr_cci:
143927 + qm_dqrr_cci_consume(portal, dqrr->fill);
143928 + break;
143929 + case qm_dqrr_cce:
143930 + qm_dqrr_cce_consume(portal, dqrr->fill);
143931 + break;
143932 + case qm_dqrr_cdc:
143933 + qm_dqrr_cdc_consume_n(portal, (1<<QM_DQRR_SIZE) - 1);
143934 + break;
143935 + default:
143936 + DPA_ASSERT(0);
143937 + }
143938 + }
143939 +
143940 +#ifdef CONFIG_FSL_DPA_CHECKING
143941 + dqrr->dmode = dmode;
143942 + dqrr->pmode = pmode;
143943 + dqrr->cmode = cmode;
143944 +#endif
143945 + /* Invalidate every ring entry before beginning */
143946 + for (cfg = 0; cfg < QM_DQRR_SIZE; cfg++)
143947 + dcbi(qm_cl(dqrr->ring, cfg));
143948 + cfg = (qm_in(CFG) & 0xff000f00) |
143949 + ((max_fill & (QM_DQRR_SIZE - 1)) << 20) | /* DQRR_MF */
143950 + ((dmode & 1) << 18) | /* DP */
143951 + ((cmode & 3) << 16) | /* DCM */
143952 + 0xa0 | /* RE+SE */
143953 + (0 ? 0x40 : 0) | /* Ignore RP */
143954 + (0 ? 0x10 : 0); /* Ignore SP */
143955 + qm_out(CFG, cfg);
143956 + qm_dqrr_set_maxfill(portal, max_fill);
143957 +
143958 + /* Recalculate cursor as we may have consumed frames */
143959 + dqrr->cursor = dqrr->ring + dqrr->ci;
143960 + return 0;
143961 +}
143962 +
143963 +static inline void qm_dqrr_finish(struct qm_portal *portal)
143964 +{
143965 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
143966 +#ifdef CONFIG_FSL_DPA_CHECKING
143967 + if ((dqrr->cmode != qm_dqrr_cdc) &&
143968 + (dqrr->ci != DQRR_PTR2IDX(dqrr->cursor)))
143969 + pr_crit("Ignoring completed DQRR entries\n");
143970 +#endif
143971 +}
143972 +
143973 +static inline const struct qm_dqrr_entry *qm_dqrr_current(
143974 + struct qm_portal *portal)
143975 +{
143976 + register struct qm_dqrr *dqrr = &portal->dqrr;
143977 + if (!dqrr->fill)
143978 + return NULL;
143979 + return dqrr->cursor;
143980 +}
143981 +
143982 +static inline u8 qm_dqrr_cursor(struct qm_portal *portal)
143983 +{
143984 + register struct qm_dqrr *dqrr = &portal->dqrr;
143985 + return DQRR_PTR2IDX(dqrr->cursor);
143986 +}
143987 +
143988 +static inline u8 qm_dqrr_next(struct qm_portal *portal)
143989 +{
143990 + register struct qm_dqrr *dqrr = &portal->dqrr;
143991 + DPA_ASSERT(dqrr->fill);
143992 + dqrr->cursor = DQRR_INC(dqrr->cursor);
143993 + return --dqrr->fill;
143994 +}
143995 +
143996 +static inline u8 qm_dqrr_pci_update(struct qm_portal *portal)
143997 +{
143998 + register struct qm_dqrr *dqrr = &portal->dqrr;
143999 + u8 diff, old_pi = dqrr->pi;
144000 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pci);
144001 + dqrr->pi = qm_in(DQRR_PI_CINH) & (QM_DQRR_SIZE - 1);
144002 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
144003 + dqrr->fill += diff;
144004 + return diff;
144005 +}
144006 +
144007 +static inline void qm_dqrr_pce_prefetch(struct qm_portal *portal)
144008 +{
144009 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
144010 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
144011 + qm_cl_invalidate(DQRR_PI);
144012 + qm_cl_touch_ro(DQRR_PI);
144013 +}
144014 +
144015 +static inline u8 qm_dqrr_pce_update(struct qm_portal *portal)
144016 +{
144017 + register struct qm_dqrr *dqrr = &portal->dqrr;
144018 + u8 diff, old_pi = dqrr->pi;
144019 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pce);
144020 + dqrr->pi = qm_cl_in(DQRR_PI) & (QM_DQRR_SIZE - 1);
144021 + diff = qm_cyc_diff(QM_DQRR_SIZE, old_pi, dqrr->pi);
144022 + dqrr->fill += diff;
144023 + return diff;
144024 +}
144025 +
144026 +static inline void qm_dqrr_pvb_update(struct qm_portal *portal)
144027 +{
144028 + register struct qm_dqrr *dqrr = &portal->dqrr;
144029 + const struct qm_dqrr_entry *res = qm_cl(dqrr->ring, dqrr->pi);
144030 + DPA_ASSERT(dqrr->pmode == qm_dqrr_pvb);
144031 +#if (defined CONFIG_PPC || defined CONFIG_PPC64) && !defined CONFIG_FSL_PAMU
144032 + /*
144033 + * On PowerPC platforms if PAMU is not available we need to
144034 + * manually invalidate the cache. When PAMU is available the
144035 + * cache is updated by stashing operations generated by QMan
144036 + */
144037 + dcbi(res);
144038 + dcbt_ro(res);
144039 +#endif
144040 +
144041 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
144042 + * inlining doesn't try to optimise out "excess reads". */
144043 + if ((__raw_readb(&res->verb) & QM_DQRR_VERB_VBIT) == dqrr->vbit) {
144044 + dqrr->pi = (dqrr->pi + 1) & (QM_DQRR_SIZE - 1);
144045 + if (!dqrr->pi)
144046 + dqrr->vbit ^= QM_DQRR_VERB_VBIT;
144047 + dqrr->fill++;
144048 + }
144049 +}
144050 +
144051 +
144052 +static inline void qm_dqrr_cci_consume_to_current(struct qm_portal *portal)
144053 +{
144054 + register struct qm_dqrr *dqrr = &portal->dqrr;
144055 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cci);
144056 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
144057 + qm_out(DQRR_CI_CINH, dqrr->ci);
144058 +}
144059 +
144060 +static inline void qm_dqrr_cce_prefetch(struct qm_portal *portal)
144061 +{
144062 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
144063 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
144064 + qm_cl_invalidate(DQRR_CI);
144065 + qm_cl_touch_rw(DQRR_CI);
144066 +}
144067 +
144068 +static inline void qm_dqrr_cce_consume_to_current(struct qm_portal *portal)
144069 +{
144070 + register struct qm_dqrr *dqrr = &portal->dqrr;
144071 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cce);
144072 + dqrr->ci = DQRR_PTR2IDX(dqrr->cursor);
144073 + qm_cl_out(DQRR_CI, dqrr->ci);
144074 +}
144075 +
144076 +static inline void qm_dqrr_cdc_consume_1(struct qm_portal *portal, u8 idx,
144077 + int park)
144078 +{
144079 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
144080 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
144081 + DPA_ASSERT(idx < QM_DQRR_SIZE);
144082 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
144083 + ((park ? 1 : 0) << 6) | /* PK */
144084 + idx); /* DCAP_CI */
144085 +}
144086 +
144087 +static inline void qm_dqrr_cdc_consume_1ptr(struct qm_portal *portal,
144088 + const struct qm_dqrr_entry *dq,
144089 + int park)
144090 +{
144091 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
144092 + u8 idx = DQRR_PTR2IDX(dq);
144093 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
144094 + DPA_ASSERT((dqrr->ring + idx) == dq);
144095 + DPA_ASSERT(idx < QM_DQRR_SIZE);
144096 + qm_out(DQRR_DCAP, (0 << 8) | /* DQRR_DCAP::S */
144097 + ((park ? 1 : 0) << 6) | /* DQRR_DCAP::PK */
144098 + idx); /* DQRR_DCAP::DCAP_CI */
144099 +}
144100 +
144101 +static inline u8 qm_dqrr_cdc_cci(struct qm_portal *portal)
144102 +{
144103 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
144104 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
144105 + return qm_in(DQRR_CI_CINH) & (QM_DQRR_SIZE - 1);
144106 +}
144107 +
144108 +static inline void qm_dqrr_cdc_cce_prefetch(struct qm_portal *portal)
144109 +{
144110 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
144111 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
144112 + qm_cl_invalidate(DQRR_CI);
144113 + qm_cl_touch_ro(DQRR_CI);
144114 +}
144115 +
144116 +static inline u8 qm_dqrr_cdc_cce(struct qm_portal *portal)
144117 +{
144118 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
144119 + DPA_ASSERT(dqrr->cmode == qm_dqrr_cdc);
144120 + return qm_cl_in(DQRR_CI) & (QM_DQRR_SIZE - 1);
144121 +}
144122 +
144123 +static inline u8 qm_dqrr_get_ci(struct qm_portal *portal)
144124 +{
144125 + register struct qm_dqrr *dqrr = &portal->dqrr;
144126 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
144127 + return dqrr->ci;
144128 +}
144129 +
144130 +static inline void qm_dqrr_park(struct qm_portal *portal, u8 idx)
144131 +{
144132 + __maybe_unused register struct qm_dqrr *dqrr = &portal->dqrr;
144133 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
144134 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
144135 + (1 << 6) | /* PK */
144136 + (idx & (QM_DQRR_SIZE - 1))); /* DCAP_CI */
144137 +}
144138 +
144139 +static inline void qm_dqrr_park_current(struct qm_portal *portal)
144140 +{
144141 + register struct qm_dqrr *dqrr = &portal->dqrr;
144142 + DPA_ASSERT(dqrr->cmode != qm_dqrr_cdc);
144143 + qm_out(DQRR_DCAP, (0 << 8) | /* S */
144144 + (1 << 6) | /* PK */
144145 + DQRR_PTR2IDX(dqrr->cursor)); /* DCAP_CI */
144146 +}
144147 +
144148 +static inline void qm_dqrr_sdqcr_set(struct qm_portal *portal, u32 sdqcr)
144149 +{
144150 + qm_out(DQRR_SDQCR, sdqcr);
144151 +}
144152 +
144153 +static inline u32 qm_dqrr_sdqcr_get(struct qm_portal *portal)
144154 +{
144155 + return qm_in(DQRR_SDQCR);
144156 +}
144157 +
144158 +static inline void qm_dqrr_vdqcr_set(struct qm_portal *portal, u32 vdqcr)
144159 +{
144160 + qm_out(DQRR_VDQCR, vdqcr);
144161 +}
144162 +
144163 +static inline u32 qm_dqrr_vdqcr_get(struct qm_portal *portal)
144164 +{
144165 + return qm_in(DQRR_VDQCR);
144166 +}
144167 +
144168 +static inline void qm_dqrr_pdqcr_set(struct qm_portal *portal, u32 pdqcr)
144169 +{
144170 + qm_out(DQRR_PDQCR, pdqcr);
144171 +}
144172 +
144173 +static inline u32 qm_dqrr_pdqcr_get(struct qm_portal *portal)
144174 +{
144175 + return qm_in(DQRR_PDQCR);
144176 +}
144177 +
144178 +static inline u8 qm_dqrr_get_ithresh(struct qm_portal *portal)
144179 +{
144180 + register struct qm_dqrr *dqrr = &portal->dqrr;
144181 + return dqrr->ithresh;
144182 +}
144183 +
144184 +static inline void qm_dqrr_set_ithresh(struct qm_portal *portal, u8 ithresh)
144185 +{
144186 + qm_out(DQRR_ITR, ithresh);
144187 +}
144188 +
144189 +static inline u8 qm_dqrr_get_maxfill(struct qm_portal *portal)
144190 +{
144191 + return (qm_in(CFG) & 0x00f00000) >> 20;
144192 +}
144193 +
144194 +
144195 +/* -------------- */
144196 +/* --- MR API --- */
144197 +
144198 +#define MR_CARRYCLEAR(p) \
144199 + (void *)((unsigned long)(p) & (~(unsigned long)(QM_MR_SIZE << 6)))
144200 +
144201 +static inline u8 MR_PTR2IDX(const struct qm_mr_entry *e)
144202 +{
144203 + return ((uintptr_t)e >> 6) & (QM_MR_SIZE - 1);
144204 +}
144205 +
144206 +static inline const struct qm_mr_entry *MR_INC(const struct qm_mr_entry *e)
144207 +{
144208 + return MR_CARRYCLEAR(e + 1);
144209 +}
144210 +
144211 +static inline int qm_mr_init(struct qm_portal *portal, enum qm_mr_pmode pmode,
144212 + enum qm_mr_cmode cmode)
144213 +{
144214 + register struct qm_mr *mr = &portal->mr;
144215 + u32 cfg;
144216 +
144217 + mr->ring = portal->addr.addr_ce + QM_CL_MR;
144218 + mr->pi = qm_in(MR_PI_CINH) & (QM_MR_SIZE - 1);
144219 + mr->ci = qm_in(MR_CI_CINH) & (QM_MR_SIZE - 1);
144220 + mr->cursor = mr->ring + mr->ci;
144221 + mr->fill = qm_cyc_diff(QM_MR_SIZE, mr->ci, mr->pi);
144222 + mr->vbit = (qm_in(MR_PI_CINH) & QM_MR_SIZE) ? QM_MR_VERB_VBIT : 0;
144223 + mr->ithresh = qm_in(MR_ITR);
144224 +#ifdef CONFIG_FSL_DPA_CHECKING
144225 + mr->pmode = pmode;
144226 + mr->cmode = cmode;
144227 +#endif
144228 + cfg = (qm_in(CFG) & 0xfffff0ff) |
144229 + ((cmode & 1) << 8); /* QCSP_CFG:MM */
144230 + qm_out(CFG, cfg);
144231 + return 0;
144232 +}
144233 +
144234 +static inline void qm_mr_finish(struct qm_portal *portal)
144235 +{
144236 + register struct qm_mr *mr = &portal->mr;
144237 + if (mr->ci != MR_PTR2IDX(mr->cursor))
144238 + pr_crit("Ignoring completed MR entries\n");
144239 +}
144240 +
144241 +static inline const struct qm_mr_entry *qm_mr_current(struct qm_portal *portal)
144242 +{
144243 + register struct qm_mr *mr = &portal->mr;
144244 + if (!mr->fill)
144245 + return NULL;
144246 + return mr->cursor;
144247 +}
144248 +
144249 +static inline u8 qm_mr_cursor(struct qm_portal *portal)
144250 +{
144251 + register struct qm_mr *mr = &portal->mr;
144252 + return MR_PTR2IDX(mr->cursor);
144253 +}
144254 +
144255 +static inline u8 qm_mr_next(struct qm_portal *portal)
144256 +{
144257 + register struct qm_mr *mr = &portal->mr;
144258 + DPA_ASSERT(mr->fill);
144259 + mr->cursor = MR_INC(mr->cursor);
144260 + return --mr->fill;
144261 +}
144262 +
144263 +static inline u8 qm_mr_pci_update(struct qm_portal *portal)
144264 +{
144265 + register struct qm_mr *mr = &portal->mr;
144266 + u8 diff, old_pi = mr->pi;
144267 + DPA_ASSERT(mr->pmode == qm_mr_pci);
144268 + mr->pi = qm_in(MR_PI_CINH);
144269 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
144270 + mr->fill += diff;
144271 + return diff;
144272 +}
144273 +
144274 +static inline void qm_mr_pce_prefetch(struct qm_portal *portal)
144275 +{
144276 + __maybe_unused register struct qm_mr *mr = &portal->mr;
144277 + DPA_ASSERT(mr->pmode == qm_mr_pce);
144278 + qm_cl_invalidate(MR_PI);
144279 + qm_cl_touch_ro(MR_PI);
144280 +}
144281 +
144282 +static inline u8 qm_mr_pce_update(struct qm_portal *portal)
144283 +{
144284 + register struct qm_mr *mr = &portal->mr;
144285 + u8 diff, old_pi = mr->pi;
144286 + DPA_ASSERT(mr->pmode == qm_mr_pce);
144287 + mr->pi = qm_cl_in(MR_PI) & (QM_MR_SIZE - 1);
144288 + diff = qm_cyc_diff(QM_MR_SIZE, old_pi, mr->pi);
144289 + mr->fill += diff;
144290 + return diff;
144291 +}
144292 +
144293 +static inline void qm_mr_pvb_update(struct qm_portal *portal)
144294 +{
144295 + register struct qm_mr *mr = &portal->mr;
144296 + const struct qm_mr_entry *res = qm_cl(mr->ring, mr->pi);
144297 + DPA_ASSERT(mr->pmode == qm_mr_pvb);
144298 + /* when accessing 'verb', use __raw_readb() to ensure that compiler
144299 + * inlining doesn't try to optimise out "excess reads". */
144300 + if ((__raw_readb(&res->verb) & QM_MR_VERB_VBIT) == mr->vbit) {
144301 + mr->pi = (mr->pi + 1) & (QM_MR_SIZE - 1);
144302 + if (!mr->pi)
144303 + mr->vbit ^= QM_MR_VERB_VBIT;
144304 + mr->fill++;
144305 + res = MR_INC(res);
144306 + }
144307 + dcbit_ro(res);
144308 +}
144309 +
144310 +static inline void qm_mr_cci_consume(struct qm_portal *portal, u8 num)
144311 +{
144312 + register struct qm_mr *mr = &portal->mr;
144313 + DPA_ASSERT(mr->cmode == qm_mr_cci);
144314 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
144315 + qm_out(MR_CI_CINH, mr->ci);
144316 +}
144317 +
144318 +static inline void qm_mr_cci_consume_to_current(struct qm_portal *portal)
144319 +{
144320 + register struct qm_mr *mr = &portal->mr;
144321 + DPA_ASSERT(mr->cmode == qm_mr_cci);
144322 + mr->ci = MR_PTR2IDX(mr->cursor);
144323 + qm_out(MR_CI_CINH, mr->ci);
144324 +}
144325 +
144326 +static inline void qm_mr_cce_prefetch(struct qm_portal *portal)
144327 +{
144328 + __maybe_unused register struct qm_mr *mr = &portal->mr;
144329 + DPA_ASSERT(mr->cmode == qm_mr_cce);
144330 + qm_cl_invalidate(MR_CI);
144331 + qm_cl_touch_rw(MR_CI);
144332 +}
144333 +
144334 +static inline void qm_mr_cce_consume(struct qm_portal *portal, u8 num)
144335 +{
144336 + register struct qm_mr *mr = &portal->mr;
144337 + DPA_ASSERT(mr->cmode == qm_mr_cce);
144338 + mr->ci = (mr->ci + num) & (QM_MR_SIZE - 1);
144339 + qm_cl_out(MR_CI, mr->ci);
144340 +}
144341 +
144342 +static inline void qm_mr_cce_consume_to_current(struct qm_portal *portal)
144343 +{
144344 + register struct qm_mr *mr = &portal->mr;
144345 + DPA_ASSERT(mr->cmode == qm_mr_cce);
144346 + mr->ci = MR_PTR2IDX(mr->cursor);
144347 + qm_cl_out(MR_CI, mr->ci);
144348 +}
144349 +
144350 +static inline u8 qm_mr_get_ci(struct qm_portal *portal)
144351 +{
144352 + register struct qm_mr *mr = &portal->mr;
144353 + return mr->ci;
144354 +}
144355 +
144356 +static inline u8 qm_mr_get_ithresh(struct qm_portal *portal)
144357 +{
144358 + register struct qm_mr *mr = &portal->mr;
144359 + return mr->ithresh;
144360 +}
144361 +
144362 +static inline void qm_mr_set_ithresh(struct qm_portal *portal, u8 ithresh)
144363 +{
144364 + qm_out(MR_ITR, ithresh);
144365 +}
144366 +
144367 +
144368 +/* ------------------------------ */
144369 +/* --- Management command API --- */
144370 +
144371 +static inline int qm_mc_init(struct qm_portal *portal)
144372 +{
144373 + u8 rr0, rr1;
144374 + register struct qm_mc *mc = &portal->mc;
144375 +
144376 + mc->cr = portal->addr.addr_ce + QM_CL_CR;
144377 + mc->rr = portal->addr.addr_ce + QM_CL_RR0;
144378 +
144379 + /*
144380 + * The expected valid bit polarity for the next CR command is 0
144381 + * if RR1 contains a valid response, and is 1 if RR0 contains a
144382 + * valid response. If both RR contain all 0, this indicates either
144383 + * that no command has been executed since reset (in which case the
144384 + * expected valid bit polarity is 1)
144385 + */
144386 + rr0 = __raw_readb(&mc->rr->verb);
144387 + rr1 = __raw_readb(&(mc->rr+1)->verb);
144388 + if ((rr0 == 0 && rr1 == 0) || rr0 != 0)
144389 + mc->rridx = 1;
144390 + else
144391 + mc->rridx = 0;
144392 +
144393 + mc->vbit = mc->rridx ? QM_MCC_VERB_VBIT : 0;
144394 +#ifdef CONFIG_FSL_DPA_CHECKING
144395 + mc->state = qman_mc_idle;
144396 +#endif
144397 + return 0;
144398 +}
144399 +
144400 +static inline void qm_mc_finish(struct qm_portal *portal)
144401 +{
144402 + __maybe_unused register struct qm_mc *mc = &portal->mc;
144403 + DPA_ASSERT(mc->state == qman_mc_idle);
144404 +#ifdef CONFIG_FSL_DPA_CHECKING
144405 + if (mc->state != qman_mc_idle)
144406 + pr_crit("Losing incomplete MC command\n");
144407 +#endif
144408 +}
144409 +
144410 +static inline struct qm_mc_command *qm_mc_start(struct qm_portal *portal)
144411 +{
144412 + register struct qm_mc *mc = &portal->mc;
144413 + DPA_ASSERT(mc->state == qman_mc_idle);
144414 +#ifdef CONFIG_FSL_DPA_CHECKING
144415 + mc->state = qman_mc_user;
144416 +#endif
144417 +#if defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
144418 + dcbz_64(mc->cr);
144419 +#endif
144420 + return mc->cr;
144421 +}
144422 +
144423 +static inline void qm_mc_abort(struct qm_portal *portal)
144424 +{
144425 + __maybe_unused register struct qm_mc *mc = &portal->mc;
144426 + DPA_ASSERT(mc->state == qman_mc_user);
144427 +#ifdef CONFIG_FSL_DPA_CHECKING
144428 + mc->state = qman_mc_idle;
144429 +#endif
144430 +}
144431 +
144432 +static inline void qm_mc_commit(struct qm_portal *portal, u8 myverb)
144433 +{
144434 + register struct qm_mc *mc = &portal->mc;
144435 + struct qm_mc_result *rr = mc->rr + mc->rridx;
144436 + DPA_ASSERT(mc->state == qman_mc_user);
144437 + lwsync();
144438 + mc->cr->__dont_write_directly__verb = myverb | mc->vbit;
144439 + dcbf(mc->cr);
144440 + dcbit_ro(rr);
144441 +#ifdef CONFIG_FSL_DPA_CHECKING
144442 + mc->state = qman_mc_hw;
144443 +#endif
144444 +}
144445 +
144446 +static inline struct qm_mc_result *qm_mc_result(struct qm_portal *portal)
144447 +{
144448 + register struct qm_mc *mc = &portal->mc;
144449 + struct qm_mc_result *rr = mc->rr + mc->rridx;
144450 + DPA_ASSERT(mc->state == qman_mc_hw);
144451 + /* The inactive response register's verb byte always returns zero until
144452 + * its command is submitted and completed. This includes the valid-bit,
144453 + * in case you were wondering... */
144454 + if (!__raw_readb(&rr->verb)) {
144455 + dcbit_ro(rr);
144456 + return NULL;
144457 + }
144458 + mc->rridx ^= 1;
144459 + mc->vbit ^= QM_MCC_VERB_VBIT;
144460 +#ifdef CONFIG_FSL_DPA_CHECKING
144461 + mc->state = qman_mc_idle;
144462 +#endif
144463 + return rr;
144464 +}
144465 +
144466 +
144467 +/* ------------------------------------- */
144468 +/* --- Portal interrupt register API --- */
144469 +
144470 +static inline int qm_isr_init(__always_unused struct qm_portal *portal)
144471 +{
144472 + return 0;
144473 +}
144474 +
144475 +static inline void qm_isr_finish(__always_unused struct qm_portal *portal)
144476 +{
144477 +}
144478 +
144479 +static inline void qm_isr_set_iperiod(struct qm_portal *portal, u16 iperiod)
144480 +{
144481 + qm_out(ITPR, iperiod);
144482 +}
144483 +
144484 +static inline u32 __qm_isr_read(struct qm_portal *portal, enum qm_isr_reg n)
144485 +{
144486 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
144487 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 6));
144488 +#else
144489 + return __qm_in(&portal->addr, QM_REG_ISR + (n << 2));
144490 +#endif
144491 +}
144492 +
144493 +static inline void __qm_isr_write(struct qm_portal *portal, enum qm_isr_reg n,
144494 + u32 val)
144495 +{
144496 +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
144497 + __qm_out(&portal->addr, QM_REG_ISR + (n << 6), val);
144498 +#else
144499 + __qm_out(&portal->addr, QM_REG_ISR + (n << 2), val);
144500 +#endif
144501 +}
144502 +
144503 +/* Cleanup FQs */
144504 +static inline int qm_shutdown_fq(struct qm_portal **portal, int portal_count,
144505 + u32 fqid)
144506 +{
144507 +
144508 + struct qm_mc_command *mcc;
144509 + struct qm_mc_result *mcr;
144510 + u8 state;
144511 + int orl_empty, fq_empty, i, drain = 0;
144512 + u32 result;
144513 + u32 channel, wq;
144514 + u16 dest_wq;
144515 +
144516 + /* Determine the state of the FQID */
144517 + mcc = qm_mc_start(portal[0]);
144518 + mcc->queryfq_np.fqid = cpu_to_be32(fqid);
144519 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ_NP);
144520 + while (!(mcr = qm_mc_result(portal[0])))
144521 + cpu_relax();
144522 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ_NP);
144523 + state = mcr->queryfq_np.state & QM_MCR_NP_STATE_MASK;
144524 + if (state == QM_MCR_NP_STATE_OOS)
144525 + return 0; /* Already OOS, no need to do anymore checks */
144526 +
144527 + /* Query which channel the FQ is using */
144528 + mcc = qm_mc_start(portal[0]);
144529 + mcc->queryfq.fqid = cpu_to_be32(fqid);
144530 + qm_mc_commit(portal[0], QM_MCC_VERB_QUERYFQ);
144531 + while (!(mcr = qm_mc_result(portal[0])))
144532 + cpu_relax();
144533 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) == QM_MCR_VERB_QUERYFQ);
144534 +
144535 + /* Need to store these since the MCR gets reused */
144536 + dest_wq = be16_to_cpu(mcr->queryfq.fqd.dest_wq);
144537 + wq = dest_wq & 0x7;
144538 + channel = dest_wq>>3;
144539 +
144540 + switch (state) {
144541 + case QM_MCR_NP_STATE_TEN_SCHED:
144542 + case QM_MCR_NP_STATE_TRU_SCHED:
144543 + case QM_MCR_NP_STATE_ACTIVE:
144544 + case QM_MCR_NP_STATE_PARKED:
144545 + orl_empty = 0;
144546 + mcc = qm_mc_start(portal[0]);
144547 + mcc->alterfq.fqid = cpu_to_be32(fqid);
144548 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_RETIRE);
144549 + while (!(mcr = qm_mc_result(portal[0])))
144550 + cpu_relax();
144551 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
144552 + QM_MCR_VERB_ALTER_RETIRE);
144553 + result = mcr->result; /* Make a copy as we reuse MCR below */
144554 +
144555 + if (result == QM_MCR_RESULT_PENDING) {
144556 + /* Need to wait for the FQRN in the message ring, which
144557 + will only occur once the FQ has been drained. In
144558 + order for the FQ to drain the portal needs to be set
144559 + to dequeue from the channel the FQ is scheduled on */
144560 + const struct qm_mr_entry *msg;
144561 + const struct qm_dqrr_entry *dqrr = NULL;
144562 + int found_fqrn = 0;
144563 + u16 dequeue_wq = 0;
144564 +
144565 + /* Flag that we need to drain FQ */
144566 + drain = 1;
144567 +
144568 + if (channel >= qm_channel_pool1 &&
144569 + channel < (qm_channel_pool1 + 15)) {
144570 + /* Pool channel, enable the bit in the portal */
144571 + dequeue_wq = (channel -
144572 + qm_channel_pool1 + 1)<<4 | wq;
144573 + } else if (channel < qm_channel_pool1) {
144574 + /* Dedicated channel */
144575 + dequeue_wq = wq;
144576 + } else {
144577 + pr_info("Cannot recover FQ 0x%x, it is "
144578 + "scheduled on channel 0x%x",
144579 + fqid, channel);
144580 + return -EBUSY;
144581 + }
144582 + /* Set the sdqcr to drain this channel */
144583 + if (channel < qm_channel_pool1)
144584 + for (i = 0; i < portal_count; i++)
144585 + qm_dqrr_sdqcr_set(portal[i],
144586 + QM_SDQCR_TYPE_ACTIVE |
144587 + QM_SDQCR_CHANNELS_DEDICATED);
144588 + else
144589 + for (i = 0; i < portal_count; i++)
144590 + qm_dqrr_sdqcr_set(
144591 + portal[i],
144592 + QM_SDQCR_TYPE_ACTIVE |
144593 + QM_SDQCR_CHANNELS_POOL_CONV
144594 + (channel));
144595 + while (!found_fqrn) {
144596 + /* Keep draining DQRR while checking the MR*/
144597 + for (i = 0; i < portal_count; i++) {
144598 + qm_dqrr_pvb_update(portal[i]);
144599 + dqrr = qm_dqrr_current(portal[i]);
144600 + while (dqrr) {
144601 + qm_dqrr_cdc_consume_1ptr(
144602 + portal[i], dqrr, 0);
144603 + qm_dqrr_pvb_update(portal[i]);
144604 + qm_dqrr_next(portal[i]);
144605 + dqrr = qm_dqrr_current(
144606 + portal[i]);
144607 + }
144608 + /* Process message ring too */
144609 + qm_mr_pvb_update(portal[i]);
144610 + msg = qm_mr_current(portal[i]);
144611 + while (msg) {
144612 + if ((msg->verb &
144613 + QM_MR_VERB_TYPE_MASK)
144614 + == QM_MR_VERB_FQRN)
144615 + found_fqrn = 1;
144616 + qm_mr_next(portal[i]);
144617 + qm_mr_cci_consume_to_current(
144618 + portal[i]);
144619 + qm_mr_pvb_update(portal[i]);
144620 + msg = qm_mr_current(portal[i]);
144621 + }
144622 + cpu_relax();
144623 + }
144624 + }
144625 + }
144626 + if (result != QM_MCR_RESULT_OK &&
144627 + result != QM_MCR_RESULT_PENDING) {
144628 + /* error */
144629 + pr_err("qman_retire_fq failed on FQ 0x%x, result=0x%x\n",
144630 + fqid, result);
144631 + return -1;
144632 + }
144633 + if (!(mcr->alterfq.fqs & QM_MCR_FQS_ORLPRESENT)) {
144634 + /* ORL had no entries, no need to wait until the
144635 + ERNs come in */
144636 + orl_empty = 1;
144637 + }
144638 + /* Retirement succeeded, check to see if FQ needs
144639 + to be drained */
144640 + if (drain || mcr->alterfq.fqs & QM_MCR_FQS_NOTEMPTY) {
144641 + /* FQ is Not Empty, drain using volatile DQ commands */
144642 + fq_empty = 0;
144643 + do {
144644 + const struct qm_dqrr_entry *dqrr = NULL;
144645 + u32 vdqcr = fqid | QM_VDQCR_NUMFRAMES_SET(3);
144646 + qm_dqrr_vdqcr_set(portal[0], vdqcr);
144647 +
144648 + /* Wait for a dequeue to occur */
144649 + while (dqrr == NULL) {
144650 + qm_dqrr_pvb_update(portal[0]);
144651 + dqrr = qm_dqrr_current(portal[0]);
144652 + if (!dqrr)
144653 + cpu_relax();
144654 + }
144655 + /* Process the dequeues, making sure to
144656 + empty the ring completely */
144657 + while (dqrr) {
144658 + if (be32_to_cpu(dqrr->fqid) == fqid &&
144659 + dqrr->stat & QM_DQRR_STAT_FQ_EMPTY)
144660 + fq_empty = 1;
144661 + qm_dqrr_cdc_consume_1ptr(portal[0],
144662 + dqrr, 0);
144663 + qm_dqrr_pvb_update(portal[0]);
144664 + qm_dqrr_next(portal[0]);
144665 + dqrr = qm_dqrr_current(portal[0]);
144666 + }
144667 + } while (fq_empty == 0);
144668 + }
144669 + for (i = 0; i < portal_count; i++)
144670 + qm_dqrr_sdqcr_set(portal[i], 0);
144671 +
144672 + /* Wait for the ORL to have been completely drained */
144673 + while (orl_empty == 0) {
144674 + const struct qm_mr_entry *msg;
144675 + qm_mr_pvb_update(portal[0]);
144676 + msg = qm_mr_current(portal[0]);
144677 + while (msg) {
144678 + if ((msg->verb & QM_MR_VERB_TYPE_MASK) ==
144679 + QM_MR_VERB_FQRL)
144680 + orl_empty = 1;
144681 + qm_mr_next(portal[0]);
144682 + qm_mr_cci_consume_to_current(portal[0]);
144683 + qm_mr_pvb_update(portal[0]);
144684 + msg = qm_mr_current(portal[0]);
144685 + }
144686 + cpu_relax();
144687 + }
144688 + mcc = qm_mc_start(portal[0]);
144689 + mcc->alterfq.fqid = cpu_to_be32(fqid);
144690 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
144691 + while (!(mcr = qm_mc_result(portal[0])))
144692 + cpu_relax();
144693 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
144694 + QM_MCR_VERB_ALTER_OOS);
144695 + if (mcr->result != QM_MCR_RESULT_OK) {
144696 + pr_err("OOS after drain Failed on FQID 0x%x, result 0x%x\n",
144697 + fqid, mcr->result);
144698 + return -1;
144699 + }
144700 + return 0;
144701 + case QM_MCR_NP_STATE_RETIRED:
144702 + /* Send OOS Command */
144703 + mcc = qm_mc_start(portal[0]);
144704 + mcc->alterfq.fqid = cpu_to_be32(fqid);
144705 + qm_mc_commit(portal[0], QM_MCC_VERB_ALTER_OOS);
144706 + while (!(mcr = qm_mc_result(portal[0])))
144707 + cpu_relax();
144708 + DPA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
144709 + QM_MCR_VERB_ALTER_OOS);
144710 + if (mcr->result) {
144711 + pr_err("OOS Failed on FQID 0x%x\n", fqid);
144712 + return -1;
144713 + }
144714 + return 0;
144715 + }
144716 + return -1;
144717 +}
144718 --- /dev/null
144719 +++ b/drivers/staging/fsl_qbman/qman_private.h
144720 @@ -0,0 +1,398 @@
144721 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
144722 + *
144723 + * Redistribution and use in source and binary forms, with or without
144724 + * modification, are permitted provided that the following conditions are met:
144725 + * * Redistributions of source code must retain the above copyright
144726 + * notice, this list of conditions and the following disclaimer.
144727 + * * Redistributions in binary form must reproduce the above copyright
144728 + * notice, this list of conditions and the following disclaimer in the
144729 + * documentation and/or other materials provided with the distribution.
144730 + * * Neither the name of Freescale Semiconductor nor the
144731 + * names of its contributors may be used to endorse or promote products
144732 + * derived from this software without specific prior written permission.
144733 + *
144734 + *
144735 + * ALTERNATIVELY, this software may be distributed under the terms of the
144736 + * GNU General Public License ("GPL") as published by the Free Software
144737 + * Foundation, either version 2 of that License or (at your option) any
144738 + * later version.
144739 + *
144740 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
144741 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
144742 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
144743 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
144744 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
144745 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
144746 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
144747 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
144748 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
144749 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
144750 + */
144751 +
144752 +#include "dpa_sys.h"
144753 +#include <linux/fsl_qman.h>
144754 +#include <linux/iommu.h>
144755 +
144756 +#if defined(CONFIG_FSL_PAMU)
144757 +#include <asm/fsl_pamu_stash.h>
144758 +#endif
144759 +
144760 +#if !defined(CONFIG_FSL_QMAN_FQ_LOOKUP) && defined(CONFIG_PPC64)
144761 +#error "_PPC64 requires _FSL_QMAN_FQ_LOOKUP"
144762 +#endif
144763 +
144764 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
144765 + /* ----------------- */
144766 + /* Congestion Groups */
144767 + /* ----------------- */
144768 +/* This wrapper represents a bit-array for the state of the 256 Qman congestion
144769 + * groups. Is also used as a *mask* for congestion groups, eg. so we ignore
144770 + * those that don't concern us. We harness the structure and accessor details
144771 + * already used in the management command to query congestion groups. */
144772 +struct qman_cgrs {
144773 + struct __qm_mcr_querycongestion q;
144774 +};
144775 +static inline void qman_cgrs_init(struct qman_cgrs *c)
144776 +{
144777 + memset(c, 0, sizeof(*c));
144778 +}
144779 +static inline void qman_cgrs_fill(struct qman_cgrs *c)
144780 +{
144781 + memset(c, 0xff, sizeof(*c));
144782 +}
144783 +static inline int qman_cgrs_get(struct qman_cgrs *c, int num)
144784 +{
144785 + return QM_MCR_QUERYCONGESTION(&c->q, num);
144786 +}
144787 +static inline void qman_cgrs_set(struct qman_cgrs *c, int num)
144788 +{
144789 + c->q.__state[__CGR_WORD(num)] |= (0x80000000 >> __CGR_SHIFT(num));
144790 +}
144791 +static inline void qman_cgrs_unset(struct qman_cgrs *c, int num)
144792 +{
144793 + c->q.__state[__CGR_WORD(num)] &= ~(0x80000000 >> __CGR_SHIFT(num));
144794 +}
144795 +static inline int qman_cgrs_next(struct qman_cgrs *c, int num)
144796 +{
144797 + while ((++num < __CGR_NUM) && !qman_cgrs_get(c, num))
144798 + ;
144799 + return num;
144800 +}
144801 +static inline void qman_cgrs_cp(struct qman_cgrs *dest,
144802 + const struct qman_cgrs *src)
144803 +{
144804 + *dest = *src;
144805 +}
144806 +static inline void qman_cgrs_and(struct qman_cgrs *dest,
144807 + const struct qman_cgrs *a, const struct qman_cgrs *b)
144808 +{
144809 + int ret;
144810 + u32 *_d = dest->q.__state;
144811 + const u32 *_a = a->q.__state;
144812 + const u32 *_b = b->q.__state;
144813 + for (ret = 0; ret < 8; ret++)
144814 + *(_d++) = *(_a++) & *(_b++);
144815 +}
144816 +static inline void qman_cgrs_xor(struct qman_cgrs *dest,
144817 + const struct qman_cgrs *a, const struct qman_cgrs *b)
144818 +{
144819 + int ret;
144820 + u32 *_d = dest->q.__state;
144821 + const u32 *_a = a->q.__state;
144822 + const u32 *_b = b->q.__state;
144823 + for (ret = 0; ret < 8; ret++)
144824 + *(_d++) = *(_a++) ^ *(_b++);
144825 +}
144826 +
144827 + /* ----------------------- */
144828 + /* CEETM Congestion Groups */
144829 + /* ----------------------- */
144830 +/* This wrapper represents a bit-array for the state of the 512 Qman CEETM
144831 + * congestion groups.
144832 + */
144833 +struct qman_ccgrs {
144834 + struct __qm_mcr_querycongestion q[2];
144835 +};
144836 +static inline void qman_ccgrs_init(struct qman_ccgrs *c)
144837 +{
144838 + memset(c, 0, sizeof(*c));
144839 +}
144840 +static inline void qman_ccgrs_fill(struct qman_ccgrs *c)
144841 +{
144842 + memset(c, 0xff, sizeof(*c));
144843 +}
144844 +static inline int qman_ccgrs_get(struct qman_ccgrs *c, int num)
144845 +{
144846 + if (num < __CGR_NUM)
144847 + return QM_MCR_QUERYCONGESTION(&c->q[0], num);
144848 + else
144849 + return QM_MCR_QUERYCONGESTION(&c->q[1], (num - __CGR_NUM));
144850 +}
144851 +static inline int qman_ccgrs_next(struct qman_ccgrs *c, int num)
144852 +{
144853 + while ((++num < __CGR_NUM) && !qman_ccgrs_get(c, num))
144854 + ;
144855 + return num;
144856 +}
144857 +static inline void qman_ccgrs_cp(struct qman_ccgrs *dest,
144858 + const struct qman_ccgrs *src)
144859 +{
144860 + *dest = *src;
144861 +}
144862 +static inline void qman_ccgrs_and(struct qman_ccgrs *dest,
144863 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
144864 +{
144865 + int ret, i;
144866 + u32 *_d;
144867 + const u32 *_a, *_b;
144868 + for (i = 0; i < 2; i++) {
144869 + _d = dest->q[i].__state;
144870 + _a = a->q[i].__state;
144871 + _b = b->q[i].__state;
144872 + for (ret = 0; ret < 8; ret++)
144873 + *(_d++) = *(_a++) & *(_b++);
144874 + }
144875 +}
144876 +static inline void qman_ccgrs_xor(struct qman_ccgrs *dest,
144877 + const struct qman_ccgrs *a, const struct qman_ccgrs *b)
144878 +{
144879 + int ret, i;
144880 + u32 *_d;
144881 + const u32 *_a, *_b;
144882 + for (i = 0; i < 2; i++) {
144883 + _d = dest->q[i].__state;
144884 + _a = a->q[i].__state;
144885 + _b = b->q[i].__state;
144886 + for (ret = 0; ret < 8; ret++)
144887 + *(_d++) = *(_a++) ^ *(_b++);
144888 + }
144889 +}
144890 +
144891 +/* used by CCSR and portal interrupt code */
144892 +enum qm_isr_reg {
144893 + qm_isr_status = 0,
144894 + qm_isr_enable = 1,
144895 + qm_isr_disable = 2,
144896 + qm_isr_inhibit = 3
144897 +};
144898 +
144899 +struct qm_portal_config {
144900 + /* Corenet portal addresses;
144901 + * [0]==cache-enabled, [1]==cache-inhibited. */
144902 + __iomem void *addr_virt[2];
144903 + struct resource addr_phys[2];
144904 + struct device dev;
144905 + struct iommu_domain *iommu_domain;
144906 + /* Allow these to be joined in lists */
144907 + struct list_head list;
144908 + /* User-visible portal configuration settings */
144909 + struct qman_portal_config public_cfg;
144910 + /* power management saved data */
144911 + u32 saved_isdr;
144912 +};
144913 +
144914 +/* Revision info (for errata and feature handling) */
144915 +#define QMAN_REV11 0x0101
144916 +#define QMAN_REV12 0x0102
144917 +#define QMAN_REV20 0x0200
144918 +#define QMAN_REV30 0x0300
144919 +#define QMAN_REV31 0x0301
144920 +#define QMAN_REV32 0x0302
144921 +
144922 +/* QMan REV_2 register contains the Cfg option */
144923 +#define QMAN_REV_CFG_0 0x0
144924 +#define QMAN_REV_CFG_1 0x1
144925 +#define QMAN_REV_CFG_2 0x2
144926 +#define QMAN_REV_CFG_3 0x3
144927 +
144928 +extern u16 qman_ip_rev; /* 0 if uninitialised, otherwise QMAN_REVx */
144929 +extern u8 qman_ip_cfg;
144930 +extern u32 qman_clk;
144931 +extern u16 qman_portal_max;
144932 +
144933 +#ifdef CONFIG_FSL_QMAN_CONFIG
144934 +/* Hooks from qman_driver.c to qman_config.c */
144935 +int qman_init_ccsr(struct device_node *node);
144936 +void qman_liodn_fixup(u16 channel);
144937 +int qman_set_sdest(u16 channel, unsigned int cpu_idx);
144938 +size_t get_qman_fqd_size(void);
144939 +#else
144940 +static inline size_t get_qman_fqd_size(void)
144941 +{
144942 + return (PAGE_SIZE << CONFIG_FSL_QMAN_FQD_SZ);
144943 +}
144944 +#endif
144945 +
144946 +int qm_set_wpm(int wpm);
144947 +int qm_get_wpm(int *wpm);
144948 +
144949 +/* Hooks from qman_driver.c in to qman_high.c */
144950 +struct qman_portal *qman_create_portal(
144951 + struct qman_portal *portal,
144952 + const struct qm_portal_config *config,
144953 + const struct qman_cgrs *cgrs);
144954 +
144955 +struct qman_portal *qman_create_affine_portal(
144956 + const struct qm_portal_config *config,
144957 + const struct qman_cgrs *cgrs);
144958 +struct qman_portal *qman_create_affine_slave(struct qman_portal *redirect,
144959 + int cpu);
144960 +const struct qm_portal_config *qman_destroy_affine_portal(void);
144961 +void qman_destroy_portal(struct qman_portal *qm);
144962 +
144963 +/* Hooks from fsl_usdpaa.c to qman_driver.c */
144964 +struct qm_portal_config *qm_get_unused_portal(void);
144965 +struct qm_portal_config *qm_get_unused_portal_idx(uint32_t idx);
144966 +
144967 +void qm_put_unused_portal(struct qm_portal_config *pcfg);
144968 +void qm_set_liodns(struct qm_portal_config *pcfg);
144969 +
144970 +/* This CGR feature is supported by h/w and required by unit-tests and the
144971 + * debugfs hooks, so is implemented in the driver. However it allows an explicit
144972 + * corruption of h/w fields by s/w that are usually incorruptible (because the
144973 + * counters are usually maintained entirely within h/w). As such, we declare
144974 + * this API internally. */
144975 +int qman_testwrite_cgr(struct qman_cgr *cgr, u64 i_bcnt,
144976 + struct qm_mcr_cgrtestwrite *result);
144977 +
144978 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
144979 +/* If the fq object pointer is greater than the size of context_b field,
144980 + * than a lookup table is required. */
144981 +int qman_setup_fq_lookup_table(size_t num_entries);
144982 +#endif
144983 +
144984 +
144985 +/*************************************************/
144986 +/* QMan s/w corenet portal, low-level i/face */
144987 +/*************************************************/
144988 +
144989 +/* Note: most functions are only used by the high-level interface, so are
144990 + * inlined from qman_low.h. The stuff below is for use by other parts of the
144991 + * driver. */
144992 +
144993 +/* For qm_dqrr_sdqcr_set(); Choose one SOURCE. Choose one COUNT. Choose one
144994 + * dequeue TYPE. Choose TOKEN (8-bit).
144995 + * If SOURCE == CHANNELS,
144996 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL(n).
144997 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
144998 + * priority.
144999 + * If SOURCE == SPECIFICWQ,
145000 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
145001 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
145002 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
145003 + * same value.
145004 + */
145005 +#define QM_SDQCR_SOURCE_CHANNELS 0x0
145006 +#define QM_SDQCR_SOURCE_SPECIFICWQ 0x40000000
145007 +#define QM_SDQCR_COUNT_EXACT1 0x0
145008 +#define QM_SDQCR_COUNT_UPTO3 0x20000000
145009 +#define QM_SDQCR_DEDICATED_PRECEDENCE 0x10000000
145010 +#define QM_SDQCR_TYPE_MASK 0x03000000
145011 +#define QM_SDQCR_TYPE_NULL 0x0
145012 +#define QM_SDQCR_TYPE_PRIO_QOS 0x01000000
145013 +#define QM_SDQCR_TYPE_ACTIVE_QOS 0x02000000
145014 +#define QM_SDQCR_TYPE_ACTIVE 0x03000000
145015 +#define QM_SDQCR_TOKEN_MASK 0x00ff0000
145016 +#define QM_SDQCR_TOKEN_SET(v) (((v) & 0xff) << 16)
145017 +#define QM_SDQCR_TOKEN_GET(v) (((v) >> 16) & 0xff)
145018 +#define QM_SDQCR_CHANNELS_DEDICATED 0x00008000
145019 +#define QM_SDQCR_SPECIFICWQ_MASK 0x000000f7
145020 +#define QM_SDQCR_SPECIFICWQ_DEDICATED 0x00000000
145021 +#define QM_SDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
145022 +#define QM_SDQCR_SPECIFICWQ_WQ(n) (n)
145023 +
145024 +/* For qm_dqrr_vdqcr_set(): use FQID(n) to fill in the frame queue ID */
145025 +#define QM_VDQCR_FQID_MASK 0x00ffffff
145026 +#define QM_VDQCR_FQID(n) ((n) & QM_VDQCR_FQID_MASK)
145027 +
145028 +/* For qm_dqrr_pdqcr_set(); Choose one MODE. Choose one COUNT.
145029 + * If MODE==SCHEDULED
145030 + * Choose SCHEDULED_CHANNELS or SCHEDULED_SPECIFICWQ. Choose one dequeue TYPE.
145031 + * If CHANNELS,
145032 + * Choose CHANNELS_DEDICATED and/or CHANNELS_POOL() channels.
145033 + * You can choose DEDICATED_PRECEDENCE if the portal channel should have
145034 + * priority.
145035 + * If SPECIFICWQ,
145036 + * Either select the work-queue ID with SPECIFICWQ_WQ(), or select the
145037 + * channel (SPECIFICWQ_DEDICATED or SPECIFICWQ_POOL()) and specify the
145038 + * work-queue priority (0-7) with SPECIFICWQ_WQ() - either way, you get the
145039 + * same value.
145040 + * If MODE==UNSCHEDULED
145041 + * Choose FQID().
145042 + */
145043 +#define QM_PDQCR_MODE_SCHEDULED 0x0
145044 +#define QM_PDQCR_MODE_UNSCHEDULED 0x80000000
145045 +#define QM_PDQCR_SCHEDULED_CHANNELS 0x0
145046 +#define QM_PDQCR_SCHEDULED_SPECIFICWQ 0x40000000
145047 +#define QM_PDQCR_COUNT_EXACT1 0x0
145048 +#define QM_PDQCR_COUNT_UPTO3 0x20000000
145049 +#define QM_PDQCR_DEDICATED_PRECEDENCE 0x10000000
145050 +#define QM_PDQCR_TYPE_MASK 0x03000000
145051 +#define QM_PDQCR_TYPE_NULL 0x0
145052 +#define QM_PDQCR_TYPE_PRIO_QOS 0x01000000
145053 +#define QM_PDQCR_TYPE_ACTIVE_QOS 0x02000000
145054 +#define QM_PDQCR_TYPE_ACTIVE 0x03000000
145055 +#define QM_PDQCR_CHANNELS_DEDICATED 0x00008000
145056 +#define QM_PDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
145057 +#define QM_PDQCR_SPECIFICWQ_MASK 0x000000f7
145058 +#define QM_PDQCR_SPECIFICWQ_DEDICATED 0x00000000
145059 +#define QM_PDQCR_SPECIFICWQ_POOL(n) ((n) << 4)
145060 +#define QM_PDQCR_SPECIFICWQ_WQ(n) (n)
145061 +#define QM_PDQCR_FQID(n) ((n) & 0xffffff)
145062 +
145063 +/* Used by all portal interrupt registers except 'inhibit'
145064 + * Channels with frame availability
145065 + */
145066 +#define QM_PIRQ_DQAVAIL 0x0000ffff
145067 +
145068 +/* The DQAVAIL interrupt fields break down into these bits; */
145069 +#define QM_DQAVAIL_PORTAL 0x8000 /* Portal channel */
145070 +#define QM_DQAVAIL_POOL(n) (0x8000 >> (n)) /* Pool channel, n==[1..15] */
145071 +#define QM_DQAVAIL_MASK 0xffff
145072 +/* This mask contains all the "irqsource" bits visible to API users */
145073 +#define QM_PIRQ_VISIBLE (QM_PIRQ_SLOW | QM_PIRQ_DQRI)
145074 +
145075 +/* These are qm_<reg>_<verb>(). So for example, qm_disable_write() means "write
145076 + * the disable register" rather than "disable the ability to write". */
145077 +#define qm_isr_status_read(qm) __qm_isr_read(qm, qm_isr_status)
145078 +#define qm_isr_status_clear(qm, m) __qm_isr_write(qm, qm_isr_status, m)
145079 +#define qm_isr_enable_read(qm) __qm_isr_read(qm, qm_isr_enable)
145080 +#define qm_isr_enable_write(qm, v) __qm_isr_write(qm, qm_isr_enable, v)
145081 +#define qm_isr_disable_read(qm) __qm_isr_read(qm, qm_isr_disable)
145082 +#define qm_isr_disable_write(qm, v) __qm_isr_write(qm, qm_isr_disable, v)
145083 +/* TODO: unfortunate name-clash here, reword? */
145084 +#define qm_isr_inhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 1)
145085 +#define qm_isr_uninhibit(qm) __qm_isr_write(qm, qm_isr_inhibit, 0)
145086 +
145087 +#ifdef CONFIG_FSL_QMAN_CONFIG
145088 +int qman_have_ccsr(void);
145089 +#else
145090 +#define qman_have_ccsr 0
145091 +#endif
145092 +
145093 +__init int qman_init(void);
145094 +__init int qman_resource_init(void);
145095 +
145096 +/* CEETM related */
145097 +#define QMAN_CEETM_MAX 2
145098 +extern u8 num_ceetms;
145099 +extern struct qm_ceetm qman_ceetms[QMAN_CEETM_MAX];
145100 +int qman_sp_enable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
145101 +int qman_sp_disable_ceetm_mode(enum qm_dc_portal portal, u16 sub_portal);
145102 +int qman_ceetm_set_prescaler(enum qm_dc_portal portal);
145103 +int qman_ceetm_get_prescaler(u16 *pres);
145104 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
145105 + struct qm_mcr_ceetm_cq_query *cq_query);
145106 +int qman_ceetm_query_ccgr(struct qm_mcc_ceetm_ccgr_query *ccgr_query,
145107 + struct qm_mcr_ceetm_ccgr_query *response);
145108 +int qman_ceetm_get_xsfdr(enum qm_dc_portal portal, unsigned int *num);
145109 +
145110 +extern void *affine_portals[NR_CPUS];
145111 +const struct qm_portal_config *qman_get_qm_portal_config(
145112 + struct qman_portal *portal);
145113 +
145114 +/* power management */
145115 +#ifdef CONFIG_SUSPEND
145116 +void suspend_unused_qportal(void);
145117 +void resume_unused_qportal(void);
145118 +#endif
145119 --- /dev/null
145120 +++ b/drivers/staging/fsl_qbman/qman_test.c
145121 @@ -0,0 +1,57 @@
145122 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
145123 + *
145124 + * Redistribution and use in source and binary forms, with or without
145125 + * modification, are permitted provided that the following conditions are met:
145126 + * * Redistributions of source code must retain the above copyright
145127 + * notice, this list of conditions and the following disclaimer.
145128 + * * Redistributions in binary form must reproduce the above copyright
145129 + * notice, this list of conditions and the following disclaimer in the
145130 + * documentation and/or other materials provided with the distribution.
145131 + * * Neither the name of Freescale Semiconductor nor the
145132 + * names of its contributors may be used to endorse or promote products
145133 + * derived from this software without specific prior written permission.
145134 + *
145135 + *
145136 + * ALTERNATIVELY, this software may be distributed under the terms of the
145137 + * GNU General Public License ("GPL") as published by the Free Software
145138 + * Foundation, either version 2 of that License or (at your option) any
145139 + * later version.
145140 + *
145141 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145142 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145143 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145144 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145145 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145146 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145147 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145148 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145149 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145150 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145151 + */
145152 +
145153 +#include "qman_test.h"
145154 +
145155 +MODULE_AUTHOR("Geoff Thorpe");
145156 +MODULE_LICENSE("Dual BSD/GPL");
145157 +MODULE_DESCRIPTION("Qman testing");
145158 +
145159 +static int test_init(void)
145160 +{
145161 + int loop = 1;
145162 + while (loop--) {
145163 +#ifdef CONFIG_FSL_QMAN_TEST_STASH_POTATO
145164 + qman_test_hotpotato();
145165 +#endif
145166 +#ifdef CONFIG_FSL_QMAN_TEST_HIGH
145167 + qman_test_high();
145168 +#endif
145169 + }
145170 + return 0;
145171 +}
145172 +
145173 +static void test_exit(void)
145174 +{
145175 +}
145176 +
145177 +module_init(test_init);
145178 +module_exit(test_exit);
145179 --- /dev/null
145180 +++ b/drivers/staging/fsl_qbman/qman_test.h
145181 @@ -0,0 +1,45 @@
145182 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
145183 + *
145184 + * Redistribution and use in source and binary forms, with or without
145185 + * modification, are permitted provided that the following conditions are met:
145186 + * * Redistributions of source code must retain the above copyright
145187 + * notice, this list of conditions and the following disclaimer.
145188 + * * Redistributions in binary form must reproduce the above copyright
145189 + * notice, this list of conditions and the following disclaimer in the
145190 + * documentation and/or other materials provided with the distribution.
145191 + * * Neither the name of Freescale Semiconductor nor the
145192 + * names of its contributors may be used to endorse or promote products
145193 + * derived from this software without specific prior written permission.
145194 + *
145195 + *
145196 + * ALTERNATIVELY, this software may be distributed under the terms of the
145197 + * GNU General Public License ("GPL") as published by the Free Software
145198 + * Foundation, either version 2 of that License or (at your option) any
145199 + * later version.
145200 + *
145201 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145202 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145203 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145204 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145205 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145206 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145207 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145208 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145209 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145210 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145211 + */
145212 +
145213 +#include <linux/kernel.h>
145214 +#include <linux/errno.h>
145215 +#include <linux/io.h>
145216 +#include <linux/slab.h>
145217 +#include <linux/module.h>
145218 +#include <linux/interrupt.h>
145219 +#include <linux/delay.h>
145220 +#include <linux/sched.h>
145221 +
145222 +#include <linux/fsl_qman.h>
145223 +
145224 +void qman_test_hotpotato(void);
145225 +void qman_test_high(void);
145226 +
145227 --- /dev/null
145228 +++ b/drivers/staging/fsl_qbman/qman_test_high.c
145229 @@ -0,0 +1,216 @@
145230 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
145231 + *
145232 + * Redistribution and use in source and binary forms, with or without
145233 + * modification, are permitted provided that the following conditions are met:
145234 + * * Redistributions of source code must retain the above copyright
145235 + * notice, this list of conditions and the following disclaimer.
145236 + * * Redistributions in binary form must reproduce the above copyright
145237 + * notice, this list of conditions and the following disclaimer in the
145238 + * documentation and/or other materials provided with the distribution.
145239 + * * Neither the name of Freescale Semiconductor nor the
145240 + * names of its contributors may be used to endorse or promote products
145241 + * derived from this software without specific prior written permission.
145242 + *
145243 + *
145244 + * ALTERNATIVELY, this software may be distributed under the terms of the
145245 + * GNU General Public License ("GPL") as published by the Free Software
145246 + * Foundation, either version 2 of that License or (at your option) any
145247 + * later version.
145248 + *
145249 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145250 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145251 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145252 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145253 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145254 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145255 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145256 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145257 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145258 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145259 + */
145260 +
145261 +#include "qman_test.h"
145262 +
145263 +/*************/
145264 +/* constants */
145265 +/*************/
145266 +
145267 +#define CGR_ID 27
145268 +#define POOL_ID 2
145269 +#define FQ_FLAGS QMAN_FQ_FLAG_DYNAMIC_FQID
145270 +#define NUM_ENQUEUES 10
145271 +#define NUM_PARTIAL 4
145272 +#define PORTAL_SDQCR (QM_SDQCR_SOURCE_CHANNELS | \
145273 + QM_SDQCR_TYPE_PRIO_QOS | \
145274 + QM_SDQCR_TOKEN_SET(0x98) | \
145275 + QM_SDQCR_CHANNELS_DEDICATED | \
145276 + QM_SDQCR_CHANNELS_POOL(POOL_ID))
145277 +#define PORTAL_OPAQUE ((void *)0xf00dbeef)
145278 +#define VDQCR_FLAGS (QMAN_VOLATILE_FLAG_WAIT | QMAN_VOLATILE_FLAG_FINISH)
145279 +
145280 +/*************************************/
145281 +/* Predeclarations (eg. for fq_base) */
145282 +/*************************************/
145283 +
145284 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *,
145285 + struct qman_fq *,
145286 + const struct qm_dqrr_entry *);
145287 +static void cb_ern(struct qman_portal *, struct qman_fq *,
145288 + const struct qm_mr_entry *);
145289 +static void cb_fqs(struct qman_portal *, struct qman_fq *,
145290 + const struct qm_mr_entry *);
145291 +
145292 +/***************/
145293 +/* global vars */
145294 +/***************/
145295 +
145296 +static struct qm_fd fd, fd_dq;
145297 +static struct qman_fq fq_base = {
145298 + .cb.dqrr = cb_dqrr,
145299 + .cb.ern = cb_ern,
145300 + .cb.fqs = cb_fqs
145301 +};
145302 +static DECLARE_WAIT_QUEUE_HEAD(waitqueue);
145303 +static int retire_complete, sdqcr_complete;
145304 +
145305 +/**********************/
145306 +/* internal functions */
145307 +/**********************/
145308 +
145309 +/* Helpers for initialising and "incrementing" a frame descriptor */
145310 +static void fd_init(struct qm_fd *__fd)
145311 +{
145312 + qm_fd_addr_set64(__fd, 0xabdeadbeefLLU);
145313 + __fd->format = qm_fd_contig_big;
145314 + __fd->length29 = 0x0000ffff;
145315 + __fd->cmd = 0xfeedf00d;
145316 +}
145317 +
145318 +static void fd_inc(struct qm_fd *__fd)
145319 +{
145320 + u64 t = qm_fd_addr_get64(__fd);
145321 + int z = t >> 40;
145322 + t <<= 1;
145323 + if (z)
145324 + t |= 1;
145325 + qm_fd_addr_set64(__fd, t);
145326 + __fd->length29--;
145327 + __fd->cmd++;
145328 +}
145329 +
145330 +/* The only part of the 'fd' we can't memcmp() is the ppid */
145331 +static int fd_cmp(const struct qm_fd *a, const struct qm_fd *b)
145332 +{
145333 + int r = (qm_fd_addr_get64(a) == qm_fd_addr_get64(b)) ? 0 : -1;
145334 + if (!r)
145335 + r = a->format - b->format;
145336 + if (!r)
145337 + r = a->opaque - b->opaque;
145338 + if (!r)
145339 + r = a->cmd - b->cmd;
145340 + return r;
145341 +}
145342 +
145343 +/********/
145344 +/* test */
145345 +/********/
145346 +
145347 +static void do_enqueues(struct qman_fq *fq)
145348 +{
145349 + unsigned int loop;
145350 + for (loop = 0; loop < NUM_ENQUEUES; loop++) {
145351 + if (qman_enqueue(fq, &fd, QMAN_ENQUEUE_FLAG_WAIT |
145352 + (((loop + 1) == NUM_ENQUEUES) ?
145353 + QMAN_ENQUEUE_FLAG_WAIT_SYNC : 0)))
145354 + panic("qman_enqueue() failed\n");
145355 + fd_inc(&fd);
145356 + }
145357 +}
145358 +
145359 +void qman_test_high(void)
145360 +{
145361 + unsigned int flags;
145362 + int res;
145363 + struct qman_fq *fq = &fq_base;
145364 +
145365 + pr_info("qman_test_high starting\n");
145366 + fd_init(&fd);
145367 + fd_init(&fd_dq);
145368 +
145369 + /* Initialise (parked) FQ */
145370 + if (qman_create_fq(0, FQ_FLAGS, fq))
145371 + panic("qman_create_fq() failed\n");
145372 + if (qman_init_fq(fq, QMAN_INITFQ_FLAG_LOCAL, NULL))
145373 + panic("qman_init_fq() failed\n");
145374 +
145375 + /* Do enqueues + VDQCR, twice. (Parked FQ) */
145376 + do_enqueues(fq);
145377 + pr_info("VDQCR (till-empty);\n");
145378 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
145379 + QM_VDQCR_NUMFRAMES_TILLEMPTY))
145380 + panic("qman_volatile_dequeue() failed\n");
145381 + do_enqueues(fq);
145382 + pr_info("VDQCR (%d of %d);\n", NUM_PARTIAL, NUM_ENQUEUES);
145383 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
145384 + QM_VDQCR_NUMFRAMES_SET(NUM_PARTIAL)))
145385 + panic("qman_volatile_dequeue() failed\n");
145386 + pr_info("VDQCR (%d of %d);\n", NUM_ENQUEUES - NUM_PARTIAL,
145387 + NUM_ENQUEUES);
145388 + if (qman_volatile_dequeue(fq, VDQCR_FLAGS,
145389 + QM_VDQCR_NUMFRAMES_SET(NUM_ENQUEUES - NUM_PARTIAL)))
145390 + panic("qman_volatile_dequeue() failed\n");
145391 +
145392 + do_enqueues(fq);
145393 + pr_info("scheduled dequeue (till-empty)\n");
145394 + if (qman_schedule_fq(fq))
145395 + panic("qman_schedule_fq() failed\n");
145396 + wait_event(waitqueue, sdqcr_complete);
145397 +
145398 + /* Retire and OOS the FQ */
145399 + res = qman_retire_fq(fq, &flags);
145400 + if (res < 0)
145401 + panic("qman_retire_fq() failed\n");
145402 + wait_event(waitqueue, retire_complete);
145403 + if (flags & QMAN_FQ_STATE_BLOCKOOS)
145404 + panic("leaking frames\n");
145405 + if (qman_oos_fq(fq))
145406 + panic("qman_oos_fq() failed\n");
145407 + qman_destroy_fq(fq, 0);
145408 + pr_info("qman_test_high finished\n");
145409 +}
145410 +
145411 +static enum qman_cb_dqrr_result cb_dqrr(struct qman_portal *p,
145412 + struct qman_fq *fq,
145413 + const struct qm_dqrr_entry *dq)
145414 +{
145415 + if (fd_cmp(&fd_dq, &dq->fd)) {
145416 + pr_err("BADNESS: dequeued frame doesn't match;\n");
145417 + pr_err("Expected 0x%llx, got 0x%llx\n",
145418 + (unsigned long long)fd_dq.length29,
145419 + (unsigned long long)dq->fd.length29);
145420 + BUG();
145421 + }
145422 + fd_inc(&fd_dq);
145423 + if (!(dq->stat & QM_DQRR_STAT_UNSCHEDULED) && !fd_cmp(&fd_dq, &fd)) {
145424 + sdqcr_complete = 1;
145425 + wake_up(&waitqueue);
145426 + }
145427 + return qman_cb_dqrr_consume;
145428 +}
145429 +
145430 +static void cb_ern(struct qman_portal *p, struct qman_fq *fq,
145431 + const struct qm_mr_entry *msg)
145432 +{
145433 + panic("cb_ern() unimplemented");
145434 +}
145435 +
145436 +static void cb_fqs(struct qman_portal *p, struct qman_fq *fq,
145437 + const struct qm_mr_entry *msg)
145438 +{
145439 + u8 verb = (msg->verb & QM_MR_VERB_TYPE_MASK);
145440 + if ((verb != QM_MR_VERB_FQRN) && (verb != QM_MR_VERB_FQRNI))
145441 + panic("unexpected FQS message");
145442 + pr_info("Retirement message received\n");
145443 + retire_complete = 1;
145444 + wake_up(&waitqueue);
145445 +}
145446 --- /dev/null
145447 +++ b/drivers/staging/fsl_qbman/qman_test_hotpotato.c
145448 @@ -0,0 +1,502 @@
145449 +/* Copyright 2009-2012 Freescale Semiconductor, Inc.
145450 + *
145451 + * Redistribution and use in source and binary forms, with or without
145452 + * modification, are permitted provided that the following conditions are met:
145453 + * * Redistributions of source code must retain the above copyright
145454 + * notice, this list of conditions and the following disclaimer.
145455 + * * Redistributions in binary form must reproduce the above copyright
145456 + * notice, this list of conditions and the following disclaimer in the
145457 + * documentation and/or other materials provided with the distribution.
145458 + * * Neither the name of Freescale Semiconductor nor the
145459 + * names of its contributors may be used to endorse or promote products
145460 + * derived from this software without specific prior written permission.
145461 + *
145462 + *
145463 + * ALTERNATIVELY, this software may be distributed under the terms of the
145464 + * GNU General Public License ("GPL") as published by the Free Software
145465 + * Foundation, either version 2 of that License or (at your option) any
145466 + * later version.
145467 + *
145468 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145469 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145470 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145471 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145472 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145473 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145474 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145475 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145476 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145477 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145478 + */
145479 +
145480 +#include <linux/kthread.h>
145481 +#include <linux/platform_device.h>
145482 +#include <linux/dma-mapping.h>
145483 +#include "qman_test.h"
145484 +
145485 +/* Algorithm:
145486 + *
145487 + * Each cpu will have HP_PER_CPU "handlers" set up, each of which incorporates
145488 + * an rx/tx pair of FQ objects (both of which are stashed on dequeue). The
145489 + * organisation of FQIDs is such that the HP_PER_CPU*NUM_CPUS handlers will
145490 + * shuttle a "hot potato" frame around them such that every forwarding action
145491 + * moves it from one cpu to another. (The use of more than one handler per cpu
145492 + * is to allow enough handlers/FQs to truly test the significance of caching -
145493 + * ie. when cache-expiries are occurring.)
145494 + *
145495 + * The "hot potato" frame content will be HP_NUM_WORDS*4 bytes in size, and the
145496 + * first and last words of the frame data will undergo a transformation step on
145497 + * each forwarding action. To achieve this, each handler will be assigned a
145498 + * 32-bit "mixer", that is produced using a 32-bit LFSR. When a frame is
145499 + * received by a handler, the mixer of the expected sender is XOR'd into all
145500 + * words of the entire frame, which is then validated against the original
145501 + * values. Then, before forwarding, the entire frame is XOR'd with the mixer of
145502 + * the current handler. Apart from validating that the frame is taking the
145503 + * expected path, this also provides some quasi-realistic overheads to each
145504 + * forwarding action - dereferencing *all* the frame data, computation, and
145505 + * conditional branching. There is a "special" handler designated to act as the
145506 + * instigator of the test by creating an enqueuing the "hot potato" frame, and
145507 + * to determine when the test has completed by counting HP_LOOPS iterations.
145508 + *
145509 + * Init phases:
145510 + *
145511 + * 1. prepare each cpu's 'hp_cpu' struct using on_each_cpu(,,1) and link them
145512 + * into 'hp_cpu_list'. Specifically, set processor_id, allocate HP_PER_CPU
145513 + * handlers and link-list them (but do no other handler setup).
145514 + *
145515 + * 2. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
145516 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
145517 + * allocate rx/tx FQIDs and mixer values to the hp_cpu's iterator handler
145518 + * and advance the iterator for the next loop. This includes a final fixup,
145519 + * which connects the last handler to the first (and which is why phase 2
145520 + * and 3 are separate).
145521 + *
145522 + * 3. scan over 'hp_cpu_list' HP_PER_CPU times, the first time sets each
145523 + * hp_cpu's 'iterator' to point to its first handler. With each loop,
145524 + * initialise FQ objects and advance the iterator for the next loop.
145525 + * Moreover, do this initialisation on the cpu it applies to so that Rx FQ
145526 + * initialisation targets the correct cpu.
145527 + */
145528 +
145529 +/* helper to run something on all cpus (can't use on_each_cpu(), as that invokes
145530 + * the fn from irq context, which is too restrictive). */
145531 +struct bstrap {
145532 + void (*fn)(void);
145533 + atomic_t started;
145534 +};
145535 +static int bstrap_fn(void *__bstrap)
145536 +{
145537 + struct bstrap *bstrap = __bstrap;
145538 + atomic_inc(&bstrap->started);
145539 + bstrap->fn();
145540 + while (!kthread_should_stop())
145541 + msleep(1);
145542 + return 0;
145543 +}
145544 +static int on_all_cpus(void (*fn)(void))
145545 +{
145546 + int cpu;
145547 + for_each_cpu(cpu, cpu_online_mask) {
145548 + struct bstrap bstrap = {
145549 + .fn = fn,
145550 + .started = ATOMIC_INIT(0)
145551 + };
145552 + struct task_struct *k = kthread_create(bstrap_fn, &bstrap,
145553 + "hotpotato%d", cpu);
145554 + int ret;
145555 + if (IS_ERR(k))
145556 + return -ENOMEM;
145557 + kthread_bind(k, cpu);
145558 + wake_up_process(k);
145559 + /* If we call kthread_stop() before the "wake up" has had an
145560 + * effect, then the thread may exit with -EINTR without ever
145561 + * running the function. So poll until it's started before
145562 + * requesting it to stop. */
145563 + while (!atomic_read(&bstrap.started))
145564 + msleep(10);
145565 + ret = kthread_stop(k);
145566 + if (ret)
145567 + return ret;
145568 + }
145569 + return 0;
145570 +}
145571 +
145572 +struct hp_handler {
145573 +
145574 + /* The following data is stashed when 'rx' is dequeued; */
145575 + /* -------------- */
145576 + /* The Rx FQ, dequeues of which will stash the entire hp_handler */
145577 + struct qman_fq rx;
145578 + /* The Tx FQ we should forward to */
145579 + struct qman_fq tx;
145580 + /* The value we XOR post-dequeue, prior to validating */
145581 + u32 rx_mixer;
145582 + /* The value we XOR pre-enqueue, after validating */
145583 + u32 tx_mixer;
145584 + /* what the hotpotato address should be on dequeue */
145585 + dma_addr_t addr;
145586 + u32 *frame_ptr;
145587 +
145588 + /* The following data isn't (necessarily) stashed on dequeue; */
145589 + /* -------------- */
145590 + u32 fqid_rx, fqid_tx;
145591 + /* list node for linking us into 'hp_cpu' */
145592 + struct list_head node;
145593 + /* Just to check ... */
145594 + unsigned int processor_id;
145595 +} ____cacheline_aligned;
145596 +
145597 +struct hp_cpu {
145598 + /* identify the cpu we run on; */
145599 + unsigned int processor_id;
145600 + /* root node for the per-cpu list of handlers */
145601 + struct list_head handlers;
145602 + /* list node for linking us into 'hp_cpu_list' */
145603 + struct list_head node;
145604 + /* when repeatedly scanning 'hp_list', each time linking the n'th
145605 + * handlers together, this is used as per-cpu iterator state */
145606 + struct hp_handler *iterator;
145607 +};
145608 +
145609 +/* Each cpu has one of these */
145610 +static DEFINE_PER_CPU(struct hp_cpu, hp_cpus);
145611 +
145612 +/* links together the hp_cpu structs, in first-come first-serve order. */
145613 +static LIST_HEAD(hp_cpu_list);
145614 +static spinlock_t hp_lock = __SPIN_LOCK_UNLOCKED(hp_lock);
145615 +
145616 +static unsigned int hp_cpu_list_length;
145617 +
145618 +/* the "special" handler, that starts and terminates the test. */
145619 +static struct hp_handler *special_handler;
145620 +static int loop_counter;
145621 +
145622 +/* handlers are allocated out of this, so they're properly aligned. */
145623 +static struct kmem_cache *hp_handler_slab;
145624 +
145625 +/* this is the frame data */
145626 +static void *__frame_ptr;
145627 +static u32 *frame_ptr;
145628 +static dma_addr_t frame_dma;
145629 +
145630 +/* the main function waits on this */
145631 +static DECLARE_WAIT_QUEUE_HEAD(queue);
145632 +
145633 +#define HP_PER_CPU 2
145634 +#define HP_LOOPS 8
145635 +/* 80 bytes, like a small ethernet frame, and bleeds into a second cacheline */
145636 +#define HP_NUM_WORDS 80
145637 +/* First word of the LFSR-based frame data */
145638 +#define HP_FIRST_WORD 0xabbaf00d
145639 +
145640 +static inline u32 do_lfsr(u32 prev)
145641 +{
145642 + return (prev >> 1) ^ (-(prev & 1u) & 0xd0000001u);
145643 +}
145644 +
145645 +static void allocate_frame_data(void)
145646 +{
145647 + u32 lfsr = HP_FIRST_WORD;
145648 + int loop;
145649 + struct platform_device *pdev = platform_device_alloc("foobar", -1);
145650 + if (!pdev)
145651 + panic("platform_device_alloc() failed");
145652 + if (platform_device_add(pdev))
145653 + panic("platform_device_add() failed");
145654 + __frame_ptr = kmalloc(4 * HP_NUM_WORDS, GFP_KERNEL);
145655 + if (!__frame_ptr)
145656 + panic("kmalloc() failed");
145657 + frame_ptr = (void *)(((unsigned long)__frame_ptr + 63) &
145658 + ~(unsigned long)63);
145659 + for (loop = 0; loop < HP_NUM_WORDS; loop++) {
145660 + frame_ptr[loop] = lfsr;
145661 + lfsr = do_lfsr(lfsr);
145662 + }
145663 + frame_dma = dma_map_single(&pdev->dev, frame_ptr, 4 * HP_NUM_WORDS,
145664 + DMA_BIDIRECTIONAL);
145665 + platform_device_del(pdev);
145666 + platform_device_put(pdev);
145667 +}
145668 +
145669 +static void deallocate_frame_data(void)
145670 +{
145671 + kfree(__frame_ptr);
145672 +}
145673 +
145674 +static inline void process_frame_data(struct hp_handler *handler,
145675 + const struct qm_fd *fd)
145676 +{
145677 + u32 *p = handler->frame_ptr;
145678 + u32 lfsr = HP_FIRST_WORD;
145679 + int loop;
145680 + if (qm_fd_addr_get64(fd) != (handler->addr & 0xffffffffff)) {
145681 + pr_err("Got 0x%llx expected 0x%llx\n",
145682 + qm_fd_addr_get64(fd), handler->addr);
145683 + panic("bad frame address");
145684 + }
145685 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
145686 + *p ^= handler->rx_mixer;
145687 + if (*p != lfsr)
145688 + panic("corrupt frame data");
145689 + *p ^= handler->tx_mixer;
145690 + lfsr = do_lfsr(lfsr);
145691 + }
145692 +}
145693 +
145694 +static enum qman_cb_dqrr_result normal_dqrr(struct qman_portal *portal,
145695 + struct qman_fq *fq,
145696 + const struct qm_dqrr_entry *dqrr)
145697 +{
145698 + struct hp_handler *handler = (struct hp_handler *)fq;
145699 +
145700 + process_frame_data(handler, &dqrr->fd);
145701 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
145702 + panic("qman_enqueue() failed");
145703 + return qman_cb_dqrr_consume;
145704 +}
145705 +
145706 +static enum qman_cb_dqrr_result special_dqrr(struct qman_portal *portal,
145707 + struct qman_fq *fq,
145708 + const struct qm_dqrr_entry *dqrr)
145709 +{
145710 + struct hp_handler *handler = (struct hp_handler *)fq;
145711 +
145712 + process_frame_data(handler, &dqrr->fd);
145713 + if (++loop_counter < HP_LOOPS) {
145714 + if (qman_enqueue(&handler->tx, &dqrr->fd, 0))
145715 + panic("qman_enqueue() failed");
145716 + } else {
145717 + pr_info("Received final (%dth) frame\n", loop_counter);
145718 + wake_up(&queue);
145719 + }
145720 + return qman_cb_dqrr_consume;
145721 +}
145722 +
145723 +static void create_per_cpu_handlers(void)
145724 +{
145725 + struct hp_handler *handler;
145726 + int loop;
145727 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
145728 +
145729 + hp_cpu->processor_id = smp_processor_id();
145730 + spin_lock(&hp_lock);
145731 + list_add_tail(&hp_cpu->node, &hp_cpu_list);
145732 + hp_cpu_list_length++;
145733 + spin_unlock(&hp_lock);
145734 + INIT_LIST_HEAD(&hp_cpu->handlers);
145735 + for (loop = 0; loop < HP_PER_CPU; loop++) {
145736 + handler = kmem_cache_alloc(hp_handler_slab, GFP_KERNEL);
145737 + if (!handler)
145738 + panic("kmem_cache_alloc() failed");
145739 + handler->processor_id = hp_cpu->processor_id;
145740 + handler->addr = frame_dma;
145741 + handler->frame_ptr = frame_ptr;
145742 + list_add_tail(&handler->node, &hp_cpu->handlers);
145743 + }
145744 + put_cpu_var(hp_cpus);
145745 +}
145746 +
145747 +static void destroy_per_cpu_handlers(void)
145748 +{
145749 + struct list_head *loop, *tmp;
145750 + struct hp_cpu *hp_cpu = &get_cpu_var(hp_cpus);
145751 +
145752 + spin_lock(&hp_lock);
145753 + list_del(&hp_cpu->node);
145754 + spin_unlock(&hp_lock);
145755 + list_for_each_safe(loop, tmp, &hp_cpu->handlers) {
145756 + u32 flags;
145757 + struct hp_handler *handler = list_entry(loop, struct hp_handler,
145758 + node);
145759 + if (qman_retire_fq(&handler->rx, &flags))
145760 + panic("qman_retire_fq(rx) failed");
145761 + BUG_ON(flags & QMAN_FQ_STATE_BLOCKOOS);
145762 + if (qman_oos_fq(&handler->rx))
145763 + panic("qman_oos_fq(rx) failed");
145764 + qman_destroy_fq(&handler->rx, 0);
145765 + qman_destroy_fq(&handler->tx, 0);
145766 + qman_release_fqid(handler->fqid_rx);
145767 + list_del(&handler->node);
145768 + kmem_cache_free(hp_handler_slab, handler);
145769 + }
145770 + put_cpu_var(hp_cpus);
145771 +}
145772 +
145773 +static inline u8 num_cachelines(u32 offset)
145774 +{
145775 + u8 res = (offset + (L1_CACHE_BYTES - 1))
145776 + / (L1_CACHE_BYTES);
145777 + if (res > 3)
145778 + return 3;
145779 + return res;
145780 +}
145781 +#define STASH_DATA_CL \
145782 + num_cachelines(HP_NUM_WORDS * 4)
145783 +#define STASH_CTX_CL \
145784 + num_cachelines(offsetof(struct hp_handler, fqid_rx))
145785 +
145786 +static void init_handler(void *__handler)
145787 +{
145788 + struct qm_mcc_initfq opts;
145789 + struct hp_handler *handler = __handler;
145790 + BUG_ON(handler->processor_id != smp_processor_id());
145791 + /* Set up rx */
145792 + memset(&handler->rx, 0, sizeof(handler->rx));
145793 + if (handler == special_handler)
145794 + handler->rx.cb.dqrr = special_dqrr;
145795 + else
145796 + handler->rx.cb.dqrr = normal_dqrr;
145797 + if (qman_create_fq(handler->fqid_rx, 0, &handler->rx))
145798 + panic("qman_create_fq(rx) failed");
145799 + memset(&opts, 0, sizeof(opts));
145800 + opts.we_mask = QM_INITFQ_WE_FQCTRL | QM_INITFQ_WE_CONTEXTA;
145801 + opts.fqd.fq_ctrl = QM_FQCTRL_CTXASTASHING;
145802 + opts.fqd.context_a.stashing.data_cl = STASH_DATA_CL;
145803 + opts.fqd.context_a.stashing.context_cl = STASH_CTX_CL;
145804 + if (qman_init_fq(&handler->rx, QMAN_INITFQ_FLAG_SCHED |
145805 + QMAN_INITFQ_FLAG_LOCAL, &opts))
145806 + panic("qman_init_fq(rx) failed");
145807 + /* Set up tx */
145808 + memset(&handler->tx, 0, sizeof(handler->tx));
145809 + if (qman_create_fq(handler->fqid_tx, QMAN_FQ_FLAG_NO_MODIFY,
145810 + &handler->tx))
145811 + panic("qman_create_fq(tx) failed");
145812 +}
145813 +
145814 +static void init_phase2(void)
145815 +{
145816 + int loop;
145817 + u32 fqid = 0;
145818 + u32 lfsr = 0xdeadbeef;
145819 + struct hp_cpu *hp_cpu;
145820 + struct hp_handler *handler;
145821 +
145822 + for (loop = 0; loop < HP_PER_CPU; loop++) {
145823 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
145824 + int ret;
145825 + if (!loop)
145826 + hp_cpu->iterator = list_first_entry(
145827 + &hp_cpu->handlers,
145828 + struct hp_handler, node);
145829 + else
145830 + hp_cpu->iterator = list_entry(
145831 + hp_cpu->iterator->node.next,
145832 + struct hp_handler, node);
145833 + /* Rx FQID is the previous handler's Tx FQID */
145834 + hp_cpu->iterator->fqid_rx = fqid;
145835 + /* Allocate new FQID for Tx */
145836 + ret = qman_alloc_fqid(&fqid);
145837 + if (ret)
145838 + panic("qman_alloc_fqid() failed");
145839 + hp_cpu->iterator->fqid_tx = fqid;
145840 + /* Rx mixer is the previous handler's Tx mixer */
145841 + hp_cpu->iterator->rx_mixer = lfsr;
145842 + /* Get new mixer for Tx */
145843 + lfsr = do_lfsr(lfsr);
145844 + hp_cpu->iterator->tx_mixer = lfsr;
145845 + }
145846 + }
145847 + /* Fix up the first handler (fqid_rx==0, rx_mixer=0xdeadbeef) */
145848 + hp_cpu = list_first_entry(&hp_cpu_list, struct hp_cpu, node);
145849 + handler = list_first_entry(&hp_cpu->handlers, struct hp_handler, node);
145850 + BUG_ON((handler->fqid_rx != 0) || (handler->rx_mixer != 0xdeadbeef));
145851 + handler->fqid_rx = fqid;
145852 + handler->rx_mixer = lfsr;
145853 + /* and tag it as our "special" handler */
145854 + special_handler = handler;
145855 +}
145856 +
145857 +static void init_phase3(void)
145858 +{
145859 + int loop;
145860 + struct hp_cpu *hp_cpu;
145861 +
145862 + for (loop = 0; loop < HP_PER_CPU; loop++) {
145863 + list_for_each_entry(hp_cpu, &hp_cpu_list, node) {
145864 + if (!loop)
145865 + hp_cpu->iterator = list_first_entry(
145866 + &hp_cpu->handlers,
145867 + struct hp_handler, node);
145868 + else
145869 + hp_cpu->iterator = list_entry(
145870 + hp_cpu->iterator->node.next,
145871 + struct hp_handler, node);
145872 + preempt_disable();
145873 + if (hp_cpu->processor_id == smp_processor_id())
145874 + init_handler(hp_cpu->iterator);
145875 + else
145876 + smp_call_function_single(hp_cpu->processor_id,
145877 + init_handler, hp_cpu->iterator, 1);
145878 + preempt_enable();
145879 + }
145880 + }
145881 +}
145882 +
145883 +static void send_first_frame(void *ignore)
145884 +{
145885 + u32 *p = special_handler->frame_ptr;
145886 + u32 lfsr = HP_FIRST_WORD;
145887 + int loop;
145888 + struct qm_fd fd;
145889 +
145890 + BUG_ON(special_handler->processor_id != smp_processor_id());
145891 + memset(&fd, 0, sizeof(fd));
145892 + qm_fd_addr_set64(&fd, special_handler->addr);
145893 + fd.format = qm_fd_contig_big;
145894 + fd.length29 = HP_NUM_WORDS * 4;
145895 + for (loop = 0; loop < HP_NUM_WORDS; loop++, p++) {
145896 + if (*p != lfsr)
145897 + panic("corrupt frame data");
145898 + *p ^= special_handler->tx_mixer;
145899 + lfsr = do_lfsr(lfsr);
145900 + }
145901 + pr_info("Sending first frame\n");
145902 + if (qman_enqueue(&special_handler->tx, &fd, 0))
145903 + panic("qman_enqueue() failed");
145904 +}
145905 +
145906 +void qman_test_hotpotato(void)
145907 +{
145908 + if (cpumask_weight(cpu_online_mask) < 2) {
145909 + pr_info("qman_test_hotpotato, skip - only 1 CPU\n");
145910 + return;
145911 + }
145912 +
145913 + pr_info("qman_test_hotpotato starting\n");
145914 +
145915 + hp_cpu_list_length = 0;
145916 + loop_counter = 0;
145917 + hp_handler_slab = kmem_cache_create("hp_handler_slab",
145918 + sizeof(struct hp_handler), L1_CACHE_BYTES,
145919 + SLAB_HWCACHE_ALIGN, NULL);
145920 + if (!hp_handler_slab)
145921 + panic("kmem_cache_create() failed");
145922 +
145923 + allocate_frame_data();
145924 +
145925 + /* Init phase 1 */
145926 + pr_info("Creating %d handlers per cpu...\n", HP_PER_CPU);
145927 + if (on_all_cpus(create_per_cpu_handlers))
145928 + panic("on_each_cpu() failed");
145929 + pr_info("Number of cpus: %d, total of %d handlers\n",
145930 + hp_cpu_list_length, hp_cpu_list_length * HP_PER_CPU);
145931 +
145932 + init_phase2();
145933 +
145934 + init_phase3();
145935 +
145936 + preempt_disable();
145937 + if (special_handler->processor_id == smp_processor_id())
145938 + send_first_frame(NULL);
145939 + else
145940 + smp_call_function_single(special_handler->processor_id,
145941 + send_first_frame, NULL, 1);
145942 + preempt_enable();
145943 +
145944 + wait_event(queue, loop_counter == HP_LOOPS);
145945 + deallocate_frame_data();
145946 + if (on_all_cpus(destroy_per_cpu_handlers))
145947 + panic("on_each_cpu() failed");
145948 + kmem_cache_destroy(hp_handler_slab);
145949 + pr_info("qman_test_hotpotato finished\n");
145950 +}
145951 --- /dev/null
145952 +++ b/drivers/staging/fsl_qbman/qman_utility.c
145953 @@ -0,0 +1,129 @@
145954 +/* Copyright 2008-2011 Freescale Semiconductor, Inc.
145955 + *
145956 + * Redistribution and use in source and binary forms, with or without
145957 + * modification, are permitted provided that the following conditions are met:
145958 + * * Redistributions of source code must retain the above copyright
145959 + * notice, this list of conditions and the following disclaimer.
145960 + * * Redistributions in binary form must reproduce the above copyright
145961 + * notice, this list of conditions and the following disclaimer in the
145962 + * documentation and/or other materials provided with the distribution.
145963 + * * Neither the name of Freescale Semiconductor nor the
145964 + * names of its contributors may be used to endorse or promote products
145965 + * derived from this software without specific prior written permission.
145966 + *
145967 + *
145968 + * ALTERNATIVELY, this software may be distributed under the terms of the
145969 + * GNU General Public License ("GPL") as published by the Free Software
145970 + * Foundation, either version 2 of that License or (at your option) any
145971 + * later version.
145972 + *
145973 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
145974 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
145975 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
145976 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
145977 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
145978 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
145979 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
145980 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
145981 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
145982 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145983 + */
145984 +
145985 +#include "qman_private.h"
145986 +
145987 +/* ----------------- */
145988 +/* --- FQID Pool --- */
145989 +
145990 +struct qman_fqid_pool {
145991 + /* Base and size of the FQID range */
145992 + u32 fqid_base;
145993 + u32 total;
145994 + /* Number of FQIDs currently "allocated" */
145995 + u32 used;
145996 + /* Allocation optimisation. When 'used<total', it is the index of an
145997 + * available FQID. Otherwise there are no available FQIDs, and this
145998 + * will be set when the next deallocation occurs. */
145999 + u32 next;
146000 + /* A bit-field representation of the FQID range. */
146001 + unsigned long *bits;
146002 +};
146003 +
146004 +#define QLONG_BYTES sizeof(unsigned long)
146005 +#define QLONG_BITS (QLONG_BYTES * 8)
146006 +/* Number of 'longs' required for the given number of bits */
146007 +#define QNUM_LONGS(b) (((b) + QLONG_BITS - 1) / QLONG_BITS)
146008 +/* Shorthand for the number of bytes of same (kmalloc, memset, etc) */
146009 +#define QNUM_BYTES(b) (QNUM_LONGS(b) * QLONG_BYTES)
146010 +/* And in bits */
146011 +#define QNUM_BITS(b) (QNUM_LONGS(b) * QLONG_BITS)
146012 +
146013 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num)
146014 +{
146015 + struct qman_fqid_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
146016 + unsigned int i;
146017 +
146018 + BUG_ON(!num);
146019 + if (!pool)
146020 + return NULL;
146021 + pool->fqid_base = fqid_start;
146022 + pool->total = num;
146023 + pool->used = 0;
146024 + pool->next = 0;
146025 + pool->bits = kzalloc(QNUM_BYTES(num), GFP_KERNEL);
146026 + if (!pool->bits) {
146027 + kfree(pool);
146028 + return NULL;
146029 + }
146030 + /* If num is not an even multiple of QLONG_BITS (or even 8, for
146031 + * byte-oriented searching) then we fill the trailing bits with 1, to
146032 + * make them look allocated (permanently). */
146033 + for (i = num + 1; i < QNUM_BITS(num); i++)
146034 + set_bit(i, pool->bits);
146035 + return pool;
146036 +}
146037 +EXPORT_SYMBOL(qman_fqid_pool_create);
146038 +
146039 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool)
146040 +{
146041 + int ret = pool->used;
146042 + kfree(pool->bits);
146043 + kfree(pool);
146044 + return ret;
146045 +}
146046 +EXPORT_SYMBOL(qman_fqid_pool_destroy);
146047 +
146048 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid)
146049 +{
146050 + int ret;
146051 + if (pool->used == pool->total)
146052 + return -ENOMEM;
146053 + *fqid = pool->fqid_base + pool->next;
146054 + ret = test_and_set_bit(pool->next, pool->bits);
146055 + BUG_ON(ret);
146056 + if (++pool->used == pool->total)
146057 + return 0;
146058 + pool->next = find_next_zero_bit(pool->bits, pool->total, pool->next);
146059 + if (pool->next >= pool->total)
146060 + pool->next = find_first_zero_bit(pool->bits, pool->total);
146061 + BUG_ON(pool->next >= pool->total);
146062 + return 0;
146063 +}
146064 +EXPORT_SYMBOL(qman_fqid_pool_alloc);
146065 +
146066 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid)
146067 +{
146068 + int ret;
146069 +
146070 + fqid -= pool->fqid_base;
146071 + ret = test_and_clear_bit(fqid, pool->bits);
146072 + BUG_ON(!ret);
146073 + if (pool->used-- == pool->total)
146074 + pool->next = fqid;
146075 +}
146076 +EXPORT_SYMBOL(qman_fqid_pool_free);
146077 +
146078 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool)
146079 +{
146080 + return pool->used;
146081 +}
146082 +EXPORT_SYMBOL(qman_fqid_pool_used);
146083 --- /dev/null
146084 +++ b/include/linux/fsl/svr.h
146085 @@ -0,0 +1,97 @@
146086 +/*
146087 + * MPC85xx cpu type detection
146088 + *
146089 + * Copyright 2011-2012 Freescale Semiconductor, Inc.
146090 + *
146091 + * This is free software; you can redistribute it and/or modify
146092 + * it under the terms of the GNU General Public License as published by
146093 + * the Free Software Foundation; either version 2 of the License, or
146094 + * (at your option) any later version.
146095 + */
146096 +
146097 +#ifndef FSL_SVR_H
146098 +#define FSL_SVR_H
146099 +
146100 +#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */
146101 +#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/
146102 +#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/
146103 +
146104 +/* Some parts define SVR[0:23] as the SOC version */
146105 +#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC Version fields */
146106 +
146107 +#define SVR_8533 0x803400
146108 +#define SVR_8535 0x803701
146109 +#define SVR_8536 0x803700
146110 +#define SVR_8540 0x803000
146111 +#define SVR_8541 0x807200
146112 +#define SVR_8543 0x803200
146113 +#define SVR_8544 0x803401
146114 +#define SVR_8545 0x803102
146115 +#define SVR_8547 0x803101
146116 +#define SVR_8548 0x803100
146117 +#define SVR_8555 0x807100
146118 +#define SVR_8560 0x807000
146119 +#define SVR_8567 0x807501
146120 +#define SVR_8568 0x807500
146121 +#define SVR_8569 0x808000
146122 +#define SVR_8572 0x80E000
146123 +#define SVR_P1010 0x80F100
146124 +#define SVR_P1011 0x80E500
146125 +#define SVR_P1012 0x80E501
146126 +#define SVR_P1013 0x80E700
146127 +#define SVR_P1014 0x80F101
146128 +#define SVR_P1017 0x80F700
146129 +#define SVR_P1020 0x80E400
146130 +#define SVR_P1021 0x80E401
146131 +#define SVR_P1022 0x80E600
146132 +#define SVR_P1023 0x80F600
146133 +#define SVR_P1024 0x80E402
146134 +#define SVR_P1025 0x80E403
146135 +#define SVR_P2010 0x80E300
146136 +#define SVR_P2020 0x80E200
146137 +#define SVR_P2040 0x821000
146138 +#define SVR_P2041 0x821001
146139 +#define SVR_P3041 0x821103
146140 +#define SVR_P4040 0x820100
146141 +#define SVR_P4080 0x820000
146142 +#define SVR_P5010 0x822100
146143 +#define SVR_P5020 0x822000
146144 +#define SVR_P5021 0X820500
146145 +#define SVR_P5040 0x820400
146146 +#define SVR_T4240 0x824000
146147 +#define SVR_T4120 0x824001
146148 +#define SVR_T4160 0x824100
146149 +#define SVR_T4080 0x824102
146150 +#define SVR_C291 0x850000
146151 +#define SVR_C292 0x850020
146152 +#define SVR_C293 0x850030
146153 +#define SVR_B4860 0X868000
146154 +#define SVR_G4860 0x868001
146155 +#define SVR_G4060 0x868003
146156 +#define SVR_B4440 0x868100
146157 +#define SVR_G4440 0x868101
146158 +#define SVR_B4420 0x868102
146159 +#define SVR_B4220 0x868103
146160 +#define SVR_T1040 0x852000
146161 +#define SVR_T1041 0x852001
146162 +#define SVR_T1042 0x852002
146163 +#define SVR_T1020 0x852100
146164 +#define SVR_T1021 0x852101
146165 +#define SVR_T1022 0x852102
146166 +#define SVR_T1023 0x854100
146167 +#define SVR_T1024 0x854000
146168 +#define SVR_T2080 0x853000
146169 +#define SVR_T2081 0x853100
146170 +
146171 +#define SVR_8610 0x80A000
146172 +#define SVR_8641 0x809000
146173 +#define SVR_8641D 0x809001
146174 +
146175 +#define SVR_9130 0x860001
146176 +#define SVR_9131 0x860000
146177 +#define SVR_9132 0x861000
146178 +#define SVR_9232 0x861400
146179 +
146180 +#define SVR_Unknown 0xFFFFFF
146181 +
146182 +#endif
146183 --- /dev/null
146184 +++ b/include/linux/fsl_bman.h
146185 @@ -0,0 +1,532 @@
146186 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
146187 + *
146188 + * Redistribution and use in source and binary forms, with or without
146189 + * modification, are permitted provided that the following conditions are met:
146190 + * * Redistributions of source code must retain the above copyright
146191 + * notice, this list of conditions and the following disclaimer.
146192 + * * Redistributions in binary form must reproduce the above copyright
146193 + * notice, this list of conditions and the following disclaimer in the
146194 + * documentation and/or other materials provided with the distribution.
146195 + * * Neither the name of Freescale Semiconductor nor the
146196 + * names of its contributors may be used to endorse or promote products
146197 + * derived from this software without specific prior written permission.
146198 + *
146199 + *
146200 + * ALTERNATIVELY, this software may be distributed under the terms of the
146201 + * GNU General Public License ("GPL") as published by the Free Software
146202 + * Foundation, either version 2 of that License or (at your option) any
146203 + * later version.
146204 + *
146205 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
146206 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
146207 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
146208 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
146209 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
146210 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
146211 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
146212 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
146213 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
146214 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146215 + */
146216 +
146217 +#ifndef FSL_BMAN_H
146218 +#define FSL_BMAN_H
146219 +
146220 +#ifdef __cplusplus
146221 +extern "C" {
146222 +#endif
146223 +
146224 +/* Last updated for v00.79 of the BG */
146225 +
146226 +/* Portal processing (interrupt) sources */
146227 +#define BM_PIRQ_RCRI 0x00000002 /* RCR Ring (below threshold) */
146228 +#define BM_PIRQ_BSCN 0x00000001 /* Buffer depletion State Change */
146229 +
146230 +/* This wrapper represents a bit-array for the depletion state of the 64 Bman
146231 + * buffer pools. */
146232 +struct bman_depletion {
146233 + u32 __state[2];
146234 +};
146235 +#define BMAN_DEPLETION_EMPTY { { 0x00000000, 0x00000000 } }
146236 +#define BMAN_DEPLETION_FULL { { 0xffffffff, 0xffffffff } }
146237 +#define __bmdep_word(x) ((x) >> 5)
146238 +#define __bmdep_shift(x) ((x) & 0x1f)
146239 +#define __bmdep_bit(x) (0x80000000 >> __bmdep_shift(x))
146240 +static inline void bman_depletion_init(struct bman_depletion *c)
146241 +{
146242 + c->__state[0] = c->__state[1] = 0;
146243 +}
146244 +static inline void bman_depletion_fill(struct bman_depletion *c)
146245 +{
146246 + c->__state[0] = c->__state[1] = ~0;
146247 +}
146248 +static inline int bman_depletion_get(const struct bman_depletion *c, u8 bpid)
146249 +{
146250 + return c->__state[__bmdep_word(bpid)] & __bmdep_bit(bpid);
146251 +}
146252 +static inline void bman_depletion_set(struct bman_depletion *c, u8 bpid)
146253 +{
146254 + c->__state[__bmdep_word(bpid)] |= __bmdep_bit(bpid);
146255 +}
146256 +static inline void bman_depletion_unset(struct bman_depletion *c, u8 bpid)
146257 +{
146258 + c->__state[__bmdep_word(bpid)] &= ~__bmdep_bit(bpid);
146259 +}
146260 +
146261 +/* ------------------------------------------------------- */
146262 +/* --- Bman data structures (and associated constants) --- */
146263 +
146264 +/* Represents s/w corenet portal mapped data structures */
146265 +struct bm_rcr_entry; /* RCR (Release Command Ring) entries */
146266 +struct bm_mc_command; /* MC (Management Command) command */
146267 +struct bm_mc_result; /* MC result */
146268 +
146269 +/* Code-reduction, define a wrapper for 48-bit buffers. In cases where a buffer
146270 + * pool id specific to this buffer is needed (BM_RCR_VERB_CMD_BPID_MULTI,
146271 + * BM_MCC_VERB_ACQUIRE), the 'bpid' field is used. */
146272 +struct bm_buffer {
146273 + union {
146274 + struct {
146275 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146276 + u8 __reserved1;
146277 + u8 bpid;
146278 + u16 hi; /* High 16-bits of 48-bit address */
146279 + u32 lo; /* Low 32-bits of 48-bit address */
146280 +#else
146281 + u32 lo;
146282 + u16 hi;
146283 + u8 bpid;
146284 + u8 __reserved;
146285 +#endif
146286 + };
146287 + struct {
146288 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146289 + u64 __notaddress:16;
146290 + u64 addr:48;
146291 +#else
146292 + u64 addr:48;
146293 + u64 __notaddress:16;
146294 +#endif
146295 + };
146296 + u64 opaque;
146297 + };
146298 +} __aligned(8);
146299 +static inline u64 bm_buffer_get64(const struct bm_buffer *buf)
146300 +{
146301 + return buf->addr;
146302 +}
146303 +static inline dma_addr_t bm_buf_addr(const struct bm_buffer *buf)
146304 +{
146305 + return (dma_addr_t)buf->addr;
146306 +}
146307 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146308 +#define bm_buffer_set64(buf, v) \
146309 + do { \
146310 + struct bm_buffer *__buf931 = (buf); \
146311 + __buf931->hi = upper_32_bits(v); \
146312 + __buf931->lo = lower_32_bits(v); \
146313 + } while (0)
146314 +
146315 +/* See 1.5.3.5.4: "Release Command" */
146316 +struct bm_rcr_entry {
146317 + union {
146318 + struct {
146319 + u8 __dont_write_directly__verb;
146320 + u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
146321 + u8 __reserved1[62];
146322 + };
146323 + struct bm_buffer bufs[8];
146324 + };
146325 +} __packed;
146326 +#define BM_RCR_VERB_VBIT 0x80
146327 +#define BM_RCR_VERB_CMD_MASK 0x70 /* one of two values; */
146328 +#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
146329 +#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
146330 +#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f /* values 1..8 */
146331 +
146332 +/* See 1.5.3.1: "Acquire Command" */
146333 +/* See 1.5.3.2: "Query Command" */
146334 +struct bm_mcc_acquire {
146335 + u8 bpid;
146336 + u8 __reserved1[62];
146337 +} __packed;
146338 +struct bm_mcc_query {
146339 + u8 __reserved2[63];
146340 +} __packed;
146341 +struct bm_mc_command {
146342 + u8 __dont_write_directly__verb;
146343 + union {
146344 + struct bm_mcc_acquire acquire;
146345 + struct bm_mcc_query query;
146346 + };
146347 +} __packed;
146348 +#define BM_MCC_VERB_VBIT 0x80
146349 +#define BM_MCC_VERB_CMD_MASK 0x70 /* where the verb contains; */
146350 +#define BM_MCC_VERB_CMD_ACQUIRE 0x10
146351 +#define BM_MCC_VERB_CMD_QUERY 0x40
146352 +#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f /* values 1..8 go here */
146353 +
146354 +/* See 1.5.3.3: "Acquire Response" */
146355 +/* See 1.5.3.4: "Query Response" */
146356 +struct bm_pool_state {
146357 + u8 __reserved1[32];
146358 + /* "availability state" and "depletion state" */
146359 + struct {
146360 + u8 __reserved1[8];
146361 + /* Access using bman_depletion_***() */
146362 + struct bman_depletion state;
146363 + } as, ds;
146364 +};
146365 +struct bm_mc_result {
146366 + union {
146367 + struct {
146368 + u8 verb;
146369 + u8 __reserved1[63];
146370 + };
146371 + union {
146372 + struct {
146373 + u8 __reserved1;
146374 + u8 bpid;
146375 + u8 __reserved2[62];
146376 + };
146377 + struct bm_buffer bufs[8];
146378 + } acquire;
146379 + struct bm_pool_state query;
146380 + };
146381 +} __packed;
146382 +#define BM_MCR_VERB_VBIT 0x80
146383 +#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
146384 +#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
146385 +#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
146386 +#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
146387 +#define BM_MCR_VERB_CMD_ERR_ECC 0x70
146388 +#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT /* 0..8 */
146389 +/* Determine the "availability state" of pool 'p' from a query result 'r' */
146390 +#define BM_MCR_QUERY_AVAILABILITY(r, p) \
146391 + bman_depletion_get(&r->query.as.state, p)
146392 +/* Determine the "depletion state" of pool 'p' from a query result 'r' */
146393 +#define BM_MCR_QUERY_DEPLETION(r, p) \
146394 + bman_depletion_get(&r->query.ds.state, p)
146395 +
146396 +/*******************************************************************/
146397 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
146398 +/*******************************************************************/
146399 +
146400 + /* Portal and Buffer Pools */
146401 + /* ----------------------- */
146402 +/* Represents a managed portal */
146403 +struct bman_portal;
146404 +
146405 +/* This object type represents Bman buffer pools. */
146406 +struct bman_pool;
146407 +
146408 +struct bman_portal_config {
146409 + /* This is used for any "core-affine" portals, ie. default portals
146410 + * associated to the corresponding cpu. -1 implies that there is no core
146411 + * affinity configured. */
146412 + int cpu;
146413 + /* portal interrupt line */
146414 + int irq;
146415 + /* the unique index of this portal */
146416 + u32 index;
146417 + /* Is this portal shared? (If so, it has coarser locking and demuxes
146418 + * processing on behalf of other CPUs.) */
146419 + int is_shared;
146420 + /* These are the buffer pool IDs that may be used via this portal. */
146421 + struct bman_depletion mask;
146422 +};
146423 +
146424 +/* This callback type is used when handling pool depletion entry/exit. The
146425 + * 'cb_ctx' value is the opaque value associated with the pool object in
146426 + * bman_new_pool(). 'depleted' is non-zero on depletion-entry, and zero on
146427 + * depletion-exit. */
146428 +typedef void (*bman_cb_depletion)(struct bman_portal *bm,
146429 + struct bman_pool *pool, void *cb_ctx, int depleted);
146430 +
146431 +/* This struct specifies parameters for a bman_pool object. */
146432 +struct bman_pool_params {
146433 + /* index of the buffer pool to encapsulate (0-63), ignored if
146434 + * BMAN_POOL_FLAG_DYNAMIC_BPID is set. */
146435 + u32 bpid;
146436 + /* bit-mask of BMAN_POOL_FLAG_*** options */
146437 + u32 flags;
146438 + /* depletion-entry/exit callback, if BMAN_POOL_FLAG_DEPLETION is set */
146439 + bman_cb_depletion cb;
146440 + /* opaque user value passed as a parameter to 'cb' */
146441 + void *cb_ctx;
146442 + /* depletion-entry/exit thresholds, if BMAN_POOL_FLAG_THRESH is set. NB:
146443 + * this is only allowed if BMAN_POOL_FLAG_DYNAMIC_BPID is used *and*
146444 + * when run in the control plane (which controls Bman CCSR). This array
146445 + * matches the definition of bm_pool_set(). */
146446 + u32 thresholds[4];
146447 +};
146448 +
146449 +/* Flags to bman_new_pool() */
146450 +#define BMAN_POOL_FLAG_NO_RELEASE 0x00000001 /* can't release to pool */
146451 +#define BMAN_POOL_FLAG_ONLY_RELEASE 0x00000002 /* can only release to pool */
146452 +#define BMAN_POOL_FLAG_DEPLETION 0x00000004 /* track depletion entry/exit */
146453 +#define BMAN_POOL_FLAG_DYNAMIC_BPID 0x00000008 /* (de)allocate bpid */
146454 +#define BMAN_POOL_FLAG_THRESH 0x00000010 /* set depletion thresholds */
146455 +#define BMAN_POOL_FLAG_STOCKPILE 0x00000020 /* stockpile to reduce hw ops */
146456 +
146457 +/* Flags to bman_release() */
146458 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
146459 +#define BMAN_RELEASE_FLAG_WAIT 0x00000001 /* wait if RCR is full */
146460 +#define BMAN_RELEASE_FLAG_WAIT_INT 0x00000002 /* if we wait, interruptible? */
146461 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
146462 +#define BMAN_RELEASE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
146463 +#endif
146464 +#endif
146465 +#define BMAN_RELEASE_FLAG_NOW 0x00000008 /* issue immediate release */
146466 +
146467 +/* Flags to bman_acquire() */
146468 +#define BMAN_ACQUIRE_FLAG_STOCKPILE 0x00000001 /* no hw op, stockpile only */
146469 +
146470 + /* Portal Management */
146471 + /* ----------------- */
146472 +/**
146473 + * bman_get_portal_config - get portal configuration settings
146474 + *
146475 + * This returns a read-only view of the current cpu's affine portal settings.
146476 + */
146477 +const struct bman_portal_config *bman_get_portal_config(void);
146478 +
146479 +/**
146480 + * bman_irqsource_get - return the portal work that is interrupt-driven
146481 + *
146482 + * Returns a bitmask of BM_PIRQ_**I processing sources that are currently
146483 + * enabled for interrupt handling on the current cpu's affine portal. These
146484 + * sources will trigger the portal interrupt and the interrupt handler (or a
146485 + * tasklet/bottom-half it defers to) will perform the corresponding processing
146486 + * work. The bman_poll_***() functions will only process sources that are not in
146487 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
146488 + * this always returns zero.
146489 + */
146490 +u32 bman_irqsource_get(void);
146491 +
146492 +/**
146493 + * bman_irqsource_add - add processing sources to be interrupt-driven
146494 + * @bits: bitmask of BM_PIRQ_**I processing sources
146495 + *
146496 + * Adds processing sources that should be interrupt-driven (rather than
146497 + * processed via bman_poll_***() functions). Returns zero for success, or
146498 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
146499 +int bman_irqsource_add(u32 bits);
146500 +
146501 +/**
146502 + * bman_irqsource_remove - remove processing sources from being interrupt-driven
146503 + * @bits: bitmask of BM_PIRQ_**I processing sources
146504 + *
146505 + * Removes processing sources from being interrupt-driven, so that they will
146506 + * instead be processed via bman_poll_***() functions. Returns zero for success,
146507 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU. */
146508 +int bman_irqsource_remove(u32 bits);
146509 +
146510 +/**
146511 + * bman_affine_cpus - return a mask of cpus that have affine portals
146512 + */
146513 +const cpumask_t *bman_affine_cpus(void);
146514 +
146515 +/**
146516 + * bman_poll_slow - process anything that isn't interrupt-driven.
146517 + *
146518 + * This function does any portal processing that isn't interrupt-driven. If the
146519 + * current CPU is sharing a portal hosted on another CPU, this function will
146520 + * return -EINVAL, otherwise the return value is a bitmask of BM_PIRQ_* sources
146521 + * indicating what interrupt sources were actually processed by the call.
146522 + *
146523 + * NB, unlike the legacy wrapper bman_poll(), this function will
146524 + * deterministically check for the presence of portal processing work and do it,
146525 + * which implies some latency even if there's nothing to do. The bman_poll()
146526 + * wrapper on the other hand (like the qman_poll() wrapper) attenuates this by
146527 + * checking for (and doing) portal processing infrequently. Ie. such that
146528 + * qman_poll() and bman_poll() can be called from core-processing loops. Use
146529 + * bman_poll_slow() when you yourself are deciding when to incur the overhead of
146530 + * processing.
146531 + */
146532 +u32 bman_poll_slow(void);
146533 +
146534 +/**
146535 + * bman_poll - process anything that isn't interrupt-driven.
146536 + *
146537 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
146538 + * affine portal. This function does whatever processing is not triggered by
146539 + * interrupts. This is a legacy wrapper that can be used in core-processing
146540 + * loops but mitigates the performance overhead of portal processing by
146541 + * adaptively bypassing true portal processing most of the time. (Processing is
146542 + * done once every 10 calls if the previous processing revealed that work needed
146543 + * to be done, or once very 1000 calls if the previous processing revealed no
146544 + * work needed doing.) If you wish to control this yourself, call
146545 + * bman_poll_slow() instead, which always checks for portal processing work.
146546 + */
146547 +void bman_poll(void);
146548 +
146549 +/**
146550 + * bman_rcr_is_empty - Determine if portal's RCR is empty
146551 + *
146552 + * For use in situations where a cpu-affine caller needs to determine when all
146553 + * releases for the local portal have been processed by Bman but can't use the
146554 + * BMAN_RELEASE_FLAG_WAIT_SYNC flag to do this from the final bman_release().
146555 + * The function forces tracking of RCR consumption (which normally doesn't
146556 + * happen until release processing needs to find space to put new release
146557 + * commands), and returns zero if the ring still has unprocessed entries,
146558 + * non-zero if it is empty.
146559 + */
146560 +int bman_rcr_is_empty(void);
146561 +
146562 +/**
146563 + * bman_alloc_bpid_range - Allocate a contiguous range of BPIDs
146564 + * @result: is set by the API to the base BPID of the allocated range
146565 + * @count: the number of BPIDs required
146566 + * @align: required alignment of the allocated range
146567 + * @partial: non-zero if the API can return fewer than @count BPIDs
146568 + *
146569 + * Returns the number of buffer pools allocated, or a negative error code. If
146570 + * @partial is non zero, the allocation request may return a smaller range of
146571 + * BPs than requested (though alignment will be as requested). If @partial is
146572 + * zero, the return value will either be 'count' or negative.
146573 + */
146574 +int bman_alloc_bpid_range(u32 *result, u32 count, u32 align, int partial);
146575 +static inline int bman_alloc_bpid(u32 *result)
146576 +{
146577 + int ret = bman_alloc_bpid_range(result, 1, 0, 0);
146578 + return (ret > 0) ? 0 : ret;
146579 +}
146580 +
146581 +/**
146582 + * bman_release_bpid_range - Release the specified range of buffer pool IDs
146583 + * @bpid: the base BPID of the range to deallocate
146584 + * @count: the number of BPIDs in the range
146585 + *
146586 + * This function can also be used to seed the allocator with ranges of BPIDs
146587 + * that it can subsequently allocate from.
146588 + */
146589 +void bman_release_bpid_range(u32 bpid, unsigned int count);
146590 +static inline void bman_release_bpid(u32 bpid)
146591 +{
146592 + bman_release_bpid_range(bpid, 1);
146593 +}
146594 +
146595 +int bman_reserve_bpid_range(u32 bpid, unsigned int count);
146596 +static inline int bman_reserve_bpid(u32 bpid)
146597 +{
146598 + return bman_reserve_bpid_range(bpid, 1);
146599 +}
146600 +
146601 +void bman_seed_bpid_range(u32 bpid, unsigned int count);
146602 +
146603 +
146604 +int bman_shutdown_pool(u32 bpid);
146605 +
146606 + /* Pool management */
146607 + /* --------------- */
146608 +/**
146609 + * bman_new_pool - Allocates a Buffer Pool object
146610 + * @params: parameters specifying the buffer pool ID and behaviour
146611 + *
146612 + * Creates a pool object for the given @params. A portal and the depletion
146613 + * callback field of @params are only used if the BMAN_POOL_FLAG_DEPLETION flag
146614 + * is set. NB, the fields from @params are copied into the new pool object, so
146615 + * the structure provided by the caller can be released or reused after the
146616 + * function returns.
146617 + */
146618 +struct bman_pool *bman_new_pool(const struct bman_pool_params *params);
146619 +
146620 +/**
146621 + * bman_free_pool - Deallocates a Buffer Pool object
146622 + * @pool: the pool object to release
146623 + *
146624 + */
146625 +void bman_free_pool(struct bman_pool *pool);
146626 +
146627 +/**
146628 + * bman_get_params - Returns a pool object's parameters.
146629 + * @pool: the pool object
146630 + *
146631 + * The returned pointer refers to state within the pool object so must not be
146632 + * modified and can no longer be read once the pool object is destroyed.
146633 + */
146634 +const struct bman_pool_params *bman_get_params(const struct bman_pool *pool);
146635 +
146636 +/**
146637 + * bman_release - Release buffer(s) to the buffer pool
146638 + * @pool: the buffer pool object to release to
146639 + * @bufs: an array of buffers to release
146640 + * @num: the number of buffers in @bufs (1-8)
146641 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
146642 + *
146643 + * Adds the given buffers to RCR entries. If the portal @p was created with the
146644 + * "COMPACT" flag, then it will be using a compaction algorithm to improve
146645 + * utilisation of RCR. As such, these buffers may join an existing ring entry
146646 + * and/or it may not be issued right away so as to allow future releases to join
146647 + * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
146648 + * behaviour by committing the RCR entry (or entries) right away. If the RCR
146649 + * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
146650 + * is selected, in which case it will sleep waiting for space to become
146651 + * available in RCR. If the function receives a signal before such time (and
146652 + * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
146653 + * it returns zero.
146654 + */
146655 +int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num,
146656 + u32 flags);
146657 +
146658 +/**
146659 + * bman_acquire - Acquire buffer(s) from a buffer pool
146660 + * @pool: the buffer pool object to acquire from
146661 + * @bufs: array for storing the acquired buffers
146662 + * @num: the number of buffers desired (@bufs is at least this big)
146663 + *
146664 + * Issues an "Acquire" command via the portal's management command interface.
146665 + * The return value will be the number of buffers obtained from the pool, or a
146666 + * negative error code if a h/w error or pool starvation was encountered. In
146667 + * the latter case, the content of @bufs is undefined.
146668 + */
146669 +int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num,
146670 + u32 flags);
146671 +
146672 +/**
146673 + * bman_flush_stockpile - Flush stockpile buffer(s) to the buffer pool
146674 + * @pool: the buffer pool object the stockpile belongs
146675 + * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
146676 + *
146677 + * Adds stockpile buffers to RCR entries until the stockpile is empty.
146678 + * The return value will be a negative error code if a h/w error occurred.
146679 + * If BMAN_RELEASE_FLAG_NOW flag is passed and RCR ring is full,
146680 + * -EAGAIN will be returned.
146681 + */
146682 +int bman_flush_stockpile(struct bman_pool *pool, u32 flags);
146683 +
146684 +/**
146685 + * bman_query_pools - Query all buffer pool states
146686 + * @state: storage for the queried availability and depletion states
146687 + */
146688 +int bman_query_pools(struct bm_pool_state *state);
146689 +
146690 +#ifdef CONFIG_FSL_BMAN_CONFIG
146691 +/**
146692 + * bman_query_free_buffers - Query how many free buffers are in buffer pool
146693 + * @pool: the buffer pool object to query
146694 + *
146695 + * Return the number of the free buffers
146696 + */
146697 +u32 bman_query_free_buffers(struct bman_pool *pool);
146698 +
146699 +/**
146700 + * bman_update_pool_thresholds - Change the buffer pool's depletion thresholds
146701 + * @pool: the buffer pool object to which the thresholds will be set
146702 + * @thresholds: the new thresholds
146703 + */
146704 +int bman_update_pool_thresholds(struct bman_pool *pool, const u32 *thresholds);
146705 +#endif
146706 +
146707 +/**
146708 + * The below bman_p_***() variant might be called in a situation that the cpu
146709 + * which the portal affine to is not online yet.
146710 + * @bman_portal specifies which portal the API will use.
146711 +*/
146712 +int bman_p_irqsource_add(struct bman_portal *p, __maybe_unused u32 bits);
146713 +#ifdef __cplusplus
146714 +}
146715 +#endif
146716 +
146717 +#endif /* FSL_BMAN_H */
146718 --- /dev/null
146719 +++ b/include/linux/fsl_qman.h
146720 @@ -0,0 +1,3910 @@
146721 +/* Copyright 2008-2012 Freescale Semiconductor, Inc.
146722 + *
146723 + * Redistribution and use in source and binary forms, with or without
146724 + * modification, are permitted provided that the following conditions are met:
146725 + * * Redistributions of source code must retain the above copyright
146726 + * notice, this list of conditions and the following disclaimer.
146727 + * * Redistributions in binary form must reproduce the above copyright
146728 + * notice, this list of conditions and the following disclaimer in the
146729 + * documentation and/or other materials provided with the distribution.
146730 + * * Neither the name of Freescale Semiconductor nor the
146731 + * names of its contributors may be used to endorse or promote products
146732 + * derived from this software without specific prior written permission.
146733 + *
146734 + *
146735 + * ALTERNATIVELY, this software may be distributed under the terms of the
146736 + * GNU General Public License ("GPL") as published by the Free Software
146737 + * Foundation, either version 2 of that License or (at your option) any
146738 + * later version.
146739 + *
146740 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
146741 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
146742 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
146743 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
146744 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
146745 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
146746 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
146747 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
146748 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
146749 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
146750 + */
146751 +
146752 +#ifndef FSL_QMAN_H
146753 +#define FSL_QMAN_H
146754 +
146755 +#ifdef __cplusplus
146756 +extern "C" {
146757 +#endif
146758 +
146759 +/* Last updated for v00.800 of the BG */
146760 +
146761 +/* Hardware constants */
146762 +#define QM_CHANNEL_SWPORTAL0 0
146763 +#define QMAN_CHANNEL_POOL1 0x21
146764 +#define QMAN_CHANNEL_CAAM 0x80
146765 +#define QMAN_CHANNEL_PME 0xa0
146766 +#define QMAN_CHANNEL_POOL1_REV3 0x401
146767 +#define QMAN_CHANNEL_CAAM_REV3 0x840
146768 +#define QMAN_CHANNEL_PME_REV3 0x860
146769 +#define QMAN_CHANNEL_DCE 0x8a0
146770 +#define QMAN_CHANNEL_DCE_QMANREV312 0x880
146771 +extern u16 qm_channel_pool1;
146772 +extern u16 qm_channel_caam;
146773 +extern u16 qm_channel_pme;
146774 +extern u16 qm_channel_dce;
146775 +enum qm_dc_portal {
146776 + qm_dc_portal_fman0 = 0,
146777 + qm_dc_portal_fman1 = 1,
146778 + qm_dc_portal_caam = 2,
146779 + qm_dc_portal_pme = 3,
146780 + qm_dc_portal_rman = 4,
146781 + qm_dc_portal_dce = 5
146782 +};
146783 +
146784 +/* Portal processing (interrupt) sources */
146785 +#define QM_PIRQ_CCSCI 0x00200000 /* CEETM Congestion State Change */
146786 +#define QM_PIRQ_CSCI 0x00100000 /* Congestion State Change */
146787 +#define QM_PIRQ_EQCI 0x00080000 /* Enqueue Command Committed */
146788 +#define QM_PIRQ_EQRI 0x00040000 /* EQCR Ring (below threshold) */
146789 +#define QM_PIRQ_DQRI 0x00020000 /* DQRR Ring (non-empty) */
146790 +#define QM_PIRQ_MRI 0x00010000 /* MR Ring (non-empty) */
146791 +/* This mask contains all the interrupt sources that need handling except DQRI,
146792 + * ie. that if present should trigger slow-path processing. */
146793 +#define QM_PIRQ_SLOW (QM_PIRQ_CSCI | QM_PIRQ_EQCI | QM_PIRQ_EQRI | \
146794 + QM_PIRQ_MRI | QM_PIRQ_CCSCI)
146795 +
146796 +/* --- Clock speed --- */
146797 +/* A qman driver instance may or may not know the current qman clock speed.
146798 + * However, certain CEETM calculations may not be possible if this is not known.
146799 + * The 'set' function will only succeed (return zero) if the driver did not
146800 + * already know the clock speed. Likewise, the 'get' function will only succeed
146801 + * if the driver does know the clock speed (either because it knew when booting,
146802 + * or was told via 'set'). In cases where software is running on a driver
146803 + * instance that does not know the clock speed (eg. on a hypervised data-plane),
146804 + * and the user can obtain the current qman clock speed by other means (eg. from
146805 + * a message sent from the control-plane), then the 'set' function can be used
146806 + * to enable rate-calculations in a driver where it would otherwise not be
146807 + * possible. */
146808 +int qm_get_clock(u64 *clock_hz);
146809 +int qm_set_clock(u64 clock_hz);
146810 +
146811 +/* For qman_static_dequeue_*** APIs */
146812 +#define QM_SDQCR_CHANNELS_POOL_MASK 0x00007fff
146813 +/* for n in [1,15] */
146814 +#define QM_SDQCR_CHANNELS_POOL(n) (0x00008000 >> (n))
146815 +/* for conversion from n of qm_channel */
146816 +static inline u32 QM_SDQCR_CHANNELS_POOL_CONV(u16 channel)
146817 +{
146818 + return QM_SDQCR_CHANNELS_POOL(channel + 1 - qm_channel_pool1);
146819 +}
146820 +
146821 +/* For qman_volatile_dequeue(); Choose one PRECEDENCE. EXACT is optional. Use
146822 + * NUMFRAMES(n) (6-bit) or NUMFRAMES_TILLEMPTY to fill in the frame-count. Use
146823 + * FQID(n) to fill in the frame queue ID. */
146824 +#define QM_VDQCR_PRECEDENCE_VDQCR 0x0
146825 +#define QM_VDQCR_PRECEDENCE_SDQCR 0x80000000
146826 +#define QM_VDQCR_EXACT 0x40000000
146827 +#define QM_VDQCR_NUMFRAMES_MASK 0x3f000000
146828 +#define QM_VDQCR_NUMFRAMES_SET(n) (((n) & 0x3f) << 24)
146829 +#define QM_VDQCR_NUMFRAMES_GET(n) (((n) >> 24) & 0x3f)
146830 +#define QM_VDQCR_NUMFRAMES_TILLEMPTY QM_VDQCR_NUMFRAMES_SET(0)
146831 +
146832 +
146833 +/* ------------------------------------------------------- */
146834 +/* --- Qman data structures (and associated constants) --- */
146835 +
146836 +/* Represents s/w corenet portal mapped data structures */
146837 +struct qm_eqcr_entry; /* EQCR (EnQueue Command Ring) entries */
146838 +struct qm_dqrr_entry; /* DQRR (DeQueue Response Ring) entries */
146839 +struct qm_mr_entry; /* MR (Message Ring) entries */
146840 +struct qm_mc_command; /* MC (Management Command) command */
146841 +struct qm_mc_result; /* MC result */
146842 +
146843 +/* See David Lapp's "Frame formats" document, "dpateam", Jan 07, 2008 */
146844 +#define QM_FD_FORMAT_SG 0x4
146845 +#define QM_FD_FORMAT_LONG 0x2
146846 +#define QM_FD_FORMAT_COMPOUND 0x1
146847 +enum qm_fd_format {
146848 + /* 'contig' implies a contiguous buffer, whereas 'sg' implies a
146849 + * scatter-gather table. 'big' implies a 29-bit length with no offset
146850 + * field, otherwise length is 20-bit and offset is 9-bit. 'compound'
146851 + * implies a s/g-like table, where each entry itself represents a frame
146852 + * (contiguous or scatter-gather) and the 29-bit "length" is
146853 + * interpreted purely for congestion calculations, ie. a "congestion
146854 + * weight". */
146855 + qm_fd_contig = 0,
146856 + qm_fd_contig_big = QM_FD_FORMAT_LONG,
146857 + qm_fd_sg = QM_FD_FORMAT_SG,
146858 + qm_fd_sg_big = QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG,
146859 + qm_fd_compound = QM_FD_FORMAT_COMPOUND
146860 +};
146861 +
146862 +/* Capitalised versions are un-typed but can be used in static expressions */
146863 +#define QM_FD_CONTIG 0
146864 +#define QM_FD_CONTIG_BIG QM_FD_FORMAT_LONG
146865 +#define QM_FD_SG QM_FD_FORMAT_SG
146866 +#define QM_FD_SG_BIG (QM_FD_FORMAT_SG | QM_FD_FORMAT_LONG)
146867 +#define QM_FD_COMPOUND QM_FD_FORMAT_COMPOUND
146868 +
146869 +/* See 1.5.1.1: "Frame Descriptor (FD)" */
146870 +struct qm_fd {
146871 + union {
146872 + struct {
146873 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146874 + u8 dd:2; /* dynamic debug */
146875 + u8 liodn_offset:6;
146876 + u8 bpid:8; /* Buffer Pool ID */
146877 + u8 eliodn_offset:4;
146878 + u8 __reserved:4;
146879 + u8 addr_hi; /* high 8-bits of 40-bit address */
146880 + u32 addr_lo; /* low 32-bits of 40-bit address */
146881 +#else
146882 + u32 addr_lo; /* low 32-bits of 40-bit address */
146883 + u8 addr_hi; /* high 8-bits of 40-bit address */
146884 + u8 __reserved:4;
146885 + u8 eliodn_offset:4;
146886 + u8 bpid:8; /* Buffer Pool ID */
146887 + u8 liodn_offset:6;
146888 + u8 dd:2; /* dynamic debug */
146889 +#endif
146890 + };
146891 + struct {
146892 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146893 + u64 __notaddress:24;
146894 + u64 addr:40;
146895 +#else
146896 + u64 addr:40;
146897 + u64 __notaddress:24;
146898 +#endif
146899 + };
146900 + u64 opaque_addr;
146901 + };
146902 + /* The 'format' field indicates the interpretation of the remaining 29
146903 + * bits of the 32-bit word. For packing reasons, it is duplicated in the
146904 + * other union elements. Note, union'd structs are difficult to use with
146905 + * static initialisation under gcc, in which case use the "opaque" form
146906 + * with one of the macros. */
146907 + union {
146908 + /* For easier/faster copying of this part of the fd (eg. from a
146909 + * DQRR entry to an EQCR entry) copy 'opaque' */
146910 + u32 opaque;
146911 + /* If 'format' is _contig or _sg, 20b length and 9b offset */
146912 + struct {
146913 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146914 + enum qm_fd_format format:3;
146915 + u16 offset:9;
146916 + u32 length20:20;
146917 +#else
146918 + u32 length20:20;
146919 + u16 offset:9;
146920 + enum qm_fd_format format:3;
146921 +#endif
146922 + };
146923 + /* If 'format' is _contig_big or _sg_big, 29b length */
146924 + struct {
146925 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146926 + enum qm_fd_format _format1:3;
146927 + u32 length29:29;
146928 +#else
146929 + u32 length29:29;
146930 + enum qm_fd_format _format1:3;
146931 +#endif
146932 + };
146933 + /* If 'format' is _compound, 29b "congestion weight" */
146934 + struct {
146935 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146936 + enum qm_fd_format _format2:3;
146937 + u32 cong_weight:29;
146938 +#else
146939 + u32 cong_weight:29;
146940 + enum qm_fd_format _format2:3;
146941 +#endif
146942 + };
146943 + };
146944 + union {
146945 + u32 cmd;
146946 + u32 status;
146947 + };
146948 +} __aligned(8);
146949 +#define QM_FD_DD_NULL 0x00
146950 +#define QM_FD_PID_MASK 0x3f
146951 +static inline u64 qm_fd_addr_get64(const struct qm_fd *fd)
146952 +{
146953 + return fd->addr;
146954 +}
146955 +
146956 +static inline dma_addr_t qm_fd_addr(const struct qm_fd *fd)
146957 +{
146958 + return (dma_addr_t)fd->addr;
146959 +}
146960 +/* Macro, so we compile better if 'v' isn't always 64-bit */
146961 +#define qm_fd_addr_set64(fd, v) \
146962 + do { \
146963 + struct qm_fd *__fd931 = (fd); \
146964 + __fd931->addr = v; \
146965 + } while (0)
146966 +
146967 +/* For static initialisation of FDs (which is complicated by the use of unions
146968 + * in "struct qm_fd"), use the following macros. Note that;
146969 + * - 'dd', 'pid' and 'bpid' are ignored because there's no static initialisation
146970 + * use-case),
146971 + * - use capitalised QM_FD_*** formats for static initialisation.
146972 + */
146973 +#define QM_FD_FMT_20(cmd, addr_hi, addr_lo, fmt, off, len) \
146974 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
146975 + { (((fmt)&0x7) << 29) | (((off)&0x1ff) << 20) | ((len)&0xfffff) }, \
146976 + { cmd } }
146977 +#define QM_FD_FMT_29(cmd, addr_hi, addr_lo, fmt, len) \
146978 + { 0, 0, 0, 0, 0, addr_hi, addr_lo, \
146979 + { (((fmt)&0x7) << 29) | ((len)&0x1fffffff) }, \
146980 + { cmd } }
146981 +
146982 +/* See 2.2.1.3 Multi-Core Datapath Acceleration Architecture */
146983 +#define QM_SG_OFFSET_MASK 0x1FFF
146984 +struct qm_sg_entry {
146985 + union {
146986 + struct {
146987 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146988 + u8 __reserved1[3];
146989 + u8 addr_hi; /* high 8-bits of 40-bit address */
146990 + u32 addr_lo; /* low 32-bits of 40-bit address */
146991 +#else
146992 + u32 addr_lo; /* low 32-bits of 40-bit address */
146993 + u8 addr_hi; /* high 8-bits of 40-bit address */
146994 + u8 __reserved1[3];
146995 +#endif
146996 + };
146997 + struct {
146998 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
146999 + u64 __notaddress:24;
147000 + u64 addr:40;
147001 +#else
147002 + u64 addr:40;
147003 + u64 __notaddress:24;
147004 +#endif
147005 + };
147006 + u64 opaque;
147007 + };
147008 + union {
147009 + struct {
147010 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147011 + u32 extension:1; /* Extension bit */
147012 + u32 final:1; /* Final bit */
147013 + u32 length:30;
147014 +#else
147015 + u32 length:30;
147016 + u32 final:1; /* Final bit */
147017 + u32 extension:1; /* Extension bit */
147018 +#endif
147019 + };
147020 + u32 sgt_efl;
147021 + };
147022 + u8 __reserved2;
147023 + u8 bpid;
147024 + union {
147025 + struct {
147026 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147027 + u16 __reserved3:3;
147028 + u16 offset:13;
147029 +#else
147030 + u16 offset:13;
147031 + u16 __reserved3:3;
147032 +#endif
147033 + };
147034 + u16 opaque_offset;
147035 + };
147036 +} __packed;
147037 +union qm_sg_efl {
147038 + struct {
147039 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147040 + u32 extension:1; /* Extension bit */
147041 + u32 final:1; /* Final bit */
147042 + u32 length:30;
147043 +#else
147044 + u32 length:30;
147045 + u32 final:1; /* Final bit */
147046 + u32 extension:1; /* Extension bit */
147047 +#endif
147048 + };
147049 + u32 efl;
147050 +};
147051 +static inline dma_addr_t qm_sg_addr(const struct qm_sg_entry *sg)
147052 +{
147053 + return (dma_addr_t)be64_to_cpu(sg->opaque) & 0xffffffffffULL;
147054 +}
147055 +static inline u8 qm_sg_entry_get_ext(const struct qm_sg_entry *sg)
147056 +{
147057 + union qm_sg_efl u;
147058 +
147059 + u.efl = be32_to_cpu(sg->sgt_efl);
147060 + return u.extension;
147061 +}
147062 +static inline u8 qm_sg_entry_get_final(const struct qm_sg_entry *sg)
147063 +{
147064 + union qm_sg_efl u;
147065 +
147066 + u.efl = be32_to_cpu(sg->sgt_efl);
147067 + return u.final;
147068 +}
147069 +static inline u32 qm_sg_entry_get_len(const struct qm_sg_entry *sg)
147070 +{
147071 + union qm_sg_efl u;
147072 +
147073 + u.efl = be32_to_cpu(sg->sgt_efl);
147074 + return u.length;
147075 +}
147076 +static inline u8 qm_sg_entry_get_bpid(const struct qm_sg_entry *sg)
147077 +{
147078 + return sg->bpid;
147079 +}
147080 +static inline u16 qm_sg_entry_get_offset(const struct qm_sg_entry *sg)
147081 +{
147082 + u32 opaque_offset = be16_to_cpu(sg->opaque_offset);
147083 +
147084 + return opaque_offset & 0x1fff;
147085 +}
147086 +
147087 +/* Macro, so we compile better if 'v' isn't always 64-bit */
147088 +#define qm_sg_entry_set64(sg, v) \
147089 + do { \
147090 + struct qm_sg_entry *__sg931 = (sg); \
147091 + __sg931->opaque = cpu_to_be64(v); \
147092 + } while (0)
147093 +#define qm_sg_entry_set_ext(sg, v) \
147094 + do { \
147095 + union qm_sg_efl __u932; \
147096 + __u932.efl = be32_to_cpu((sg)->sgt_efl); \
147097 + __u932.extension = v; \
147098 + (sg)->sgt_efl = cpu_to_be32(__u932.efl); \
147099 + } while (0)
147100 +#define qm_sg_entry_set_final(sg, v) \
147101 + do { \
147102 + union qm_sg_efl __u933; \
147103 + __u933.efl = be32_to_cpu((sg)->sgt_efl); \
147104 + __u933.final = v; \
147105 + (sg)->sgt_efl = cpu_to_be32(__u933.efl); \
147106 + } while (0)
147107 +#define qm_sg_entry_set_len(sg, v) \
147108 + do { \
147109 + union qm_sg_efl __u934; \
147110 + __u934.efl = be32_to_cpu((sg)->sgt_efl); \
147111 + __u934.length = v; \
147112 + (sg)->sgt_efl = cpu_to_be32(__u934.efl); \
147113 + } while (0)
147114 +#define qm_sg_entry_set_bpid(sg, v) \
147115 + do { \
147116 + struct qm_sg_entry *__u935 = (sg); \
147117 + __u935->bpid = v; \
147118 + } while (0)
147119 +#define qm_sg_entry_set_offset(sg, v) \
147120 + do { \
147121 + struct qm_sg_entry *__u936 = (sg); \
147122 + __u936->opaque_offset = cpu_to_be16(v); \
147123 + } while (0)
147124 +
147125 +/* See 1.5.8.1: "Enqueue Command" */
147126 +struct qm_eqcr_entry {
147127 + u8 __dont_write_directly__verb;
147128 + u8 dca;
147129 + u16 seqnum;
147130 + u32 orp; /* 24-bit */
147131 + u32 fqid; /* 24-bit */
147132 + u32 tag;
147133 + struct qm_fd fd;
147134 + u8 __reserved3[32];
147135 +} __packed;
147136 +#define QM_EQCR_VERB_VBIT 0x80
147137 +#define QM_EQCR_VERB_CMD_MASK 0x61 /* but only one value; */
147138 +#define QM_EQCR_VERB_CMD_ENQUEUE 0x01
147139 +#define QM_EQCR_VERB_COLOUR_MASK 0x18 /* 4 possible values; */
147140 +#define QM_EQCR_VERB_COLOUR_GREEN 0x00
147141 +#define QM_EQCR_VERB_COLOUR_YELLOW 0x08
147142 +#define QM_EQCR_VERB_COLOUR_RED 0x10
147143 +#define QM_EQCR_VERB_COLOUR_OVERRIDE 0x18
147144 +#define QM_EQCR_VERB_INTERRUPT 0x04 /* on command consumption */
147145 +#define QM_EQCR_VERB_ORP 0x02 /* enable order restoration */
147146 +#define QM_EQCR_DCA_ENABLE 0x80
147147 +#define QM_EQCR_DCA_PARK 0x40
147148 +#define QM_EQCR_DCA_IDXMASK 0x0f /* "DQRR::idx" goes here */
147149 +#define QM_EQCR_SEQNUM_NESN 0x8000 /* Advance NESN */
147150 +#define QM_EQCR_SEQNUM_NLIS 0x4000 /* More fragments to come */
147151 +#define QM_EQCR_SEQNUM_SEQMASK 0x3fff /* sequence number goes here */
147152 +#define QM_EQCR_FQID_NULL 0 /* eg. for an ORP seqnum hole */
147153 +
147154 +/* See 1.5.8.2: "Frame Dequeue Response" */
147155 +struct qm_dqrr_entry {
147156 + u8 verb;
147157 + u8 stat;
147158 + u16 seqnum; /* 15-bit */
147159 + u8 tok;
147160 + u8 __reserved2[3];
147161 + u32 fqid; /* 24-bit */
147162 + u32 contextB;
147163 + struct qm_fd fd;
147164 + u8 __reserved4[32];
147165 +};
147166 +#define QM_DQRR_VERB_VBIT 0x80
147167 +#define QM_DQRR_VERB_MASK 0x7f /* where the verb contains; */
147168 +#define QM_DQRR_VERB_FRAME_DEQUEUE 0x60 /* "this format" */
147169 +#define QM_DQRR_STAT_FQ_EMPTY 0x80 /* FQ empty */
147170 +#define QM_DQRR_STAT_FQ_HELDACTIVE 0x40 /* FQ held active */
147171 +#define QM_DQRR_STAT_FQ_FORCEELIGIBLE 0x20 /* FQ was force-eligible'd */
147172 +#define QM_DQRR_STAT_FD_VALID 0x10 /* has a non-NULL FD */
147173 +#define QM_DQRR_STAT_UNSCHEDULED 0x02 /* Unscheduled dequeue */
147174 +#define QM_DQRR_STAT_DQCR_EXPIRED 0x01 /* VDQCR or PDQCR expired*/
147175 +
147176 +/* See 1.5.8.3: "ERN Message Response" */
147177 +/* See 1.5.8.4: "FQ State Change Notification" */
147178 +struct qm_mr_entry {
147179 + u8 verb;
147180 + union {
147181 + struct {
147182 + u8 dca;
147183 + u16 seqnum;
147184 + u8 rc; /* Rejection Code */
147185 + u32 orp:24;
147186 + u32 fqid; /* 24-bit */
147187 + u32 tag;
147188 + struct qm_fd fd;
147189 + } __packed ern;
147190 + struct {
147191 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147192 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
147193 + u8 __reserved1:3;
147194 + enum qm_dc_portal portal:3;
147195 +#else
147196 + enum qm_dc_portal portal:3;
147197 + u8 __reserved1:3;
147198 + u8 colour:2; /* See QM_MR_DCERN_COLOUR_* */
147199 +#endif
147200 + u16 __reserved2;
147201 + u8 rc; /* Rejection Code */
147202 + u32 __reserved3:24;
147203 + u32 fqid; /* 24-bit */
147204 + u32 tag;
147205 + struct qm_fd fd;
147206 + } __packed dcern;
147207 + struct {
147208 + u8 fqs; /* Frame Queue Status */
147209 + u8 __reserved1[6];
147210 + u32 fqid; /* 24-bit */
147211 + u32 contextB;
147212 + u8 __reserved2[16];
147213 + } __packed fq; /* FQRN/FQRNI/FQRL/FQPN */
147214 + };
147215 + u8 __reserved2[32];
147216 +} __packed;
147217 +#define QM_MR_VERB_VBIT 0x80
147218 +/* The "ern" VERB bits match QM_EQCR_VERB_*** so aren't reproduced here. ERNs
147219 + * originating from direct-connect portals ("dcern") use 0x20 as a verb which
147220 + * would be invalid as a s/w enqueue verb. A s/w ERN can be distinguished from
147221 + * the other MR types by noting if the 0x20 bit is unset. */
147222 +#define QM_MR_VERB_TYPE_MASK 0x27
147223 +#define QM_MR_VERB_DC_ERN 0x20
147224 +#define QM_MR_VERB_FQRN 0x21
147225 +#define QM_MR_VERB_FQRNI 0x22
147226 +#define QM_MR_VERB_FQRL 0x23
147227 +#define QM_MR_VERB_FQPN 0x24
147228 +#define QM_MR_RC_MASK 0xf0 /* contains one of; */
147229 +#define QM_MR_RC_CGR_TAILDROP 0x00
147230 +#define QM_MR_RC_WRED 0x10
147231 +#define QM_MR_RC_ERROR 0x20
147232 +#define QM_MR_RC_ORPWINDOW_EARLY 0x30
147233 +#define QM_MR_RC_ORPWINDOW_LATE 0x40
147234 +#define QM_MR_RC_FQ_TAILDROP 0x50
147235 +#define QM_MR_RC_ORPWINDOW_RETIRED 0x60
147236 +#define QM_MR_RC_ORP_ZERO 0x70
147237 +#define QM_MR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
147238 +#define QM_MR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
147239 +#define QM_MR_DCERN_COLOUR_GREEN 0x00
147240 +#define QM_MR_DCERN_COLOUR_YELLOW 0x01
147241 +#define QM_MR_DCERN_COLOUR_RED 0x02
147242 +#define QM_MR_DCERN_COLOUR_OVERRIDE 0x03
147243 +
147244 +/* An identical structure of FQD fields is present in the "Init FQ" command and
147245 + * the "Query FQ" result, it's suctioned out into the "struct qm_fqd" type.
147246 + * Within that, the 'stashing' and 'taildrop' pieces are also factored out, the
147247 + * latter has two inlines to assist with converting to/from the mant+exp
147248 + * representation. */
147249 +struct qm_fqd_stashing {
147250 + /* See QM_STASHING_EXCL_<...> */
147251 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147252 + u8 exclusive;
147253 + u8 __reserved1:2;
147254 + /* Numbers of cachelines */
147255 + u8 annotation_cl:2;
147256 + u8 data_cl:2;
147257 + u8 context_cl:2;
147258 +#else
147259 + u8 context_cl:2;
147260 + u8 data_cl:2;
147261 + u8 annotation_cl:2;
147262 + u8 __reserved1:2;
147263 + u8 exclusive;
147264 +#endif
147265 +} __packed;
147266 +struct qm_fqd_taildrop {
147267 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147268 + u16 __reserved1:3;
147269 + u16 mant:8;
147270 + u16 exp:5;
147271 +#else
147272 + u16 exp:5;
147273 + u16 mant:8;
147274 + u16 __reserved1:3;
147275 +#endif
147276 +} __packed;
147277 +struct qm_fqd_oac {
147278 + /* See QM_OAC_<...> */
147279 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147280 + u8 oac:2; /* "Overhead Accounting Control" */
147281 + u8 __reserved1:6;
147282 +#else
147283 + u8 __reserved1:6;
147284 + u8 oac:2; /* "Overhead Accounting Control" */
147285 +#endif
147286 + /* Two's-complement value (-128 to +127) */
147287 + signed char oal; /* "Overhead Accounting Length" */
147288 +} __packed;
147289 +struct qm_fqd {
147290 + union {
147291 + u8 orpc;
147292 + struct {
147293 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147294 + u8 __reserved1:2;
147295 + u8 orprws:3;
147296 + u8 oa:1;
147297 + u8 olws:2;
147298 +#else
147299 + u8 olws:2;
147300 + u8 oa:1;
147301 + u8 orprws:3;
147302 + u8 __reserved1:2;
147303 +#endif
147304 + } __packed;
147305 + };
147306 + u8 cgid;
147307 + u16 fq_ctrl; /* See QM_FQCTRL_<...> */
147308 + union {
147309 + u16 dest_wq;
147310 + struct {
147311 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147312 + u16 channel:13; /* qm_channel */
147313 + u16 wq:3;
147314 +#else
147315 + u16 wq:3;
147316 + u16 channel:13; /* qm_channel */
147317 +#endif
147318 + } __packed dest;
147319 + };
147320 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147321 + u16 __reserved2:1;
147322 + u16 ics_cred:15;
147323 +#else
147324 + u16 __reserved2:1;
147325 + u16 ics_cred:15;
147326 +#endif
147327 + /* For "Initialize Frame Queue" commands, the write-enable mask
147328 + * determines whether 'td' or 'oac_init' is observed. For query
147329 + * commands, this field is always 'td', and 'oac_query' (below) reflects
147330 + * the Overhead ACcounting values. */
147331 + union {
147332 + struct qm_fqd_taildrop td;
147333 + struct qm_fqd_oac oac_init;
147334 + };
147335 + u32 context_b;
147336 + union {
147337 + /* Treat it as 64-bit opaque */
147338 + u64 opaque;
147339 + struct {
147340 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147341 + u32 hi;
147342 + u32 lo;
147343 +#else
147344 + u32 lo;
147345 + u32 hi;
147346 +#endif
147347 + };
147348 + /* Treat it as s/w portal stashing config */
147349 + /* See 1.5.6.7.1: "FQD Context_A field used for [...] */
147350 + struct {
147351 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147352 + struct qm_fqd_stashing stashing;
147353 + /* 48-bit address of FQ context to
147354 + * stash, must be cacheline-aligned */
147355 + u16 context_hi;
147356 + u32 context_lo;
147357 +#else
147358 + u32 context_lo;
147359 + u16 context_hi;
147360 + struct qm_fqd_stashing stashing;
147361 +#endif
147362 + } __packed;
147363 + } context_a;
147364 + struct qm_fqd_oac oac_query;
147365 +} __packed;
147366 +/* 64-bit converters for context_hi/lo */
147367 +static inline u64 qm_fqd_stashing_get64(const struct qm_fqd *fqd)
147368 +{
147369 + return ((u64)fqd->context_a.context_hi << 32) |
147370 + (u64)fqd->context_a.context_lo;
147371 +}
147372 +static inline dma_addr_t qm_fqd_stashing_addr(const struct qm_fqd *fqd)
147373 +{
147374 + return (dma_addr_t)qm_fqd_stashing_get64(fqd);
147375 +}
147376 +static inline u64 qm_fqd_context_a_get64(const struct qm_fqd *fqd)
147377 +{
147378 + return ((u64)fqd->context_a.hi << 32) |
147379 + (u64)fqd->context_a.lo;
147380 +}
147381 +/* Macro, so we compile better when 'v' isn't necessarily 64-bit */
147382 +#define qm_fqd_stashing_set64(fqd, v) \
147383 + do { \
147384 + struct qm_fqd *__fqd931 = (fqd); \
147385 + __fqd931->context_a.context_hi = upper_32_bits(v); \
147386 + __fqd931->context_a.context_lo = lower_32_bits(v); \
147387 + } while (0)
147388 +#define qm_fqd_context_a_set64(fqd, v) \
147389 + do { \
147390 + struct qm_fqd *__fqd931 = (fqd); \
147391 + __fqd931->context_a.hi = upper_32_bits(v); \
147392 + __fqd931->context_a.lo = lower_32_bits(v); \
147393 + } while (0)
147394 +/* convert a threshold value into mant+exp representation */
147395 +static inline int qm_fqd_taildrop_set(struct qm_fqd_taildrop *td, u32 val,
147396 + int roundup)
147397 +{
147398 + u32 e = 0;
147399 + int oddbit = 0;
147400 + if (val > 0xe0000000)
147401 + return -ERANGE;
147402 + while (val > 0xff) {
147403 + oddbit = val & 1;
147404 + val >>= 1;
147405 + e++;
147406 + if (roundup && oddbit)
147407 + val++;
147408 + }
147409 + td->exp = e;
147410 + td->mant = val;
147411 + return 0;
147412 +}
147413 +/* and the other direction */
147414 +static inline u32 qm_fqd_taildrop_get(const struct qm_fqd_taildrop *td)
147415 +{
147416 + return (u32)td->mant << td->exp;
147417 +}
147418 +
147419 +/* See 1.5.2.2: "Frame Queue Descriptor (FQD)" */
147420 +/* Frame Queue Descriptor (FQD) field 'fq_ctrl' uses these constants */
147421 +#define QM_FQCTRL_MASK 0x07ff /* 'fq_ctrl' flags; */
147422 +#define QM_FQCTRL_CGE 0x0400 /* Congestion Group Enable */
147423 +#define QM_FQCTRL_TDE 0x0200 /* Tail-Drop Enable */
147424 +#define QM_FQCTRL_ORP 0x0100 /* ORP Enable */
147425 +#define QM_FQCTRL_CTXASTASHING 0x0080 /* Context-A stashing */
147426 +#define QM_FQCTRL_CPCSTASH 0x0040 /* CPC Stash Enable */
147427 +#define QM_FQCTRL_FORCESFDR 0x0008 /* High-priority SFDRs */
147428 +#define QM_FQCTRL_AVOIDBLOCK 0x0004 /* Don't block active */
147429 +#define QM_FQCTRL_HOLDACTIVE 0x0002 /* Hold active in portal */
147430 +#define QM_FQCTRL_PREFERINCACHE 0x0001 /* Aggressively cache FQD */
147431 +#define QM_FQCTRL_LOCKINCACHE QM_FQCTRL_PREFERINCACHE /* older naming */
147432 +
147433 +/* See 1.5.6.7.1: "FQD Context_A field used for [...] */
147434 +/* Frame Queue Descriptor (FQD) field 'CONTEXT_A' uses these constants */
147435 +#define QM_STASHING_EXCL_ANNOTATION 0x04
147436 +#define QM_STASHING_EXCL_DATA 0x02
147437 +#define QM_STASHING_EXCL_CTX 0x01
147438 +
147439 +/* See 1.5.5.3: "Intra Class Scheduling" */
147440 +/* FQD field 'OAC' (Overhead ACcounting) uses these constants */
147441 +#define QM_OAC_ICS 0x2 /* Accounting for Intra-Class Scheduling */
147442 +#define QM_OAC_CG 0x1 /* Accounting for Congestion Groups */
147443 +
147444 +/* See 1.5.8.4: "FQ State Change Notification" */
147445 +/* This struct represents the 32-bit "WR_PARM_[GYR]" parameters in CGR fields
147446 + * and associated commands/responses. The WRED parameters are calculated from
147447 + * these fields as follows;
147448 + * MaxTH = MA * (2 ^ Mn)
147449 + * Slope = SA / (2 ^ Sn)
147450 + * MaxP = 4 * (Pn + 1)
147451 + */
147452 +struct qm_cgr_wr_parm {
147453 + union {
147454 + u32 word;
147455 + struct {
147456 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147457 + u32 MA:8;
147458 + u32 Mn:5;
147459 + u32 SA:7; /* must be between 64-127 */
147460 + u32 Sn:6;
147461 + u32 Pn:6;
147462 +#else
147463 + u32 Pn:6;
147464 + u32 Sn:6;
147465 + u32 SA:7; /* must be between 64-127 */
147466 + u32 Mn:5;
147467 + u32 MA:8;
147468 +#endif
147469 + } __packed;
147470 + };
147471 +} __packed;
147472 +/* This struct represents the 13-bit "CS_THRES" CGR field. In the corresponding
147473 + * management commands, this is padded to a 16-bit structure field, so that's
147474 + * how we represent it here. The congestion state threshold is calculated from
147475 + * these fields as follows;
147476 + * CS threshold = TA * (2 ^ Tn)
147477 + */
147478 +struct qm_cgr_cs_thres {
147479 + union {
147480 + u16 hword;
147481 + struct {
147482 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147483 + u16 __reserved:3;
147484 + u16 TA:8;
147485 + u16 Tn:5;
147486 +#else
147487 + u16 Tn:5;
147488 + u16 TA:8;
147489 + u16 __reserved:3;
147490 +#endif
147491 + } __packed;
147492 + };
147493 +} __packed;
147494 +/* This identical structure of CGR fields is present in the "Init/Modify CGR"
147495 + * commands and the "Query CGR" result. It's suctioned out here into its own
147496 + * struct. */
147497 +struct __qm_mc_cgr {
147498 + struct qm_cgr_wr_parm wr_parm_g;
147499 + struct qm_cgr_wr_parm wr_parm_y;
147500 + struct qm_cgr_wr_parm wr_parm_r;
147501 + u8 wr_en_g; /* boolean, use QM_CGR_EN */
147502 + u8 wr_en_y; /* boolean, use QM_CGR_EN */
147503 + u8 wr_en_r; /* boolean, use QM_CGR_EN */
147504 + u8 cscn_en; /* boolean, use QM_CGR_EN */
147505 + union {
147506 + struct {
147507 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147508 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
147509 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
147510 +#else
147511 + u16 cscn_targ_dcp_low; /* CSCN_TARG_DCP low-16bits */
147512 + u16 cscn_targ_upd_ctrl; /* use QM_CSCN_TARG_UDP_ */
147513 +#endif
147514 + };
147515 + u32 cscn_targ; /* use QM_CGR_TARG_* */
147516 + };
147517 + u8 cstd_en; /* boolean, use QM_CGR_EN */
147518 + u8 cs; /* boolean, only used in query response */
147519 + union {
147520 + /* use qm_cgr_cs_thres_set64() */
147521 + struct qm_cgr_cs_thres cs_thres;
147522 + u16 __cs_thres;
147523 + };
147524 + u8 mode; /* QMAN_CGR_MODE_FRAME not supported in rev1.0 */
147525 +} __packed;
147526 +#define QM_CGR_EN 0x01 /* For wr_en_*, cscn_en, cstd_en */
147527 +#define QM_CGR_TARG_UDP_CTRL_WRITE_BIT 0x8000 /* value written to portal bit*/
147528 +#define QM_CGR_TARG_UDP_CTRL_DCP 0x4000 /* 0: SWP, 1: DCP */
147529 +#define QM_CGR_TARG_PORTAL(n) (0x80000000 >> (n)) /* s/w portal, 0-9 */
147530 +#define QM_CGR_TARG_FMAN0 0x00200000 /* direct-connect portal: fman0 */
147531 +#define QM_CGR_TARG_FMAN1 0x00100000 /* : fman1 */
147532 +/* Convert CGR thresholds to/from "cs_thres" format */
147533 +static inline u64 qm_cgr_cs_thres_get64(const struct qm_cgr_cs_thres *th)
147534 +{
147535 + return (u64)th->TA << th->Tn;
147536 +}
147537 +static inline int qm_cgr_cs_thres_set64(struct qm_cgr_cs_thres *th, u64 val,
147538 + int roundup)
147539 +{
147540 + u32 e = 0;
147541 + int oddbit = 0;
147542 + while (val > 0xff) {
147543 + oddbit = val & 1;
147544 + val >>= 1;
147545 + e++;
147546 + if (roundup && oddbit)
147547 + val++;
147548 + }
147549 + th->Tn = e;
147550 + th->TA = val;
147551 + return 0;
147552 +}
147553 +
147554 +/* See 1.5.8.5.1: "Initialize FQ" */
147555 +/* See 1.5.8.5.2: "Query FQ" */
147556 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
147557 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
147558 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
147559 +/* See 1.5.8.6.2: "CGR Test Write" */
147560 +/* See 1.5.8.6.3: "Query CGR" */
147561 +/* See 1.5.8.6.4: "Query Congestion Group State" */
147562 +struct qm_mcc_initfq {
147563 + u8 __reserved1;
147564 + u16 we_mask; /* Write Enable Mask */
147565 + u32 fqid; /* 24-bit */
147566 + u16 count; /* Initialises 'count+1' FQDs */
147567 + struct qm_fqd fqd; /* the FQD fields go here */
147568 + u8 __reserved3[30];
147569 +} __packed;
147570 +struct qm_mcc_queryfq {
147571 + u8 __reserved1[3];
147572 + u32 fqid; /* 24-bit */
147573 + u8 __reserved2[56];
147574 +} __packed;
147575 +struct qm_mcc_queryfq_np {
147576 + u8 __reserved1[3];
147577 + u32 fqid; /* 24-bit */
147578 + u8 __reserved2[56];
147579 +} __packed;
147580 +struct qm_mcc_alterfq {
147581 + u8 __reserved1[3];
147582 + u32 fqid; /* 24-bit */
147583 + u8 __reserved2;
147584 + u8 count; /* number of consecutive FQID */
147585 + u8 __reserved3[10];
147586 + u32 context_b; /* frame queue context b */
147587 + u8 __reserved4[40];
147588 +} __packed;
147589 +struct qm_mcc_initcgr {
147590 + u8 __reserved1;
147591 + u16 we_mask; /* Write Enable Mask */
147592 + struct __qm_mc_cgr cgr; /* CGR fields */
147593 + u8 __reserved2[2];
147594 + u8 cgid;
147595 + u8 __reserved4[32];
147596 +} __packed;
147597 +struct qm_mcc_cgrtestwrite {
147598 + u8 __reserved1[2];
147599 + u8 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
147600 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
147601 + u8 __reserved2[23];
147602 + u8 cgid;
147603 + u8 __reserved3[32];
147604 +} __packed;
147605 +struct qm_mcc_querycgr {
147606 + u8 __reserved1[30];
147607 + u8 cgid;
147608 + u8 __reserved2[32];
147609 +} __packed;
147610 +struct qm_mcc_querycongestion {
147611 + u8 __reserved[63];
147612 +} __packed;
147613 +struct qm_mcc_querywq {
147614 + u8 __reserved;
147615 + /* select channel if verb != QUERYWQ_DEDICATED */
147616 + union {
147617 + u16 channel_wq; /* ignores wq (3 lsbits) */
147618 + struct {
147619 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147620 + u16 id:13; /* qm_channel */
147621 + u16 __reserved1:3;
147622 +#else
147623 + u16 __reserved1:3;
147624 + u16 id:13; /* qm_channel */
147625 +#endif
147626 + } __packed channel;
147627 + };
147628 + u8 __reserved2[60];
147629 +} __packed;
147630 +
147631 +struct qm_mcc_ceetm_lfqmt_config {
147632 + u8 __reserved1[4];
147633 + u32 lfqid:24;
147634 + u8 __reserved2[2];
147635 + u16 cqid;
147636 + u8 __reserved3[2];
147637 + u16 dctidx;
147638 + u8 __reserved4[48];
147639 +} __packed;
147640 +
147641 +struct qm_mcc_ceetm_lfqmt_query {
147642 + u8 __reserved1[4];
147643 + u32 lfqid:24;
147644 + u8 __reserved2[56];
147645 +} __packed;
147646 +
147647 +struct qm_mcc_ceetm_cq_config {
147648 + u8 __reserved1;
147649 + u16 cqid;
147650 + u8 dcpid;
147651 + u8 __reserved2;
147652 + u16 ccgid;
147653 + u8 __reserved3[56];
147654 +} __packed;
147655 +
147656 +struct qm_mcc_ceetm_cq_query {
147657 + u8 __reserved1;
147658 + u16 cqid;
147659 + u8 dcpid;
147660 + u8 __reserved2[59];
147661 +} __packed;
147662 +
147663 +struct qm_mcc_ceetm_dct_config {
147664 + u8 __reserved1;
147665 + u16 dctidx;
147666 + u8 dcpid;
147667 + u8 __reserved2[15];
147668 + u32 context_b;
147669 + u64 context_a;
147670 + u8 __reserved3[32];
147671 +} __packed;
147672 +
147673 +struct qm_mcc_ceetm_dct_query {
147674 + u8 __reserved1;
147675 + u16 dctidx;
147676 + u8 dcpid;
147677 + u8 __reserved2[59];
147678 +} __packed;
147679 +
147680 +struct qm_mcc_ceetm_class_scheduler_config {
147681 + u8 __reserved1;
147682 + u16 cqcid;
147683 + u8 dcpid;
147684 + u8 __reserved2[6];
147685 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147686 + u8 gpc_reserved:1;
147687 + u8 gpc_combine_flag:1;
147688 + u8 gpc_prio_b:3;
147689 + u8 gpc_prio_a:3;
147690 +#else
147691 + u8 gpc_prio_a:3;
147692 + u8 gpc_prio_b:3;
147693 + u8 gpc_combine_flag:1;
147694 + u8 gpc_reserved:1;
147695 +#endif
147696 + u16 crem;
147697 + u16 erem;
147698 + u8 w[8];
147699 + u8 __reserved3[40];
147700 +} __packed;
147701 +
147702 +struct qm_mcc_ceetm_class_scheduler_query {
147703 + u8 __reserved1;
147704 + u16 cqcid;
147705 + u8 dcpid;
147706 + u8 __reserved2[59];
147707 +} __packed;
147708 +
147709 +#define CEETM_COMMAND_CHANNEL_MAPPING (0 << 12)
147710 +#define CEETM_COMMAND_SP_MAPPING (1 << 12)
147711 +#define CEETM_COMMAND_CHANNEL_SHAPER (2 << 12)
147712 +#define CEETM_COMMAND_LNI_SHAPER (3 << 12)
147713 +#define CEETM_COMMAND_TCFC (4 << 12)
147714 +
147715 +#define CEETM_CCGRID_MASK 0x01FF
147716 +#define CEETM_CCGR_CM_CONFIGURE (0 << 14)
147717 +#define CEETM_CCGR_DN_CONFIGURE (1 << 14)
147718 +#define CEETM_CCGR_TEST_WRITE (2 << 14)
147719 +#define CEETM_CCGR_CM_QUERY (0 << 14)
147720 +#define CEETM_CCGR_DN_QUERY (1 << 14)
147721 +#define CEETM_CCGR_DN_QUERY_FLUSH (2 << 14)
147722 +#define CEETM_QUERY_CONGESTION_STATE (3 << 14)
147723 +
147724 +struct qm_mcc_ceetm_mapping_shaper_tcfc_config {
147725 + u8 __reserved1;
147726 + u16 cid;
147727 + u8 dcpid;
147728 + union {
147729 + struct {
147730 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147731 + u8 map_shaped:1;
147732 + u8 map_reserved:4;
147733 + u8 map_lni_id:3;
147734 +#else
147735 + u8 map_lni_id:3;
147736 + u8 map_reserved:4;
147737 + u8 map_shaped:1;
147738 +#endif
147739 + u8 __reserved2[58];
147740 + } __packed channel_mapping;
147741 + struct {
147742 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147743 + u8 map_reserved:5;
147744 + u8 map_lni_id:3;
147745 +#else
147746 + u8 map_lni_id:3;
147747 + u8 map_reserved:5;
147748 +#endif
147749 + u8 __reserved2[58];
147750 + } __packed sp_mapping;
147751 + struct {
147752 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147753 + u8 cpl:1;
147754 + u8 cpl_reserved:2;
147755 + u8 oal:5;
147756 +#else
147757 + u8 oal:5;
147758 + u8 cpl_reserved:2;
147759 + u8 cpl:1;
147760 +#endif
147761 + u32 crtcr:24;
147762 + u32 ertcr:24;
147763 + u16 crtbl;
147764 + u16 ertbl;
147765 + u8 mps; /* This will be hardcoded by driver with 60 */
147766 + u8 __reserved2[47];
147767 + } __packed shaper_config;
147768 + struct {
147769 + u8 __reserved2[11];
147770 + u64 lnitcfcc;
147771 + u8 __reserved3[40];
147772 + } __packed tcfc_config;
147773 + };
147774 +} __packed;
147775 +
147776 +struct qm_mcc_ceetm_mapping_shaper_tcfc_query {
147777 + u8 __reserved1;
147778 + u16 cid;
147779 + u8 dcpid;
147780 + u8 __reserved2[59];
147781 +} __packed;
147782 +
147783 +struct qm_mcc_ceetm_ccgr_config {
147784 + u8 __reserved1;
147785 + u16 ccgrid;
147786 + u8 dcpid;
147787 + u8 __reserved2;
147788 + u16 we_mask;
147789 + union {
147790 + struct {
147791 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147792 + u8 ctl_reserved:1;
147793 + u8 ctl_wr_en_g:1;
147794 + u8 ctl_wr_en_y:1;
147795 + u8 ctl_wr_en_r:1;
147796 + u8 ctl_td_en:1;
147797 + u8 ctl_td_mode:1;
147798 + u8 ctl_cscn_en:1;
147799 + u8 ctl_mode:1;
147800 +#else
147801 + u8 ctl_mode:1;
147802 + u8 ctl_cscn_en:1;
147803 + u8 ctl_td_mode:1;
147804 + u8 ctl_td_en:1;
147805 + u8 ctl_wr_en_r:1;
147806 + u8 ctl_wr_en_y:1;
147807 + u8 ctl_wr_en_g:1;
147808 + u8 ctl_reserved:1;
147809 +#endif
147810 + u8 cdv;
147811 + u16 cscn_tupd;
147812 + u8 oal;
147813 + u8 __reserved3;
147814 + struct qm_cgr_cs_thres cs_thres;
147815 + struct qm_cgr_cs_thres cs_thres_x;
147816 + struct qm_cgr_cs_thres td_thres;
147817 + struct qm_cgr_wr_parm wr_parm_g;
147818 + struct qm_cgr_wr_parm wr_parm_y;
147819 + struct qm_cgr_wr_parm wr_parm_r;
147820 + } __packed cm_config;
147821 + struct {
147822 + u8 dnc;
147823 + u8 dn0;
147824 + u8 dn1;
147825 + u64 dnba:40;
147826 + u8 __reserved3[2];
147827 + u16 dnth_0;
147828 + u8 __reserved4[2];
147829 + u16 dnth_1;
147830 + u8 __reserved5[8];
147831 + } __packed dn_config;
147832 + struct {
147833 + u8 __reserved3[3];
147834 + u64 i_cnt:40;
147835 + u8 __reserved4[16];
147836 + } __packed test_write;
147837 + };
147838 + u8 __reserved5[32];
147839 +} __packed;
147840 +
147841 +struct qm_mcc_ceetm_ccgr_query {
147842 + u8 __reserved1;
147843 + u16 ccgrid;
147844 + u8 dcpid;
147845 + u8 __reserved2[59];
147846 +} __packed;
147847 +
147848 +struct qm_mcc_ceetm_cq_peek_pop_xsfdrread {
147849 + u8 __reserved1;
147850 + u16 cqid;
147851 + u8 dcpid;
147852 + u8 ct;
147853 + u16 xsfdr;
147854 + u8 __reserved2[56];
147855 +} __packed;
147856 +
147857 +#define CEETM_QUERY_DEQUEUE_STATISTICS 0x00
147858 +#define CEETM_QUERY_DEQUEUE_CLEAR_STATISTICS 0x01
147859 +#define CEETM_WRITE_DEQUEUE_STATISTICS 0x02
147860 +#define CEETM_QUERY_REJECT_STATISTICS 0x03
147861 +#define CEETM_QUERY_REJECT_CLEAR_STATISTICS 0x04
147862 +#define CEETM_WRITE_REJECT_STATISTICS 0x05
147863 +struct qm_mcc_ceetm_statistics_query_write {
147864 + u8 __reserved1;
147865 + u16 cid;
147866 + u8 dcpid;
147867 + u8 ct;
147868 + u8 __reserved2[13];
147869 + u64 frm_cnt:40;
147870 + u8 __reserved3[2];
147871 + u64 byte_cnt:48;
147872 + u8 __reserved[32];
147873 +} __packed;
147874 +
147875 +struct qm_mc_command {
147876 + u8 __dont_write_directly__verb;
147877 + union {
147878 + struct qm_mcc_initfq initfq;
147879 + struct qm_mcc_queryfq queryfq;
147880 + struct qm_mcc_queryfq_np queryfq_np;
147881 + struct qm_mcc_alterfq alterfq;
147882 + struct qm_mcc_initcgr initcgr;
147883 + struct qm_mcc_cgrtestwrite cgrtestwrite;
147884 + struct qm_mcc_querycgr querycgr;
147885 + struct qm_mcc_querycongestion querycongestion;
147886 + struct qm_mcc_querywq querywq;
147887 + struct qm_mcc_ceetm_lfqmt_config lfqmt_config;
147888 + struct qm_mcc_ceetm_lfqmt_query lfqmt_query;
147889 + struct qm_mcc_ceetm_cq_config cq_config;
147890 + struct qm_mcc_ceetm_cq_query cq_query;
147891 + struct qm_mcc_ceetm_dct_config dct_config;
147892 + struct qm_mcc_ceetm_dct_query dct_query;
147893 + struct qm_mcc_ceetm_class_scheduler_config csch_config;
147894 + struct qm_mcc_ceetm_class_scheduler_query csch_query;
147895 + struct qm_mcc_ceetm_mapping_shaper_tcfc_config mst_config;
147896 + struct qm_mcc_ceetm_mapping_shaper_tcfc_query mst_query;
147897 + struct qm_mcc_ceetm_ccgr_config ccgr_config;
147898 + struct qm_mcc_ceetm_ccgr_query ccgr_query;
147899 + struct qm_mcc_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
147900 + struct qm_mcc_ceetm_statistics_query_write stats_query_write;
147901 + };
147902 +} __packed;
147903 +#define QM_MCC_VERB_VBIT 0x80
147904 +#define QM_MCC_VERB_MASK 0x7f /* where the verb contains; */
147905 +#define QM_MCC_VERB_INITFQ_PARKED 0x40
147906 +#define QM_MCC_VERB_INITFQ_SCHED 0x41
147907 +#define QM_MCC_VERB_QUERYFQ 0x44
147908 +#define QM_MCC_VERB_QUERYFQ_NP 0x45 /* "non-programmable" fields */
147909 +#define QM_MCC_VERB_QUERYWQ 0x46
147910 +#define QM_MCC_VERB_QUERYWQ_DEDICATED 0x47
147911 +#define QM_MCC_VERB_ALTER_SCHED 0x48 /* Schedule FQ */
147912 +#define QM_MCC_VERB_ALTER_FE 0x49 /* Force Eligible FQ */
147913 +#define QM_MCC_VERB_ALTER_RETIRE 0x4a /* Retire FQ */
147914 +#define QM_MCC_VERB_ALTER_OOS 0x4b /* Take FQ out of service */
147915 +#define QM_MCC_VERB_ALTER_FQXON 0x4d /* FQ XON */
147916 +#define QM_MCC_VERB_ALTER_FQXOFF 0x4e /* FQ XOFF */
147917 +#define QM_MCC_VERB_INITCGR 0x50
147918 +#define QM_MCC_VERB_MODIFYCGR 0x51
147919 +#define QM_MCC_VERB_CGRTESTWRITE 0x52
147920 +#define QM_MCC_VERB_QUERYCGR 0x58
147921 +#define QM_MCC_VERB_QUERYCONGESTION 0x59
147922 +/* INITFQ-specific flags */
147923 +#define QM_INITFQ_WE_MASK 0x01ff /* 'Write Enable' flags; */
147924 +#define QM_INITFQ_WE_OAC 0x0100
147925 +#define QM_INITFQ_WE_ORPC 0x0080
147926 +#define QM_INITFQ_WE_CGID 0x0040
147927 +#define QM_INITFQ_WE_FQCTRL 0x0020
147928 +#define QM_INITFQ_WE_DESTWQ 0x0010
147929 +#define QM_INITFQ_WE_ICSCRED 0x0008
147930 +#define QM_INITFQ_WE_TDTHRESH 0x0004
147931 +#define QM_INITFQ_WE_CONTEXTB 0x0002
147932 +#define QM_INITFQ_WE_CONTEXTA 0x0001
147933 +/* INITCGR/MODIFYCGR-specific flags */
147934 +#define QM_CGR_WE_MASK 0x07ff /* 'Write Enable Mask'; */
147935 +#define QM_CGR_WE_WR_PARM_G 0x0400
147936 +#define QM_CGR_WE_WR_PARM_Y 0x0200
147937 +#define QM_CGR_WE_WR_PARM_R 0x0100
147938 +#define QM_CGR_WE_WR_EN_G 0x0080
147939 +#define QM_CGR_WE_WR_EN_Y 0x0040
147940 +#define QM_CGR_WE_WR_EN_R 0x0020
147941 +#define QM_CGR_WE_CSCN_EN 0x0010
147942 +#define QM_CGR_WE_CSCN_TARG 0x0008
147943 +#define QM_CGR_WE_CSTD_EN 0x0004
147944 +#define QM_CGR_WE_CS_THRES 0x0002
147945 +#define QM_CGR_WE_MODE 0x0001
147946 +
147947 +/* See 1.5.9.7 CEETM Management Commands */
147948 +#define QM_CEETM_VERB_LFQMT_CONFIG 0x70
147949 +#define QM_CEETM_VERB_LFQMT_QUERY 0x71
147950 +#define QM_CEETM_VERB_CQ_CONFIG 0x72
147951 +#define QM_CEETM_VERB_CQ_QUERY 0x73
147952 +#define QM_CEETM_VERB_DCT_CONFIG 0x74
147953 +#define QM_CEETM_VERB_DCT_QUERY 0x75
147954 +#define QM_CEETM_VERB_CLASS_SCHEDULER_CONFIG 0x76
147955 +#define QM_CEETM_VERB_CLASS_SCHEDULER_QUERY 0x77
147956 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_CONFIG 0x78
147957 +#define QM_CEETM_VERB_MAPPING_SHAPER_TCFC_QUERY 0x79
147958 +#define QM_CEETM_VERB_CCGR_CONFIG 0x7A
147959 +#define QM_CEETM_VERB_CCGR_QUERY 0x7B
147960 +#define QM_CEETM_VERB_CQ_PEEK_POP_XFDRREAD 0x7C
147961 +#define QM_CEETM_VERB_STATISTICS_QUERY_WRITE 0x7D
147962 +
147963 +/* See 1.5.8.5.1: "Initialize FQ" */
147964 +/* See 1.5.8.5.2: "Query FQ" */
147965 +/* See 1.5.8.5.3: "Query FQ Non-Programmable Fields" */
147966 +/* See 1.5.8.5.4: "Alter FQ State Commands " */
147967 +/* See 1.5.8.6.1: "Initialize/Modify CGR" */
147968 +/* See 1.5.8.6.2: "CGR Test Write" */
147969 +/* See 1.5.8.6.3: "Query CGR" */
147970 +/* See 1.5.8.6.4: "Query Congestion Group State" */
147971 +struct qm_mcr_initfq {
147972 + u8 __reserved1[62];
147973 +} __packed;
147974 +struct qm_mcr_queryfq {
147975 + u8 __reserved1[8];
147976 + struct qm_fqd fqd; /* the FQD fields are here */
147977 + u8 __reserved2[30];
147978 +} __packed;
147979 +struct qm_mcr_queryfq_np {
147980 + u8 __reserved1;
147981 + u8 state; /* QM_MCR_NP_STATE_*** */
147982 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
147983 + u8 __reserved2;
147984 + u32 fqd_link:24;
147985 + u16 __reserved3:2;
147986 + u16 odp_seq:14;
147987 + u16 __reserved4:2;
147988 + u16 orp_nesn:14;
147989 + u16 __reserved5:1;
147990 + u16 orp_ea_hseq:15;
147991 + u16 __reserved6:1;
147992 + u16 orp_ea_tseq:15;
147993 + u8 __reserved7;
147994 + u32 orp_ea_hptr:24;
147995 + u8 __reserved8;
147996 + u32 orp_ea_tptr:24;
147997 + u8 __reserved9;
147998 + u32 pfdr_hptr:24;
147999 + u8 __reserved10;
148000 + u32 pfdr_tptr:24;
148001 + u8 __reserved11[5];
148002 + u8 __reserved12:7;
148003 + u8 is:1;
148004 + u16 ics_surp;
148005 + u32 byte_cnt;
148006 + u8 __reserved13;
148007 + u32 frm_cnt:24;
148008 + u32 __reserved14;
148009 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
148010 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
148011 + u16 __reserved15;
148012 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
148013 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
148014 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
148015 +#else
148016 + u8 __reserved2;
148017 + u32 fqd_link:24;
148018 +
148019 + u16 odp_seq:14;
148020 + u16 __reserved3:2;
148021 +
148022 + u16 orp_nesn:14;
148023 + u16 __reserved4:2;
148024 +
148025 + u16 orp_ea_hseq:15;
148026 + u16 __reserved5:1;
148027 +
148028 + u16 orp_ea_tseq:15;
148029 + u16 __reserved6:1;
148030 +
148031 + u8 __reserved7;
148032 + u32 orp_ea_hptr:24;
148033 +
148034 + u8 __reserved8;
148035 + u32 orp_ea_tptr:24;
148036 +
148037 + u8 __reserved9;
148038 + u32 pfdr_hptr:24;
148039 +
148040 + u8 __reserved10;
148041 + u32 pfdr_tptr:24;
148042 +
148043 + u8 __reserved11[5];
148044 + u8 is:1;
148045 + u8 __reserved12:7;
148046 + u16 ics_surp;
148047 + u32 byte_cnt;
148048 + u8 __reserved13;
148049 + u32 frm_cnt:24;
148050 + u32 __reserved14;
148051 + u16 ra1_sfdr; /* QM_MCR_NP_RA1_*** */
148052 + u16 ra2_sfdr; /* QM_MCR_NP_RA2_*** */
148053 + u16 __reserved15;
148054 + u16 od1_sfdr; /* QM_MCR_NP_OD1_*** */
148055 + u16 od2_sfdr; /* QM_MCR_NP_OD2_*** */
148056 + u16 od3_sfdr; /* QM_MCR_NP_OD3_*** */
148057 +#endif
148058 +} __packed;
148059 +
148060 +
148061 +struct qm_mcr_alterfq {
148062 + u8 fqs; /* Frame Queue Status */
148063 + u8 __reserved1[61];
148064 +} __packed;
148065 +struct qm_mcr_initcgr {
148066 + u8 __reserved1[62];
148067 +} __packed;
148068 +struct qm_mcr_cgrtestwrite {
148069 + u16 __reserved1;
148070 + struct __qm_mc_cgr cgr; /* CGR fields */
148071 + u8 __reserved2[3];
148072 + u32 __reserved3:24;
148073 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
148074 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
148075 + u32 __reserved4:24;
148076 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
148077 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
148078 + u16 lgt; /* Last Group Tick */
148079 + u16 wr_prob_g;
148080 + u16 wr_prob_y;
148081 + u16 wr_prob_r;
148082 + u8 __reserved5[8];
148083 +} __packed;
148084 +struct qm_mcr_querycgr {
148085 + u16 __reserved1;
148086 + struct __qm_mc_cgr cgr; /* CGR fields */
148087 + u8 __reserved2[3];
148088 + union {
148089 + struct {
148090 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
148091 + u32 __reserved3:24;
148092 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
148093 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
148094 +#else
148095 + u32 i_bcnt_lo; /* low 32-bits of 40-bit */
148096 + u32 i_bcnt_hi:8;/* high 8-bits of 40-bit "Instant" */
148097 + u32 __reserved3:24;
148098 +#endif
148099 + };
148100 + u64 i_bcnt;
148101 + };
148102 + union {
148103 + struct {
148104 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
148105 + u32 __reserved4:24;
148106 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
148107 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
148108 +#else
148109 + u32 a_bcnt_lo; /* low 32-bits of 40-bit */
148110 + u32 a_bcnt_hi:8;/* high 8-bits of 40-bit "Average" */
148111 + u32 __reserved4:24;
148112 +#endif
148113 + };
148114 + u64 a_bcnt;
148115 + };
148116 + union {
148117 + u32 cscn_targ_swp[4];
148118 + u8 __reserved5[16];
148119 + };
148120 +} __packed;
148121 +static inline u64 qm_mcr_querycgr_i_get64(const struct qm_mcr_querycgr *q)
148122 +{
148123 + return be64_to_cpu(q->i_bcnt);
148124 +}
148125 +static inline u64 qm_mcr_querycgr_a_get64(const struct qm_mcr_querycgr *q)
148126 +{
148127 + return be64_to_cpu(q->a_bcnt);
148128 +}
148129 +static inline u64 qm_mcr_cgrtestwrite_i_get64(
148130 + const struct qm_mcr_cgrtestwrite *q)
148131 +{
148132 + return be64_to_cpu(((u64)q->i_bcnt_hi << 32) | (u64)q->i_bcnt_lo);
148133 +}
148134 +static inline u64 qm_mcr_cgrtestwrite_a_get64(
148135 + const struct qm_mcr_cgrtestwrite *q)
148136 +{
148137 + return be64_to_cpu(((u64)q->a_bcnt_hi << 32) | (u64)q->a_bcnt_lo);
148138 +}
148139 +/* Macro, so we compile better if 'v' isn't always 64-bit */
148140 +#define qm_mcr_querycgr_i_set64(q, v) \
148141 + do { \
148142 + struct qm_mcr_querycgr *__q931 = (fd); \
148143 + __q931->i_bcnt_hi = upper_32_bits(v); \
148144 + __q931->i_bcnt_lo = lower_32_bits(v); \
148145 + } while (0)
148146 +#define qm_mcr_querycgr_a_set64(q, v) \
148147 + do { \
148148 + struct qm_mcr_querycgr *__q931 = (fd); \
148149 + __q931->a_bcnt_hi = upper_32_bits(v); \
148150 + __q931->a_bcnt_lo = lower_32_bits(v); \
148151 + } while (0)
148152 +struct __qm_mcr_querycongestion {
148153 + u32 __state[8];
148154 +};
148155 +struct qm_mcr_querycongestion {
148156 + u8 __reserved[30];
148157 + /* Access this struct using QM_MCR_QUERYCONGESTION() */
148158 + struct __qm_mcr_querycongestion state;
148159 +} __packed;
148160 +struct qm_mcr_querywq {
148161 + union {
148162 + u16 channel_wq; /* ignores wq (3 lsbits) */
148163 + struct {
148164 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
148165 + u16 id:13; /* qm_channel */
148166 + u16 __reserved:3;
148167 +#else
148168 + u16 __reserved:3;
148169 + u16 id:13; /* qm_channel */
148170 +#endif
148171 + } __packed channel;
148172 + };
148173 + u8 __reserved[28];
148174 + u32 wq_len[8];
148175 +} __packed;
148176 +
148177 +/* QMAN CEETM Management Command Response */
148178 +struct qm_mcr_ceetm_lfqmt_config {
148179 + u8 __reserved1[62];
148180 +} __packed;
148181 +struct qm_mcr_ceetm_lfqmt_query {
148182 + u8 __reserved1[8];
148183 + u16 cqid;
148184 + u8 __reserved2[2];
148185 + u16 dctidx;
148186 + u8 __reserved3[2];
148187 + u16 ccgid;
148188 + u8 __reserved4[44];
148189 +} __packed;
148190 +
148191 +struct qm_mcr_ceetm_cq_config {
148192 + u8 __reserved1[62];
148193 +} __packed;
148194 +
148195 +struct qm_mcr_ceetm_cq_query {
148196 + u8 __reserved1[4];
148197 + u16 ccgid;
148198 + u16 state;
148199 + u32 pfdr_hptr:24;
148200 + u32 pfdr_tptr:24;
148201 + u16 od1_xsfdr;
148202 + u16 od2_xsfdr;
148203 + u16 od3_xsfdr;
148204 + u16 od4_xsfdr;
148205 + u16 od5_xsfdr;
148206 + u16 od6_xsfdr;
148207 + u16 ra1_xsfdr;
148208 + u16 ra2_xsfdr;
148209 + u8 __reserved2;
148210 + u32 frm_cnt:24;
148211 + u8 __reserved333[28];
148212 +} __packed;
148213 +
148214 +struct qm_mcr_ceetm_dct_config {
148215 + u8 __reserved1[62];
148216 +} __packed;
148217 +
148218 +struct qm_mcr_ceetm_dct_query {
148219 + u8 __reserved1[18];
148220 + u32 context_b;
148221 + u64 context_a;
148222 + u8 __reserved2[32];
148223 +} __packed;
148224 +
148225 +struct qm_mcr_ceetm_class_scheduler_config {
148226 + u8 __reserved1[62];
148227 +} __packed;
148228 +
148229 +struct qm_mcr_ceetm_class_scheduler_query {
148230 + u8 __reserved1[9];
148231 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
148232 + u8 gpc_reserved:1;
148233 + u8 gpc_combine_flag:1;
148234 + u8 gpc_prio_b:3;
148235 + u8 gpc_prio_a:3;
148236 +#else
148237 + u8 gpc_prio_a:3;
148238 + u8 gpc_prio_b:3;
148239 + u8 gpc_combine_flag:1;
148240 + u8 gpc_reserved:1;
148241 +#endif
148242 + u16 crem;
148243 + u16 erem;
148244 + u8 w[8];
148245 + u8 __reserved2[5];
148246 + u32 wbfslist:24;
148247 + u32 d8;
148248 + u32 d9;
148249 + u32 d10;
148250 + u32 d11;
148251 + u32 d12;
148252 + u32 d13;
148253 + u32 d14;
148254 + u32 d15;
148255 +} __packed;
148256 +
148257 +struct qm_mcr_ceetm_mapping_shaper_tcfc_config {
148258 + u16 cid;
148259 + u8 __reserved2[60];
148260 +} __packed;
148261 +
148262 +struct qm_mcr_ceetm_mapping_shaper_tcfc_query {
148263 + u16 cid;
148264 + u8 __reserved1;
148265 + union {
148266 + struct {
148267 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
148268 + u8 map_shaped:1;
148269 + u8 map_reserved:4;
148270 + u8 map_lni_id:3;
148271 +#else
148272 + u8 map_lni_id:3;
148273 + u8 map_reserved:4;
148274 + u8 map_shaped:1;
148275 +#endif
148276 + u8 __reserved2[58];
148277 + } __packed channel_mapping_query;
148278 + struct {
148279 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
148280 + u8 map_reserved:5;
148281 + u8 map_lni_id:3;
148282 +#else
148283 + u8 map_lni_id:3;
148284 + u8 map_reserved:5;
148285 +#endif
148286 + u8 __reserved2[58];
148287 + } __packed sp_mapping_query;
148288 + struct {
148289 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
148290 + u8 cpl:1;
148291 + u8 cpl_reserved:2;
148292 + u8 oal:5;
148293 +#else
148294 + u8 oal:5;
148295 + u8 cpl_reserved:2;
148296 + u8 cpl:1;
148297 +#endif
148298 + u32 crtcr:24;
148299 + u32 ertcr:24;
148300 + u16 crtbl;
148301 + u16 ertbl;
148302 + u8 mps;
148303 + u8 __reserved2[15];
148304 + u32 crat;
148305 + u32 erat;
148306 + u8 __reserved3[24];
148307 + } __packed shaper_query;
148308 + struct {
148309 + u8 __reserved1[11];
148310 + u64 lnitcfcc;
148311 + u8 __reserved3[40];
148312 + } __packed tcfc_query;
148313 + };
148314 +} __packed;
148315 +
148316 +struct qm_mcr_ceetm_ccgr_config {
148317 + u8 __reserved1[46];
148318 + union {
148319 + u8 __reserved2[8];
148320 + struct {
148321 + u16 timestamp;
148322 + u16 wr_porb_g;
148323 + u16 wr_prob_y;
148324 + u16 wr_prob_r;
148325 + } __packed test_write;
148326 + };
148327 + u8 __reserved3[8];
148328 +} __packed;
148329 +
148330 +struct qm_mcr_ceetm_ccgr_query {
148331 + u8 __reserved1[6];
148332 + union {
148333 + struct {
148334 +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
148335 + u8 ctl_reserved:1;
148336 + u8 ctl_wr_en_g:1;
148337 + u8 ctl_wr_en_y:1;
148338 + u8 ctl_wr_en_r:1;
148339 + u8 ctl_td_en:1;
148340 + u8 ctl_td_mode:1;
148341 + u8 ctl_cscn_en:1;
148342 + u8 ctl_mode:1;
148343 +#else
148344 + u8 ctl_mode:1;
148345 + u8 ctl_cscn_en:1;
148346 + u8 ctl_td_mode:1;
148347 + u8 ctl_td_en:1;
148348 + u8 ctl_wr_en_r:1;
148349 + u8 ctl_wr_en_y:1;
148350 + u8 ctl_wr_en_g:1;
148351 + u8 ctl_reserved:1;
148352 +#endif
148353 + u8 cdv;
148354 + u8 __reserved2[2];
148355 + u8 oal;
148356 + u8 __reserved3;
148357 + struct qm_cgr_cs_thres cs_thres;
148358 + struct qm_cgr_cs_thres cs_thres_x;
148359 + struct qm_cgr_cs_thres td_thres;
148360 + struct qm_cgr_wr_parm wr_parm_g;
148361 + struct qm_cgr_wr_parm wr_parm_y;
148362 + struct qm_cgr_wr_parm wr_parm_r;
148363 + u16 cscn_targ_dcp;
148364 + u8 dcp_lsn;
148365 + u64 i_cnt:40;
148366 + u8 __reserved4[3];
148367 + u64 a_cnt:40;
148368 + u32 cscn_targ_swp[4];
148369 + } __packed cm_query;
148370 + struct {
148371 + u8 dnc;
148372 + u8 dn0;
148373 + u8 dn1;
148374 + u64 dnba:40;
148375 + u8 __reserved2[2];
148376 + u16 dnth_0;
148377 + u8 __reserved3[2];
148378 + u16 dnth_1;
148379 + u8 __reserved4[10];
148380 + u16 dnacc_0;
148381 + u8 __reserved5[2];
148382 + u16 dnacc_1;
148383 + u8 __reserved6[24];
148384 + } __packed dn_query;
148385 + struct {
148386 + u8 __reserved2[24];
148387 + struct __qm_mcr_querycongestion state;
148388 + } __packed congestion_state;
148389 +
148390 + };
148391 +} __packed;
148392 +
148393 +struct qm_mcr_ceetm_cq_peek_pop_xsfdrread {
148394 + u8 stat;
148395 + u8 __reserved1[11];
148396 + u16 dctidx;
148397 + struct qm_fd fd;
148398 + u8 __reserved2[32];
148399 +} __packed;
148400 +
148401 +struct qm_mcr_ceetm_statistics_query {
148402 + u8 __reserved1[17];
148403 + u64 frm_cnt:40;
148404 + u8 __reserved2[2];
148405 + u64 byte_cnt:48;
148406 + u8 __reserved3[32];
148407 +} __packed;
148408 +
148409 +struct qm_mc_result {
148410 + u8 verb;
148411 + u8 result;
148412 + union {
148413 + struct qm_mcr_initfq initfq;
148414 + struct qm_mcr_queryfq queryfq;
148415 + struct qm_mcr_queryfq_np queryfq_np;
148416 + struct qm_mcr_alterfq alterfq;
148417 + struct qm_mcr_initcgr initcgr;
148418 + struct qm_mcr_cgrtestwrite cgrtestwrite;
148419 + struct qm_mcr_querycgr querycgr;
148420 + struct qm_mcr_querycongestion querycongestion;
148421 + struct qm_mcr_querywq querywq;
148422 + struct qm_mcr_ceetm_lfqmt_config lfqmt_config;
148423 + struct qm_mcr_ceetm_lfqmt_query lfqmt_query;
148424 + struct qm_mcr_ceetm_cq_config cq_config;
148425 + struct qm_mcr_ceetm_cq_query cq_query;
148426 + struct qm_mcr_ceetm_dct_config dct_config;
148427 + struct qm_mcr_ceetm_dct_query dct_query;
148428 + struct qm_mcr_ceetm_class_scheduler_config csch_config;
148429 + struct qm_mcr_ceetm_class_scheduler_query csch_query;
148430 + struct qm_mcr_ceetm_mapping_shaper_tcfc_config mst_config;
148431 + struct qm_mcr_ceetm_mapping_shaper_tcfc_query mst_query;
148432 + struct qm_mcr_ceetm_ccgr_config ccgr_config;
148433 + struct qm_mcr_ceetm_ccgr_query ccgr_query;
148434 + struct qm_mcr_ceetm_cq_peek_pop_xsfdrread cq_ppxr;
148435 + struct qm_mcr_ceetm_statistics_query stats_query;
148436 + };
148437 +} __packed;
148438 +
148439 +#define QM_MCR_VERB_RRID 0x80
148440 +#define QM_MCR_VERB_MASK QM_MCC_VERB_MASK
148441 +#define QM_MCR_VERB_INITFQ_PARKED QM_MCC_VERB_INITFQ_PARKED
148442 +#define QM_MCR_VERB_INITFQ_SCHED QM_MCC_VERB_INITFQ_SCHED
148443 +#define QM_MCR_VERB_QUERYFQ QM_MCC_VERB_QUERYFQ
148444 +#define QM_MCR_VERB_QUERYFQ_NP QM_MCC_VERB_QUERYFQ_NP
148445 +#define QM_MCR_VERB_QUERYWQ QM_MCC_VERB_QUERYWQ
148446 +#define QM_MCR_VERB_QUERYWQ_DEDICATED QM_MCC_VERB_QUERYWQ_DEDICATED
148447 +#define QM_MCR_VERB_ALTER_SCHED QM_MCC_VERB_ALTER_SCHED
148448 +#define QM_MCR_VERB_ALTER_FE QM_MCC_VERB_ALTER_FE
148449 +#define QM_MCR_VERB_ALTER_RETIRE QM_MCC_VERB_ALTER_RETIRE
148450 +#define QM_MCR_VERB_ALTER_OOS QM_MCC_VERB_ALTER_OOS
148451 +#define QM_MCR_RESULT_NULL 0x00
148452 +#define QM_MCR_RESULT_OK 0xf0
148453 +#define QM_MCR_RESULT_ERR_FQID 0xf1
148454 +#define QM_MCR_RESULT_ERR_FQSTATE 0xf2
148455 +#define QM_MCR_RESULT_ERR_NOTEMPTY 0xf3 /* OOS fails if FQ is !empty */
148456 +#define QM_MCR_RESULT_ERR_BADCHANNEL 0xf4
148457 +#define QM_MCR_RESULT_PENDING 0xf8
148458 +#define QM_MCR_RESULT_ERR_BADCOMMAND 0xff
148459 +#define QM_MCR_NP_STATE_FE 0x10
148460 +#define QM_MCR_NP_STATE_R 0x08
148461 +#define QM_MCR_NP_STATE_MASK 0x07 /* Reads FQD::STATE; */
148462 +#define QM_MCR_NP_STATE_OOS 0x00
148463 +#define QM_MCR_NP_STATE_RETIRED 0x01
148464 +#define QM_MCR_NP_STATE_TEN_SCHED 0x02
148465 +#define QM_MCR_NP_STATE_TRU_SCHED 0x03
148466 +#define QM_MCR_NP_STATE_PARKED 0x04
148467 +#define QM_MCR_NP_STATE_ACTIVE 0x05
148468 +#define QM_MCR_NP_PTR_MASK 0x07ff /* for RA[12] & OD[123] */
148469 +#define QM_MCR_NP_RA1_NRA(v) (((v) >> 14) & 0x3) /* FQD::NRA */
148470 +#define QM_MCR_NP_RA2_IT(v) (((v) >> 14) & 0x1) /* FQD::IT */
148471 +#define QM_MCR_NP_OD1_NOD(v) (((v) >> 14) & 0x3) /* FQD::NOD */
148472 +#define QM_MCR_NP_OD3_NPC(v) (((v) >> 14) & 0x3) /* FQD::NPC */
148473 +#define QM_MCR_FQS_ORLPRESENT 0x02 /* ORL fragments to come */
148474 +#define QM_MCR_FQS_NOTEMPTY 0x01 /* FQ has enqueued frames */
148475 +/* This extracts the state for congestion group 'n' from a query response.
148476 + * Eg.
148477 + * u8 cgr = [...];
148478 + * struct qm_mc_result *res = [...];
148479 + * printf("congestion group %d congestion state: %d\n", cgr,
148480 + * QM_MCR_QUERYCONGESTION(&res->querycongestion.state, cgr));
148481 + */
148482 +#define __CGR_WORD(num) (num >> 5)
148483 +#define __CGR_SHIFT(num) (num & 0x1f)
148484 +#define __CGR_NUM (sizeof(struct __qm_mcr_querycongestion) << 3)
148485 +static inline int QM_MCR_QUERYCONGESTION(struct __qm_mcr_querycongestion *p,
148486 + u8 cgr)
148487 +{
148488 + return p->__state[__CGR_WORD(cgr)] & (0x80000000 >> __CGR_SHIFT(cgr));
148489 +}
148490 +
148491 +
148492 +/*********************/
148493 +/* Utility interface */
148494 +/*********************/
148495 +
148496 +/* Represents an allocator over a range of FQIDs. NB, accesses are not locked,
148497 + * spinlock them yourself if needed. */
148498 +struct qman_fqid_pool;
148499 +
148500 +/* Create/destroy a FQID pool, num must be a multiple of 32. NB, _destroy()
148501 + * always succeeds, but returns non-zero if there were "leaked" FQID
148502 + * allocations. */
148503 +struct qman_fqid_pool *qman_fqid_pool_create(u32 fqid_start, u32 num);
148504 +int qman_fqid_pool_destroy(struct qman_fqid_pool *pool);
148505 +/* Alloc/free a FQID from the range. _alloc() returns zero for success. */
148506 +int qman_fqid_pool_alloc(struct qman_fqid_pool *pool, u32 *fqid);
148507 +void qman_fqid_pool_free(struct qman_fqid_pool *pool, u32 fqid);
148508 +u32 qman_fqid_pool_used(struct qman_fqid_pool *pool);
148509 +
148510 +/*******************************************************************/
148511 +/* Managed (aka "shared" or "mux/demux") portal, high-level i/face */
148512 +/*******************************************************************/
148513 +
148514 + /* Portal and Frame Queues */
148515 + /* ----------------------- */
148516 +/* Represents a managed portal */
148517 +struct qman_portal;
148518 +
148519 +/* This object type represents Qman frame queue descriptors (FQD), it is
148520 + * cacheline-aligned, and initialised by qman_create_fq(). The structure is
148521 + * defined further down. */
148522 +struct qman_fq;
148523 +
148524 +/* This object type represents a Qman congestion group, it is defined further
148525 + * down. */
148526 +struct qman_cgr;
148527 +
148528 +struct qman_portal_config {
148529 + /* If the caller enables DQRR stashing (and thus wishes to operate the
148530 + * portal from only one cpu), this is the logical CPU that the portal
148531 + * will stash to. Whether stashing is enabled or not, this setting is
148532 + * also used for any "core-affine" portals, ie. default portals
148533 + * associated to the corresponding cpu. -1 implies that there is no core
148534 + * affinity configured. */
148535 + int cpu;
148536 + /* portal interrupt line */
148537 + int irq;
148538 + /* the unique index of this portal */
148539 + u32 index;
148540 + /* Is this portal shared? (If so, it has coarser locking and demuxes
148541 + * processing on behalf of other CPUs.) */
148542 + int is_shared;
148543 + /* The portal's dedicated channel id, use this value for initialising
148544 + * frame queues to target this portal when scheduled. */
148545 + u16 channel;
148546 + /* A mask of which pool channels this portal has dequeue access to
148547 + * (using QM_SDQCR_CHANNELS_POOL(n) for the bitmask) */
148548 + u32 pools;
148549 +};
148550 +
148551 +/* This enum, and the callback type that returns it, are used when handling
148552 + * dequeued frames via DQRR. Note that for "null" callbacks registered with the
148553 + * portal object (for handling dequeues that do not demux because contextB is
148554 + * NULL), the return value *MUST* be qman_cb_dqrr_consume. */
148555 +enum qman_cb_dqrr_result {
148556 + /* DQRR entry can be consumed */
148557 + qman_cb_dqrr_consume,
148558 + /* Like _consume, but requests parking - FQ must be held-active */
148559 + qman_cb_dqrr_park,
148560 + /* Does not consume, for DCA mode only. This allows out-of-order
148561 + * consumes by explicit calls to qman_dca() and/or the use of implicit
148562 + * DCA via EQCR entries. */
148563 + qman_cb_dqrr_defer,
148564 + /* Stop processing without consuming this ring entry. Exits the current
148565 + * qman_poll_dqrr() or interrupt-handling, as appropriate. If within an
148566 + * interrupt handler, the callback would typically call
148567 + * qman_irqsource_remove(QM_PIRQ_DQRI) before returning this value,
148568 + * otherwise the interrupt will reassert immediately. */
148569 + qman_cb_dqrr_stop,
148570 + /* Like qman_cb_dqrr_stop, but consumes the current entry. */
148571 + qman_cb_dqrr_consume_stop
148572 +};
148573 +typedef enum qman_cb_dqrr_result (*qman_cb_dqrr)(struct qman_portal *qm,
148574 + struct qman_fq *fq,
148575 + const struct qm_dqrr_entry *dqrr);
148576 +
148577 +/* This callback type is used when handling ERNs, FQRNs and FQRLs via MR. They
148578 + * are always consumed after the callback returns. */
148579 +typedef void (*qman_cb_mr)(struct qman_portal *qm, struct qman_fq *fq,
148580 + const struct qm_mr_entry *msg);
148581 +
148582 +/* This callback type is used when handling DCP ERNs */
148583 +typedef void (*qman_cb_dc_ern)(struct qman_portal *qm,
148584 + const struct qm_mr_entry *msg);
148585 +
148586 +/* s/w-visible states. Ie. tentatively scheduled + truly scheduled + active +
148587 + * held-active + held-suspended are just "sched". Things like "retired" will not
148588 + * be assumed until it is complete (ie. QMAN_FQ_STATE_CHANGING is set until
148589 + * then, to indicate it's completing and to gate attempts to retry the retire
148590 + * command). Note, park commands do not set QMAN_FQ_STATE_CHANGING because it's
148591 + * technically impossible in the case of enqueue DCAs (which refer to DQRR ring
148592 + * index rather than the FQ that ring entry corresponds to), so repeated park
148593 + * commands are allowed (if you're silly enough to try) but won't change FQ
148594 + * state, and the resulting park notifications move FQs from "sched" to
148595 + * "parked". */
148596 +enum qman_fq_state {
148597 + qman_fq_state_oos,
148598 + qman_fq_state_parked,
148599 + qman_fq_state_sched,
148600 + qman_fq_state_retired
148601 +};
148602 +
148603 +/* Frame queue objects (struct qman_fq) are stored within memory passed to
148604 + * qman_create_fq(), as this allows stashing of caller-provided demux callback
148605 + * pointers at no extra cost to stashing of (driver-internal) FQ state. If the
148606 + * caller wishes to add per-FQ state and have it benefit from dequeue-stashing,
148607 + * they should;
148608 + *
148609 + * (a) extend the qman_fq structure with their state; eg.
148610 + *
148611 + * // myfq is allocated and driver_fq callbacks filled in;
148612 + * struct my_fq {
148613 + * struct qman_fq base;
148614 + * int an_extra_field;
148615 + * [ ... add other fields to be associated with each FQ ...]
148616 + * } *myfq = some_my_fq_allocator();
148617 + * struct qman_fq *fq = qman_create_fq(fqid, flags, &myfq->base);
148618 + *
148619 + * // in a dequeue callback, access extra fields from 'fq' via a cast;
148620 + * struct my_fq *myfq = (struct my_fq *)fq;
148621 + * do_something_with(myfq->an_extra_field);
148622 + * [...]
148623 + *
148624 + * (b) when and if configuring the FQ for context stashing, specify how ever
148625 + * many cachelines are required to stash 'struct my_fq', to accelerate not
148626 + * only the Qman driver but the callback as well.
148627 + */
148628 +
148629 +struct qman_fq_cb {
148630 + qman_cb_dqrr dqrr; /* for dequeued frames */
148631 + qman_cb_mr ern; /* for s/w ERNs */
148632 + qman_cb_mr fqs; /* frame-queue state changes*/
148633 +};
148634 +
148635 +struct qman_fq {
148636 + /* Caller of qman_create_fq() provides these demux callbacks */
148637 + struct qman_fq_cb cb;
148638 + /* These are internal to the driver, don't touch. In particular, they
148639 + * may change, be removed, or extended (so you shouldn't rely on
148640 + * sizeof(qman_fq) being a constant). */
148641 + spinlock_t fqlock;
148642 + u32 fqid;
148643 + volatile unsigned long flags;
148644 + enum qman_fq_state state;
148645 + int cgr_groupid;
148646 + struct rb_node node;
148647 +#ifdef CONFIG_FSL_QMAN_FQ_LOOKUP
148648 + u32 key;
148649 +#endif
148650 +};
148651 +
148652 +/* This callback type is used when handling congestion group entry/exit.
148653 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit. */
148654 +typedef void (*qman_cb_cgr)(struct qman_portal *qm,
148655 + struct qman_cgr *cgr, int congested);
148656 +
148657 +struct qman_cgr {
148658 + /* Set these prior to qman_create_cgr() */
148659 + u32 cgrid; /* 0..255, but u32 to allow specials like -1, 256, etc.*/
148660 + qman_cb_cgr cb;
148661 + /* These are private to the driver */
148662 + u16 chan; /* portal channel this object is created on */
148663 + struct list_head node;
148664 +};
148665 +
148666 +/* Flags to qman_create_fq() */
148667 +#define QMAN_FQ_FLAG_NO_ENQUEUE 0x00000001 /* can't enqueue */
148668 +#define QMAN_FQ_FLAG_NO_MODIFY 0x00000002 /* can only enqueue */
148669 +#define QMAN_FQ_FLAG_TO_DCPORTAL 0x00000004 /* consumed by CAAM/PME/Fman */
148670 +#define QMAN_FQ_FLAG_LOCKED 0x00000008 /* multi-core locking */
148671 +#define QMAN_FQ_FLAG_AS_IS 0x00000010 /* query h/w state */
148672 +#define QMAN_FQ_FLAG_DYNAMIC_FQID 0x00000020 /* (de)allocate fqid */
148673 +
148674 +/* Flags to qman_destroy_fq() */
148675 +#define QMAN_FQ_DESTROY_PARKED 0x00000001 /* FQ can be parked or OOS */
148676 +
148677 +/* Flags from qman_fq_state() */
148678 +#define QMAN_FQ_STATE_CHANGING 0x80000000 /* 'state' is changing */
148679 +#define QMAN_FQ_STATE_NE 0x40000000 /* retired FQ isn't empty */
148680 +#define QMAN_FQ_STATE_ORL 0x20000000 /* retired FQ has ORL */
148681 +#define QMAN_FQ_STATE_BLOCKOOS 0xe0000000 /* if any are set, no OOS */
148682 +#define QMAN_FQ_STATE_CGR_EN 0x10000000 /* CGR enabled */
148683 +#define QMAN_FQ_STATE_VDQCR 0x08000000 /* being volatile dequeued */
148684 +
148685 +/* Flags to qman_init_fq() */
148686 +#define QMAN_INITFQ_FLAG_SCHED 0x00000001 /* schedule rather than park */
148687 +#define QMAN_INITFQ_FLAG_LOCAL 0x00000004 /* set dest portal */
148688 +
148689 +/* Flags to qman_volatile_dequeue() */
148690 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
148691 +#define QMAN_VOLATILE_FLAG_WAIT 0x00000001 /* wait if VDQCR is in use */
148692 +#define QMAN_VOLATILE_FLAG_WAIT_INT 0x00000002 /* if wait, interruptible? */
148693 +#define QMAN_VOLATILE_FLAG_FINISH 0x00000004 /* wait till VDQCR completes */
148694 +#endif
148695 +
148696 +/* Flags to qman_enqueue(). NB, the strange numbering is to align with hardware,
148697 + * bit-wise. (NB: the PME API is sensitive to these precise numberings too, so
148698 + * any change here should be audited in PME.) */
148699 +#ifdef CONFIG_FSL_DPA_CAN_WAIT
148700 +#define QMAN_ENQUEUE_FLAG_WAIT 0x00010000 /* wait if EQCR is full */
148701 +#define QMAN_ENQUEUE_FLAG_WAIT_INT 0x00020000 /* if wait, interruptible? */
148702 +#ifdef CONFIG_FSL_DPA_CAN_WAIT_SYNC
148703 +#define QMAN_ENQUEUE_FLAG_WAIT_SYNC 0x00000004 /* if wait, until consumed? */
148704 +#endif
148705 +#endif
148706 +#define QMAN_ENQUEUE_FLAG_WATCH_CGR 0x00080000 /* watch congestion state */
148707 +#define QMAN_ENQUEUE_FLAG_DCA 0x00008000 /* perform enqueue-DCA */
148708 +#define QMAN_ENQUEUE_FLAG_DCA_PARK 0x00004000 /* If DCA, requests park */
148709 +#define QMAN_ENQUEUE_FLAG_DCA_PTR(p) /* If DCA, p is DQRR entry */ \
148710 + (((u32)(p) << 2) & 0x00000f00)
148711 +#define QMAN_ENQUEUE_FLAG_C_GREEN 0x00000000 /* choose one C_*** flag */
148712 +#define QMAN_ENQUEUE_FLAG_C_YELLOW 0x00000008
148713 +#define QMAN_ENQUEUE_FLAG_C_RED 0x00000010
148714 +#define QMAN_ENQUEUE_FLAG_C_OVERRIDE 0x00000018
148715 +/* For the ORP-specific qman_enqueue_orp() variant;
148716 + * - this flag indicates "Not Last In Sequence", ie. all but the final fragment
148717 + * of a frame. */
148718 +#define QMAN_ENQUEUE_FLAG_NLIS 0x01000000
148719 +/* - this flag performs no enqueue but fills in an ORP sequence number that
148720 + * would otherwise block it (eg. if a frame has been dropped). */
148721 +#define QMAN_ENQUEUE_FLAG_HOLE 0x02000000
148722 +/* - this flag performs no enqueue but advances NESN to the given sequence
148723 + * number. */
148724 +#define QMAN_ENQUEUE_FLAG_NESN 0x04000000
148725 +
148726 +/* Flags to qman_modify_cgr() */
148727 +#define QMAN_CGR_FLAG_USE_INIT 0x00000001
148728 +#define QMAN_CGR_MODE_FRAME 0x00000001
148729 +
148730 + /* Portal Management */
148731 + /* ----------------- */
148732 +/**
148733 + * qman_get_portal_config - get portal configuration settings
148734 + *
148735 + * This returns a read-only view of the current cpu's affine portal settings.
148736 + */
148737 +const struct qman_portal_config *qman_get_portal_config(void);
148738 +
148739 +/**
148740 + * qman_irqsource_get - return the portal work that is interrupt-driven
148741 + *
148742 + * Returns a bitmask of QM_PIRQ_**I processing sources that are currently
148743 + * enabled for interrupt handling on the current cpu's affine portal. These
148744 + * sources will trigger the portal interrupt and the interrupt handler (or a
148745 + * tasklet/bottom-half it defers to) will perform the corresponding processing
148746 + * work. The qman_poll_***() functions will only process sources that are not in
148747 + * this bitmask. If the current CPU is sharing a portal hosted on another CPU,
148748 + * this always returns zero.
148749 + */
148750 +u32 qman_irqsource_get(void);
148751 +
148752 +/**
148753 + * qman_irqsource_add - add processing sources to be interrupt-driven
148754 + * @bits: bitmask of QM_PIRQ_**I processing sources
148755 + *
148756 + * Adds processing sources that should be interrupt-driven (rather than
148757 + * processed via qman_poll_***() functions). Returns zero for success, or
148758 + * -EINVAL if the current CPU is sharing a portal hosted on another CPU.
148759 + */
148760 +int qman_irqsource_add(u32 bits);
148761 +
148762 +/**
148763 + * qman_irqsource_remove - remove processing sources from being interrupt-driven
148764 + * @bits: bitmask of QM_PIRQ_**I processing sources
148765 + *
148766 + * Removes processing sources from being interrupt-driven, so that they will
148767 + * instead be processed via qman_poll_***() functions. Returns zero for success,
148768 + * or -EINVAL if the current CPU is sharing a portal hosted on another CPU.
148769 + */
148770 +int qman_irqsource_remove(u32 bits);
148771 +
148772 +/**
148773 + * qman_affine_cpus - return a mask of cpus that have affine portals
148774 + */
148775 +const cpumask_t *qman_affine_cpus(void);
148776 +
148777 +/**
148778 + * qman_affine_channel - return the channel ID of an portal
148779 + * @cpu: the cpu whose affine portal is the subject of the query
148780 + *
148781 + * If @cpu is -1, the affine portal for the current CPU will be used. It is a
148782 + * bug to call this function for any value of @cpu (other than -1) that is not a
148783 + * member of the mask returned from qman_affine_cpus().
148784 + */
148785 +u16 qman_affine_channel(int cpu);
148786 +
148787 +/**
148788 + * qman_get_affine_portal - return the portal pointer affine to cpu
148789 + * @cpu: the cpu whose affine portal is the subject of the query
148790 + *
148791 + */
148792 +void *qman_get_affine_portal(int cpu);
148793 +
148794 +/**
148795 + * qman_poll_dqrr - process DQRR (fast-path) entries
148796 + * @limit: the maximum number of DQRR entries to process
148797 + *
148798 + * Use of this function requires that DQRR processing not be interrupt-driven.
148799 + * Ie. the value returned by qman_irqsource_get() should not include
148800 + * QM_PIRQ_DQRI. If the current CPU is sharing a portal hosted on another CPU,
148801 + * this function will return -EINVAL, otherwise the return value is >=0 and
148802 + * represents the number of DQRR entries processed.
148803 + */
148804 +int qman_poll_dqrr(unsigned int limit);
148805 +
148806 +/**
148807 + * qman_poll_slow - process anything (except DQRR) that isn't interrupt-driven.
148808 + *
148809 + * This function does any portal processing that isn't interrupt-driven. If the
148810 + * current CPU is sharing a portal hosted on another CPU, this function will
148811 + * return (u32)-1, otherwise the return value is a bitmask of QM_PIRQ_* sources
148812 + * indicating what interrupt sources were actually processed by the call.
148813 + */
148814 +u32 qman_poll_slow(void);
148815 +
148816 +/**
148817 + * qman_poll - legacy wrapper for qman_poll_dqrr() and qman_poll_slow()
148818 + *
148819 + * Dispatcher logic on a cpu can use this to trigger any maintenance of the
148820 + * affine portal. There are two classes of portal processing in question;
148821 + * fast-path (which involves demuxing dequeue ring (DQRR) entries and tracking
148822 + * enqueue ring (EQCR) consumption), and slow-path (which involves EQCR
148823 + * thresholds, congestion state changes, etc). This function does whatever
148824 + * processing is not triggered by interrupts.
148825 + *
148826 + * Note, if DQRR and some slow-path processing are poll-driven (rather than
148827 + * interrupt-driven) then this function uses a heuristic to determine how often
148828 + * to run slow-path processing - as slow-path processing introduces at least a
148829 + * minimum latency each time it is run, whereas fast-path (DQRR) processing is
148830 + * close to zero-cost if there is no work to be done. Applications can tune this
148831 + * behaviour themselves by using qman_poll_dqrr() and qman_poll_slow() directly
148832 + * rather than going via this wrapper.
148833 + */
148834 +void qman_poll(void);
148835 +
148836 +/**
148837 + * qman_stop_dequeues - Stop h/w dequeuing to the s/w portal
148838 + *
148839 + * Disables DQRR processing of the portal. This is reference-counted, so
148840 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
148841 + * truly re-enable dequeuing.
148842 + */
148843 +void qman_stop_dequeues(void);
148844 +
148845 +/**
148846 + * qman_start_dequeues - (Re)start h/w dequeuing to the s/w portal
148847 + *
148848 + * Enables DQRR processing of the portal. This is reference-counted, so
148849 + * qman_start_dequeues() must be called as many times as qman_stop_dequeues() to
148850 + * truly re-enable dequeuing.
148851 + */
148852 +void qman_start_dequeues(void);
148853 +
148854 +/**
148855 + * qman_static_dequeue_add - Add pool channels to the portal SDQCR
148856 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
148857 + *
148858 + * Adds a set of pool channels to the portal's static dequeue command register
148859 + * (SDQCR). The requested pools are limited to those the portal has dequeue
148860 + * access to.
148861 + */
148862 +void qman_static_dequeue_add(u32 pools);
148863 +
148864 +/**
148865 + * qman_static_dequeue_del - Remove pool channels from the portal SDQCR
148866 + * @pools: bit-mask of pool channels, using QM_SDQCR_CHANNELS_POOL(n)
148867 + *
148868 + * Removes a set of pool channels from the portal's static dequeue command
148869 + * register (SDQCR). The requested pools are limited to those the portal has
148870 + * dequeue access to.
148871 + */
148872 +void qman_static_dequeue_del(u32 pools);
148873 +
148874 +/**
148875 + * qman_static_dequeue_get - return the portal's current SDQCR
148876 + *
148877 + * Returns the portal's current static dequeue command register (SDQCR). The
148878 + * entire register is returned, so if only the currently-enabled pool channels
148879 + * are desired, mask the return value with QM_SDQCR_CHANNELS_POOL_MASK.
148880 + */
148881 +u32 qman_static_dequeue_get(void);
148882 +
148883 +/**
148884 + * qman_dca - Perform a Discrete Consumption Acknowledgement
148885 + * @dq: the DQRR entry to be consumed
148886 + * @park_request: indicates whether the held-active @fq should be parked
148887 + *
148888 + * Only allowed in DCA-mode portals, for DQRR entries whose handler callback had
148889 + * previously returned 'qman_cb_dqrr_defer'. NB, as with the other APIs, this
148890 + * does not take a 'portal' argument but implies the core affine portal from the
148891 + * cpu that is currently executing the function. For reasons of locking, this
148892 + * function must be called from the same CPU as that which processed the DQRR
148893 + * entry in the first place.
148894 + */
148895 +void qman_dca(struct qm_dqrr_entry *dq, int park_request);
148896 +
148897 +/**
148898 + * qman_eqcr_is_empty - Determine if portal's EQCR is empty
148899 + *
148900 + * For use in situations where a cpu-affine caller needs to determine when all
148901 + * enqueues for the local portal have been processed by Qman but can't use the
148902 + * QMAN_ENQUEUE_FLAG_WAIT_SYNC flag to do this from the final qman_enqueue().
148903 + * The function forces tracking of EQCR consumption (which normally doesn't
148904 + * happen until enqueue processing needs to find space to put new enqueue
148905 + * commands), and returns zero if the ring still has unprocessed entries,
148906 + * non-zero if it is empty.
148907 + */
148908 +int qman_eqcr_is_empty(void);
148909 +
148910 +/**
148911 + * qman_set_dc_ern - Set the handler for DCP enqueue rejection notifications
148912 + * @handler: callback for processing DCP ERNs
148913 + * @affine: whether this handler is specific to the locally affine portal
148914 + *
148915 + * If a hardware block's interface to Qman (ie. its direct-connect portal, or
148916 + * DCP) is configured not to receive enqueue rejections, then any enqueues
148917 + * through that DCP that are rejected will be sent to a given software portal.
148918 + * If @affine is non-zero, then this handler will only be used for DCP ERNs
148919 + * received on the portal affine to the current CPU. If multiple CPUs share a
148920 + * portal and they all call this function, they will be setting the handler for
148921 + * the same portal! If @affine is zero, then this handler will be global to all
148922 + * portals handled by this instance of the driver. Only those portals that do
148923 + * not have their own affine handler will use the global handler.
148924 + */
148925 +void qman_set_dc_ern(qman_cb_dc_ern handler, int affine);
148926 +
148927 + /* FQ management */
148928 + /* ------------- */
148929 +/**
148930 + * qman_create_fq - Allocates a FQ
148931 + * @fqid: the index of the FQD to encapsulate, must be "Out of Service"
148932 + * @flags: bit-mask of QMAN_FQ_FLAG_*** options
148933 + * @fq: memory for storing the 'fq', with callbacks filled in
148934 + *
148935 + * Creates a frame queue object for the given @fqid, unless the
148936 + * QMAN_FQ_FLAG_DYNAMIC_FQID flag is set in @flags, in which case a FQID is
148937 + * dynamically allocated (or the function fails if none are available). Once
148938 + * created, the caller should not touch the memory at 'fq' except as extended to
148939 + * adjacent memory for user-defined fields (see the definition of "struct
148940 + * qman_fq" for more info). NO_MODIFY is only intended for enqueuing to
148941 + * pre-existing frame-queues that aren't to be otherwise interfered with, it
148942 + * prevents all other modifications to the frame queue. The TO_DCPORTAL flag
148943 + * causes the driver to honour any contextB modifications requested in the
148944 + * qm_init_fq() API, as this indicates the frame queue will be consumed by a
148945 + * direct-connect portal (PME, CAAM, or Fman). When frame queues are consumed by
148946 + * software portals, the contextB field is controlled by the driver and can't be
148947 + * modified by the caller. If the AS_IS flag is specified, management commands
148948 + * will be used on portal @p to query state for frame queue @fqid and construct
148949 + * a frame queue object based on that, rather than assuming/requiring that it be
148950 + * Out of Service.
148951 + */
148952 +int qman_create_fq(u32 fqid, u32 flags, struct qman_fq *fq);
148953 +
148954 +/**
148955 + * qman_destroy_fq - Deallocates a FQ
148956 + * @fq: the frame queue object to release
148957 + * @flags: bit-mask of QMAN_FQ_FREE_*** options
148958 + *
148959 + * The memory for this frame queue object ('fq' provided in qman_create_fq()) is
148960 + * not deallocated but the caller regains ownership, to do with as desired. The
148961 + * FQ must be in the 'out-of-service' state unless the QMAN_FQ_FREE_PARKED flag
148962 + * is specified, in which case it may also be in the 'parked' state.
148963 + */
148964 +void qman_destroy_fq(struct qman_fq *fq, u32 flags);
148965 +
148966 +/**
148967 + * qman_fq_fqid - Queries the frame queue ID of a FQ object
148968 + * @fq: the frame queue object to query
148969 + */
148970 +u32 qman_fq_fqid(struct qman_fq *fq);
148971 +
148972 +/**
148973 + * qman_fq_state - Queries the state of a FQ object
148974 + * @fq: the frame queue object to query
148975 + * @state: pointer to state enum to return the FQ scheduling state
148976 + * @flags: pointer to state flags to receive QMAN_FQ_STATE_*** bitmask
148977 + *
148978 + * Queries the state of the FQ object, without performing any h/w commands.
148979 + * This captures the state, as seen by the driver, at the time the function
148980 + * executes.
148981 + */
148982 +void qman_fq_state(struct qman_fq *fq, enum qman_fq_state *state, u32 *flags);
148983 +
148984 +/**
148985 + * qman_init_fq - Initialises FQ fields, leaves the FQ "parked" or "scheduled"
148986 + * @fq: the frame queue object to modify, must be 'parked' or new.
148987 + * @flags: bit-mask of QMAN_INITFQ_FLAG_*** options
148988 + * @opts: the FQ-modification settings, as defined in the low-level API
148989 + *
148990 + * The @opts parameter comes from the low-level portal API. Select
148991 + * QMAN_INITFQ_FLAG_SCHED in @flags to cause the frame queue to be scheduled
148992 + * rather than parked. NB, @opts can be NULL.
148993 + *
148994 + * Note that some fields and options within @opts may be ignored or overwritten
148995 + * by the driver;
148996 + * 1. the 'count' and 'fqid' fields are always ignored (this operation only
148997 + * affects one frame queue: @fq).
148998 + * 2. the QM_INITFQ_WE_CONTEXTB option of the 'we_mask' field and the associated
148999 + * 'fqd' structure's 'context_b' field are sometimes overwritten;
149000 + * - if @fq was not created with QMAN_FQ_FLAG_TO_DCPORTAL, then context_b is
149001 + * initialised to a value used by the driver for demux.
149002 + * - if context_b is initialised for demux, so is context_a in case stashing
149003 + * is requested (see item 4).
149004 + * (So caller control of context_b is only possible for TO_DCPORTAL frame queue
149005 + * objects.)
149006 + * 3. if @flags contains QMAN_INITFQ_FLAG_LOCAL, the 'fqd' structure's
149007 + * 'dest::channel' field will be overwritten to match the portal used to issue
149008 + * the command. If the WE_DESTWQ write-enable bit had already been set by the
149009 + * caller, the channel workqueue will be left as-is, otherwise the write-enable
149010 + * bit is set and the workqueue is set to a default of 4. If the "LOCAL" flag
149011 + * isn't set, the destination channel/workqueue fields and the write-enable bit
149012 + * are left as-is.
149013 + * 4. if the driver overwrites context_a/b for demux, then if
149014 + * QM_INITFQ_WE_CONTEXTA is set, the driver will only overwrite
149015 + * context_a.address fields and will leave the stashing fields provided by the
149016 + * user alone, otherwise it will zero out the context_a.stashing fields.
149017 + */
149018 +int qman_init_fq(struct qman_fq *fq, u32 flags, struct qm_mcc_initfq *opts);
149019 +
149020 +/**
149021 + * qman_schedule_fq - Schedules a FQ
149022 + * @fq: the frame queue object to schedule, must be 'parked'
149023 + *
149024 + * Schedules the frame queue, which must be Parked, which takes it to
149025 + * Tentatively-Scheduled or Truly-Scheduled depending on its fill-level.
149026 + */
149027 +int qman_schedule_fq(struct qman_fq *fq);
149028 +
149029 +/**
149030 + * qman_retire_fq - Retires a FQ
149031 + * @fq: the frame queue object to retire
149032 + * @flags: FQ flags (as per qman_fq_state) if retirement completes immediately
149033 + *
149034 + * Retires the frame queue. This returns zero if it succeeds immediately, +1 if
149035 + * the retirement was started asynchronously, otherwise it returns negative for
149036 + * failure. When this function returns zero, @flags is set to indicate whether
149037 + * the retired FQ is empty and/or whether it has any ORL fragments (to show up
149038 + * as ERNs). Otherwise the corresponding flags will be known when a subsequent
149039 + * FQRN message shows up on the portal's message ring.
149040 + *
149041 + * NB, if the retirement is asynchronous (the FQ was in the Truly Scheduled or
149042 + * Active state), the completion will be via the message ring as a FQRN - but
149043 + * the corresponding callback may occur before this function returns!! Ie. the
149044 + * caller should be prepared to accept the callback as the function is called,
149045 + * not only once it has returned.
149046 + */
149047 +int qman_retire_fq(struct qman_fq *fq, u32 *flags);
149048 +
149049 +/**
149050 + * qman_oos_fq - Puts a FQ "out of service"
149051 + * @fq: the frame queue object to be put out-of-service, must be 'retired'
149052 + *
149053 + * The frame queue must be retired and empty, and if any order restoration list
149054 + * was released as ERNs at the time of retirement, they must all be consumed.
149055 + */
149056 +int qman_oos_fq(struct qman_fq *fq);
149057 +
149058 +/**
149059 + * qman_fq_flow_control - Set the XON/XOFF state of a FQ
149060 + * @fq: the frame queue object to be set to XON/XOFF state, must not be 'oos',
149061 + * or 'retired' or 'parked' state
149062 + * @xon: boolean to set fq in XON or XOFF state
149063 + *
149064 + * The frame should be in Tentatively Scheduled state or Truly Schedule sate,
149065 + * otherwise the IFSI interrupt will be asserted.
149066 + */
149067 +int qman_fq_flow_control(struct qman_fq *fq, int xon);
149068 +
149069 +/**
149070 + * qman_query_fq - Queries FQD fields (via h/w query command)
149071 + * @fq: the frame queue object to be queried
149072 + * @fqd: storage for the queried FQD fields
149073 + */
149074 +int qman_query_fq(struct qman_fq *fq, struct qm_fqd *fqd);
149075 +
149076 +/**
149077 + * qman_query_fq_np - Queries non-programmable FQD fields
149078 + * @fq: the frame queue object to be queried
149079 + * @np: storage for the queried FQD fields
149080 + */
149081 +int qman_query_fq_np(struct qman_fq *fq, struct qm_mcr_queryfq_np *np);
149082 +
149083 +/**
149084 + * qman_query_wq - Queries work queue lengths
149085 + * @query_dedicated: If non-zero, query length of WQs in the channel dedicated
149086 + * to this software portal. Otherwise, query length of WQs in a
149087 + * channel specified in wq.
149088 + * @wq: storage for the queried WQs lengths. Also specified the channel to
149089 + * to query if query_dedicated is zero.
149090 + */
149091 +int qman_query_wq(u8 query_dedicated, struct qm_mcr_querywq *wq);
149092 +
149093 +/**
149094 + * qman_volatile_dequeue - Issue a volatile dequeue command
149095 + * @fq: the frame queue object to dequeue from
149096 + * @flags: a bit-mask of QMAN_VOLATILE_FLAG_*** options
149097 + * @vdqcr: bit mask of QM_VDQCR_*** options, as per qm_dqrr_vdqcr_set()
149098 + *
149099 + * Attempts to lock access to the portal's VDQCR volatile dequeue functionality.
149100 + * The function will block and sleep if QMAN_VOLATILE_FLAG_WAIT is specified and
149101 + * the VDQCR is already in use, otherwise returns non-zero for failure. If
149102 + * QMAN_VOLATILE_FLAG_FINISH is specified, the function will only return once
149103 + * the VDQCR command has finished executing (ie. once the callback for the last
149104 + * DQRR entry resulting from the VDQCR command has been called). If not using
149105 + * the FINISH flag, completion can be determined either by detecting the
149106 + * presence of the QM_DQRR_STAT_UNSCHEDULED and QM_DQRR_STAT_DQCR_EXPIRED bits
149107 + * in the "stat" field of the "struct qm_dqrr_entry" passed to the FQ's dequeue
149108 + * callback, or by waiting for the QMAN_FQ_STATE_VDQCR bit to disappear from the
149109 + * "flags" retrieved from qman_fq_state().
149110 + */
149111 +int qman_volatile_dequeue(struct qman_fq *fq, u32 flags, u32 vdqcr);
149112 +
149113 +/**
149114 + * qman_enqueue - Enqueue a frame to a frame queue
149115 + * @fq: the frame queue object to enqueue to
149116 + * @fd: a descriptor of the frame to be enqueued
149117 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
149118 + *
149119 + * Fills an entry in the EQCR of portal @qm to enqueue the frame described by
149120 + * @fd. The descriptor details are copied from @fd to the EQCR entry, the 'pid'
149121 + * field is ignored. The return value is non-zero on error, such as ring full
149122 + * (and FLAG_WAIT not specified), congestion avoidance (FLAG_WATCH_CGR
149123 + * specified), etc. If the ring is full and FLAG_WAIT is specified, this
149124 + * function will block. If FLAG_INTERRUPT is set, the EQCI bit of the portal
149125 + * interrupt will assert when Qman consumes the EQCR entry (subject to "status
149126 + * disable", "enable", and "inhibit" registers). If FLAG_DCA is set, Qman will
149127 + * perform an implied "discrete consumption acknowledgement" on the dequeue
149128 + * ring's (DQRR) entry, at the ring index specified by the FLAG_DCA_IDX(x)
149129 + * macro. (As an alternative to issuing explicit DCA actions on DQRR entries,
149130 + * this implicit DCA can delay the release of a "held active" frame queue
149131 + * corresponding to a DQRR entry until Qman consumes the EQCR entry - providing
149132 + * order-preservation semantics in packet-forwarding scenarios.) If FLAG_DCA is
149133 + * set, then FLAG_DCA_PARK can also be set to imply that the DQRR consumption
149134 + * acknowledgement should "park request" the "held active" frame queue. Ie.
149135 + * when the portal eventually releases that frame queue, it will be left in the
149136 + * Parked state rather than Tentatively Scheduled or Truly Scheduled. If the
149137 + * portal is watching congestion groups, the QMAN_ENQUEUE_FLAG_WATCH_CGR flag
149138 + * is requested, and the FQ is a member of a congestion group, then this
149139 + * function returns -EAGAIN if the congestion group is currently congested.
149140 + * Note, this does not eliminate ERNs, as the async interface means we can be
149141 + * sending enqueue commands to an un-congested FQ that becomes congested before
149142 + * the enqueue commands are processed, but it does minimise needless thrashing
149143 + * of an already busy hardware resource by throttling many of the to-be-dropped
149144 + * enqueues "at the source".
149145 + */
149146 +int qman_enqueue(struct qman_fq *fq, const struct qm_fd *fd, u32 flags);
149147 +
149148 +typedef int (*qman_cb_precommit) (void *arg);
149149 +/**
149150 + * qman_enqueue_precommit - Enqueue a frame to a frame queue and call cb
149151 + * @fq: the frame queue object to enqueue to
149152 + * @fd: a descriptor of the frame to be enqueued
149153 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
149154 + * @cb: user supplied callback function to invoke before writing commit verb.
149155 + * @cb_arg: callback function argument
149156 + *
149157 + * This is similar to qman_enqueue except that it will invoke a user supplied
149158 + * callback function just before writng the commit verb. This is useful
149159 + * when the user want to do something *just before* enqueuing the request and
149160 + * the enqueue can't fail.
149161 + */
149162 +int qman_enqueue_precommit(struct qman_fq *fq, const struct qm_fd *fd,
149163 + u32 flags, qman_cb_precommit cb, void *cb_arg);
149164 +
149165 +/**
149166 + * qman_enqueue_orp - Enqueue a frame to a frame queue using an ORP
149167 + * @fq: the frame queue object to enqueue to
149168 + * @fd: a descriptor of the frame to be enqueued
149169 + * @flags: bit-mask of QMAN_ENQUEUE_FLAG_*** options
149170 + * @orp: the frame queue object used as an order restoration point.
149171 + * @orp_seqnum: the sequence number of this frame in the order restoration path
149172 + *
149173 + * Similar to qman_enqueue(), but with the addition of an Order Restoration
149174 + * Point (@orp) and corresponding sequence number (@orp_seqnum) for this
149175 + * enqueue operation to employ order restoration. Each frame queue object acts
149176 + * as an Order Definition Point (ODP) by providing each frame dequeued from it
149177 + * with an incrementing sequence number, this value is generally ignored unless
149178 + * that sequence of dequeued frames will need order restoration later. Each
149179 + * frame queue object also encapsulates an Order Restoration Point (ORP), which
149180 + * is a re-assembly context for re-ordering frames relative to their sequence
149181 + * numbers as they are enqueued. The ORP does not have to be within the frame
149182 + * queue that receives the enqueued frame, in fact it is usually the frame
149183 + * queue from which the frames were originally dequeued. For the purposes of
149184 + * order restoration, multiple frames (or "fragments") can be enqueued for a
149185 + * single sequence number by setting the QMAN_ENQUEUE_FLAG_NLIS flag for all
149186 + * enqueues except the final fragment of a given sequence number. Ordering
149187 + * between sequence numbers is guaranteed, even if fragments of different
149188 + * sequence numbers are interlaced with one another. Fragments of the same
149189 + * sequence number will retain the order in which they are enqueued. If no
149190 + * enqueue is to performed, QMAN_ENQUEUE_FLAG_HOLE indicates that the given
149191 + * sequence number is to be "skipped" by the ORP logic (eg. if a frame has been
149192 + * dropped from a sequence), or QMAN_ENQUEUE_FLAG_NESN indicates that the given
149193 + * sequence number should become the ORP's "Next Expected Sequence Number".
149194 + *
149195 + * Side note: a frame queue object can be used purely as an ORP, without
149196 + * carrying any frames at all. Care should be taken not to deallocate a frame
149197 + * queue object that is being actively used as an ORP, as a future allocation
149198 + * of the frame queue object may start using the internal ORP before the
149199 + * previous use has finished.
149200 + */
149201 +int qman_enqueue_orp(struct qman_fq *fq, const struct qm_fd *fd, u32 flags,
149202 + struct qman_fq *orp, u16 orp_seqnum);
149203 +
149204 +/**
149205 + * qman_alloc_fqid_range - Allocate a contiguous range of FQIDs
149206 + * @result: is set by the API to the base FQID of the allocated range
149207 + * @count: the number of FQIDs required
149208 + * @align: required alignment of the allocated range
149209 + * @partial: non-zero if the API can return fewer than @count FQIDs
149210 + *
149211 + * Returns the number of frame queues allocated, or a negative error code. If
149212 + * @partial is non zero, the allocation request may return a smaller range of
149213 + * FQs than requested (though alignment will be as requested). If @partial is
149214 + * zero, the return value will either be 'count' or negative.
149215 + */
149216 +int qman_alloc_fqid_range(u32 *result, u32 count, u32 align, int partial);
149217 +static inline int qman_alloc_fqid(u32 *result)
149218 +{
149219 + int ret = qman_alloc_fqid_range(result, 1, 0, 0);
149220 + return (ret > 0) ? 0 : ret;
149221 +}
149222 +
149223 +/**
149224 + * qman_release_fqid_range - Release the specified range of frame queue IDs
149225 + * @fqid: the base FQID of the range to deallocate
149226 + * @count: the number of FQIDs in the range
149227 + *
149228 + * This function can also be used to seed the allocator with ranges of FQIDs
149229 + * that it can subsequently allocate from.
149230 + */
149231 +void qman_release_fqid_range(u32 fqid, unsigned int count);
149232 +static inline void qman_release_fqid(u32 fqid)
149233 +{
149234 + qman_release_fqid_range(fqid, 1);
149235 +}
149236 +
149237 +void qman_seed_fqid_range(u32 fqid, unsigned int count);
149238 +
149239 +
149240 +int qman_shutdown_fq(u32 fqid);
149241 +
149242 +/**
149243 + * qman_reserve_fqid_range - Reserve the specified range of frame queue IDs
149244 + * @fqid: the base FQID of the range to deallocate
149245 + * @count: the number of FQIDs in the range
149246 + */
149247 +int qman_reserve_fqid_range(u32 fqid, unsigned int count);
149248 +static inline int qman_reserve_fqid(u32 fqid)
149249 +{
149250 + return qman_reserve_fqid_range(fqid, 1);
149251 +}
149252 +
149253 + /* Pool-channel management */
149254 + /* ----------------------- */
149255 +/**
149256 + * qman_alloc_pool_range - Allocate a contiguous range of pool-channel IDs
149257 + * @result: is set by the API to the base pool-channel ID of the allocated range
149258 + * @count: the number of pool-channel IDs required
149259 + * @align: required alignment of the allocated range
149260 + * @partial: non-zero if the API can return fewer than @count
149261 + *
149262 + * Returns the number of pool-channel IDs allocated, or a negative error code.
149263 + * If @partial is non zero, the allocation request may return a smaller range of
149264 + * than requested (though alignment will be as requested). If @partial is zero,
149265 + * the return value will either be 'count' or negative.
149266 + */
149267 +int qman_alloc_pool_range(u32 *result, u32 count, u32 align, int partial);
149268 +static inline int qman_alloc_pool(u32 *result)
149269 +{
149270 + int ret = qman_alloc_pool_range(result, 1, 0, 0);
149271 + return (ret > 0) ? 0 : ret;
149272 +}
149273 +
149274 +/**
149275 + * qman_release_pool_range - Release the specified range of pool-channel IDs
149276 + * @id: the base pool-channel ID of the range to deallocate
149277 + * @count: the number of pool-channel IDs in the range
149278 + */
149279 +void qman_release_pool_range(u32 id, unsigned int count);
149280 +static inline void qman_release_pool(u32 id)
149281 +{
149282 + qman_release_pool_range(id, 1);
149283 +}
149284 +
149285 +/**
149286 + * qman_reserve_pool_range - Reserve the specified range of pool-channel IDs
149287 + * @id: the base pool-channel ID of the range to reserve
149288 + * @count: the number of pool-channel IDs in the range
149289 + */
149290 +int qman_reserve_pool_range(u32 id, unsigned int count);
149291 +static inline int qman_reserve_pool(u32 id)
149292 +{
149293 + return qman_reserve_pool_range(id, 1);
149294 +}
149295 +
149296 +void qman_seed_pool_range(u32 id, unsigned int count);
149297 +
149298 + /* CGR management */
149299 + /* -------------- */
149300 +/**
149301 + * qman_create_cgr - Register a congestion group object
149302 + * @cgr: the 'cgr' object, with fields filled in
149303 + * @flags: QMAN_CGR_FLAG_* values
149304 + * @opts: optional state of CGR settings
149305 + *
149306 + * Registers this object to receiving congestion entry/exit callbacks on the
149307 + * portal affine to the cpu portal on which this API is executed. If opts is
149308 + * NULL then only the callback (cgr->cb) function is registered. If @flags
149309 + * contains QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset
149310 + * any unspecified parameters) will be used rather than a modify hw hardware
149311 + * (which only modifies the specified parameters).
149312 + */
149313 +int qman_create_cgr(struct qman_cgr *cgr, u32 flags,
149314 + struct qm_mcc_initcgr *opts);
149315 +
149316 +/**
149317 + * qman_create_cgr_to_dcp - Register a congestion group object to DCP portal
149318 + * @cgr: the 'cgr' object, with fields filled in
149319 + * @flags: QMAN_CGR_FLAG_* values
149320 + * @dcp_portal: the DCP portal to which the cgr object is registered.
149321 + * @opts: optional state of CGR settings
149322 + *
149323 + */
149324 +int qman_create_cgr_to_dcp(struct qman_cgr *cgr, u32 flags, u16 dcp_portal,
149325 + struct qm_mcc_initcgr *opts);
149326 +
149327 +/**
149328 + * qman_delete_cgr - Deregisters a congestion group object
149329 + * @cgr: the 'cgr' object to deregister
149330 + *
149331 + * "Unplugs" this CGR object from the portal affine to the cpu on which this API
149332 + * is executed. This must be excuted on the same affine portal on which it was
149333 + * created.
149334 + */
149335 +int qman_delete_cgr(struct qman_cgr *cgr);
149336 +
149337 +/**
149338 + * qman_delete_cgr_safe - Deregisters a congestion group object from any CPU
149339 + * @cgr: the 'cgr' object to deregister
149340 + *
149341 + * This will select the proper CPU and run there qman_delete_cgr().
149342 + */
149343 +void qman_delete_cgr_safe(struct qman_cgr *cgr);
149344 +
149345 +/**
149346 + * qman_modify_cgr - Modify CGR fields
149347 + * @cgr: the 'cgr' object to modify
149348 + * @flags: QMAN_CGR_FLAG_* values
149349 + * @opts: the CGR-modification settings
149350 + *
149351 + * The @opts parameter comes from the low-level portal API, and can be NULL.
149352 + * Note that some fields and options within @opts may be ignored or overwritten
149353 + * by the driver, in particular the 'cgrid' field is ignored (this operation
149354 + * only affects the given CGR object). If @flags contains
149355 + * QMAN_CGR_FLAG_USE_INIT, then an init hw command (which will reset any
149356 + * unspecified parameters) will be used rather than a modify hw hardware (which
149357 + * only modifies the specified parameters).
149358 + */
149359 +int qman_modify_cgr(struct qman_cgr *cgr, u32 flags,
149360 + struct qm_mcc_initcgr *opts);
149361 +
149362 +/**
149363 +* qman_query_cgr - Queries CGR fields
149364 +* @cgr: the 'cgr' object to query
149365 +* @result: storage for the queried congestion group record
149366 +*/
149367 +int qman_query_cgr(struct qman_cgr *cgr, struct qm_mcr_querycgr *result);
149368 +
149369 +/**
149370 + * qman_query_congestion - Queries the state of all congestion groups
149371 + * @congestion: storage for the queried state of all congestion groups
149372 + */
149373 +int qman_query_congestion(struct qm_mcr_querycongestion *congestion);
149374 +
149375 +/**
149376 + * qman_alloc_cgrid_range - Allocate a contiguous range of CGR IDs
149377 + * @result: is set by the API to the base CGR ID of the allocated range
149378 + * @count: the number of CGR IDs required
149379 + * @align: required alignment of the allocated range
149380 + * @partial: non-zero if the API can return fewer than @count
149381 + *
149382 + * Returns the number of CGR IDs allocated, or a negative error code.
149383 + * If @partial is non zero, the allocation request may return a smaller range of
149384 + * than requested (though alignment will be as requested). If @partial is zero,
149385 + * the return value will either be 'count' or negative.
149386 + */
149387 +int qman_alloc_cgrid_range(u32 *result, u32 count, u32 align, int partial);
149388 +static inline int qman_alloc_cgrid(u32 *result)
149389 +{
149390 + int ret = qman_alloc_cgrid_range(result, 1, 0, 0);
149391 + return (ret > 0) ? 0 : ret;
149392 +}
149393 +
149394 +/**
149395 + * qman_release_cgrid_range - Release the specified range of CGR IDs
149396 + * @id: the base CGR ID of the range to deallocate
149397 + * @count: the number of CGR IDs in the range
149398 + */
149399 +void qman_release_cgrid_range(u32 id, unsigned int count);
149400 +static inline void qman_release_cgrid(u32 id)
149401 +{
149402 + qman_release_cgrid_range(id, 1);
149403 +}
149404 +
149405 +/**
149406 + * qman_reserve_cgrid_range - Reserve the specified range of CGR ID
149407 + * @id: the base CGR ID of the range to reserve
149408 + * @count: the number of CGR IDs in the range
149409 + */
149410 +int qman_reserve_cgrid_range(u32 id, unsigned int count);
149411 +static inline int qman_reserve_cgrid(u32 id)
149412 +{
149413 + return qman_reserve_cgrid_range(id, 1);
149414 +}
149415 +
149416 +void qman_seed_cgrid_range(u32 id, unsigned int count);
149417 +
149418 +
149419 + /* Helpers */
149420 + /* ------- */
149421 +/**
149422 + * qman_poll_fq_for_init - Check if an FQ has been initialised from OOS
149423 + * @fqid: the FQID that will be initialised by other s/w
149424 + *
149425 + * In many situations, a FQID is provided for communication between s/w
149426 + * entities, and whilst the consumer is responsible for initialising and
149427 + * scheduling the FQ, the producer(s) generally create a wrapper FQ object using
149428 + * and only call qman_enqueue() (no FQ initialisation, scheduling, etc). Ie;
149429 + * qman_create_fq(..., QMAN_FQ_FLAG_NO_MODIFY, ...);
149430 + * However, data can not be enqueued to the FQ until it is initialised out of
149431 + * the OOS state - this function polls for that condition. It is particularly
149432 + * useful for users of IPC functions - each endpoint's Rx FQ is the other
149433 + * endpoint's Tx FQ, so each side can initialise and schedule their Rx FQ object
149434 + * and then use this API on the (NO_MODIFY) Tx FQ object in order to
149435 + * synchronise. The function returns zero for success, +1 if the FQ is still in
149436 + * the OOS state, or negative if there was an error.
149437 + */
149438 +static inline int qman_poll_fq_for_init(struct qman_fq *fq)
149439 +{
149440 + struct qm_mcr_queryfq_np np;
149441 + int err;
149442 + err = qman_query_fq_np(fq, &np);
149443 + if (err)
149444 + return err;
149445 + if ((np.state & QM_MCR_NP_STATE_MASK) == QM_MCR_NP_STATE_OOS)
149446 + return 1;
149447 + return 0;
149448 +}
149449 +
149450 + /* -------------- */
149451 + /* CEETM :: types */
149452 + /* -------------- */
149453 +/**
149454 + * Token Rate Structure
149455 + * Shaping rates are based on a "credit" system and a pre-configured h/w
149456 + * internal timer. The following type represents a shaper "rate" parameter as a
149457 + * fractional number of "tokens". Here's how it works. This (fractional) number
149458 + * of tokens is added to the shaper's "credit" every time the h/w timer elapses
149459 + * (up to a limit which is set by another shaper parameter). Every time a frame
149460 + * is enqueued through a shaper, the shaper deducts as many tokens as there are
149461 + * bytes of data in the enqueued frame. A shaper will not allow itself to
149462 + * enqueue any frames if its token count is negative. As such;
149463 + *
149464 + * The rate at which data is enqueued is limited by the
149465 + * rate at which tokens are added.
149466 + *
149467 + * Therefore if the user knows the period between these h/w timer updates in
149468 + * seconds, they can calculate the maximum traffic rate of the shaper (in
149469 + * bytes-per-second) from the token rate. And vice versa, they can calculate
149470 + * the token rate to use in order to achieve a given traffic rate.
149471 + */
149472 +struct qm_ceetm_rate {
149473 + /* The token rate is; whole + (fraction/8192) */
149474 + u32 whole:11; /* 0..2047 */
149475 + u32 fraction:13; /* 0..8191 */
149476 +};
149477 +
149478 +struct qm_ceetm_weight_code {
149479 + /* The weight code is; 5 msbits + 3 lsbits */
149480 + u8 y:5;
149481 + u8 x:3;
149482 +};
149483 +
149484 +struct qm_ceetm {
149485 + unsigned int idx;
149486 + struct list_head sub_portals;
149487 + struct list_head lnis;
149488 + unsigned int sp_range[2];
149489 + unsigned int lni_range[2];
149490 +};
149491 +
149492 +struct qm_ceetm_sp {
149493 + struct list_head node;
149494 + unsigned int idx;
149495 + unsigned int dcp_idx;
149496 + int is_claimed;
149497 + struct qm_ceetm_lni *lni;
149498 +};
149499 +
149500 +/* Logical Network Interface */
149501 +struct qm_ceetm_lni {
149502 + struct list_head node;
149503 + unsigned int idx;
149504 + unsigned int dcp_idx;
149505 + int is_claimed;
149506 + struct qm_ceetm_sp *sp;
149507 + struct list_head channels;
149508 + int shaper_enable;
149509 + int shaper_couple;
149510 + int oal;
149511 + struct qm_ceetm_rate cr_token_rate;
149512 + struct qm_ceetm_rate er_token_rate;
149513 + u16 cr_token_bucket_limit;
149514 + u16 er_token_bucket_limit;
149515 +};
149516 +
149517 +/* Class Queue Channel */
149518 +struct qm_ceetm_channel {
149519 + struct list_head node;
149520 + unsigned int idx;
149521 + unsigned int lni_idx;
149522 + unsigned int dcp_idx;
149523 + struct list_head class_queues;
149524 + struct list_head ccgs;
149525 + u8 shaper_enable;
149526 + u8 shaper_couple;
149527 + struct qm_ceetm_rate cr_token_rate;
149528 + struct qm_ceetm_rate er_token_rate;
149529 + u16 cr_token_bucket_limit;
149530 + u16 er_token_bucket_limit;
149531 +};
149532 +
149533 +struct qm_ceetm_ccg;
149534 +
149535 +/* This callback type is used when handling congestion entry/exit. The
149536 + * 'cb_ctx' value is the opaque value associated with ccg object.
149537 + * 'congested' is non-zero on congestion-entry, and zero on congestion-exit.
149538 + */
149539 +typedef void (*qman_cb_ccgr)(struct qm_ceetm_ccg *ccg, void *cb_ctx,
149540 + int congested);
149541 +
149542 +/* Class Congestion Group */
149543 +struct qm_ceetm_ccg {
149544 + struct qm_ceetm_channel *parent;
149545 + struct list_head node;
149546 + struct list_head cb_node;
149547 + qman_cb_ccgr cb;
149548 + void *cb_ctx;
149549 + unsigned int idx;
149550 +};
149551 +
149552 +/* Class Queue */
149553 +struct qm_ceetm_cq {
149554 + struct qm_ceetm_channel *parent;
149555 + struct qm_ceetm_ccg *ccg;
149556 + struct list_head node;
149557 + unsigned int idx;
149558 + int is_claimed;
149559 + struct list_head bound_lfqids;
149560 + struct list_head binding_node;
149561 +};
149562 +
149563 +/* Logical Frame Queue */
149564 +struct qm_ceetm_lfq {
149565 + struct qm_ceetm_channel *parent;
149566 + struct list_head node;
149567 + unsigned int idx;
149568 + unsigned int dctidx;
149569 + u64 context_a;
149570 + u32 context_b;
149571 + qman_cb_mr ern;
149572 +};
149573 +
149574 +/**
149575 + * qman_ceetm_bps2tokenrate - Given a desired rate 'bps' measured in bps
149576 + * (ie. bits-per-second), compute the 'token_rate' fraction that best
149577 + * approximates that rate.
149578 + * @bps: the desired shaper rate in bps.
149579 + * @token_rate: the output token rate computed with the given kbps.
149580 + * @rounding: dictates how to round if an exact conversion is not possible; if
149581 + * it is negative then 'token_rate' will round down to the highest value that
149582 + * does not exceed the desired rate, if it is positive then 'token_rate' will
149583 + * round up to the lowest value that is greater than or equal to the desired
149584 + * rate, and if it is zero then it will round to the nearest approximation,
149585 + * whether that be up or down.
149586 + *
149587 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
149588 + */
149589 +int qman_ceetm_bps2tokenrate(u64 bps,
149590 + struct qm_ceetm_rate *token_rate,
149591 + int rounding);
149592 +
149593 +/**
149594 + * qman_ceetm_tokenrate2bps - Given a 'token_rate', compute the
149595 + * corresponding number of 'bps'.
149596 + * @token_rate: the input desired token_rate fraction.
149597 + * @bps: the output shaper rate in bps computed with the give token rate.
149598 + * @rounding: has the same semantics as the previous function.
149599 + *
149600 + * Return 0 for success, or -EINVAL if prescaler or qman clock is not available.
149601 + */
149602 +int qman_ceetm_tokenrate2bps(const struct qm_ceetm_rate *token_rate,
149603 + u64 *bps,
149604 + int rounding);
149605 +
149606 +int qman_alloc_ceetm0_channel_range(u32 *result, u32 count, u32 align,
149607 + int partial);
149608 +static inline int qman_alloc_ceetm0_channel(u32 *result)
149609 +{
149610 + int ret = qman_alloc_ceetm0_channel_range(result, 1, 0, 0);
149611 + return (ret > 0) ? 0 : ret;
149612 +}
149613 +void qman_release_ceetm0_channel_range(u32 channelid, u32 count);
149614 +static inline void qman_release_ceetm0_channelid(u32 channelid)
149615 +{
149616 + qman_release_ceetm0_channel_range(channelid, 1);
149617 +}
149618 +
149619 +int qman_reserve_ceetm0_channel_range(u32 channelid, u32 count);
149620 +static inline int qman_reserve_ceetm0_channelid(u32 channelid)
149621 +{
149622 + return qman_reserve_ceetm0_channel_range(channelid, 1);
149623 +}
149624 +
149625 +void qman_seed_ceetm0_channel_range(u32 channelid, u32 count);
149626 +
149627 +
149628 +int qman_alloc_ceetm1_channel_range(u32 *result, u32 count, u32 align,
149629 + int partial);
149630 +static inline int qman_alloc_ceetm1_channel(u32 *result)
149631 +{
149632 + int ret = qman_alloc_ceetm1_channel_range(result, 1, 0, 0);
149633 + return (ret > 0) ? 0 : ret;
149634 +}
149635 +void qman_release_ceetm1_channel_range(u32 channelid, u32 count);
149636 +static inline void qman_release_ceetm1_channelid(u32 channelid)
149637 +{
149638 + qman_release_ceetm1_channel_range(channelid, 1);
149639 +}
149640 +int qman_reserve_ceetm1_channel_range(u32 channelid, u32 count);
149641 +static inline int qman_reserve_ceetm1_channelid(u32 channelid)
149642 +{
149643 + return qman_reserve_ceetm1_channel_range(channelid, 1);
149644 +}
149645 +
149646 +void qman_seed_ceetm1_channel_range(u32 channelid, u32 count);
149647 +
149648 +
149649 +int qman_alloc_ceetm0_lfqid_range(u32 *result, u32 count, u32 align,
149650 + int partial);
149651 +static inline int qman_alloc_ceetm0_lfqid(u32 *result)
149652 +{
149653 + int ret = qman_alloc_ceetm0_lfqid_range(result, 1, 0, 0);
149654 + return (ret > 0) ? 0 : ret;
149655 +}
149656 +void qman_release_ceetm0_lfqid_range(u32 lfqid, u32 count);
149657 +static inline void qman_release_ceetm0_lfqid(u32 lfqid)
149658 +{
149659 + qman_release_ceetm0_lfqid_range(lfqid, 1);
149660 +}
149661 +int qman_reserve_ceetm0_lfqid_range(u32 lfqid, u32 count);
149662 +static inline int qman_reserve_ceetm0_lfqid(u32 lfqid)
149663 +{
149664 + return qman_reserve_ceetm0_lfqid_range(lfqid, 1);
149665 +}
149666 +
149667 +void qman_seed_ceetm0_lfqid_range(u32 lfqid, u32 count);
149668 +
149669 +
149670 +int qman_alloc_ceetm1_lfqid_range(u32 *result, u32 count, u32 align,
149671 + int partial);
149672 +static inline int qman_alloc_ceetm1_lfqid(u32 *result)
149673 +{
149674 + int ret = qman_alloc_ceetm1_lfqid_range(result, 1, 0, 0);
149675 + return (ret > 0) ? 0 : ret;
149676 +}
149677 +void qman_release_ceetm1_lfqid_range(u32 lfqid, u32 count);
149678 +static inline void qman_release_ceetm1_lfqid(u32 lfqid)
149679 +{
149680 + qman_release_ceetm1_lfqid_range(lfqid, 1);
149681 +}
149682 +int qman_reserve_ceetm1_lfqid_range(u32 lfqid, u32 count);
149683 +static inline int qman_reserve_ceetm1_lfqid(u32 lfqid)
149684 +{
149685 + return qman_reserve_ceetm1_lfqid_range(lfqid, 1);
149686 +}
149687 +
149688 +void qman_seed_ceetm1_lfqid_range(u32 lfqid, u32 count);
149689 +
149690 +
149691 + /* ----------------------------- */
149692 + /* CEETM :: sub-portals */
149693 + /* ----------------------------- */
149694 +
149695 +/**
149696 + * qman_ceetm_sp_claim - Claims the given sub-portal, provided it is available
149697 + * to us and configured for traffic-management.
149698 + * @sp: the returned sub-portal object, if successful.
149699 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
149700 + * instance),
149701 + * @sp_idx" is the desired sub-portal index from 0 to 15.
149702 + *
149703 + * Returns zero for success, or -ENODEV if the sub-portal is in use, or -EINVAL
149704 + * if the sp_idx is out of range.
149705 + *
149706 + * Note that if there are multiple driver domains (eg. a linux kernel versus
149707 + * user-space drivers in USDPAA, or multiple guests running under a hypervisor)
149708 + * then a sub-portal may be accessible by more than one instance of a qman
149709 + * driver and so it may be claimed multiple times. If this is the case, it is
149710 + * up to the system architect to prevent conflicting configuration actions
149711 + * coming from the different driver domains. The qman drivers do not have any
149712 + * behind-the-scenes coordination to prevent this from happening.
149713 + */
149714 +int qman_ceetm_sp_claim(struct qm_ceetm_sp **sp,
149715 + enum qm_dc_portal dcp_idx,
149716 + unsigned int sp_idx);
149717 +
149718 +/**
149719 + * qman_ceetm_sp_release - Releases a previously claimed sub-portal.
149720 + * @sp: the sub-portal to be released.
149721 + *
149722 + * Returns 0 for success, or -EBUSY for failure if the dependencies are not
149723 + * released.
149724 + */
149725 +int qman_ceetm_sp_release(struct qm_ceetm_sp *sp);
149726 +
149727 + /* ----------------------------------- */
149728 + /* CEETM :: logical network interfaces */
149729 + /* ----------------------------------- */
149730 +
149731 +/**
149732 + * qman_ceetm_lni_claim - Claims an unclaimed LNI.
149733 + * @lni: the returned LNI object, if successful.
149734 + * @dcp_id: specifies the desired Fman block (and thus the relevant CEETM
149735 + * instance)
149736 + * @lni_idx: is the desired LNI index.
149737 + *
149738 + * Returns zero for success, or -EINVAL on failure, which will happen if the LNI
149739 + * is not available or has already been claimed (and not yet successfully
149740 + * released), or lni_dix is out of range.
149741 + *
149742 + * Note that there may be multiple driver domains (or instances) that need to
149743 + * transmit out the same LNI, so this claim is only guaranteeing exclusivity
149744 + * within the domain of the driver being called. See qman_ceetm_sp_claim() and
149745 + * qman_ceetm_sp_get_lni() for more information.
149746 + */
149747 +int qman_ceetm_lni_claim(struct qm_ceetm_lni **lni,
149748 + enum qm_dc_portal dcp_id,
149749 + unsigned int lni_idx);
149750 +
149751 +/**
149752 + * qman_ceetm_lni_releaes - Releases a previously claimed LNI.
149753 + * @lni: the lni needs to be released.
149754 + *
149755 + * This will only succeed if all dependent objects have been released.
149756 + * Returns zero for success, or -EBUSY if the dependencies are not released.
149757 + */
149758 +int qman_ceetm_lni_release(struct qm_ceetm_lni *lni);
149759 +
149760 +/**
149761 + * qman_ceetm_sp_set_lni
149762 + * qman_ceetm_sp_get_lni - Set/get the LNI that the sub-portal is currently
149763 + * mapped to.
149764 + * @sp: the given sub-portal.
149765 + * @lni(in "set"function): the LNI object which the sp will be mappaed to.
149766 + * @lni_idx(in "get" function): the LNI index which the sp is mapped to.
149767 + *
149768 + * Returns zero for success, or -EINVAL for the "set" function when this sp-lni
149769 + * mapping has been set, or configure mapping command returns error, and
149770 + * -EINVAL for "get" function when this sp-lni mapping is not set or the query
149771 + * mapping command returns error.
149772 + *
149773 + * This may be useful in situations where multiple driver domains have access
149774 + * to the same sub-portals in order to all be able to transmit out the same
149775 + * physical interface (perhaps they're on different IP addresses or VPNs, so
149776 + * Fman is splitting Rx traffic and here we need to converge Tx traffic). In
149777 + * that case, a control-plane is likely to use qman_ceetm_lni_claim() followed
149778 + * by qman_ceetm_sp_set_lni() to configure the sub-portal, and other domains
149779 + * are likely to use qman_ceetm_sp_get_lni() followed by qman_ceetm_lni_claim()
149780 + * in order to determine the LNI that the control-plane had assigned. This is
149781 + * why the "get" returns an index, whereas the "set" takes an (already claimed)
149782 + * LNI object.
149783 + */
149784 +int qman_ceetm_sp_set_lni(struct qm_ceetm_sp *sp,
149785 + struct qm_ceetm_lni *lni);
149786 +int qman_ceetm_sp_get_lni(struct qm_ceetm_sp *sp,
149787 + unsigned int *lni_idx);
149788 +
149789 +/**
149790 + * qman_ceetm_lni_enable_shaper
149791 + * qman_ceetm_lni_disable_shaper - Enables/disables shaping on the LNI.
149792 + * @lni: the given LNI.
149793 + * @coupled: indicates whether CR and ER are coupled.
149794 + * @oal: the overhead accounting length which is added to the actual length of
149795 + * each frame when performing shaper calculations.
149796 + *
149797 + * When the number of (unused) committed-rate tokens reach the committed-rate
149798 + * token limit, 'coupled' indicates whether surplus tokens should be added to
149799 + * the excess-rate token count (up to the excess-rate token limit).
149800 + * When LNI is claimed, the shaper is disabled by default. The enable function
149801 + * will turn on this shaper for this lni.
149802 + * Whenever a claimed LNI is first enabled for shaping, its committed and
149803 + * excess token rates and limits are zero, so will need to be changed to do
149804 + * anything useful. The shaper can subsequently be enabled/disabled without
149805 + * resetting the shaping parameters, but the shaping parameters will be reset
149806 + * when the LNI is released.
149807 + *
149808 + * Returns zero for success, or errno for "enable" function in the cases as:
149809 + * a) -EINVAL if the shaper is already enabled,
149810 + * b) -EIO if the configure shaper command returns error.
149811 + * For "disable" function, returns:
149812 + * a) -EINVAL if the shaper is has already disabled.
149813 + * b) -EIO if calling configure shaper command returns error.
149814 + */
149815 +int qman_ceetm_lni_enable_shaper(struct qm_ceetm_lni *lni, int coupled,
149816 + int oal);
149817 +int qman_ceetm_lni_disable_shaper(struct qm_ceetm_lni *lni);
149818 +
149819 +/**
149820 + * qman_ceetm_lni_is_shaper_enabled - Check LNI shaper status
149821 + * @lni: the give LNI
149822 + */
149823 +int qman_ceetm_lni_is_shaper_enabled(struct qm_ceetm_lni *lni);
149824 +
149825 +/**
149826 + * qman_ceetm_lni_set_commit_rate
149827 + * qman_ceetm_lni_get_commit_rate
149828 + * qman_ceetm_lni_set_excess_rate
149829 + * qman_ceetm_lni_get_excess_rate - Set/get the shaper CR/ER token rate and
149830 + * token limit for the given LNI.
149831 + * @lni: the given LNI.
149832 + * @token_rate: the desired token rate for "set" fuction, or the token rate of
149833 + * the LNI queried by "get" function.
149834 + * @token_limit: the desired token bucket limit for "set" function, or the token
149835 + * limit of the given LNI queried by "get" function.
149836 + *
149837 + * Returns zero for success. The "set" function returns -EINVAL if the given
149838 + * LNI is unshapped or -EIO if the configure shaper command returns error.
149839 + * The "get" function returns -EINVAL if the token rate or the token limit is
149840 + * not set or the query command returns error.
149841 + */
149842 +int qman_ceetm_lni_set_commit_rate(struct qm_ceetm_lni *lni,
149843 + const struct qm_ceetm_rate *token_rate,
149844 + u16 token_limit);
149845 +int qman_ceetm_lni_get_commit_rate(struct qm_ceetm_lni *lni,
149846 + struct qm_ceetm_rate *token_rate,
149847 + u16 *token_limit);
149848 +int qman_ceetm_lni_set_excess_rate(struct qm_ceetm_lni *lni,
149849 + const struct qm_ceetm_rate *token_rate,
149850 + u16 token_limit);
149851 +int qman_ceetm_lni_get_excess_rate(struct qm_ceetm_lni *lni,
149852 + struct qm_ceetm_rate *token_rate,
149853 + u16 *token_limit);
149854 +/**
149855 + * qman_ceetm_lni_set_commit_rate_bps
149856 + * qman_ceetm_lni_get_commit_rate_bps
149857 + * qman_ceetm_lni_set_excess_rate_bps
149858 + * qman_ceetm_lni_get_excess_rate_bps - Set/get the shaper CR/ER rate
149859 + * and token limit for the given LNI.
149860 + * @lni: the given LNI.
149861 + * @bps: the desired shaping rate in bps for "set" fuction, or the shaping rate
149862 + * of the LNI queried by "get" function.
149863 + * @token_limit: the desired token bucket limit for "set" function, or the token
149864 + * limit of the given LNI queried by "get" function.
149865 + *
149866 + * Returns zero for success. The "set" function returns -EINVAL if the given
149867 + * LNI is unshapped or -EIO if the configure shaper command returns error.
149868 + * The "get" function returns -EINVAL if the token rate or the token limit is
149869 + * not set or the query command returns error.
149870 + */
149871 +int qman_ceetm_lni_set_commit_rate_bps(struct qm_ceetm_lni *lni,
149872 + u64 bps,
149873 + u16 token_limit);
149874 +int qman_ceetm_lni_get_commit_rate_bps(struct qm_ceetm_lni *lni,
149875 + u64 *bps, u16 *token_limit);
149876 +int qman_ceetm_lni_set_excess_rate_bps(struct qm_ceetm_lni *lni,
149877 + u64 bps,
149878 + u16 token_limit);
149879 +int qman_ceetm_lni_get_excess_rate_bps(struct qm_ceetm_lni *lni,
149880 + u64 *bps, u16 *token_limit);
149881 +
149882 +/**
149883 + * qman_ceetm_lni_set_tcfcc
149884 + * qman_ceetm_lni_get_tcfcc - Configure/query "Traffic Class Flow Control".
149885 + * @lni: the given LNI.
149886 + * @cq_level: is between 0 and 15, representing individual class queue levels
149887 + * (CQ0 to CQ7 for every channel) and grouped class queue levels (CQ8 to CQ15
149888 + * for every channel).
149889 + * @traffic_class: is between 0 and 7 when associating a given class queue level
149890 + * to a traffic class, or -1 when disabling traffic class flow control for this
149891 + * class queue level.
149892 + *
149893 + * Return zero for success, or -EINVAL if the cq_level or traffic_class is out
149894 + * of range as indicated above, or -EIO if the configure/query tcfcc command
149895 + * returns error.
149896 + *
149897 + * Refer to the section of QMan CEETM traffic class flow control in the
149898 + * Reference Manual.
149899 + */
149900 +int qman_ceetm_lni_set_tcfcc(struct qm_ceetm_lni *lni,
149901 + unsigned int cq_level,
149902 + int traffic_class);
149903 +int qman_ceetm_lni_get_tcfcc(struct qm_ceetm_lni *lni,
149904 + unsigned int cq_level,
149905 + int *traffic_class);
149906 +
149907 + /* ----------------------------- */
149908 + /* CEETM :: class queue channels */
149909 + /* ----------------------------- */
149910 +
149911 +/**
149912 + * qman_ceetm_channel_claim - Claims an unclaimed CQ channel that is mapped to
149913 + * the given LNI.
149914 + * @channel: the returned class queue channel object, if successful.
149915 + * @lni: the LNI that the channel belongs to.
149916 + *
149917 + * Channels are always initially "unshaped".
149918 + *
149919 + * Return zero for success, or -ENODEV if there is no channel available(all 32
149920 + * channels are claimed) or -EINVAL if the channel mapping command returns
149921 + * error.
149922 + */
149923 +int qman_ceetm_channel_claim(struct qm_ceetm_channel **channel,
149924 + struct qm_ceetm_lni *lni);
149925 +
149926 +/**
149927 + * qman_ceetm_channel_release - Releases a previously claimed CQ channel.
149928 + * @channel: the channel needs to be released.
149929 + *
149930 + * Returns zero for success, or -EBUSY if the dependencies are still in use.
149931 + *
149932 + * Note any shaping of the channel will be cleared to leave it in an unshaped
149933 + * state.
149934 + */
149935 +int qman_ceetm_channel_release(struct qm_ceetm_channel *channel);
149936 +
149937 +/**
149938 + * qman_ceetm_channel_enable_shaper
149939 + * qman_ceetm_channel_disable_shaper - Enables/disables shaping on the channel.
149940 + * @channel: the given channel.
149941 + * @coupled: indicates whether surplus CR tokens should be added to the
149942 + * excess-rate token count (up to the excess-rate token limit) when the number
149943 + * of (unused) committed-rate tokens reach the committed_rate token limit.
149944 + *
149945 + * Whenever a claimed channel is first enabled for shaping, its committed and
149946 + * excess token rates and limits are zero, so will need to be changed to do
149947 + * anything useful. The shaper can subsequently be enabled/disabled without
149948 + * resetting the shaping parameters, but the shaping parameters will be reset
149949 + * when the channel is released.
149950 + *
149951 + * Return 0 for success, or -EINVAL for failure, in the case that the channel
149952 + * shaper has been enabled/disabled or the management command returns error.
149953 + */
149954 +int qman_ceetm_channel_enable_shaper(struct qm_ceetm_channel *channel,
149955 + int coupled);
149956 +int qman_ceetm_channel_disable_shaper(struct qm_ceetm_channel *channel);
149957 +
149958 +/**
149959 + * qman_ceetm_channel_is_shaper_enabled - Check channel shaper status.
149960 + * @channel: the give channel.
149961 + */
149962 +int qman_ceetm_channel_is_shaper_enabled(struct qm_ceetm_channel *channel);
149963 +
149964 +/**
149965 + * qman_ceetm_channel_set_commit_rate
149966 + * qman_ceetm_channel_get_commit_rate
149967 + * qman_ceetm_channel_set_excess_rate
149968 + * qman_ceetm_channel_get_excess_rate - Set/get channel CR/ER shaper parameters.
149969 + * @channel: the given channel.
149970 + * @token_rate: the desired token rate for "set" function, or the queried token
149971 + * rate for "get" function.
149972 + * @token_limit: the desired token limit for "set" function, or the queried
149973 + * token limit for "get" function.
149974 + *
149975 + * Return zero for success. The "set" function returns -EINVAL if the channel
149976 + * is unshaped, or -EIO if the configure shapper command returns error. The
149977 + * "get" function returns -EINVAL if token rate of token limit is not set, or
149978 + * the query shaper command returns error.
149979 + */
149980 +int qman_ceetm_channel_set_commit_rate(struct qm_ceetm_channel *channel,
149981 + const struct qm_ceetm_rate *token_rate,
149982 + u16 token_limit);
149983 +int qman_ceetm_channel_get_commit_rate(struct qm_ceetm_channel *channel,
149984 + struct qm_ceetm_rate *token_rate,
149985 + u16 *token_limit);
149986 +int qman_ceetm_channel_set_excess_rate(struct qm_ceetm_channel *channel,
149987 + const struct qm_ceetm_rate *token_rate,
149988 + u16 token_limit);
149989 +int qman_ceetm_channel_get_excess_rate(struct qm_ceetm_channel *channel,
149990 + struct qm_ceetm_rate *token_rate,
149991 + u16 *token_limit);
149992 +/**
149993 + * qman_ceetm_channel_set_commit_rate_bps
149994 + * qman_ceetm_channel_get_commit_rate_bps
149995 + * qman_ceetm_channel_set_excess_rate_bps
149996 + * qman_ceetm_channel_get_excess_rate_bps - Set/get channel CR/ER shaper
149997 + * parameters.
149998 + * @channel: the given channel.
149999 + * @token_rate: the desired shaper rate in bps for "set" function, or the
150000 + * shaper rate in bps for "get" function.
150001 + * @token_limit: the desired token limit for "set" function, or the queried
150002 + * token limit for "get" function.
150003 + *
150004 + * Return zero for success. The "set" function returns -EINVAL if the channel
150005 + * is unshaped, or -EIO if the configure shapper command returns error. The
150006 + * "get" function returns -EINVAL if token rate of token limit is not set, or
150007 + * the query shaper command returns error.
150008 + */
150009 +int qman_ceetm_channel_set_commit_rate_bps(struct qm_ceetm_channel *channel,
150010 + u64 bps, u16 token_limit);
150011 +int qman_ceetm_channel_get_commit_rate_bps(struct qm_ceetm_channel *channel,
150012 + u64 *bps, u16 *token_limit);
150013 +int qman_ceetm_channel_set_excess_rate_bps(struct qm_ceetm_channel *channel,
150014 + u64 bps, u16 token_limit);
150015 +int qman_ceetm_channel_get_excess_rate_bps(struct qm_ceetm_channel *channel,
150016 + u64 *bps, u16 *token_limit);
150017 +
150018 +/**
150019 + * qman_ceetm_channel_set_weight
150020 + * qman_ceetm_channel_get_weight - Set/get the weight for unshaped channel
150021 + * @channel: the given channel.
150022 + * @token_limit: the desired token limit as the weight of the unshaped channel
150023 + * for "set" function, or the queried token limit for "get" function.
150024 + *
150025 + * The algorithm of unshaped fair queuing (uFQ) is used for unshaped channel.
150026 + * It allows the unshaped channels to be included in the CR time eligible list,
150027 + * and thus use the configured CR token limit value as their fair queuing
150028 + * weight.
150029 + *
150030 + * Return zero for success, or -EINVAL if the channel is a shaped channel or
150031 + * the management command returns error.
150032 + */
150033 +int qman_ceetm_channel_set_weight(struct qm_ceetm_channel *channel,
150034 + u16 token_limit);
150035 +int qman_ceetm_channel_get_weight(struct qm_ceetm_channel *channel,
150036 + u16 *token_limit);
150037 +
150038 +/**
150039 + * qman_ceetm_channel_set_group
150040 + * qman_ceetm_channel_get_group - Set/get the grouping of the class scheduler.
150041 + * @channel: the given channel.
150042 + * @group_b: indicates whether there is group B in this channel.
150043 + * @prio_a: the priority of group A.
150044 + * @prio_b: the priority of group B.
150045 + *
150046 + * There are 8 individual class queues (CQ0-CQ7), and 8 grouped class queues
150047 + * (CQ8-CQ15). If 'group_b' is zero, then all the grouped class queues are in
150048 + * group A, otherwise they are split into group A (CQ8-11) and group B
150049 + * (CQ12-C15). The individual class queues and the group(s) are in strict
150050 + * priority order relative to each other. Within the group(s), the scheduling
150051 + * is not strict priority order, but the result of scheduling within a group
150052 + * is in strict priority order relative to the other class queues in the
150053 + * channel. 'prio_a' and 'prio_b' control the priority order of the groups
150054 + * relative to the individual class queues, and take values from 0-7. Eg. if
150055 + * 'group_b' is non-zero, 'prio_a' is 2 and 'prio_b' is 6, then the strict
150056 + * priority order would be;
150057 + * CQ0, CQ1, CQ2, GROUPA, CQ3, CQ4, CQ5, CQ6, GROUPB, CQ7
150058 + *
150059 + * Return 0 for success. For "set" function, returns -EINVAL if prio_a or
150060 + * prio_b are out of the range 0 - 7 (priority of group A or group B can not
150061 + * be 0, CQ0 is always the highest class queue in this channel.), or -EIO if
150062 + * the configure scheduler command returns error. For "get" function, return
150063 + * -EINVAL if the query scheduler command returns error.
150064 + */
150065 +int qman_ceetm_channel_set_group(struct qm_ceetm_channel *channel,
150066 + int group_b,
150067 + unsigned int prio_a,
150068 + unsigned int prio_b);
150069 +int qman_ceetm_channel_get_group(struct qm_ceetm_channel *channel,
150070 + int *group_b,
150071 + unsigned int *prio_a,
150072 + unsigned int *prio_b);
150073 +
150074 +/**
150075 + * qman_ceetm_channel_set_group_cr_eligibility
150076 + * qman_ceetm_channel_set_group_er_eligibility - Set channel group eligibility
150077 + * @channel: the given channel object
150078 + * @group_b: indicates whether there is group B in this channel.
150079 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
150080 + *
150081 + * Return zero for success, or -EINVAL if eligibility setting fails.
150082 +*/
150083 +int qman_ceetm_channel_set_group_cr_eligibility(struct qm_ceetm_channel
150084 + *channel, int group_b, int cre);
150085 +int qman_ceetm_channel_set_group_er_eligibility(struct qm_ceetm_channel
150086 + *channel, int group_b, int ere);
150087 +
150088 +/**
150089 + * qman_ceetm_channel_set_cq_cr_eligibility
150090 + * qman_ceetm_channel_set_cq_er_eligibility - Set channel cq eligibility
150091 + * @channel: the given channel object
150092 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
150093 + * @cre: the commit rate eligibility, 1 for enable, 0 for disable.
150094 + *
150095 + * Return zero for success, or -EINVAL if eligibility setting fails.
150096 +*/
150097 +int qman_ceetm_channel_set_cq_cr_eligibility(struct qm_ceetm_channel *channel,
150098 + unsigned int idx, int cre);
150099 +int qman_ceetm_channel_set_cq_er_eligibility(struct qm_ceetm_channel *channel,
150100 + unsigned int idx, int ere);
150101 +
150102 + /* --------------------- */
150103 + /* CEETM :: class queues */
150104 + /* --------------------- */
150105 +
150106 +/**
150107 + * qman_ceetm_cq_claim - Claims an individual class queue.
150108 + * @cq: the returned class queue object, if successful.
150109 + * @channel: the class queue channel.
150110 + * @idx: is from 0 to 7 (representing CQ0 to CQ7).
150111 + * @ccg: represents the class congestion group that this class queue should be
150112 + * subscribed to, or NULL if no congestion group membership is desired.
150113 + *
150114 + * Returns zero for success, or -EINVAL if @idx is out of range 0 - 7 or
150115 + * if this class queue has been claimed, or configure class queue command
150116 + * returns error, or returns -ENOMEM if allocating CQ memory fails.
150117 + */
150118 +int qman_ceetm_cq_claim(struct qm_ceetm_cq **cq,
150119 + struct qm_ceetm_channel *channel,
150120 + unsigned int idx,
150121 + struct qm_ceetm_ccg *ccg);
150122 +
150123 +/**
150124 + * qman_ceetm_cq_claim_A - Claims a class queue group A.
150125 + * @cq: the returned class queue object, if successful.
150126 + * @channel: the class queue channel.
150127 + * @idx: is from 8 to 15 if only group A exits, otherwise, it is from 8 to 11.
150128 + * @ccg: represents the class congestion group that this class queue should be
150129 + * subscribed to, or NULL if no congestion group membership is desired.
150130 + *
150131 + * Return zero for success, or -EINVAL if @idx is out the range or if
150132 + * this class queue has been claimed or configure class queue command returns
150133 + * error, or returns -ENOMEM if allocating CQ memory fails.
150134 + */
150135 +int qman_ceetm_cq_claim_A(struct qm_ceetm_cq **cq,
150136 + struct qm_ceetm_channel *channel,
150137 + unsigned int idx,
150138 + struct qm_ceetm_ccg *ccg);
150139 +
150140 +/**
150141 + * qman_ceetm_cq_claim_B - Claims a class queue group B.
150142 + * @cq: the returned class queue object, if successful.
150143 + * @channel: the class queue channel.
150144 + * @idx: is from 0 to 3 (CQ12 to CQ15).
150145 + * @ccg: represents the class congestion group that this class queue should be
150146 + * subscribed to, or NULL if no congestion group membership is desired.
150147 + *
150148 + * Return zero for success, or -EINVAL if @idx is out the range or if
150149 + * this class queue has been claimed or configure class queue command returns
150150 + * error, or returns -ENOMEM if allocating CQ memory fails.
150151 + */
150152 +int qman_ceetm_cq_claim_B(struct qm_ceetm_cq **cq,
150153 + struct qm_ceetm_channel *channel,
150154 + unsigned int idx,
150155 + struct qm_ceetm_ccg *ccg);
150156 +
150157 +/**
150158 + * qman_ceetm_cq_release - Releases a previously claimed class queue.
150159 + * @cq: The class queue to be released.
150160 + *
150161 + * Return zero for success, or -EBUSY if the dependent objects (eg. logical
150162 + * FQIDs) have not been released.
150163 + */
150164 +int qman_ceetm_cq_release(struct qm_ceetm_cq *cq);
150165 +
150166 +/**
150167 + * qman_ceetm_set_queue_weight
150168 + * qman_ceetm_get_queue_weight - Configure/query the weight of a grouped class
150169 + * queue.
150170 + * @cq: the given class queue.
150171 + * @weight_code: the desired weight code to set for the given class queue for
150172 + * "set" function or the queired weight code for "get" function.
150173 + *
150174 + * Grouped class queues have a default weight code of zero, which corresponds to
150175 + * a scheduler weighting of 1. This function can be used to modify a grouped
150176 + * class queue to another weight, (Use the helpers qman_ceetm_wbfs2ratio()
150177 + * and qman_ceetm_ratio2wbfs() to convert between these 'weight_code' values
150178 + * and the corresponding sharing weight.)
150179 + *
150180 + * Returns zero for success, or -EIO if the configure weight command returns
150181 + * error for "set" function, or -EINVAL if the query command returns
150182 + * error for "get" function.
150183 + * See section "CEETM Weighted Scheduling among Grouped Classes" in Reference
150184 + * Manual for weight and weight code.
150185 + */
150186 +int qman_ceetm_set_queue_weight(struct qm_ceetm_cq *cq,
150187 + struct qm_ceetm_weight_code *weight_code);
150188 +int qman_ceetm_get_queue_weight(struct qm_ceetm_cq *cq,
150189 + struct qm_ceetm_weight_code *weight_code);
150190 +
150191 +/**
150192 + * qman_ceetm_set_queue_weight_in_ratio
150193 + * qman_ceetm_get_queue_weight_in_ratio - Configure/query the weight of a
150194 + * grouped class queue.
150195 + * @cq: the given class queue.
150196 + * @ratio: the weight in ratio. It should be the real ratio number multiplied
150197 + * by 100 to get rid of fraction.
150198 + *
150199 + * Returns zero for success, or -EIO if the configure weight command returns
150200 + * error for "set" function, or -EINVAL if the query command returns
150201 + * error for "get" function.
150202 + */
150203 +int qman_ceetm_set_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 ratio);
150204 +int qman_ceetm_get_queue_weight_in_ratio(struct qm_ceetm_cq *cq, u32 *ratio);
150205 +
150206 +/* Weights are encoded using a pseudo-exponential scheme. The weight codes 0,
150207 + * 32, 64, [...] correspond to weights of 1, 2, 4, [...]. The weights
150208 + * corresponding to intermediate weight codes are calculated using linear
150209 + * interpolation on the inverted values. Or put another way, the inverse weights
150210 + * for each 32nd weight code are 1, 1/2, 1/4, [...], and so the intervals
150211 + * between these are divided linearly into 32 intermediate values, the inverses
150212 + * of which form the remaining weight codes.
150213 + *
150214 + * The Weighted Bandwidth Fair Scheduling (WBFS) algorithm provides a form of
150215 + * scheduling within a group of class queues (group A or B). Weights are used to
150216 + * normalise the class queues to an underlying BFS algorithm where all class
150217 + * queues are assumed to require "equal bandwidth". So the weights referred to
150218 + * by the weight codes act as divisors on the size of frames being enqueued. Ie.
150219 + * one class queue in a group is assigned a weight of 2 whilst the other class
150220 + * queues in the group keep the default weight of 1, then the WBFS scheduler
150221 + * will effectively treat all frames enqueued on the weight-2 class queue as
150222 + * having half the number of bytes they really have. Ie. if all other things are
150223 + * equal, that class queue would get twice as much bytes-per-second bandwidth as
150224 + * the others. So weights should be chosen to provide bandwidth ratios between
150225 + * members of the same class queue group. These weights have no bearing on
150226 + * behaviour outside that group's WBFS mechanism though.
150227 + */
150228 +
150229 +/**
150230 + * qman_ceetm_wbfs2ratio - Given a weight code ('wbfs'), an accurate fractional
150231 + * representation of the corresponding weight is given (in order to not lose
150232 + * any precision).
150233 + * @weight_code: The given weight code in WBFS.
150234 + * @numerator: the numerator part of the weight computed by the weight code.
150235 + * @denominator: the denominator part of the weight computed by the weight code
150236 + *
150237 + * Returns zero for success or -EINVAL if the given weight code is illegal.
150238 + */
150239 +int qman_ceetm_wbfs2ratio(struct qm_ceetm_weight_code *weight_code,
150240 + u32 *numerator,
150241 + u32 *denominator);
150242 +/**
150243 + * qman_ceetm_ratio2wbfs - Given a weight, find the nearest possible weight code
150244 + * If the user needs to know how close this is, convert the resulting weight
150245 + * code back to a weight and compare.
150246 + * @numerator: numerator part of the given weight.
150247 + * @denominator: denominator part of the given weight.
150248 + * @weight_code: the weight code computed from the given weight.
150249 + *
150250 + * Returns zero for success, or -ERANGE if "numerator/denominator" is outside
150251 + * the range of weights.
150252 + */
150253 +int qman_ceetm_ratio2wbfs(u32 numerator,
150254 + u32 denominator,
150255 + struct qm_ceetm_weight_code *weight_code,
150256 + int rounding);
150257 +
150258 +#define QMAN_CEETM_FLAG_CLEAR_STATISTICS_COUNTER 0x1
150259 +/**
150260 + * qman_ceetm_cq_get_dequeue_statistics - Get the statistics provided by CEETM
150261 + * CQ counters.
150262 + * @cq: the given CQ object.
150263 + * @flags: indicates whether the statistics counter will be cleared after query.
150264 + * @frame_count: The number of the frames that have been counted since the
150265 + * counter was cleared last time.
150266 + * @byte_count: the number of bytes in all frames that have been counted.
150267 + *
150268 + * Return zero for success or -EINVAL if query statistics command returns error.
150269 + *
150270 + */
150271 +int qman_ceetm_cq_get_dequeue_statistics(struct qm_ceetm_cq *cq, u32 flags,
150272 + u64 *frame_count, u64 *byte_count);
150273 +
150274 +/**
150275 + * qman_ceetm_drain_cq - drain the CQ till it is empty.
150276 + * @cq: the give CQ object.
150277 + * Return 0 for success or -EINVAL for unsuccessful command to empty CQ.
150278 + */
150279 +int qman_ceetm_drain_cq(struct qm_ceetm_cq *cq);
150280 +
150281 + /* ---------------------- */
150282 + /* CEETM :: logical FQIDs */
150283 + /* ---------------------- */
150284 +/**
150285 + * qman_ceetm_lfq_claim - Claims an unused logical FQID, associates it with
150286 + * the given class queue.
150287 + * @lfq: the returned lfq object, if successful.
150288 + * @cq: the class queue which needs to claim a LFQID.
150289 + *
150290 + * Return zero for success, or -ENODEV if no LFQID is available or -ENOMEM if
150291 + * allocating memory for lfq fails, or -EINVAL if configuring LFQMT fails.
150292 + */
150293 +int qman_ceetm_lfq_claim(struct qm_ceetm_lfq **lfq,
150294 + struct qm_ceetm_cq *cq);
150295 +
150296 +/**
150297 + * qman_ceetm_lfq_release - Releases a previously claimed logical FQID.
150298 + * @lfq: the lfq to be released.
150299 + *
150300 + * Return zero for success.
150301 + */
150302 +int qman_ceetm_lfq_release(struct qm_ceetm_lfq *lfq);
150303 +
150304 +/**
150305 + * qman_ceetm_lfq_set_context
150306 + * qman_ceetm_lfq_get_context - Set/get the context_a/context_b pair to the
150307 + * "dequeue context table" associated with the logical FQID.
150308 + * @lfq: the given logical FQ object.
150309 + * @context_a: contextA of the dequeue context.
150310 + * @context_b: contextB of the dequeue context.
150311 + *
150312 + * Returns zero for success, or -EINVAL if there is error to set/get the
150313 + * context pair.
150314 + */
150315 +int qman_ceetm_lfq_set_context(struct qm_ceetm_lfq *lfq,
150316 + u64 context_a,
150317 + u32 context_b);
150318 +int qman_ceetm_lfq_get_context(struct qm_ceetm_lfq *lfq,
150319 + u64 *context_a,
150320 + u32 *context_b);
150321 +
150322 +/**
150323 + * qman_ceetm_create_fq - Initialise a FQ object for the LFQ.
150324 + * @lfq: the given logic fq.
150325 + * @fq: the fq object created for the given logic fq.
150326 + *
150327 + * The FQ object can be used in qman_enqueue() and qman_enqueue_orp() APIs to
150328 + * target a logical FQID (and the class queue it is associated with).
150329 + * Note that this FQ object can only be used for enqueues, and
150330 + * in the case of qman_enqueue_orp() it can not be used as the 'orp' parameter,
150331 + * only as 'fq'. This FQ object can not (and shouldn't) be destroyed, it is only
150332 + * valid as long as the underlying 'lfq' remains claimed. It is the user's
150333 + * responsibility to ensure that the underlying 'lfq' is not released until any
150334 + * enqueues to this FQ object have completed. The only field the user needs to
150335 + * fill in is fq->cb.ern, as that enqueue rejection handler is the callback that
150336 + * could conceivably be called on this FQ object. This API can be called
150337 + * multiple times to create multiple FQ objects referring to the same logical
150338 + * FQID, and any enqueue rejections will respect the callback of the object that
150339 + * issued the enqueue (and will identify the object via the parameter passed to
150340 + * the callback too). There is no 'flags' parameter to this API as there is for
150341 + * qman_create_fq() - the created FQ object behaves as though qman_create_fq()
150342 + * had been called with the single flag QMAN_FQ_FLAG_NO_MODIFY.
150343 + *
150344 + * Returns 0 for success.
150345 + */
150346 +int qman_ceetm_create_fq(struct qm_ceetm_lfq *lfq, struct qman_fq *fq);
150347 +
150348 + /* -------------------------------- */
150349 + /* CEETM :: class congestion groups */
150350 + /* -------------------------------- */
150351 +
150352 +/**
150353 + * qman_ceetm_ccg_claim - Claims an unused CCG.
150354 + * @ccg: the returned CCG object, if successful.
150355 + * @channel: the given class queue channel
150356 + * @cscn: the callback function of this CCG.
150357 + * @cb_ctx: the corresponding context to be used used if state change
150358 + * notifications are later enabled for this CCG.
150359 + *
150360 + * The congestion group is local to the given class queue channel, so only
150361 + * class queues within the channel can be associated with that congestion group.
150362 + * The association of class queues to congestion groups occurs when the class
150363 + * queues are claimed, see qman_ceetm_cq_claim() and related functions.
150364 + * Congestion groups are in a "zero" state when initially claimed, and they are
150365 + * returned to that state when released.
150366 + *
150367 + * Return zero for success, or -EINVAL if no CCG in the channel is available.
150368 + */
150369 +int qman_ceetm_ccg_claim(struct qm_ceetm_ccg **ccg,
150370 + struct qm_ceetm_channel *channel,
150371 + unsigned int idx,
150372 + void (*cscn)(struct qm_ceetm_ccg *,
150373 + void *cb_ctx,
150374 + int congested),
150375 + void *cb_ctx);
150376 +
150377 +/**
150378 + * qman_ceetm_ccg_release - Releases a previously claimed CCG.
150379 + * @ccg: the given ccg.
150380 + *
150381 + * Returns zero for success, or -EBUSY if the given ccg's dependent objects
150382 + * (class queues that are associated with the CCG) have not been released.
150383 + */
150384 +int qman_ceetm_ccg_release(struct qm_ceetm_ccg *ccg);
150385 +
150386 +/* This struct is used to specify attributes for a CCG. The 'we_mask' field
150387 + * controls which CCG attributes are to be updated, and the remainder specify
150388 + * the values for those attributes. A CCG counts either frames or the bytes
150389 + * within those frames, but not both ('mode'). A CCG can optionally cause
150390 + * enqueues to be rejected, due to tail-drop or WRED, or both (they are
150391 + * independent options, 'td_en' and 'wr_en_g,wr_en_y,wr_en_r'). Tail-drop can be
150392 + * level-triggered due to a single threshold ('td_thres') or edge-triggered due
150393 + * to a "congestion state", but not both ('td_mode'). Congestion state has
150394 + * distinct entry and exit thresholds ('cs_thres_in' and 'cs_thres_out'), and
150395 + * notifications can be sent to software the CCG goes in to and out of this
150396 + * congested state ('cscn_en'). */
150397 +struct qm_ceetm_ccg_params {
150398 + /* Boolean fields together in a single bitfield struct */
150399 + struct {
150400 + /* Whether to count bytes or frames. 1==frames */
150401 + u8 mode:1;
150402 + /* En/disable tail-drop. 1==enable */
150403 + u8 td_en:1;
150404 + /* Tail-drop on congestion-state or threshold. 1=threshold */
150405 + u8 td_mode:1;
150406 + /* Generate congestion state change notifications. 1==enable */
150407 + u8 cscn_en:1;
150408 + /* Enable WRED rejections (per colour). 1==enable */
150409 + u8 wr_en_g:1;
150410 + u8 wr_en_y:1;
150411 + u8 wr_en_r:1;
150412 + } __packed;
150413 + /* Tail-drop threshold. See qm_cgr_thres_[gs]et64(). */
150414 + struct qm_cgr_cs_thres td_thres;
150415 + /* Congestion state thresholds, for entry and exit. */
150416 + struct qm_cgr_cs_thres cs_thres_in;
150417 + struct qm_cgr_cs_thres cs_thres_out;
150418 + /* Overhead accounting length. Per-packet "tax", from -128 to +127 */
150419 + signed char oal;
150420 + /* Congestion state change notification for DCP portal, virtual CCGID*/
150421 + /* WRED parameters. */
150422 + struct qm_cgr_wr_parm wr_parm_g;
150423 + struct qm_cgr_wr_parm wr_parm_y;
150424 + struct qm_cgr_wr_parm wr_parm_r;
150425 +};
150426 +/* Bits used in 'we_mask' to qman_ceetm_ccg_set(), controls which attributes of
150427 + * the CCGR are to be updated. */
150428 +#define QM_CCGR_WE_MODE 0x0001 /* mode (bytes/frames) */
150429 +#define QM_CCGR_WE_CS_THRES_IN 0x0002 /* congestion state entry threshold */
150430 +#define QM_CCGR_WE_TD_EN 0x0004 /* congestion state tail-drop enable */
150431 +#define QM_CCGR_WE_CSCN_TUPD 0x0008 /* CSCN target update */
150432 +#define QM_CCGR_WE_CSCN_EN 0x0010 /* congestion notification enable */
150433 +#define QM_CCGR_WE_WR_EN_R 0x0020 /* WRED enable - red */
150434 +#define QM_CCGR_WE_WR_EN_Y 0x0040 /* WRED enable - yellow */
150435 +#define QM_CCGR_WE_WR_EN_G 0x0080 /* WRED enable - green */
150436 +#define QM_CCGR_WE_WR_PARM_R 0x0100 /* WRED parameters - red */
150437 +#define QM_CCGR_WE_WR_PARM_Y 0x0200 /* WRED parameters - yellow */
150438 +#define QM_CCGR_WE_WR_PARM_G 0x0400 /* WRED parameters - green */
150439 +#define QM_CCGR_WE_OAL 0x0800 /* overhead accounting length */
150440 +#define QM_CCGR_WE_CS_THRES_OUT 0x1000 /* congestion state exit threshold */
150441 +#define QM_CCGR_WE_TD_THRES 0x2000 /* tail-drop threshold */
150442 +#define QM_CCGR_WE_TD_MODE 0x4000 /* tail-drop mode (state/threshold) */
150443 +#define QM_CCGR_WE_CDV 0x8000 /* cdv */
150444 +
150445 +/**
150446 + * qman_ceetm_ccg_set
150447 + * qman_ceetm_ccg_get - Configure/query a subset of CCG attributes.
150448 + * @ccg: the given CCG object.
150449 + * @we_mask: the write enable mask.
150450 + * @params: the parameters setting for this ccg
150451 + *
150452 + * Return 0 for success, or -EIO if configure ccg command returns error for
150453 + * "set" function, or -EINVAL if query ccg command returns error for "get"
150454 + * function.
150455 + */
150456 +int qman_ceetm_ccg_set(struct qm_ceetm_ccg *ccg,
150457 + u16 we_mask,
150458 + const struct qm_ceetm_ccg_params *params);
150459 +int qman_ceetm_ccg_get(struct qm_ceetm_ccg *ccg,
150460 + struct qm_ceetm_ccg_params *params);
150461 +
150462 +/** qman_ceetm_cscn_swp_set - Add or remove a software portal from the target
150463 + * mask.
150464 + * qman_ceetm_cscn_swp_get - Query whether a given software portal index is
150465 + * in the cscn target mask.
150466 + * @ccg: the give CCG object.
150467 + * @swp_idx: the index of the software portal.
150468 + * @cscn_enabled: 1: Set the swp to be cscn target. 0: remove the swp from
150469 + * the target mask.
150470 + * @we_mask: the write enable mask.
150471 + * @params: the parameters setting for this ccg
150472 + *
150473 + * Return 0 for success, or -EINVAL if command in set/get function fails.
150474 + */
150475 +int qman_ceetm_cscn_swp_set(struct qm_ceetm_ccg *ccg,
150476 + u16 swp_idx,
150477 + unsigned int cscn_enabled,
150478 + u16 we_mask,
150479 + const struct qm_ceetm_ccg_params *params);
150480 +int qman_ceetm_cscn_swp_get(struct qm_ceetm_ccg *ccg,
150481 + u16 swp_idx,
150482 + unsigned int *cscn_enabled);
150483 +
150484 +/** qman_ceetm_cscn_dcp_set - Add or remove a direct connect portal from the\
150485 + * target mask.
150486 + * qman_ceetm_cscn_dcp_get - Query whether a given direct connect portal index
150487 + * is in the cscn target mask.
150488 + * @ccg: the give CCG object.
150489 + * @dcp_idx: the index of the direct connect portal.
150490 + * @vcgid: congestion state change notification for dcp portal, virtual CGID.
150491 + * @cscn_enabled: 1: Set the dcp to be cscn target. 0: remove the dcp from
150492 + * the target mask.
150493 + * @we_mask: the write enable mask.
150494 + * @params: the parameters setting for this ccg
150495 + *
150496 + * Return 0 for success, or -EINVAL if command in set/get function fails.
150497 + */
150498 +int qman_ceetm_cscn_dcp_set(struct qm_ceetm_ccg *ccg,
150499 + u16 dcp_idx,
150500 + u8 vcgid,
150501 + unsigned int cscn_enabled,
150502 + u16 we_mask,
150503 + const struct qm_ceetm_ccg_params *params);
150504 +int qman_ceetm_cscn_dcp_get(struct qm_ceetm_ccg *ccg,
150505 + u16 dcp_idx,
150506 + u8 *vcgid,
150507 + unsigned int *cscn_enabled);
150508 +
150509 +/**
150510 + * qman_ceetm_ccg_get_reject_statistics - Get the statistics provided by
150511 + * CEETM CCG counters.
150512 + * @ccg: the given CCG object.
150513 + * @flags: indicates whether the statistics counter will be cleared after query.
150514 + * @frame_count: The number of the frames that have been counted since the
150515 + * counter was cleared last time.
150516 + * @byte_count: the number of bytes in all frames that have been counted.
150517 + *
150518 + * Return zero for success or -EINVAL if query statistics command returns error.
150519 + *
150520 + */
150521 +int qman_ceetm_ccg_get_reject_statistics(struct qm_ceetm_ccg *ccg, u32 flags,
150522 + u64 *frame_count, u64 *byte_count);
150523 +
150524 +/**
150525 + * qman_ceetm_query_lfqmt - Query the logical frame queue mapping table
150526 + * @lfqid: Logical Frame Queue ID
150527 + * @lfqmt_query: Results of the query command
150528 + *
150529 + * Returns zero for success or -EIO if the query command returns error.
150530 + *
150531 + */
150532 +int qman_ceetm_query_lfqmt(int lfqid,
150533 + struct qm_mcr_ceetm_lfqmt_query *lfqmt_query);
150534 +
150535 +/**
150536 + * qman_ceetm_query_cq - Queries a CEETM CQ
150537 + * @cqid: the channel ID (first byte) followed by the CQ idx
150538 + * @dcpid: CEETM portal ID
150539 + * @cq_query: storage for the queried CQ fields
150540 + *
150541 + * Returns zero for success or -EIO if the query command returns error.
150542 + *
150543 +*/
150544 +int qman_ceetm_query_cq(unsigned int cqid, unsigned int dcpid,
150545 + struct qm_mcr_ceetm_cq_query *cq_query);
150546 +
150547 +/**
150548 + * qman_ceetm_query_write_statistics - Query (and optionally write) statistics
150549 + * @cid: Target ID (CQID or CCGRID)
150550 + * @dcp_idx: CEETM portal ID
150551 + * @command_type: One of the following:
150552 + * 0 = Query dequeue statistics. CID carries the CQID to be queried.
150553 + * 1 = Query and clear dequeue statistics. CID carries the CQID to be queried
150554 + * 2 = Write dequeue statistics. CID carries the CQID to be written.
150555 + * 3 = Query reject statistics. CID carries the CCGRID to be queried.
150556 + * 4 = Query and clear reject statistics. CID carries the CCGRID to be queried
150557 + * 5 = Write reject statistics. CID carries the CCGRID to be written
150558 + * @frame_count: Frame count value to be written if this is a write command
150559 + * @byte_count: Bytes count value to be written if this is a write command
150560 + *
150561 + * Returns zero for success or -EIO if the query command returns error.
150562 + */
150563 +int qman_ceetm_query_write_statistics(u16 cid, enum qm_dc_portal dcp_idx,
150564 + u16 command_type, u64 frame_count,
150565 + u64 byte_count);
150566 +
150567 +/**
150568 + * qman_set_wpm - Set waterfall power management
150569 + *
150570 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
150571 + *
150572 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
150573 + * accessible.
150574 + */
150575 +int qman_set_wpm(int wpm_enable);
150576 +
150577 +/**
150578 + * qman_get_wpm - Query the waterfall power management setting
150579 + *
150580 + * @wpm_enable: boolean, 1 = enable wpm, 0 = disable wpm.
150581 + *
150582 + * Return 0 for success, return -ENODEV if QMan misc_cfg register is not
150583 + * accessible.
150584 + */
150585 +int qman_get_wpm(int *wpm_enable);
150586 +
150587 +/* The below qman_p_***() variants might be called in a migration situation
150588 + * (e.g. cpu hotplug). They are used to continue accessing the portal that
150589 + * execution was affine to prior to migration.
150590 + * @qman_portal specifies which portal the APIs will use.
150591 +*/
150592 +const struct qman_portal_config *qman_p_get_portal_config(struct qman_portal
150593 + *p);
150594 +int qman_p_irqsource_add(struct qman_portal *p, u32 bits);
150595 +int qman_p_irqsource_remove(struct qman_portal *p, u32 bits);
150596 +int qman_p_poll_dqrr(struct qman_portal *p, unsigned int limit);
150597 +u32 qman_p_poll_slow(struct qman_portal *p);
150598 +void qman_p_poll(struct qman_portal *p);
150599 +void qman_p_stop_dequeues(struct qman_portal *p);
150600 +void qman_p_start_dequeues(struct qman_portal *p);
150601 +void qman_p_static_dequeue_add(struct qman_portal *p, u32 pools);
150602 +void qman_p_static_dequeue_del(struct qman_portal *p, u32 pools);
150603 +u32 qman_p_static_dequeue_get(struct qman_portal *p);
150604 +void qman_p_dca(struct qman_portal *p, struct qm_dqrr_entry *dq,
150605 + int park_request);
150606 +int qman_p_volatile_dequeue(struct qman_portal *p, struct qman_fq *fq,
150607 + u32 flags __maybe_unused, u32 vdqcr);
150608 +int qman_p_enqueue(struct qman_portal *p, struct qman_fq *fq,
150609 + const struct qm_fd *fd, u32 flags);
150610 +int qman_p_enqueue_orp(struct qman_portal *p, struct qman_fq *fq,
150611 + const struct qm_fd *fd, u32 flags,
150612 + struct qman_fq *orp, u16 orp_seqnum);
150613 +int qman_p_enqueue_precommit(struct qman_portal *p, struct qman_fq *fq,
150614 + const struct qm_fd *fd, u32 flags,
150615 + qman_cb_precommit cb, void *cb_arg);
150616 +
150617 +static inline int qman_is_probed(void) {
150618 + return 1;
150619 +}
150620 +
150621 +
150622 +static inline int qman_portals_probed(void) {
150623 + return 1;
150624 +}
150625 +
150626 +#ifdef __cplusplus
150627 +}
150628 +#endif
150629 +
150630 +#endif /* FSL_QMAN_H */
150631 --- /dev/null
150632 +++ b/include/linux/fsl_usdpaa.h
150633 @@ -0,0 +1,372 @@
150634 +/* Copyright 2011-2012 Freescale Semiconductor, Inc.
150635 + *
150636 + * This file is licensed under the terms of the GNU General Public License
150637 + * version 2. This program is licensed "as is" without any warranty of any
150638 + * kind, whether express or implied.
150639 + */
150640 +
150641 +#ifndef FSL_USDPAA_H
150642 +#define FSL_USDPAA_H
150643 +
150644 +#ifdef __cplusplus
150645 +extern "C" {
150646 +#endif
150647 +
150648 +#include <linux/uaccess.h>
150649 +#include <linux/ioctl.h>
150650 +#include <linux/fsl_qman.h> /* For "enum qm_channel" */
150651 +#include <linux/compat.h>
150652 +
150653 +#ifdef CONFIG_FSL_USDPAA
150654 +
150655 +/******************************/
150656 +/* Allocation of resource IDs */
150657 +/******************************/
150658 +
150659 +/* This enum is used to distinguish between the type of underlying object being
150660 + * manipulated. */
150661 +enum usdpaa_id_type {
150662 + usdpaa_id_fqid,
150663 + usdpaa_id_bpid,
150664 + usdpaa_id_qpool,
150665 + usdpaa_id_cgrid,
150666 + usdpaa_id_ceetm0_lfqid,
150667 + usdpaa_id_ceetm0_channelid,
150668 + usdpaa_id_ceetm1_lfqid,
150669 + usdpaa_id_ceetm1_channelid,
150670 + usdpaa_id_max /* <-- not a valid type, represents the number of types */
150671 +};
150672 +#define USDPAA_IOCTL_MAGIC 'u'
150673 +struct usdpaa_ioctl_id_alloc {
150674 + uint32_t base; /* Return value, the start of the allocated range */
150675 + enum usdpaa_id_type id_type; /* what kind of resource(s) to allocate */
150676 + uint32_t num; /* how many IDs to allocate (and return value) */
150677 + uint32_t align; /* must be a power of 2, 0 is treated like 1 */
150678 + int partial; /* whether to allow less than 'num' */
150679 +};
150680 +struct usdpaa_ioctl_id_release {
150681 + /* Input; */
150682 + enum usdpaa_id_type id_type;
150683 + uint32_t base;
150684 + uint32_t num;
150685 +};
150686 +struct usdpaa_ioctl_id_reserve {
150687 + enum usdpaa_id_type id_type;
150688 + uint32_t base;
150689 + uint32_t num;
150690 +};
150691 +
150692 +
150693 +/* ioctl() commands */
150694 +#define USDPAA_IOCTL_ID_ALLOC \
150695 + _IOWR(USDPAA_IOCTL_MAGIC, 0x01, struct usdpaa_ioctl_id_alloc)
150696 +#define USDPAA_IOCTL_ID_RELEASE \
150697 + _IOW(USDPAA_IOCTL_MAGIC, 0x02, struct usdpaa_ioctl_id_release)
150698 +#define USDPAA_IOCTL_ID_RESERVE \
150699 + _IOW(USDPAA_IOCTL_MAGIC, 0x0A, struct usdpaa_ioctl_id_reserve)
150700 +
150701 +/**********************/
150702 +/* Mapping DMA memory */
150703 +/**********************/
150704 +
150705 +/* Maximum length for a map name, including NULL-terminator */
150706 +#define USDPAA_DMA_NAME_MAX 16
150707 +/* Flags for requesting DMA maps. Maps are private+unnamed or sharable+named.
150708 + * For a sharable and named map, specify _SHARED (whether creating one or
150709 + * binding to an existing one). If _SHARED is specified and _CREATE is not, then
150710 + * the mapping must already exist. If _SHARED and _CREATE are specified and the
150711 + * mapping doesn't already exist, it will be created. If _SHARED and _CREATE are
150712 + * specified and the mapping already exists, the mapping will fail unless _LAZY
150713 + * is specified. When mapping to a pre-existing sharable map, the length must be
150714 + * an exact match. Lengths must be a power-of-4 multiple of page size.
150715 + *
150716 + * Note that this does not actually map the memory to user-space, that is done
150717 + * by a subsequent mmap() using the page offset returned from this ioctl(). The
150718 + * ioctl() is what gives the process permission to do this, and a page-offset
150719 + * with which to do so.
150720 + */
150721 +#define USDPAA_DMA_FLAG_SHARE 0x01
150722 +#define USDPAA_DMA_FLAG_CREATE 0x02
150723 +#define USDPAA_DMA_FLAG_LAZY 0x04
150724 +#define USDPAA_DMA_FLAG_RDONLY 0x08
150725 +struct usdpaa_ioctl_dma_map {
150726 + /* Output parameters - virtual and physical addresses */
150727 + void *ptr;
150728 + uint64_t phys_addr;
150729 + /* Input parameter, the length of the region to be created (or if
150730 + * mapping an existing region, this must match it). Must be a power-of-4
150731 + * multiple of page size. */
150732 + uint64_t len;
150733 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
150734 + uint32_t flags;
150735 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
150736 + * of the existing mapping to use). */
150737 + char name[USDPAA_DMA_NAME_MAX];
150738 + /* If this ioctl() creates the mapping, this is an input parameter
150739 + * stating whether the region supports locking. If mapping an existing
150740 + * region, this is a return value indicating the same thing. */
150741 + int has_locking;
150742 + /* In the case of a successful map with _CREATE and _LAZY, this return
150743 + * value indicates whether we created the mapped region or whether it
150744 + * already existed. */
150745 + int did_create;
150746 +};
150747 +
150748 +#ifdef CONFIG_COMPAT
150749 +struct usdpaa_ioctl_dma_map_compat {
150750 + /* Output parameters - virtual and physical addresses */
150751 + compat_uptr_t ptr;
150752 + uint64_t phys_addr;
150753 + /* Input parameter, the length of the region to be created (or if
150754 + * mapping an existing region, this must match it). Must be a power-of-4
150755 + * multiple of page size. */
150756 + uint64_t len;
150757 + /* Input parameter, the USDPAA_DMA_FLAG_* settings. */
150758 + uint32_t flags;
150759 + /* If _FLAG_SHARE is specified, the name of the region to be created (or
150760 + * of the existing mapping to use). */
150761 + char name[USDPAA_DMA_NAME_MAX];
150762 + /* If this ioctl() creates the mapping, this is an input parameter
150763 + * stating whether the region supports locking. If mapping an existing
150764 + * region, this is a return value indicating the same thing. */
150765 + int has_locking;
150766 + /* In the case of a successful map with _CREATE and _LAZY, this return
150767 + * value indicates whether we created the mapped region or whether it
150768 + * already existed. */
150769 + int did_create;
150770 +};
150771 +
150772 +#define USDPAA_IOCTL_DMA_MAP_COMPAT \
150773 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map_compat)
150774 +#endif
150775 +
150776 +
150777 +#define USDPAA_IOCTL_DMA_MAP \
150778 + _IOWR(USDPAA_IOCTL_MAGIC, 0x03, struct usdpaa_ioctl_dma_map)
150779 +/* munmap() does not remove the DMA map, just the user-space mapping to it.
150780 + * This ioctl will do both (though you can munmap() before calling the ioctl
150781 + * too). */
150782 +#define USDPAA_IOCTL_DMA_UNMAP \
150783 + _IOW(USDPAA_IOCTL_MAGIC, 0x04, unsigned char)
150784 +/* We implement a cross-process locking scheme per DMA map. Call this ioctl()
150785 + * with a mmap()'d address, and the process will (interruptible) sleep if the
150786 + * lock is already held by another process. Process destruction will
150787 + * automatically clean up any held locks. */
150788 +#define USDPAA_IOCTL_DMA_LOCK \
150789 + _IOW(USDPAA_IOCTL_MAGIC, 0x05, unsigned char)
150790 +#define USDPAA_IOCTL_DMA_UNLOCK \
150791 + _IOW(USDPAA_IOCTL_MAGIC, 0x06, unsigned char)
150792 +
150793 +/***************************************/
150794 +/* Mapping and using QMan/BMan portals */
150795 +/***************************************/
150796 +enum usdpaa_portal_type {
150797 + usdpaa_portal_qman,
150798 + usdpaa_portal_bman,
150799 +};
150800 +
150801 +#define QBMAN_ANY_PORTAL_IDX 0xffffffff
150802 +
150803 +struct usdpaa_ioctl_portal_map {
150804 + /* Input parameter, is a qman or bman portal required. */
150805 +
150806 + enum usdpaa_portal_type type;
150807 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
150808 + for don't care. The portal index will be populated by the
150809 + driver when the ioctl() successfully completes */
150810 + uint32_t index;
150811 +
150812 + /* Return value if the map succeeds, this gives the mapped
150813 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
150814 + struct usdpaa_portal_map {
150815 + void *cinh;
150816 + void *cena;
150817 + } addr;
150818 + /* Qman-specific return values */
150819 + uint16_t channel;
150820 + uint32_t pools;
150821 +};
150822 +
150823 +#ifdef CONFIG_COMPAT
150824 +struct compat_usdpaa_ioctl_portal_map {
150825 + /* Input parameter, is a qman or bman portal required. */
150826 + enum usdpaa_portal_type type;
150827 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
150828 + for don't care. The portal index will be populated by the
150829 + driver when the ioctl() successfully completes */
150830 + uint32_t index;
150831 + /* Return value if the map succeeds, this gives the mapped
150832 + * cache-inhibited (cinh) and cache-enabled (cena) addresses. */
150833 + struct usdpaa_portal_map_compat {
150834 + compat_uptr_t cinh;
150835 + compat_uptr_t cena;
150836 + } addr;
150837 + /* Qman-specific return values */
150838 + uint16_t channel;
150839 + uint32_t pools;
150840 +};
150841 +#define USDPAA_IOCTL_PORTAL_MAP_COMPAT \
150842 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct compat_usdpaa_ioctl_portal_map)
150843 +#define USDPAA_IOCTL_PORTAL_UNMAP_COMPAT \
150844 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map_compat)
150845 +#endif
150846 +
150847 +#define USDPAA_IOCTL_PORTAL_MAP \
150848 + _IOWR(USDPAA_IOCTL_MAGIC, 0x07, struct usdpaa_ioctl_portal_map)
150849 +#define USDPAA_IOCTL_PORTAL_UNMAP \
150850 + _IOW(USDPAA_IOCTL_MAGIC, 0x08, struct usdpaa_portal_map)
150851 +
150852 +struct usdpaa_ioctl_irq_map {
150853 + enum usdpaa_portal_type type; /* Type of portal to map */
150854 + int fd; /* File descriptor that contains the portal */
150855 + void *portal_cinh; /* Cache inhibited area to identify the portal */
150856 +};
150857 +
150858 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP \
150859 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct usdpaa_ioctl_irq_map)
150860 +
150861 +#ifdef CONFIG_COMPAT
150862 +
150863 +struct compat_ioctl_irq_map {
150864 + enum usdpaa_portal_type type; /* Type of portal to map */
150865 + compat_int_t fd; /* File descriptor that contains the portal */
150866 + compat_uptr_t portal_cinh; /* Used identify the portal */};
150867 +
150868 +#define USDPAA_IOCTL_PORTAL_IRQ_MAP_COMPAT \
150869 + _IOW(USDPAA_IOCTL_MAGIC, 0x09, struct compat_ioctl_irq_map)
150870 +#endif
150871 +
150872 +/* ioctl to query the amount of DMA memory used in the system */
150873 +struct usdpaa_ioctl_dma_used {
150874 + uint64_t free_bytes;
150875 + uint64_t total_bytes;
150876 +};
150877 +#define USDPAA_IOCTL_DMA_USED \
150878 + _IOR(USDPAA_IOCTL_MAGIC, 0x0B, struct usdpaa_ioctl_dma_used)
150879 +
150880 +/* ioctl to allocate a raw portal */
150881 +struct usdpaa_ioctl_raw_portal {
150882 + /* inputs */
150883 + enum usdpaa_portal_type type; /* Type of portal to allocate */
150884 +
150885 + /* set to non zero to turn on stashing */
150886 + uint8_t enable_stash;
150887 + /* Stashing attributes for the portal */
150888 + uint32_t cpu;
150889 + uint32_t cache;
150890 + uint32_t window;
150891 +
150892 + /* Specifies the stash request queue this portal should use */
150893 + uint8_t sdest;
150894 +
150895 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
150896 + * for don't care. The portal index will be populated by the
150897 + * driver when the ioctl() successfully completes */
150898 + uint32_t index;
150899 +
150900 + /* outputs */
150901 + uint64_t cinh;
150902 + uint64_t cena;
150903 +};
150904 +
150905 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL \
150906 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct usdpaa_ioctl_raw_portal)
150907 +
150908 +#define USDPAA_IOCTL_FREE_RAW_PORTAL \
150909 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct usdpaa_ioctl_raw_portal)
150910 +
150911 +#ifdef CONFIG_COMPAT
150912 +
150913 +struct compat_ioctl_raw_portal {
150914 + /* inputs */
150915 + enum usdpaa_portal_type type; /* Type of portal to allocate */
150916 +
150917 + /* set to non zero to turn on stashing */
150918 + uint8_t enable_stash;
150919 + /* Stashing attributes for the portal */
150920 + uint32_t cpu;
150921 + uint32_t cache;
150922 + uint32_t window;
150923 + /* Specifies the stash request queue this portal should use */
150924 + uint8_t sdest;
150925 +
150926 + /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
150927 + * for don't care. The portal index will be populated by the
150928 + * driver when the ioctl() successfully completes */
150929 + uint32_t index;
150930 +
150931 + /* outputs */
150932 + uint64_t cinh;
150933 + uint64_t cena;
150934 +};
150935 +
150936 +#define USDPAA_IOCTL_ALLOC_RAW_PORTAL_COMPAT \
150937 + _IOWR(USDPAA_IOCTL_MAGIC, 0x0C, struct compat_ioctl_raw_portal)
150938 +
150939 +#define USDPAA_IOCTL_FREE_RAW_PORTAL_COMPAT \
150940 + _IOR(USDPAA_IOCTL_MAGIC, 0x0D, struct compat_ioctl_raw_portal)
150941 +
150942 +#endif
150943 +
150944 +#ifdef __KERNEL__
150945 +
150946 +/* Early-boot hook */
150947 +int __init fsl_usdpaa_init_early(void);
150948 +
150949 +/* Fault-handling in arch/powerpc/mm/mem.c gives USDPAA an opportunity to detect
150950 + * faults within its ranges via this hook. */
150951 +int usdpaa_test_fault(unsigned long pfn, u64 *phys_addr, u64 *size);
150952 +
150953 +#endif /* __KERNEL__ */
150954 +
150955 +#endif /* CONFIG_FSL_USDPAA */
150956 +
150957 +#ifdef __KERNEL__
150958 +/* This interface is needed in a few places and though it's not specific to
150959 + * USDPAA as such, creating a new header for it doesn't make any sense. The
150960 + * qbman kernel driver implements this interface and uses it as the backend for
150961 + * both the FQID and BPID allocators. The fsl_usdpaa driver also uses this
150962 + * interface for tracking per-process allocations handed out to user-space. */
150963 +struct dpa_alloc {
150964 + struct list_head free;
150965 + spinlock_t lock;
150966 + struct list_head used;
150967 +};
150968 +#define DECLARE_DPA_ALLOC(name) \
150969 + struct dpa_alloc name = { \
150970 + .free = { \
150971 + .prev = &name.free, \
150972 + .next = &name.free \
150973 + }, \
150974 + .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
150975 + .used = { \
150976 + .prev = &name.used, \
150977 + .next = &name.used \
150978 + } \
150979 + }
150980 +static inline void dpa_alloc_init(struct dpa_alloc *alloc)
150981 +{
150982 + INIT_LIST_HEAD(&alloc->free);
150983 + INIT_LIST_HEAD(&alloc->used);
150984 + spin_lock_init(&alloc->lock);
150985 +}
150986 +int dpa_alloc_new(struct dpa_alloc *alloc, u32 *result, u32 count, u32 align,
150987 + int partial);
150988 +void dpa_alloc_free(struct dpa_alloc *alloc, u32 base_id, u32 count);
150989 +void dpa_alloc_seed(struct dpa_alloc *alloc, u32 fqid, u32 count);
150990 +
150991 +/* Like 'new' but specifies the desired range, returns -ENOMEM if the entire
150992 + * desired range is not available, or 0 for success. */
150993 +int dpa_alloc_reserve(struct dpa_alloc *alloc, u32 base_id, u32 count);
150994 +/* Pops and returns contiguous ranges from the allocator. Returns -ENOMEM when
150995 + * 'alloc' is empty. */
150996 +int dpa_alloc_pop(struct dpa_alloc *alloc, u32 *result, u32 *count);
150997 +/* Returns 1 if the specified id is alloced, 0 otherwise */
150998 +int dpa_alloc_check(struct dpa_alloc *list, u32 id);
150999 +#endif /* __KERNEL__ */
151000 +
151001 +#ifdef __cplusplus
151002 +}
151003 +#endif
151004 +
151005 +#endif /* FSL_USDPAA_H */
151006 --- a/include/linux/netdev_features.h
151007 +++ b/include/linux/netdev_features.h
151008 @@ -79,6 +79,7 @@ enum {
151009 NETIF_F_HW_ESP_BIT, /* Hardware ESP transformation offload */
151010 NETIF_F_HW_ESP_TX_CSUM_BIT, /* ESP with TX checksum offload */
151011 NETIF_F_RX_UDP_TUNNEL_PORT_BIT, /* Offload of RX port for UDP tunnels */
151012 + NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */
151013
151014 /*
151015 * Add your fresh new feature above and remember to update
151016 @@ -144,6 +145,7 @@ enum {
151017 #define NETIF_F_HW_ESP __NETIF_F(HW_ESP)
151018 #define NETIF_F_HW_ESP_TX_CSUM __NETIF_F(HW_ESP_TX_CSUM)
151019 #define NETIF_F_RX_UDP_TUNNEL_PORT __NETIF_F(RX_UDP_TUNNEL_PORT)
151020 +#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ)
151021
151022 /* Finds the next feature with the highest number of the range of start till 0.
151023 */
151024 --- /dev/null
151025 +++ b/include/uapi/linux/fmd/Kbuild
151026 @@ -0,0 +1,5 @@
151027 +header-y += integrations/
151028 +header-y += Peripherals/
151029 +
151030 +header-y += ioctls.h
151031 +header-y += net_ioctls.h
151032 --- /dev/null
151033 +++ b/include/uapi/linux/fmd/Peripherals/Kbuild
151034 @@ -0,0 +1,4 @@
151035 +header-y += fm_ioctls.h
151036 +header-y += fm_port_ioctls.h
151037 +header-y += fm_pcd_ioctls.h
151038 +header-y += fm_test_ioctls.h
151039 --- /dev/null
151040 +++ b/include/uapi/linux/fmd/Peripherals/fm_ioctls.h
151041 @@ -0,0 +1,628 @@
151042 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
151043 + * All rights reserved.
151044 + *
151045 + * Redistribution and use in source and binary forms, with or without
151046 + * modification, are permitted provided that the following conditions are met:
151047 + * * Redistributions of source code must retain the above copyright
151048 + * notice, this list of conditions and the following disclaimer.
151049 + * * Redistributions in binary form must reproduce the above copyright
151050 + * notice, this list of conditions and the following disclaimer in the
151051 + * documentation and/or other materials provided with the distribution.
151052 + * * Neither the name of Freescale Semiconductor nor the
151053 + * names of its contributors may be used to endorse or promote products
151054 + * derived from this software without specific prior written permission.
151055 + *
151056 + *
151057 + * ALTERNATIVELY, this software may be distributed under the terms of the
151058 + * GNU General Public License ("GPL") as published by the Free Software
151059 + * Foundation, either version 2 of that License or (at your option) any
151060 + * later version.
151061 + *
151062 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
151063 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
151064 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
151065 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
151066 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
151067 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
151068 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
151069 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
151070 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
151071 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
151072 + */
151073 +
151074 +/**************************************************************************//**
151075 + @File fm_ioctls.h
151076 +
151077 + @Description FM Char device ioctls
151078 +*//***************************************************************************/
151079 +#ifndef __FM_IOCTLS_H
151080 +#define __FM_IOCTLS_H
151081 +
151082 +
151083 +/**************************************************************************//**
151084 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
151085 +
151086 + @Description FM Linux ioctls definitions and enums
151087 +
151088 + @{
151089 +*//***************************************************************************/
151090 +
151091 +/**************************************************************************//**
151092 + @Collection FM IOCTL device ('/dev') definitions
151093 +*//***************************************************************************/
151094 +#define DEV_FM_NAME "fm" /**< Name of the FM chardev */
151095 +
151096 +#define DEV_FM_MINOR_BASE 0
151097 +#define DEV_FM_PCD_MINOR_BASE (DEV_FM_MINOR_BASE + 1) /*/dev/fmx-pcd */
151098 +#define DEV_FM_OH_PORTS_MINOR_BASE (DEV_FM_PCD_MINOR_BASE + 1) /*/dev/fmx-port-ohy */
151099 +#define DEV_FM_RX_PORTS_MINOR_BASE (DEV_FM_OH_PORTS_MINOR_BASE + FM_MAX_NUM_OF_OH_PORTS) /*/dev/fmx-port-rxy */
151100 +#define DEV_FM_TX_PORTS_MINOR_BASE (DEV_FM_RX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_RX_PORTS) /*/dev/fmx-port-txy */
151101 +#define DEV_FM_MAX_MINORS (DEV_FM_TX_PORTS_MINOR_BASE + FM_MAX_NUM_OF_TX_PORTS)
151102 +
151103 +#define FM_IOC_NUM(n) (n)
151104 +#define FM_PCD_IOC_NUM(n) (n+20)
151105 +#define FM_PORT_IOC_NUM(n) (n+70)
151106 +/* @} */
151107 +
151108 +#define IOC_FM_MAX_NUM_OF_PORTS 64
151109 +
151110 +
151111 +/**************************************************************************//**
151112 + @Description Enum for defining port types
151113 + (must match enum e_FmPortType defined in fm_ext.h)
151114 +*//***************************************************************************/
151115 +typedef enum ioc_fm_port_type {
151116 + e_IOC_FM_PORT_TYPE_OH_OFFLINE_PARSING = 0, /**< Offline parsing port */
151117 + e_IOC_FM_PORT_TYPE_RX, /**< 1G Rx port */
151118 + e_IOC_FM_PORT_TYPE_RX_10G, /**< 10G Rx port */
151119 + e_IOC_FM_PORT_TYPE_TX, /**< 1G Tx port */
151120 + e_IOC_FM_PORT_TYPE_TX_10G, /**< 10G Tx port */
151121 + e_IOC_FM_PORT_TYPE_DUMMY
151122 +} ioc_fm_port_type;
151123 +
151124 +
151125 +/**************************************************************************//**
151126 + @Group lnx_ioctl_FM_lib_grp FM library
151127 +
151128 + @Description FM API functions, definitions and enums
151129 + The FM module is the main driver module and is a mandatory module
151130 + for FM driver users. Before any further module initialization,
151131 + this module must be initialized.
151132 + The FM is a "single-tone" module. It is responsible of the common
151133 + HW modules: FPM, DMA, common QMI, common BMI initializations and
151134 + run-time control routines. This module must be initialized always
151135 + when working with any of the FM modules.
151136 + NOTE - We assumes that the FML will be initialize only by core No. 0!
151137 +
151138 + @{
151139 +*//***************************************************************************/
151140 +
151141 +/**************************************************************************//**
151142 + @Description FM Exceptions
151143 +*//***************************************************************************/
151144 +typedef enum ioc_fm_exceptions {
151145 + e_IOC_FM_EX_DMA_BUS_ERROR, /**< DMA bus error. */
151146 + e_IOC_EX_DMA_READ_ECC, /**< Read Buffer ECC error (Valid for FM rev < 6)*/
151147 + e_IOC_EX_DMA_SYSTEM_WRITE_ECC, /**< Write Buffer ECC error on system side (Valid for FM rev < 6)*/
151148 + e_IOC_EX_DMA_FM_WRITE_ECC, /**< Write Buffer ECC error on FM side (Valid for FM rev < 6)*/
151149 + e_IOC_EX_DMA_SINGLE_PORT_ECC, /**< Single Port ECC error on FM side (Valid for FM rev > 6)*/
151150 + e_IOC_EX_FPM_STALL_ON_TASKS, /**< Stall of tasks on FPM */
151151 + e_IOC_EX_FPM_SINGLE_ECC, /**< Single ECC on FPM. */
151152 + e_IOC_EX_FPM_DOUBLE_ECC, /**< Double ECC error on FPM ram access */
151153 + e_IOC_EX_QMI_SINGLE_ECC, /**< Single ECC on QMI. */
151154 + e_IOC_EX_QMI_DOUBLE_ECC, /**< Double bit ECC occurred on QMI */
151155 + e_IOC_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/**< Dequeue from unknown port id */
151156 + e_IOC_EX_BMI_LIST_RAM_ECC, /**< Linked List RAM ECC error */
151157 + e_IOC_EX_BMI_STORAGE_PROFILE_ECC, /**< Storage Profile ECC Error */
151158 + e_IOC_EX_BMI_STATISTICS_RAM_ECC, /**< Statistics Count RAM ECC Error Enable */
151159 + e_IOC_EX_BMI_DISPATCH_RAM_ECC, /**< Dispatch RAM ECC Error Enable */
151160 + e_IOC_EX_IRAM_ECC, /**< Double bit ECC occurred on IRAM*/
151161 + e_IOC_EX_MURAM_ECC /**< Double bit ECC occurred on MURAM*/
151162 +} ioc_fm_exceptions;
151163 +
151164 +/**************************************************************************//**
151165 + @Group lnx_ioctl_FM_runtime_control_grp FM Runtime Control Unit
151166 +
151167 + @Description FM Runtime control unit API functions, definitions and enums.
151168 + The FM driver provides a set of control routines for each module.
151169 + These routines may only be called after the module was fully
151170 + initialized (both configuration and initialization routines were
151171 + called). They are typically used to get information from hardware
151172 + (status, counters/statistics, revision etc.), to modify a current
151173 + state or to force/enable a required action. Run-time control may
151174 + be called whenever necessary and as many times as needed.
151175 + @{
151176 +*//***************************************************************************/
151177 +
151178 +/**************************************************************************//**
151179 + @Collection General FM defines.
151180 + *//***************************************************************************/
151181 +#define IOC_FM_MAX_NUM_OF_VALID_PORTS (FM_MAX_NUM_OF_OH_PORTS + \
151182 + FM_MAX_NUM_OF_1G_RX_PORTS + \
151183 + FM_MAX_NUM_OF_10G_RX_PORTS + \
151184 + FM_MAX_NUM_OF_1G_TX_PORTS + \
151185 + FM_MAX_NUM_OF_10G_TX_PORTS)
151186 +/* @} */
151187 +
151188 +/**************************************************************************//**
151189 + @Description Structure for Port bandwidth requirement. Port is identified
151190 + by type and relative id.
151191 + (must be identical to t_FmPortBandwidth defined in fm_ext.h)
151192 +*//***************************************************************************/
151193 +typedef struct ioc_fm_port_bandwidth_t {
151194 + ioc_fm_port_type type; /**< FM port type */
151195 + uint8_t relative_port_id; /**< Type relative port id */
151196 + uint8_t bandwidth; /**< bandwidth - (in term of percents) */
151197 +} ioc_fm_port_bandwidth_t;
151198 +
151199 +/**************************************************************************//**
151200 + @Description A Structure containing an array of Port bandwidth requirements.
151201 + The user should state the ports requiring bandwidth in terms of
151202 + percentage - i.e. all port's bandwidths in the array must add
151203 + up to 100.
151204 + (must be identical to t_FmPortsBandwidthParams defined in fm_ext.h)
151205 +*//***************************************************************************/
151206 +typedef struct ioc_fm_port_bandwidth_params {
151207 + uint8_t num_of_ports;
151208 + /**< num of ports listed in the array below */
151209 + ioc_fm_port_bandwidth_t ports_bandwidths[IOC_FM_MAX_NUM_OF_VALID_PORTS];
151210 + /**< for each port, it's bandwidth (all port's
151211 + bandwidths must add up to 100.*/
151212 +} ioc_fm_port_bandwidth_params;
151213 +
151214 +/**************************************************************************//**
151215 + @Description enum for defining FM counters
151216 +*//***************************************************************************/
151217 +typedef enum ioc_fm_counters {
151218 + e_IOC_FM_COUNTERS_ENQ_TOTAL_FRAME, /**< QMI total enqueued frames counter */
151219 + e_IOC_FM_COUNTERS_DEQ_TOTAL_FRAME, /**< QMI total dequeued frames counter */
151220 + e_IOC_FM_COUNTERS_DEQ_0, /**< QMI 0 frames from QMan counter */
151221 + e_IOC_FM_COUNTERS_DEQ_1, /**< QMI 1 frames from QMan counter */
151222 + e_IOC_FM_COUNTERS_DEQ_2, /**< QMI 2 frames from QMan counter */
151223 + e_IOC_FM_COUNTERS_DEQ_3, /**< QMI 3 frames from QMan counter */
151224 + e_IOC_FM_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI dequeue from default queue counter */
151225 + e_IOC_FM_COUNTERS_DEQ_FROM_CONTEXT, /**< QMI dequeue from FQ context counter */
151226 + e_IOC_FM_COUNTERS_DEQ_FROM_FD, /**< QMI dequeue from FD command field counter */
151227 + e_IOC_FM_COUNTERS_DEQ_CONFIRM, /**< QMI dequeue confirm counter */
151228 +} ioc_fm_counters;
151229 +
151230 +typedef struct ioc_fm_obj_t {
151231 + void *obj;
151232 +} ioc_fm_obj_t;
151233 +
151234 +/**************************************************************************//**
151235 + @Description A structure for returning revision information
151236 + (must match struct t_FmRevisionInfo declared in fm_ext.h)
151237 +*//***************************************************************************/
151238 +typedef struct ioc_fm_revision_info_t {
151239 + uint8_t major; /**< Major revision */
151240 + uint8_t minor; /**< Minor revision */
151241 +} ioc_fm_revision_info_t;
151242 +
151243 +/**************************************************************************//**
151244 + @Description A structure for FM counters
151245 +*//***************************************************************************/
151246 +typedef struct ioc_fm_counters_params_t {
151247 + ioc_fm_counters cnt; /**< The requested counter */
151248 + uint32_t val; /**< The requested value to get/set from/into the counter */
151249 +} ioc_fm_counters_params_t;
151250 +
151251 +typedef union ioc_fm_api_version_t {
151252 + struct {
151253 + uint8_t major;
151254 + uint8_t minor;
151255 + uint8_t respin;
151256 + uint8_t reserved;
151257 + } version;
151258 + uint32_t ver;
151259 +} ioc_fm_api_version_t;
151260 +
151261 +#if (DPAA_VERSION >= 11)
151262 +/**************************************************************************//**
151263 + @Description A structure of information about each of the external
151264 + buffer pools used by a port or storage-profile.
151265 + (must be identical to t_FmExtPoolParams defined in fm_ext.h)
151266 +*//***************************************************************************/
151267 +typedef struct ioc_fm_ext_pool_params {
151268 + uint8_t id; /**< External buffer pool id */
151269 + uint16_t size; /**< External buffer pool buffer size */
151270 +} ioc_fm_ext_pool_params;
151271 +
151272 +/**************************************************************************//**
151273 + @Description A structure for informing the driver about the external
151274 + buffer pools allocated in the BM and used by a port or a
151275 + storage-profile.
151276 + (must be identical to t_FmExtPools defined in fm_ext.h)
151277 +*//***************************************************************************/
151278 +typedef struct ioc_fm_ext_pools {
151279 + uint8_t num_of_pools_used; /**< Number of pools use by this port */
151280 + ioc_fm_ext_pool_params ext_buf_pool[FM_PORT_MAX_NUM_OF_EXT_POOLS];
151281 + /**< Parameters for each port */
151282 +} ioc_fm_ext_pools;
151283 +
151284 +typedef struct ioc_fm_vsp_params_t {
151285 + void *p_fm; /**< A handle to the FM object this VSP related to */
151286 + ioc_fm_ext_pools ext_buf_pools; /**< Which external buffer pools are used
151287 + (up to FM_PORT_MAX_NUM_OF_EXT_POOLS), and their sizes.
151288 + parameter associated with Rx / OP port */
151289 + uint16_t liodn_offset; /**< VSP's LIODN offset */
151290 + struct {
151291 + ioc_fm_port_type port_type; /**< Port type */
151292 + uint8_t port_id; /**< Port Id - relative to type */
151293 + } port_params;
151294 + uint8_t relative_profile_id; /**< VSP Id - relative to VSP's range
151295 + defined in relevant FM object */
151296 + void *id; /**< return value */
151297 +} ioc_fm_vsp_params_t;
151298 +#endif /* (DPAA_VERSION >= 11) */
151299 +
151300 +/**************************************************************************//**
151301 + @Description A structure for defining BM pool depletion criteria
151302 +*//***************************************************************************/
151303 +typedef struct ioc_fm_buf_pool_depletion_t {
151304 + bool pools_grp_mode_enable; /**< select mode in which pause frames will be sent after
151305 + a number of pools (all together!) are depleted */
151306 + uint8_t num_of_pools; /**< the number of depleted pools that will invoke
151307 + pause frames transmission. */
151308 + bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
151309 + /**< For each pool, TRUE if it should be considered for
151310 + depletion (Note - this pool must be used by this port!). */
151311 + bool single_pool_mode_enable; /**< select mode in which pause frames will be sent after
151312 + a single-pool is depleted; */
151313 + bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
151314 + /**< For each pool, TRUE if it should be considered for
151315 + depletion (Note - this pool must be used by this port!) */
151316 +#if (DPAA_VERSION >= 11)
151317 + bool pfc_priorities_en[FM_MAX_NUM_OF_PFC_PRIORITIES];
151318 + /**< This field is used by the MAC as the Priority Enable Vector in the PFC frame
151319 + which is transmitted */
151320 +#endif /* (DPAA_VERSION >= 11) */
151321 +} ioc_fm_buf_pool_depletion_t;
151322 +
151323 +#if (DPAA_VERSION >= 11)
151324 +typedef struct ioc_fm_buf_pool_depletion_params_t {
151325 + void *p_fm_vsp;
151326 + ioc_fm_buf_pool_depletion_t fm_buf_pool_depletion;
151327 +} ioc_fm_buf_pool_depletion_params_t;
151328 +#endif /* (DPAA_VERSION >= 11) */
151329 +
151330 +typedef struct ioc_fm_buffer_prefix_content_t {
151331 + uint16_t priv_data_size; /**< Number of bytes to be left at the beginning
151332 + of the external buffer; Note that the private-area will
151333 + start from the base of the buffer address. */
151334 + bool pass_prs_result; /**< TRUE to pass the parse result to/from the FM;
151335 + User may use FM_PORT_GetBufferPrsResult() in order to
151336 + get the parser-result from a buffer. */
151337 + bool pass_time_stamp; /**< TRUE to pass the timeStamp to/from the FM
151338 + User may use FM_PORT_GetBufferTimeStamp() in order to
151339 + get the parser-result from a buffer. */
151340 + bool pass_hash_result; /**< TRUE to pass the KG hash result to/from the FM
151341 + User may use FM_PORT_GetBufferHashResult() in order to
151342 + get the parser-result from a buffer. */
151343 + bool pass_all_other_pcd_info; /**< Add all other Internal-Context information:
151344 + AD, hash-result, key, etc. */
151345 + uint16_t data_align; /**< 0 to use driver's default alignment [64],
151346 + other value for selecting a data alignment (must be a power of 2);
151347 + if write optimization is used, must be >= 16. */
151348 + uint8_t manip_extra_space; /**< Maximum extra size needed (insertion-size minus removal-size);
151349 + Note that this field impacts the size of the buffer-prefix
151350 + (i.e. it pushes the data offset);
151351 + This field is irrelevant if DPAA_VERSION==10 */
151352 +} ioc_fm_buffer_prefix_content_t;
151353 +
151354 +typedef struct ioc_fm_buffer_prefix_content_params_t {
151355 + void *p_fm_vsp;
151356 + ioc_fm_buffer_prefix_content_t fm_buffer_prefix_content;
151357 +} ioc_fm_buffer_prefix_content_params_t;
151358 +
151359 +#if (DPAA_VERSION >= 11)
151360 +typedef struct ioc_fm_vsp_config_no_sg_params_t {
151361 + void *p_fm_vsp;
151362 + bool no_sg;
151363 +} ioc_fm_vsp_config_no_sg_params_t;
151364 +
151365 +typedef struct ioc_fm_vsp_prs_result_params_t {
151366 + void *p_fm_vsp;
151367 + void *p_data;
151368 +} ioc_fm_vsp_prs_result_params_t;
151369 +#endif
151370 +
151371 +typedef struct fm_ctrl_mon_t {
151372 + uint8_t percent_cnt[2];
151373 +} fm_ctrl_mon_t;
151374 +
151375 +typedef struct ioc_fm_ctrl_mon_counters_params_t {
151376 + uint8_t fm_ctrl_index;
151377 + fm_ctrl_mon_t *p_mon;
151378 +} ioc_fm_ctrl_mon_counters_params_t;
151379 +
151380 +/**************************************************************************//**
151381 + @Function FM_IOC_SET_PORTS_BANDWIDTH
151382 +
151383 + @Description Sets relative weights between ports when accessing common resources.
151384 +
151385 + @Param[in] ioc_fm_port_bandwidth_params Port bandwidth percentages,
151386 + their sum must equal 100.
151387 +
151388 + @Return E_OK on success; Error code otherwise.
151389 +
151390 + @Cautions Allowed only following FM_Init().
151391 +*//***************************************************************************/
151392 +#define FM_IOC_SET_PORTS_BANDWIDTH _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(2), ioc_fm_port_bandwidth_params)
151393 +
151394 +/**************************************************************************//**
151395 + @Function FM_IOC_GET_REVISION
151396 +
151397 + @Description Returns the FM revision
151398 +
151399 + @Param[out] ioc_fm_revision_info_t A structure of revision information parameters.
151400 +
151401 + @Return None.
151402 +
151403 + @Cautions Allowed only following FM_Init().
151404 +*//***************************************************************************/
151405 +#define FM_IOC_GET_REVISION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(3), ioc_fm_revision_info_t)
151406 +
151407 +/**************************************************************************//**
151408 + @Function FM_IOC_GET_COUNTER
151409 +
151410 + @Description Reads one of the FM counters.
151411 +
151412 + @Param[in,out] ioc_fm_counters_params_t The requested counter parameters.
151413 +
151414 + @Return Counter's current value.
151415 +
151416 + @Cautions Allowed only following FM_Init().
151417 + Note that it is user's responsibilty to call this routine only
151418 + for enabled counters, and there will be no indication if a
151419 + disabled counter is accessed.
151420 +*//***************************************************************************/
151421 +#define FM_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(4), ioc_fm_counters_params_t)
151422 +
151423 +/**************************************************************************//**
151424 + @Function FM_IOC_SET_COUNTER
151425 +
151426 + @Description Sets a value to an enabled counter. Use "0" to reset the counter.
151427 +
151428 + @Param[in] ioc_fm_counters_params_t The requested counter parameters.
151429 +
151430 + @Return E_OK on success; Error code otherwise.
151431 +
151432 + @Cautions Allowed only following FM_Init().
151433 +*//***************************************************************************/
151434 +#define FM_IOC_SET_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(5), ioc_fm_counters_params_t)
151435 +
151436 +/**************************************************************************//**
151437 + @Function FM_IOC_FORCE_INTR
151438 +
151439 + @Description Causes an interrupt event on the requested source.
151440 +
151441 + @Param[in] ioc_fm_exceptions An exception to be forced.
151442 +
151443 + @Return E_OK on success; Error code if the exception is not enabled,
151444 + or is not able to create interrupt.
151445 +
151446 + @Cautions Allowed only following FM_Init().
151447 +*//***************************************************************************/
151448 +#define FM_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(6), ioc_fm_exceptions)
151449 +
151450 +/**************************************************************************//**
151451 + @Function FM_IOC_GET_API_VERSION
151452 +
151453 + @Description Reads the FMD IOCTL API version.
151454 +
151455 + @Param[in,out] ioc_fm_api_version_t The requested counter parameters.
151456 +
151457 + @Return Version's value.
151458 +*//***************************************************************************/
151459 +#define FM_IOC_GET_API_VERSION _IOR(FM_IOC_TYPE_BASE, FM_IOC_NUM(7), ioc_fm_api_version_t)
151460 +
151461 +#if (DPAA_VERSION >= 11)
151462 +/**************************************************************************//**
151463 + @Function FM_VSP_Config
151464 +
151465 + @Description Creates descriptor for the FM VSP module.
151466 +
151467 + The routine returns a handle (descriptor) to the FM VSP object.
151468 + This descriptor must be passed as first parameter to all other
151469 + FM VSP function calls.
151470 +
151471 + No actual initialization or configuration of FM hardware is
151472 + done by this routine.
151473 +
151474 +@Param[in] p_FmVspParams Pointer to data structure of parameters
151475 +
151476 + @Retval Handle to FM VSP object, or NULL for Failure.
151477 +*//***************************************************************************/
151478 +#if defined(CONFIG_COMPAT)
151479 +#define FM_IOC_VSP_CONFIG_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_compat_fm_vsp_params_t)
151480 +#endif
151481 +#define FM_IOC_VSP_CONFIG _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(8), ioc_fm_vsp_params_t)
151482 +
151483 +/**************************************************************************//**
151484 + @Function FM_VSP_Init
151485 +
151486 + @Description Initializes the FM VSP module
151487 +
151488 + @Param[in] h_FmVsp - FM VSP module descriptor
151489 +
151490 + @Return E_OK on success; Error code otherwise.
151491 +*//***************************************************************************/
151492 +#if defined(CONFIG_COMPAT)
151493 +#define FM_IOC_VSP_INIT_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_compat_fm_obj_t)
151494 +#endif
151495 +#define FM_IOC_VSP_INIT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(9), ioc_fm_obj_t)
151496 +
151497 +/**************************************************************************//**
151498 + @Function FM_VSP_Free
151499 +
151500 + @Description Frees all resources that were assigned to FM VSP module.
151501 +
151502 + Calling this routine invalidates the descriptor.
151503 +
151504 + @Param[in] h_FmVsp - FM VSP module descriptor
151505 +
151506 + @Return E_OK on success; Error code otherwise.
151507 +*//***************************************************************************/
151508 +#if defined(CONFIG_COMPAT)
151509 +#define FM_IOC_VSP_FREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_compat_fm_obj_t)
151510 +#endif
151511 +#define FM_IOC_VSP_FREE _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(10), ioc_fm_obj_t)
151512 +
151513 +/**************************************************************************//**
151514 + @Function FM_VSP_ConfigPoolDepletion
151515 +
151516 + @Description Calling this routine enables pause frame generation depending on the
151517 + depletion status of BM pools. It also defines the conditions to activate
151518 + this functionality. By default, this functionality is disabled.
151519 +
151520 + @Param[in] ioc_fm_buf_pool_depletion_params_t A structure holding the required parameters.
151521 +
151522 + @Return E_OK on success; Error code otherwise.
151523 +
151524 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
151525 +*//***************************************************************************/
151526 +#if defined(CONFIG_COMPAT)
151527 +#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)
151528 +#endif
151529 +#define FM_IOC_VSP_CONFIG_POOL_DEPLETION _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(11), ioc_fm_buf_pool_depletion_params_t)
151530 +
151531 +/**************************************************************************//**
151532 + @Function FM_VSP_ConfigBufferPrefixContent
151533 +
151534 + @Description Defines the structure, size and content of the application buffer.
151535 +
151536 + The prefix will
151537 + In VSPs defined for Tx ports, if 'passPrsResult', the application
151538 + should set a value to their offsets in the prefix of
151539 + the FM will save the first 'privDataSize', than,
151540 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
151541 + and timeStamp, and the packet itself (in this order), to the
151542 + application buffer, and to offset.
151543 +
151544 + Calling this routine changes the buffer margins definitions
151545 + in the internal driver data base from its default
151546 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
151547 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
151548 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
151549 +
151550 + @Param[in] ioc_fm_buffer_prefix_content_params_t A structure holding the required parameters.
151551 +
151552 + @Return E_OK on success; Error code otherwise.
151553 +
151554 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
151555 +*//***************************************************************************/
151556 +#if defined(CONFIG_COMPAT)
151557 +#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)
151558 +#endif
151559 +#define FM_IOC_VSP_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(12), ioc_fm_buffer_prefix_content_params_t)
151560 +
151561 +/**************************************************************************//**
151562 + @Function FM_VSP_ConfigNoScatherGather
151563 +
151564 + @Description Calling this routine changes the possibility to receive S/G frame
151565 + in the internal driver data base
151566 + from its default configuration: optimize = [DEFAULT_FM_SP_noScatherGather]
151567 +
151568 + @Param[in] ioc_fm_vsp_config_no_sg_params_t A structure holding the required parameters.
151569 +
151570 + @Return E_OK on success; Error code otherwise.
151571 +
151572 + @Cautions Allowed only following FM_VSP_Config() and before FM_VSP_Init().
151573 +*//***************************************************************************/
151574 +#if defined(CONFIG_COMPAT)
151575 +#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)
151576 +#endif
151577 +#define FM_IOC_VSP_CONFIG_NO_SG _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(13), ioc_fm_vsp_config_no_sg_params_t)
151578 +
151579 +/**************************************************************************//**
151580 + @Function FM_VSP_GetBufferPrsResult
151581 +
151582 + @Description Returns the pointer to the parse result in the data buffer.
151583 + In Rx ports this is relevant after reception, if parse
151584 + result is configured to be part of the data passed to the
151585 + application. For non Rx ports it may be used to get the pointer
151586 + of the area in the buffer where parse result should be
151587 + initialized - if so configured.
151588 + See FM_VSP_ConfigBufferPrefixContent for data buffer prefix
151589 + configuration.
151590 +
151591 + @Param[in] ioc_fm_vsp_prs_result_params_t A structure holding the required parameters.
151592 +
151593 + @Return Parse result pointer on success, NULL if parse result was not
151594 + configured for this port.
151595 +
151596 + @Cautions Allowed only following FM_VSP_Init().
151597 +*//***************************************************************************/
151598 +#if defined(CONFIG_COMPAT)
151599 +#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)
151600 +#endif
151601 +#define FM_IOC_VSP_GET_BUFFER_PRS_RESULT _IOWR(FM_IOC_TYPE_BASE, FM_IOC_NUM(14), ioc_fm_vsp_prs_result_params_t)
151602 +#endif /* (DPAA_VERSION >= 11) */
151603 +
151604 +/**************************************************************************//**
151605 + @Function FM_CtrlMonStart
151606 +
151607 + @Description Start monitoring utilization of all available FM controllers.
151608 +
151609 + In order to obtain FM controllers utilization the following sequence
151610 + should be used:
151611 + -# FM_CtrlMonStart()
151612 + -# FM_CtrlMonStop()
151613 + -# FM_CtrlMonGetCounters() - issued for each FM controller
151614 +
151615 + @Return E_OK on success; Error code otherwise.
151616 +
151617 + @Cautions Allowed only following FM_Init().
151618 +*//***************************************************************************/
151619 +#define FM_IOC_CTRL_MON_START _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(15))
151620 +
151621 +
151622 +/**************************************************************************//**
151623 + @Function FM_CtrlMonStop
151624 +
151625 + @Description Stop monitoring utilization of all available FM controllers.
151626 +
151627 + In order to obtain FM controllers utilization the following sequence
151628 + should be used:
151629 + -# FM_CtrlMonStart()
151630 + -# FM_CtrlMonStop()
151631 + -# FM_CtrlMonGetCounters() - issued for each FM controller
151632 +
151633 + @Return E_OK on success; Error code otherwise.
151634 +
151635 + @Cautions Allowed only following FM_Init().
151636 +*//***************************************************************************/
151637 +#define FM_IOC_CTRL_MON_STOP _IO(FM_IOC_TYPE_BASE, FM_IOC_NUM(16))
151638 +
151639 +/**************************************************************************//**
151640 + @Function FM_CtrlMonGetCounters
151641 +
151642 + @Description Obtain FM controller utilization parameters.
151643 +
151644 + In order to obtain FM controllers utilization the following sequence
151645 + should be used:
151646 + -# FM_CtrlMonStart()
151647 + -# FM_CtrlMonStop()
151648 + -# FM_CtrlMonGetCounters() - issued for each FM controller
151649 +
151650 + @Param[in] ioc_fm_ctrl_mon_counters_params_t A structure holding the required parameters.
151651 +
151652 + @Return E_OK on success; Error code otherwise.
151653 +
151654 + @Cautions Allowed only following FM_Init().
151655 +*//***************************************************************************/
151656 +#if defined(CONFIG_COMPAT)
151657 +#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)
151658 +#endif
151659 +#define FM_IOC_CTRL_MON_GET_COUNTERS _IOW(FM_IOC_TYPE_BASE, FM_IOC_NUM(17), ioc_fm_ctrl_mon_counters_params_t)
151660 +
151661 +/** @} */ /* end of lnx_ioctl_FM_runtime_control_grp group */
151662 +/** @} */ /* end of lnx_ioctl_FM_lib_grp group */
151663 +/** @} */ /* end of lnx_ioctl_FM_grp */
151664 +
151665 +#define FMD_API_VERSION_MAJOR 21
151666 +#define FMD_API_VERSION_MINOR 1
151667 +#define FMD_API_VERSION_RESPIN 0
151668 +
151669 +#endif /* __FM_IOCTLS_H */
151670 --- /dev/null
151671 +++ b/include/uapi/linux/fmd/Peripherals/fm_pcd_ioctls.h
151672 @@ -0,0 +1,3084 @@
151673 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
151674 + * All rights reserved.
151675 + *
151676 + * Redistribution and use in source and binary forms, with or without
151677 + * modification, are permitted provided that the following conditions are met:
151678 + * * Redistributions of source code must retain the above copyright
151679 + * notice, this list of conditions and the following disclaimer.
151680 + * * Redistributions in binary form must reproduce the above copyright
151681 + * notice, this list of conditions and the following disclaimer in the
151682 + * documentation and/or other materials provided with the distribution.
151683 + * * Neither the name of Freescale Semiconductor nor the
151684 + * names of its contributors may be used to endorse or promote products
151685 + * derived from this software without specific prior written permission.
151686 + *
151687 + *
151688 + * ALTERNATIVELY, this software may be distributed under the terms of the
151689 + * GNU General Public License ("GPL") as published by the Free Software
151690 + * Foundation, either version 2 of that License or (at your option) any
151691 + * later version.
151692 + *
151693 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
151694 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
151695 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
151696 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
151697 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
151698 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
151699 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
151700 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
151701 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
151702 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
151703 + */
151704 +
151705 +
151706 +/******************************************************************************
151707 + @File fm_pcd_ioctls.h
151708 +
151709 + @Description FM PCD ...
151710 +*//***************************************************************************/
151711 +#ifndef __FM_PCD_IOCTLS_H
151712 +#define __FM_PCD_IOCTLS_H
151713 +
151714 +#include "net_ioctls.h"
151715 +#include "fm_ioctls.h"
151716 +
151717 +
151718 +/**************************************************************************//**
151719 +
151720 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
151721 +
151722 + @Description Frame Manager Linux ioctls definitions and enums
151723 +
151724 + @{
151725 +*//***************************************************************************/
151726 +
151727 +/**************************************************************************//**
151728 + @Group lnx_ioctl_FM_PCD_grp FM PCD
151729 +
151730 + @Description Frame Manager PCD API functions, definitions and enums
151731 +
151732 + The FM PCD module is responsible for the initialization of all
151733 + global classifying FM modules. This includes the parser general and
151734 + common registers, the key generator global and common registers,
151735 + and the policer global and common registers.
151736 + In addition, the FM PCD SW module will initialize all required
151737 + key generator schemes, coarse classification flows, and policer
151738 + profiles. When an FM module is configured to work with one of these
151739 + entities, it will register to it using the FM PORT API. The PCD
151740 + module will manage the PCD resources - i.e. resource management of
151741 + KeyGen schemes, etc.
151742 +
151743 + @{
151744 +*//***************************************************************************/
151745 +
151746 +/**************************************************************************//**
151747 + @Collection General PCD defines
151748 +*//***************************************************************************/
151749 +#define IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS 2 /**< Number of units/headers saved for user */
151750 +
151751 +#define IOC_FM_PCD_PRS_NUM_OF_HDRS 16 /**< Number of headers supported by HW parser */
151752 +#define IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS (32 - IOC_FM_PCD_MAX_NUM_OF_PRIVATE_HDRS)
151753 + /**< Number of distinction units is limited by
151754 + register size (32 bits) minus reserved bits
151755 + for private headers. */
151756 +#define IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS 4 /**< Maximum number of interchangeable headers
151757 + in a distinction unit */
151758 +#define IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS 8 /**< Total number of generic KeyGen registers */
151759 +#define IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY 35 /**< Max number allowed on any configuration;
151760 + For HW implementation reasons, in most
151761 + cases less than this will be allowed; The
151762 + driver will return an initialization error
151763 + if resource is unavailable. */
151764 +#define IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS 4 /**< Total number of masks allowed on KeyGen extractions. */
151765 +#define IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS 16 /**< Number of default value logical groups */
151766 +
151767 +#define IOC_FM_PCD_PRS_NUM_OF_LABELS 32 /**< Maximum number of SW parser labels */
151768 +#define IOC_FM_PCD_SW_PRS_SIZE 0x00000800 /**< Total size of SW parser area */
151769 +
151770 +#define IOC_FM_PCD_MAX_MANIP_INSRT_TEMPLATE_SIZE 128 /**< Maximum size of insertion template for
151771 + insert manipulation */
151772 +
151773 +#if DPAA_VERSION >= 11
151774 +#define IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES 64 /**< Maximum possible entries for frame replicator group */
151775 +#endif /* DPAA_VERSION >= 11 */
151776 +/* @} */
151777 +
151778 +#ifdef FM_CAPWAP_SUPPORT
151779 +#error "FM_CAPWAP_SUPPORT not implemented!"
151780 +#endif
151781 +
151782 +
151783 +/**************************************************************************//**
151784 + @Group lnx_ioctl_FM_PCD_init_grp FM PCD Initialization Unit
151785 +
151786 + @Description Frame Manager PCD Initialization Unit API
151787 +
151788 + @{
151789 +*//***************************************************************************/
151790 +
151791 +/**************************************************************************//**
151792 + @Description PCD counters
151793 + (must match enum e_FmPcdCounters defined in fm_pcd_ext.h)
151794 +*//***************************************************************************/
151795 +typedef enum ioc_fm_pcd_counters {
151796 + e_IOC_FM_PCD_KG_COUNTERS_TOTAL, /**< KeyGen counter */
151797 + e_IOC_FM_PCD_PLCR_COUNTERS_RED, /**< Policer counter - counts the total number of RED packets that exit the Policer. */
151798 + e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW, /**< Policer counter - counts the total number of YELLOW packets that exit the Policer. */
151799 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_RED, /**< Policer counter - counts the number of packets that changed color to RED by the Policer;
151800 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_RED packet count, indicating active color changes. */
151801 + e_IOC_FM_PCD_PLCR_COUNTERS_RECOLORED_TO_YELLOW, /**< Policer counter - counts the number of packets that changed color to YELLOW by the Policer;
151802 + This is a subset of e_IOC_FM_PCD_PLCR_COUNTERS_YELLOW packet count, indicating active color changes. */
151803 + e_IOC_FM_PCD_PLCR_COUNTERS_TOTAL, /**< Policer counter - counts the total number of packets passed in the Policer. */
151804 + e_IOC_FM_PCD_PLCR_COUNTERS_LENGTH_MISMATCH, /**< Policer counter - counts the number of packets with length mismatch. */
151805 + e_IOC_FM_PCD_PRS_COUNTERS_PARSE_DISPATCH, /**< Parser counter - counts the number of times the parser block is dispatched. */
151806 + e_IOC_FM_PCD_PRS_COUNTERS_L2_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L2 parse result is returned (including errors). */
151807 + e_IOC_FM_PCD_PRS_COUNTERS_L3_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L3 parse result is returned (including errors). */
151808 + e_IOC_FM_PCD_PRS_COUNTERS_L4_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times L4 parse result is returned (including errors). */
151809 + e_IOC_FM_PCD_PRS_COUNTERS_SHIM_PARSE_RESULT_RETURNED, /**< Parser counter - counts the number of times SHIM parse result is returned (including errors). */
151810 + 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. */
151811 + 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. */
151812 + 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. */
151813 + 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. */
151814 + e_IOC_FM_PCD_PRS_COUNTERS_SOFT_PRS_CYCLES, /**< Parser counter - counts the number of cycles spent executing soft parser instruction (including stall cycles). */
151815 + 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. */
151816 + 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). */
151817 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory read. */
151818 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_READ_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory read. */
151819 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_CYCLES, /**< MURAM counter - counts the number of cycles while performing FMan Memory write. */
151820 + e_IOC_FM_PCD_PRS_COUNTERS_MURAM_WRITE_STALL_CYCLES, /**< MURAM counter - counts the number of cycles stalled while performing FMan Memory write. */
151821 + e_IOC_FM_PCD_PRS_COUNTERS_FPM_COMMAND_STALL_CYCLES /**< FPM counter - counts the number of cycles stalled while performing a FPM Command. */
151822 +} ioc_fm_pcd_counters;
151823 +
151824 +/**************************************************************************//**
151825 + @Description PCD interrupts
151826 + (must match enum e_FmPcdExceptions defined in fm_pcd_ext.h)
151827 +*//***************************************************************************/
151828 +typedef enum ioc_fm_pcd_exceptions {
151829 + e_IOC_FM_PCD_KG_EXCEPTION_DOUBLE_ECC, /**< KeyGen double-bit ECC error is detected on internal memory read access. */
151830 + e_IOC_FM_PCD_KG_EXCEPTION_KEYSIZE_OVERFLOW, /**< KeyGen scheme configuration error indicating a key size larger than 56 bytes. */
151831 + e_IOC_FM_PCD_PLCR_EXCEPTION_DOUBLE_ECC, /**< Policer double-bit ECC error has been detected on PRAM read access. */
151832 + e_IOC_FM_PCD_PLCR_EXCEPTION_INIT_ENTRY_ERROR, /**< Policer access to a non-initialized profile has been detected. */
151833 + e_IOC_FM_PCD_PLCR_EXCEPTION_PRAM_SELF_INIT_COMPLETE, /**< Policer RAM self-initialization complete */
151834 + e_IOC_FM_PCD_PLCR_EXCEPTION_ATOMIC_ACTION_COMPLETE, /**< Policer atomic action complete */
151835 + e_IOC_FM_PCD_PRS_EXCEPTION_DOUBLE_ECC, /**< Parser double-bit ECC error */
151836 + e_IOC_FM_PCD_PRS_EXCEPTION_SINGLE_ECC /**< Parser single-bit ECC error */
151837 +} ioc_fm_pcd_exceptions;
151838 +
151839 +/** @} */ /* end of lnx_ioctl_FM_PCD_init_grp group */
151840 +
151841 +
151842 +/**************************************************************************//**
151843 + @Group lnx_ioctl_FM_PCD_Runtime_grp FM PCD Runtime Unit
151844 +
151845 + @Description Frame Manager PCD Runtime Unit
151846 +
151847 + The runtime control allows creation of PCD infrastructure modules
151848 + such as Network Environment Characteristics, Classification Plan
151849 + Groups and Coarse Classification Trees.
151850 + It also allows on-the-fly initialization, modification and removal
151851 + of PCD modules such as KeyGen schemes, coarse classification nodes
151852 + and Policer profiles.
151853 +
151854 + In order to explain the programming model of the PCD driver interface
151855 + a few terms should be explained, and will be used below.
151856 + - Distinction Header - One of the 16 protocols supported by the FM parser,
151857 + or one of the SHIM headers (1 or 2). May be a header with a special
151858 + option (see below).
151859 + - Interchangeable Headers Group - This is a group of Headers recognized
151860 + by either one of them. For example, if in a specific context the user
151861 + chooses to treat IPv4 and IPV6 in the same way, they may create an
151862 + interchangeable Headers Unit consisting of these 2 headers.
151863 + - A Distinction Unit - a Distinction Header or an Interchangeable Headers
151864 + Group.
151865 + - Header with special option - applies to Ethernet, MPLS, VLAN, IPv4 and
151866 + IPv6, includes multicast, broadcast and other protocol specific options.
151867 + In terms of hardware it relates to the options available in the classification
151868 + plan.
151869 + - Network Environment Characteristics - a set of Distinction Units that define
151870 + the total recognizable header selection for a certain environment. This is
151871 + NOT the list of all headers that will ever appear in a flow, but rather
151872 + everything that needs distinction in a flow, where distinction is made by KeyGen
151873 + schemes and coarse classification action descriptors.
151874 +
151875 + The PCD runtime modules initialization is done in stages. The first stage after
151876 + initializing the PCD module itself is to establish a Network Flows Environment
151877 + Definition. The application may choose to establish one or more such environments.
151878 + Later, when needed, the application will have to state, for some of its modules,
151879 + to which single environment it belongs.
151880 +
151881 + @{
151882 +*//***************************************************************************/
151883 +
151884 +
151885 +/**************************************************************************//**
151886 + @Description structure for FM counters
151887 +*//***************************************************************************/
151888 +typedef struct ioc_fm_pcd_counters_params_t {
151889 + ioc_fm_pcd_counters cnt; /**< The requested counter */
151890 + uint32_t val; /**< The requested value to get/set from/into the counter */
151891 +} ioc_fm_pcd_counters_params_t;
151892 +
151893 +/**************************************************************************//**
151894 + @Description structure for FM exception definitios
151895 +*//***************************************************************************/
151896 +typedef struct ioc_fm_pcd_exception_params_t {
151897 + ioc_fm_pcd_exceptions exception; /**< The requested exception */
151898 + bool enable; /**< TRUE to enable interrupt, FALSE to mask it. */
151899 +} ioc_fm_pcd_exception_params_t;
151900 +
151901 +/**************************************************************************//**
151902 + @Description A structure for SW parser labels
151903 + (must be identical to struct t_FmPcdPrsLabelParams defined in fm_pcd_ext.h)
151904 + *//***************************************************************************/
151905 +typedef struct ioc_fm_pcd_prs_label_params_t {
151906 + uint32_t instruction_offset; /**< SW parser label instruction offset (2 bytes
151907 + resolution), relative to Parser RAM. */
151908 + ioc_net_header_type hdr; /**< The existence of this header will invoke
151909 + the SW parser code. */
151910 + uint8_t index_per_hdr; /**< Normally 0, if more than one SW parser
151911 + attachments for the same header, use this
151912 + index to distinguish between them. */
151913 +} ioc_fm_pcd_prs_label_params_t;
151914 +
151915 +/**************************************************************************//**
151916 + @Description A structure for SW parser
151917 + (Must match struct t_FmPcdPrsSwParams defined in fm_pcd_ext.h)
151918 + *//***************************************************************************/
151919 +typedef struct ioc_fm_pcd_prs_sw_params_t {
151920 + bool override; /**< FALSE to invoke a check that nothing else
151921 + was loaded to this address, including
151922 + internal patches.
151923 + TRUE to override any existing code.*/
151924 + uint32_t size; /**< SW parser code size */
151925 + uint16_t base; /**< SW parser base (in instruction counts!
151926 + must be larger than 0x20)*/
151927 + uint8_t *p_code; /**< SW parser code */
151928 + uint32_t sw_prs_data_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
151929 + /**< SW parser data (parameters) */
151930 + uint8_t num_of_labels; /**< Number of labels for SW parser. */
151931 + ioc_fm_pcd_prs_label_params_t labels_table[IOC_FM_PCD_PRS_NUM_OF_LABELS];
151932 + /**< SW parser labels table,
151933 + containing num_of_labels entries */
151934 +} ioc_fm_pcd_prs_sw_params_t;
151935 +
151936 +/**************************************************************************//**
151937 + @Description A structure to set the a KeyGen default value
151938 + *//***************************************************************************/
151939 +typedef struct ioc_fm_pcd_kg_dflt_value_params_t {
151940 + uint8_t valueId; /**< 0,1 - one of 2 global default values */
151941 + uint32_t value; /**< The requested default value */
151942 +} ioc_fm_pcd_kg_dflt_value_params_t;
151943 +
151944 +
151945 +/**************************************************************************//**
151946 + @Function FM_PCD_Enable
151947 +
151948 + @Description This routine should be called after PCD is initialized for enabling all
151949 + PCD engines according to their existing configuration.
151950 +
151951 + @Return 0 on success; Error code otherwise.
151952 +
151953 + @Cautions Allowed only when PCD is disabled.
151954 +*//***************************************************************************/
151955 +#define FM_PCD_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(1))
151956 +
151957 +/**************************************************************************//**
151958 + @Function FM_PCD_Disable
151959 +
151960 + @Description This routine may be called when PCD is enabled in order to
151961 + disable all PCD engines. It may be called
151962 + only when none of the ports in the system are using the PCD.
151963 +
151964 + @Return 0 on success; Error code otherwise.
151965 +
151966 + @Cautions Allowed only when PCD is enabled.
151967 +*//***************************************************************************/
151968 +#define FM_PCD_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(2))
151969 +
151970 + /**************************************************************************//**
151971 + @Function FM_PCD_PrsLoadSw
151972 +
151973 + @Description This routine may be called only when all ports in the
151974 + system are actively using the classification plan scheme.
151975 + In such cases it is recommended in order to save resources.
151976 + The driver automatically saves 8 classification plans for
151977 + ports that do NOT use the classification plan mechanism, to
151978 + avoid this (in order to save those entries) this routine may
151979 + be called.
151980 +
151981 + @Param[in] ioc_fm_pcd_prs_sw_params_t A pointer to the image of the software parser code.
151982 +
151983 + @Return 0 on success; Error code otherwise.
151984 +
151985 + @Cautions Allowed only when PCD is disabled.
151986 +*//***************************************************************************/
151987 +#if defined(CONFIG_COMPAT)
151988 +#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)
151989 +#endif
151990 +#define FM_PCD_IOC_PRS_LOAD_SW _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(3), ioc_fm_pcd_prs_sw_params_t)
151991 +
151992 +/**************************************************************************//**
151993 + @Function FM_PCD_KgSetDfltValue
151994 +
151995 + @Description Calling this routine sets a global default value to be used
151996 + by the KeyGen when parser does not recognize a required
151997 + field/header.
151998 + By default default values are 0.
151999 +
152000 + @Param[in] ioc_fm_pcd_kg_dflt_value_params_t A pointer to a structure with the relevant parameters
152001 +
152002 + @Return 0 on success; Error code otherwise.
152003 +
152004 + @Cautions Allowed only when PCD is disabled.
152005 +*//***************************************************************************/
152006 +#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)
152007 +
152008 +/**************************************************************************//**
152009 + @Function FM_PCD_KgSetAdditionalDataAfterParsing
152010 +
152011 + @Description Calling this routine allows the keygen to access data past
152012 + the parser finishing point.
152013 +
152014 + @Param[in] uint8_t payload-offset; the number of bytes beyond the parser location.
152015 +
152016 + @Return 0 on success; Error code otherwise.
152017 +
152018 + @Cautions Allowed only when PCD is disabled.
152019 +*//***************************************************************************/
152020 +#define FM_PCD_IOC_KG_SET_ADDITIONAL_DATA_AFTER_PARSING _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(7), uint8_t)
152021 +
152022 +/**************************************************************************//**
152023 + @Function FM_PCD_SetException
152024 +
152025 + @Description Calling this routine enables/disables PCD interrupts.
152026 +
152027 + @Param[in] ioc_fm_pcd_exception_params_t Arguments struct with exception to be enabled/disabled.
152028 +
152029 + @Return 0 on success; Error code otherwise.
152030 +*//***************************************************************************/
152031 +#define FM_PCD_IOC_SET_EXCEPTION _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(8), ioc_fm_pcd_exception_params_t)
152032 +
152033 +/**************************************************************************//**
152034 + @Function FM_PCD_GetCounter
152035 +
152036 + @Description Reads one of the FM PCD counters.
152037 +
152038 + @Param[in,out] ioc_fm_pcd_counters_params_t The requested counter parameters.
152039 +
152040 + @Return 0 on success; Error code otherwise.
152041 +
152042 + @Cautions Note that it is user's responsibilty to call this routine only
152043 + for enabled counters, and there will be no indication if a
152044 + disabled counter is accessed.
152045 +*//***************************************************************************/
152046 +#define FM_PCD_IOC_GET_COUNTER _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(9), ioc_fm_pcd_counters_params_t)
152047 +
152048 +/**************************************************************************//**
152049 +
152050 + @Function FM_PCD_KgSchemeGetCounter
152051 +
152052 + @Description Reads scheme packet counter.
152053 +
152054 + @Param[in] h_Scheme scheme handle as returned by FM_PCD_KgSchemeSet().
152055 +
152056 + @Return Counter's current value.
152057 +
152058 + @Cautions Allowed only following FM_PCD_Init() & FM_PCD_KgSchemeSet().
152059 +*//***************************************************************************/
152060 +#if defined(CONFIG_COMPAT)
152061 +#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)
152062 +#endif
152063 +#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)
152064 +
152065 +#if 0
152066 +TODO: unused IOCTL
152067 +/**************************************************************************//**
152068 + @Function FM_PCD_ModifyCounter
152069 +
152070 + @Description Writes a value to an enabled counter. Use "0" to reset the counter.
152071 +
152072 + @Param[in] ioc_fm_pcd_counters_params_t - The requested counter parameters.
152073 +
152074 + @Return 0 on success; Error code otherwise.
152075 +*//***************************************************************************/
152076 +#define FM_PCD_IOC_MODIFY_COUNTER _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(10), ioc_fm_pcd_counters_params_t)
152077 +#define FM_PCD_IOC_SET_COUNTER FM_PCD_IOC_MODIFY_COUNTER
152078 +#endif
152079 +
152080 +/**************************************************************************//**
152081 + @Function FM_PCD_ForceIntr
152082 +
152083 + @Description Causes an interrupt event on the requested source.
152084 +
152085 + @Param[in] ioc_fm_pcd_exceptions - An exception to be forced.
152086 +
152087 + @Return 0 on success; error code if the exception is not enabled,
152088 + or is not able to create interrupt.
152089 +*//***************************************************************************/
152090 +#define FM_PCD_IOC_FORCE_INTR _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(11), ioc_fm_pcd_exceptions)
152091 +
152092 +/**************************************************************************//**
152093 + @Collection Definitions of coarse classification parameters as required by KeyGen
152094 + (when coarse classification is the next engine after this scheme).
152095 +*//***************************************************************************/
152096 +#define IOC_FM_PCD_MAX_NUM_OF_CC_TREES 8
152097 +#define IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS 16
152098 +#define IOC_FM_PCD_MAX_NUM_OF_CC_UNITS 4
152099 +#define IOC_FM_PCD_MAX_NUM_OF_KEYS 256
152100 +#define IOC_FM_PCD_MAX_NUM_OF_FLOWS (4*KILOBYTE)
152101 +#define IOC_FM_PCD_MAX_SIZE_OF_KEY 56
152102 +#define IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP 16
152103 +#define IOC_FM_PCD_LAST_KEY_INDEX 0xffff
152104 +#define IOC_FM_PCD_MANIP_DSCP_VALUES 64
152105 +/* @} */
152106 +
152107 +/**************************************************************************//**
152108 + @Collection A set of definitions to allow protocol
152109 + special option description.
152110 +*//***************************************************************************/
152111 +typedef uint32_t ioc_protocol_opt_t; /**< A general type to define a protocol option. */
152112 +
152113 +typedef ioc_protocol_opt_t ioc_eth_protocol_opt_t; /**< Ethernet protocol options. */
152114 +#define IOC_ETH_BROADCAST 0x80000000 /**< Ethernet Broadcast. */
152115 +#define IOC_ETH_MULTICAST 0x40000000 /**< Ethernet Multicast. */
152116 +
152117 +typedef ioc_protocol_opt_t ioc_vlan_protocol_opt_t; /**< Vlan protocol options. */
152118 +#define IOC_VLAN_STACKED 0x20000000 /**< Stacked VLAN. */
152119 +
152120 +typedef ioc_protocol_opt_t ioc_mpls_protocol_opt_t; /**< MPLS protocol options. */
152121 +#define IOC_MPLS_STACKED 0x10000000 /**< Stacked MPLS. */
152122 +
152123 +typedef ioc_protocol_opt_t ioc_ipv4_protocol_opt_t; /**< IPv4 protocol options. */
152124 +#define IOC_IPV4_BROADCAST_1 0x08000000 /**< IPv4 Broadcast. */
152125 +#define IOC_IPV4_MULTICAST_1 0x04000000 /**< IPv4 Multicast. */
152126 +#define IOC_IPV4_UNICAST_2 0x02000000 /**< Tunneled IPv4 - Unicast. */
152127 +#define IOC_IPV4_MULTICAST_BROADCAST_2 0x01000000 /**< Tunneled IPv4 - Broadcast/Multicast. */
152128 +
152129 +#define IOC_IPV4_FRAG_1 0x00000008 /**< IPV4 reassembly option.
152130 + IPV4 Reassembly manipulation requires network
152131 + environment with IPV4 header and IPV4_FRAG_1 option */
152132 +
152133 +typedef ioc_protocol_opt_t ioc_ipv6_protocol_opt_t; /**< IPv6 protocol options. */
152134 +#define IOC_IPV6_MULTICAST_1 0x00800000 /**< IPv6 Multicast. */
152135 +#define IOC_IPV6_UNICAST_2 0x00400000 /**< Tunneled IPv6 - Unicast. */
152136 +#define IOC_IPV6_MULTICAST_2 0x00200000 /**< Tunneled IPv6 - Multicast. */
152137 +
152138 +#define IOC_IPV6_FRAG_1 0x00000004 /**< IPV6 reassembly option.
152139 + IPV6 Reassembly manipulation requires network
152140 + environment with IPV6 header and IPV6_FRAG_1 option */
152141 +#if (DPAA_VERSION >= 11)
152142 +typedef ioc_protocol_opt_t ioc_capwap_protocol_opt_t; /**< CAPWAP protocol options. */
152143 +#define CAPWAP_FRAG_1 0x00000008 /**< CAPWAP reassembly option.
152144 + CAPWAP Reassembly manipulation requires network
152145 + environment with CAPWAP header and CAPWAP_FRAG_1 option;
152146 + in case where fragment found, the fragment-extension offset
152147 + may be found at 'shim2' (in parser-result). */
152148 +#endif /* (DPAA_VERSION >= 11) */
152149 +
152150 +/* @} */
152151 +
152152 +#define IOC_FM_PCD_MANIP_MAX_HDR_SIZE 256
152153 +#define IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS 64
152154 +/**************************************************************************//**
152155 + @Collection A set of definitions to support Header Manipulation selection.
152156 +*//***************************************************************************/
152157 +typedef uint32_t ioc_hdr_manip_flags_t; /**< A general type to define a HMan update command flags. */
152158 +
152159 +typedef ioc_hdr_manip_flags_t ioc_ipv4_hdr_manip_update_flags_t; /**< IPv4 protocol HMan update command flags. */
152160 +
152161 +#define IOC_HDR_MANIP_IPV4_TOS 0x80000000 /**< update TOS with the given value ('tos' field
152162 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
152163 +#define IOC_HDR_MANIP_IPV4_ID 0x40000000 /**< update IP ID with the given value ('id' field
152164 + of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
152165 +#define IOC_HDR_MANIP_IPV4_TTL 0x20000000 /**< Decrement TTL by 1 */
152166 +#define IOC_HDR_MANIP_IPV4_SRC 0x10000000 /**< update IP source address with the given value
152167 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
152168 +#define IOC_HDR_MANIP_IPV4_DST 0x08000000 /**< update IP destination address with the given value
152169 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv4_t) */
152170 +
152171 +typedef ioc_hdr_manip_flags_t ioc_ipv6_hdr_manip_update_flags_t; /**< IPv6 protocol HMan update command flags. */
152172 +
152173 +#define IOC_HDR_MANIP_IPV6_TC 0x80000000 /**< update Traffic Class address with the given value
152174 + ('traffic_class' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
152175 +#define IOC_HDR_MANIP_IPV6_HL 0x40000000 /**< Decrement Hop Limit by 1 */
152176 +#define IOC_HDR_MANIP_IPV6_SRC 0x20000000 /**< update IP source address with the given value
152177 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
152178 +#define IOC_HDR_MANIP_IPV6_DST 0x10000000 /**< update IP destination address with the given value
152179 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_ipv6_t) */
152180 +
152181 +typedef ioc_hdr_manip_flags_t ioc_tcp_udp_hdr_manip_update_flags_t;/**< TCP/UDP protocol HMan update command flags. */
152182 +
152183 +#define IOC_HDR_MANIP_TCP_UDP_SRC 0x80000000 /**< update TCP/UDP source address with the given value
152184 + ('src' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
152185 +#define IOC_HDR_MANIP_TCP_UDP_DST 0x40000000 /**< update TCP/UDP destination address with the given value
152186 + ('dst' field of ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t) */
152187 +#define IOC_HDR_MANIP_TCP_UDP_CHECKSUM 0x20000000 /**< update TCP/UDP checksum */
152188 +
152189 +/* @} */
152190 +
152191 +/**************************************************************************//**
152192 + @Description A type used for returning the order of the key extraction.
152193 + each value in this array represents the index of the extraction
152194 + command as defined by the user in the initialization extraction array.
152195 + The valid size of this array is the user define number of extractions
152196 + required (also marked by the second '0' in this array).
152197 +*//***************************************************************************/
152198 +typedef uint8_t ioc_fm_pcd_kg_key_order_t [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
152199 +
152200 +/**************************************************************************//**
152201 + @Description All PCD engines
152202 + (must match enum e_FmPcdEngine defined in fm_pcd_ext.h)
152203 +*//***************************************************************************/
152204 +typedef enum ioc_fm_pcd_engine {
152205 + e_IOC_FM_PCD_INVALID = 0, /**< Invalid PCD engine */
152206 + e_IOC_FM_PCD_DONE, /**< No PCD Engine indicated */
152207 + e_IOC_FM_PCD_KG, /**< KeyGen */
152208 + e_IOC_FM_PCD_CC, /**< Coarse Classifier */
152209 + e_IOC_FM_PCD_PLCR, /**< Policer */
152210 + e_IOC_FM_PCD_PRS, /**< Parser */
152211 +#if DPAA_VERSION >= 11
152212 + e_IOC_FM_PCD_FR, /**< Frame Replicator */
152213 +#endif /* DPAA_VERSION >= 11 */
152214 + e_IOC_FM_PCD_HASH /**< Hash Table */
152215 +} ioc_fm_pcd_engine;
152216 +
152217 +/**************************************************************************//**
152218 + @Description An enum for selecting extraction by header types
152219 + (Must match enum e_FmPcdExtractByHdrType defined in fm_pcd_ext.h)
152220 +*//***************************************************************************/
152221 +typedef enum ioc_fm_pcd_extract_by_hdr_type {
152222 + e_IOC_FM_PCD_EXTRACT_FROM_HDR, /**< Extract bytes from header */
152223 + e_IOC_FM_PCD_EXTRACT_FROM_FIELD, /**< Extract bytes from header field */
152224 + e_IOC_FM_PCD_EXTRACT_FULL_FIELD /**< Extract a full field */
152225 +} ioc_fm_pcd_extract_by_hdr_type;
152226 +
152227 +/**************************************************************************//**
152228 + @Description An enum for selecting extraction source (when it is not the header)
152229 + (Must match enum e_FmPcdExtractFrom defined in fm_pcd_ext.h)
152230 +*//***************************************************************************/
152231 +typedef enum ioc_fm_pcd_extract_from {
152232 + e_IOC_FM_PCD_EXTRACT_FROM_FRAME_START, /**< KG & CC: Extract from beginning of frame */
152233 + e_IOC_FM_PCD_EXTRACT_FROM_DFLT_VALUE, /**< KG only: Extract from a default value */
152234 + e_IOC_FM_PCD_EXTRACT_FROM_CURR_END_OF_PARSE, /**< KG only: Extract from the point where parsing had finished */
152235 + e_IOC_FM_PCD_EXTRACT_FROM_KEY, /**< CC only: Field where saved KEY */
152236 + e_IOC_FM_PCD_EXTRACT_FROM_HASH, /**< CC only: Field where saved HASH */
152237 + e_IOC_FM_PCD_EXTRACT_FROM_PARSE_RESULT, /**< KG & CC: Extract from the parser result */
152238 + e_IOC_FM_PCD_EXTRACT_FROM_ENQ_FQID, /**< KG & CC: Extract from enqueue FQID */
152239 + e_IOC_FM_PCD_EXTRACT_FROM_FLOW_ID /**< CC only: Field where saved Dequeue FQID */
152240 +} ioc_fm_pcd_extract_from;
152241 +
152242 +/**************************************************************************//**
152243 + @Description An enum for selecting extraction type
152244 +*//***************************************************************************/
152245 +typedef enum ioc_fm_pcd_extract_type {
152246 + e_IOC_FM_PCD_EXTRACT_BY_HDR, /**< Extract according to header */
152247 + e_IOC_FM_PCD_EXTRACT_NON_HDR, /**< Extract from data that is not the header */
152248 + e_IOC_FM_PCD_KG_EXTRACT_PORT_PRIVATE_INFO /**< Extract private info as specified by user */
152249 +} ioc_fm_pcd_extract_type;
152250 +
152251 +/**************************************************************************//**
152252 + @Description An enum for selecting a default
152253 +*//***************************************************************************/
152254 +typedef enum ioc_fm_pcd_kg_extract_dflt_select {
152255 + e_IOC_FM_PCD_KG_DFLT_GBL_0, /**< Default selection is KG register 0 */
152256 + e_IOC_FM_PCD_KG_DFLT_GBL_1, /**< Default selection is KG register 1 */
152257 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_0, /**< Default selection is a per scheme register 0 */
152258 + e_IOC_FM_PCD_KG_DFLT_PRIVATE_1, /**< Default selection is a per scheme register 1 */
152259 + e_IOC_FM_PCD_KG_DFLT_ILLEGAL /**< Illegal selection */
152260 +} ioc_fm_pcd_kg_extract_dflt_select;
152261 +
152262 +/**************************************************************************//**
152263 + @Description Enumeration type defining all default groups - each group shares
152264 + a default value, one of four user-initialized values.
152265 +*//***************************************************************************/
152266 +typedef enum ioc_fm_pcd_kg_known_fields_dflt_types {
152267 + e_IOC_FM_PCD_KG_MAC_ADDR, /**< MAC Address */
152268 + e_IOC_FM_PCD_KG_TCI, /**< TCI field */
152269 + e_IOC_FM_PCD_KG_ENET_TYPE, /**< ENET Type */
152270 + e_IOC_FM_PCD_KG_PPP_SESSION_ID, /**< PPP Session id */
152271 + e_IOC_FM_PCD_KG_PPP_PROTOCOL_ID, /**< PPP Protocol id */
152272 + e_IOC_FM_PCD_KG_MPLS_LABEL, /**< MPLS label */
152273 + e_IOC_FM_PCD_KG_IP_ADDR, /**< IP addr */
152274 + e_IOC_FM_PCD_KG_PROTOCOL_TYPE, /**< Protocol type */
152275 + e_IOC_FM_PCD_KG_IP_TOS_TC, /**< TOS or TC */
152276 + e_IOC_FM_PCD_KG_IPV6_FLOW_LABEL, /**< IPV6 flow label */
152277 + e_IOC_FM_PCD_KG_IPSEC_SPI, /**< IPSEC SPI */
152278 + e_IOC_FM_PCD_KG_L4_PORT, /**< L4 Port */
152279 + e_IOC_FM_PCD_KG_TCP_FLAG, /**< TCP Flag */
152280 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA, /**< grouping implemented by SW,
152281 + any data extraction that is not the full
152282 + field described above */
152283 + e_IOC_FM_PCD_KG_GENERIC_FROM_DATA_NO_V, /**< grouping implemented by SW,
152284 + any data extraction without validation */
152285 + e_IOC_FM_PCD_KG_GENERIC_NOT_FROM_DATA /**< grouping implemented by SW,
152286 + extraction from parser result or
152287 + direct use of default value */
152288 +} ioc_fm_pcd_kg_known_fields_dflt_types;
152289 +
152290 +/**************************************************************************//**
152291 + @Description Enumeration type for defining header index for scenarios with
152292 + multiple (tunneled) headers
152293 +*//***************************************************************************/
152294 +typedef enum ioc_fm_pcd_hdr_index {
152295 + e_IOC_FM_PCD_HDR_INDEX_NONE = 0, /**< used when multiple headers not used, also
152296 + to specify regular IP (not tunneled). */
152297 + e_IOC_FM_PCD_HDR_INDEX_1, /**< may be used for VLAN, MPLS, tunneled IP */
152298 + e_IOC_FM_PCD_HDR_INDEX_2, /**< may be used for MPLS, tunneled IP */
152299 + e_IOC_FM_PCD_HDR_INDEX_3, /**< may be used for MPLS */
152300 + e_IOC_FM_PCD_HDR_INDEX_LAST = 0xFF /**< may be used for VLAN, MPLS */
152301 +} ioc_fm_pcd_hdr_index;
152302 +
152303 +/**************************************************************************//**
152304 + @Description Enumeration type for selecting the policer profile functional type
152305 +*//***************************************************************************/
152306 +typedef enum ioc_fm_pcd_profile_type_selection {
152307 + e_IOC_FM_PCD_PLCR_PORT_PRIVATE, /**< Port dedicated profile */
152308 + e_IOC_FM_PCD_PLCR_SHARED /**< Shared profile (shared within partition) */
152309 +} ioc_fm_pcd_profile_type_selection;
152310 +
152311 +/**************************************************************************//**
152312 + @Description Enumeration type for selecting the policer profile algorithm
152313 +*//***************************************************************************/
152314 +typedef enum ioc_fm_pcd_plcr_algorithm_selection {
152315 + e_IOC_FM_PCD_PLCR_PASS_THROUGH, /**< Policer pass through */
152316 + e_IOC_FM_PCD_PLCR_RFC_2698, /**< Policer algorithm RFC 2698 */
152317 + e_IOC_FM_PCD_PLCR_RFC_4115 /**< Policer algorithm RFC 4115 */
152318 +} ioc_fm_pcd_plcr_algorithm_selection;
152319 +
152320 +/**************************************************************************//**
152321 + @Description Enumeration type for selecting a policer profile color mode
152322 +*//***************************************************************************/
152323 +typedef enum ioc_fm_pcd_plcr_color_mode {
152324 + e_IOC_FM_PCD_PLCR_COLOR_BLIND, /**< Color blind */
152325 + e_IOC_FM_PCD_PLCR_COLOR_AWARE /**< Color aware */
152326 +} ioc_fm_pcd_plcr_color_mode;
152327 +
152328 +/**************************************************************************//**
152329 + @Description Enumeration type for selecting a policer profile color
152330 +*//***************************************************************************/
152331 +typedef enum ioc_fm_pcd_plcr_color {
152332 + e_IOC_FM_PCD_PLCR_GREEN, /**< Green */
152333 + e_IOC_FM_PCD_PLCR_YELLOW, /**< Yellow */
152334 + e_IOC_FM_PCD_PLCR_RED, /**< Red */
152335 + e_IOC_FM_PCD_PLCR_OVERRIDE /**< Color override */
152336 +} ioc_fm_pcd_plcr_color;
152337 +
152338 +/**************************************************************************//**
152339 + @Description Enumeration type for selecting the policer profile packet frame length selector
152340 +*//***************************************************************************/
152341 +typedef enum ioc_fm_pcd_plcr_frame_length_select {
152342 + e_IOC_FM_PCD_PLCR_L2_FRM_LEN, /**< L2 frame length */
152343 + e_IOC_FM_PCD_PLCR_L3_FRM_LEN, /**< L3 frame length */
152344 + e_IOC_FM_PCD_PLCR_L4_FRM_LEN, /**< L4 frame length */
152345 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN /**< Full frame length */
152346 +} ioc_fm_pcd_plcr_frame_length_select;
152347 +
152348 +/**************************************************************************//**
152349 + @Description Enumeration type for selecting roll-back frame
152350 +*//***************************************************************************/
152351 +typedef enum ioc_fm_pcd_plcr_roll_back_frame_select {
152352 + e_IOC_FM_PCD_PLCR_ROLLBACK_L2_FRM_LEN, /**< Rollback L2 frame length */
152353 + e_IOC_FM_PCD_PLCR_ROLLBACK_FULL_FRM_LEN /**< Rollback Full frame length */
152354 +} ioc_fm_pcd_plcr_roll_back_frame_select;
152355 +
152356 +/**************************************************************************//**
152357 + @Description Enumeration type for selecting the policer profile packet or byte mode
152358 +*//***************************************************************************/
152359 +typedef enum ioc_fm_pcd_plcr_rate_mode {
152360 + e_IOC_FM_PCD_PLCR_BYTE_MODE, /**< Byte mode */
152361 + e_IOC_FM_PCD_PLCR_PACKET_MODE /**< Packet mode */
152362 +} ioc_fm_pcd_plcr_rate_mode;
152363 +
152364 +/**************************************************************************//**
152365 + @Description Enumeration type for defining action of frame
152366 +*//***************************************************************************/
152367 +typedef enum ioc_fm_pcd_done_action {
152368 + e_IOC_FM_PCD_ENQ_FRAME = 0, /**< Enqueue frame */
152369 + e_IOC_FM_PCD_DROP_FRAME /**< Drop frame */
152370 +} ioc_fm_pcd_done_action;
152371 +
152372 +/**************************************************************************//**
152373 + @Description Enumeration type for selecting the policer counter
152374 +*//***************************************************************************/
152375 +typedef enum ioc_fm_pcd_plcr_profile_counters {
152376 + e_IOC_FM_PCD_PLCR_PROFILE_GREEN_PACKET_TOTAL_COUNTER, /**< Green packets counter */
152377 + e_IOC_FM_PCD_PLCR_PROFILE_YELLOW_PACKET_TOTAL_COUNTER, /**< Yellow packets counter */
152378 + e_IOC_FM_PCD_PLCR_PROFILE_RED_PACKET_TOTAL_COUNTER, /**< Red packets counter */
152379 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_YELLOW_PACKET_TOTAL_COUNTER, /**< Recolored yellow packets counter */
152380 + e_IOC_FM_PCD_PLCR_PROFILE_RECOLOURED_RED_PACKET_TOTAL_COUNTER /**< Recolored red packets counter */
152381 +} ioc_fm_pcd_plcr_profile_counters;
152382 +
152383 +/**************************************************************************//**
152384 + @Description Enumeration type for selecting the PCD action after extraction
152385 +*//***************************************************************************/
152386 +typedef enum ioc_fm_pcd_action {
152387 + e_IOC_FM_PCD_ACTION_NONE, /**< NONE */
152388 + e_IOC_FM_PCD_ACTION_EXACT_MATCH, /**< Exact match on the selected extraction*/
152389 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP /**< Indexed lookup on the selected extraction*/
152390 +} ioc_fm_pcd_action;
152391 +
152392 +/**************************************************************************//**
152393 + @Description Enumeration type for selecting type of insert manipulation
152394 +*//***************************************************************************/
152395 +typedef enum ioc_fm_pcd_manip_hdr_insrt_type {
152396 + e_IOC_FM_PCD_MANIP_INSRT_GENERIC, /**< Insert according to offset & size */
152397 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR, /**< Insert according to protocol */
152398 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152399 + e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE /**< Insert template to start of frame */
152400 +#endif /* FM_CAPWAP_SUPPORT */
152401 +} ioc_fm_pcd_manip_hdr_insrt_type;
152402 +
152403 +/**************************************************************************//**
152404 + @Description Enumeration type for selecting type of remove manipulation
152405 +*//***************************************************************************/
152406 +typedef enum ioc_fm_pcd_manip_hdr_rmv_type {
152407 + e_IOC_FM_PCD_MANIP_RMV_GENERIC, /**< Remove according to offset & size */
152408 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR /**< Remove according to offset & size */
152409 +} ioc_fm_pcd_manip_hdr_rmv_type;
152410 +
152411 +/**************************************************************************//**
152412 + @Description An enum for selecting specific L2 fields removal
152413 +*//***************************************************************************/
152414 +typedef enum ioc_fm_pcd_manip_hdr_rmv_specific_l2 {
152415 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET, /**< Ethernet/802.3 MAC */
152416 + e_IOC_FM_PCD_MANIP_HDR_RMV_STACKED_QTAGS, /**< stacked QTags */
152417 + e_IOC_FM_PCD_MANIP_HDR_RMV_ETHERNET_AND_MPLS, /**< MPLS and Ethernet/802.3 MAC header until
152418 + the header which follows the MPLS header */
152419 + e_IOC_FM_PCD_MANIP_HDR_RMV_MPLS /**< Remove MPLS header (Unlimited MPLS labels) */
152420 +} ioc_fm_pcd_manip_hdr_rmv_specific_l2;
152421 +
152422 +/**************************************************************************//**
152423 + @Description Enumeration type for selecting specific fields updates
152424 +*//***************************************************************************/
152425 +typedef enum ioc_fm_pcd_manip_hdr_field_update_type {
152426 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN, /**< VLAN updates */
152427 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4, /**< IPV4 updates */
152428 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6, /**< IPV6 updates */
152429 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP, /**< TCP_UDP updates */
152430 +} ioc_fm_pcd_manip_hdr_field_update_type;
152431 +
152432 +/**************************************************************************//**
152433 + @Description Enumeration type for selecting VLAN updates
152434 +*//***************************************************************************/
152435 +typedef enum ioc_fm_pcd_manip_hdr_field_update_vlan {
152436 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_VPRI, /**< Replace VPri of outer most VLAN tag. */
152437 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN /**< DSCP to VLAN priority bits translation */
152438 +} ioc_fm_pcd_manip_hdr_field_update_vlan;
152439 +
152440 +/**************************************************************************//**
152441 + @Description Enumeration type for selecting specific L2 fields removal
152442 +*//***************************************************************************/
152443 +typedef enum ioc_fm_pcd_manip_hdr_insrt_specific_l2 {
152444 + e_IOC_FM_PCD_MANIP_HDR_INSRT_MPLS /**< Insert MPLS header (Unlimited MPLS labels) */
152445 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2;
152446 +
152447 +#if (DPAA_VERSION >= 11)
152448 +/**************************************************************************//**
152449 + @Description Enumeration type for selecting QoS mapping mode
152450 +
152451 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE'
152452 + User should instruct the port to read the parser-result
152453 +*//***************************************************************************/
152454 +typedef enum ioc_fm_pcd_manip_hdr_qos_mapping_mode {
152455 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_NONE = 0, /**< No mapping, QoS field will not be changed */
152456 + e_IOC_FM_PCD_MANIP_HDR_QOS_MAPPING_AS_IS, /**< QoS field will be overwritten by the last byte in the parser-result. */
152457 +} ioc_fm_pcd_manip_hdr_qos_mapping_mode;
152458 +
152459 +/**************************************************************************//**
152460 + @Description Enumeration type for selecting QoS source
152461 +
152462 + Note: In all cases except 'e_FM_PCD_MANIP_HDR_QOS_SRC_NONE'
152463 + User should left room for the parser-result on input/output buffer
152464 + and instruct the port to read/write the parser-result to the buffer (RPD should be set)
152465 +*//***************************************************************************/
152466 +typedef enum ioc_fm_pcd_manip_hdr_qos_src {
152467 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_NONE = 0, /**< TODO */
152468 + e_IOC_FM_PCD_MANIP_HDR_QOS_SRC_USER_DEFINED, /**< QoS will be taken from the last byte in the parser-result. */
152469 +} ioc_fm_pcd_manip_hdr_qos_src;
152470 +#endif /* (DPAA_VERSION >= 11) */
152471 +
152472 +/**************************************************************************//**
152473 + @Description Enumeration type for selecting type of header insertion
152474 +*//***************************************************************************/
152475 +typedef enum ioc_fm_pcd_manip_hdr_insrt_by_hdr_type {
152476 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2, /**< Specific L2 fields insertion */
152477 +#if (DPAA_VERSION >= 11)
152478 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_IP, /**< IP insertion */
152479 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP, /**< UDP insertion */
152480 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, /**< UDP lite insertion */
152481 + e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP /**< CAPWAP insertion */
152482 +#endif /* (DPAA_VERSION >= 11) */
152483 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_type;
152484 +
152485 +/**************************************************************************//**
152486 + @Description Enumeration type for selecting specific custom command
152487 +*//***************************************************************************/
152488 +typedef enum ioc_fm_pcd_manip_hdr_custom_type {
152489 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_IP_REPLACE, /**< Replace IPv4/IPv6 */
152490 +} ioc_fm_pcd_manip_hdr_custom_type;
152491 +
152492 +/**************************************************************************//**
152493 + @Description Enumeration type for selecting specific custom command
152494 +*//***************************************************************************/
152495 +typedef enum ioc_fm_pcd_manip_hdr_custom_ip_replace {
152496 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV4_BY_IPV6, /**< Replace IPv4 by IPv6 */
152497 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 /**< Replace IPv6 by IPv4 */
152498 +} ioc_fm_pcd_manip_hdr_custom_ip_replace;
152499 +
152500 +/**************************************************************************//**
152501 + @Description Enumeration type for selecting type of header removal
152502 +*//***************************************************************************/
152503 +typedef enum ioc_fm_pcd_manip_hdr_rmv_by_hdr_type {
152504 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_SPECIFIC_L2 = 0, /**< Specific L2 fields removal */
152505 +#if (DPAA_VERSION >= 11)
152506 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_CAPWAP, /**< CAPWAP removal */
152507 +#endif /* (DPAA_VERSION >= 11) */
152508 +#if (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
152509 + e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START, /**< Locate from data that is not the header */
152510 +#endif /* (DPAA_VERSION >= 11) || ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT)) */
152511 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_type;
152512 +
152513 +/**************************************************************************//**
152514 + @Description Enumeration type for selecting type of timeout mode
152515 +*//***************************************************************************/
152516 +typedef enum ioc_fm_pcd_manip_reassem_time_out_mode {
152517 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAMES, /**< Limits the time of the reassembly process
152518 + from the first fragment to the last */
152519 + e_IOC_FM_PCD_MANIP_TIME_OUT_BETWEEN_FRAG /**< Limits the time of receiving the fragment */
152520 +} ioc_fm_pcd_manip_reassem_time_out_mode;
152521 +
152522 +/**************************************************************************//**
152523 + @Description Enumeration type for selecting type of WaysNumber mode
152524 +*//***************************************************************************/
152525 +typedef enum ioc_fm_pcd_manip_reassem_ways_number {
152526 + e_IOC_FM_PCD_MANIP_ONE_WAY_HASH = 1, /**< One way hash */
152527 + e_IOC_FM_PCD_MANIP_TWO_WAYS_HASH, /**< Two ways hash */
152528 + e_IOC_FM_PCD_MANIP_THREE_WAYS_HASH, /**< Three ways hash */
152529 + e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH, /**< Four ways hash */
152530 + e_IOC_FM_PCD_MANIP_FIVE_WAYS_HASH, /**< Five ways hash */
152531 + e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH, /**< Six ways hash */
152532 + e_IOC_FM_PCD_MANIP_SEVEN_WAYS_HASH, /**< Seven ways hash */
152533 + e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH /**< Eight ways hash */
152534 +} ioc_fm_pcd_manip_reassem_ways_number;
152535 +
152536 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
152537 +/**************************************************************************//**
152538 + @Description Enumeration type for selecting type of statistics mode
152539 +*//***************************************************************************/
152540 +typedef enum ioc_fm_pcd_stats {
152541 + e_IOC_FM_PCD_STATS_PER_FLOWID = 0 /**< Flow ID is used as index for getting statistics */
152542 +} ioc_fm_pcd_stats;
152543 +#endif
152544 +
152545 +/**************************************************************************//**
152546 + @Description Enumeration type for selecting manipulation type
152547 +*//***************************************************************************/
152548 +typedef enum ioc_fm_pcd_manip_type {
152549 + e_IOC_FM_PCD_MANIP_HDR = 0, /**< Header manipulation */
152550 + e_IOC_FM_PCD_MANIP_REASSEM, /**< Reassembly */
152551 + e_IOC_FM_PCD_MANIP_FRAG, /**< Fragmentation */
152552 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD /**< Special Offloading */
152553 +} ioc_fm_pcd_manip_type;
152554 +
152555 +/**************************************************************************//**
152556 + @Description Enumeration type for selecting type of statistics mode
152557 +*//***************************************************************************/
152558 +typedef enum ioc_fm_pcd_cc_stats_mode {
152559 + e_IOC_FM_PCD_CC_STATS_MODE_NONE = 0, /**< No statistics support */
152560 + e_IOC_FM_PCD_CC_STATS_MODE_FRAME, /**< Frame count statistics */
152561 + e_IOC_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME, /**< Byte and frame count statistics */
152562 +#if (DPAA_VERSION >= 11)
152563 + e_IOC_FM_PCD_CC_STATS_MODE_RMON, /**< Byte and frame length range count statistics */
152564 +#endif /* (DPAA_VERSION >= 11) */
152565 +} ioc_fm_pcd_cc_stats_mode;
152566 +
152567 +/**************************************************************************//**
152568 + @Description Enumeration type for determining the action in case an IP packet
152569 + is larger than MTU but its DF (Don't Fragment) bit is set.
152570 +*//***************************************************************************/
152571 +typedef enum ioc_fm_pcd_manip_dont_frag_action {
152572 + e_IOC_FM_PCD_MANIP_DISCARD_PACKET = 0, /**< Discard packet */
152573 + e_IOC_FM_PCD_MANIP_ENQ_TO_ERR_Q_OR_DISCARD_PACKET = e_IOC_FM_PCD_MANIP_DISCARD_PACKET,
152574 + /**< Obsolete, cannot enqueue to error queue;
152575 + In practice, selects to discard packets;
152576 + Will be removed in the future */
152577 + e_IOC_FM_PCD_MANIP_FRAGMENT_PACKECT, /**< Fragment packet and continue normal processing */
152578 + e_IOC_FM_PCD_MANIP_CONTINUE_WITHOUT_FRAG /**< Continue normal processing without fragmenting the packet */
152579 +} ioc_fm_pcd_manip_dont_frag_action;
152580 +
152581 +/**************************************************************************//**
152582 + @Description Enumeration type for selecting type of special offload manipulation
152583 +*//***************************************************************************/
152584 +typedef enum ioc_fm_pcd_manip_special_offload_type {
152585 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC, /**< IPSec offload manipulation */
152586 +#if (DPAA_VERSION >= 11)
152587 + e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP /**< CAPWAP offload manipulation */
152588 +#endif /* (DPAA_VERSION >= 11) */
152589 +} ioc_fm_pcd_manip_special_offload_type;
152590 +
152591 +/**************************************************************************//**
152592 + @Description A union of protocol dependent special options
152593 + (Must match union u_FmPcdHdrProtocolOpt defined in fm_pcd_ext.h)
152594 +*//***************************************************************************/
152595 +typedef union ioc_fm_pcd_hdr_protocol_opt_u {
152596 + ioc_eth_protocol_opt_t eth_opt; /**< Ethernet options */
152597 + ioc_vlan_protocol_opt_t vlan_opt; /**< Vlan options */
152598 + ioc_mpls_protocol_opt_t mpls_opt; /**< MPLS options */
152599 + ioc_ipv4_protocol_opt_t ipv4_opt; /**< IPv4 options */
152600 + ioc_ipv6_protocol_opt_t ipv6_opt; /**< IPv6 options */
152601 +#if (DPAA_VERSION >= 11)
152602 + ioc_capwap_protocol_opt_t capwap_opt; /**< CAPWAP options */
152603 +#endif /* (DPAA_VERSION >= 11) */
152604 +} ioc_fm_pcd_hdr_protocol_opt_u;
152605 +
152606 +/**************************************************************************//**
152607 + @Description A union holding all known protocol fields
152608 +*//***************************************************************************/
152609 +typedef union ioc_fm_pcd_fields_u {
152610 + ioc_header_field_eth_t eth; /**< Ethernet */
152611 + ioc_header_field_vlan_t vlan; /**< VLAN */
152612 + ioc_header_field_llc_snap_t llc_snap; /**< LLC SNAP */
152613 + ioc_header_field_pppoe_t pppoe; /**< PPPoE */
152614 + ioc_header_field_mpls_t mpls; /**< MPLS */
152615 + ioc_header_field_ip_t ip; /**< IP */
152616 + ioc_header_field_ipv4_t ipv4; /**< IPv4 */
152617 + ioc_header_field_ipv6_t ipv6; /**< IPv6 */
152618 + ioc_header_field_udp_t udp; /**< UDP */
152619 + ioc_header_field_udp_lite_t udp_lite; /**< UDP_Lite */
152620 + ioc_header_field_tcp_t tcp; /**< TCP */
152621 + ioc_header_field_sctp_t sctp; /**< SCTP */
152622 + ioc_header_field_dccp_t dccp; /**< DCCP */
152623 + ioc_header_field_gre_t gre; /**< GRE */
152624 + ioc_header_field_minencap_t minencap; /**< Minimal Encapsulation */
152625 + ioc_header_field_ipsec_ah_t ipsec_ah; /**< IPSec AH */
152626 + ioc_header_field_ipsec_esp_t ipsec_esp; /**< IPSec ESP */
152627 + ioc_header_field_udp_encap_esp_t udp_encap_esp; /**< UDP Encapsulation ESP */
152628 +} ioc_fm_pcd_fields_u;
152629 +
152630 +/**************************************************************************//**
152631 + @Description Parameters for defining header extraction for key generation
152632 +*//***************************************************************************/
152633 +typedef struct ioc_fm_pcd_from_hdr_t {
152634 + uint8_t size; /**< Size in byte */
152635 + uint8_t offset; /**< Byte offset */
152636 +} ioc_fm_pcd_from_hdr_t;
152637 +
152638 +/**************************************************************************//**
152639 + @Description Parameters for defining field extraction for key generation
152640 +*//***************************************************************************/
152641 +typedef struct ioc_fm_pcd_from_field_t {
152642 + ioc_fm_pcd_fields_u field; /**< Field selection */
152643 + uint8_t size; /**< Size in byte */
152644 + uint8_t offset; /**< Byte offset */
152645 +} ioc_fm_pcd_from_field_t;
152646 +
152647 +/**************************************************************************//**
152648 + @Description Parameters for defining a single network environment unit
152649 + A distinction unit should be defined if it will later be used
152650 + by one or more PCD engines to distinguish between flows.
152651 + (Must match struct t_FmPcdDistinctionUnit defined in fm_pcd_ext.h)
152652 +*//***************************************************************************/
152653 +typedef struct ioc_fm_pcd_distinction_unit_t {
152654 + struct {
152655 + ioc_net_header_type hdr; /**< One of the headers supported by the FM */
152656 + ioc_fm_pcd_hdr_protocol_opt_u opt; /**< Select only one option! */
152657 + } hdrs[IOC_FM_PCD_MAX_NUM_OF_INTERCHANGEABLE_HDRS];
152658 +} ioc_fm_pcd_distinction_unit_t;
152659 +
152660 +/**************************************************************************//**
152661 + @Description Parameters for defining all different distinction units supported
152662 + by a specific PCD Network Environment Characteristics module.
152663 +
152664 + Each unit represent a protocol or a group of protocols that may
152665 + be used later by the different PCD engines to distinguish between flows.
152666 + (Must match struct t_FmPcdNetEnvParams defined in fm_pcd_ext.h)
152667 +*//***************************************************************************/
152668 +typedef struct ioc_fm_pcd_net_env_params_t {
152669 + uint8_t num_of_distinction_units;/**< Number of different units to be identified */
152670 + ioc_fm_pcd_distinction_unit_t units[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
152671 + /**< An array of num_of_distinction_units of the
152672 + different units to be identified */
152673 + void *id; /**< Output parameter; Returns the net-env Id to be used */
152674 +} ioc_fm_pcd_net_env_params_t;
152675 +
152676 +/**************************************************************************//**
152677 + @Description Parameters for defining a single extraction action when
152678 + creating a key
152679 +*//***************************************************************************/
152680 +typedef struct ioc_fm_pcd_extract_entry_t {
152681 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
152682 + union {
152683 + struct {
152684 + ioc_net_header_type hdr; /**< Header selection */
152685 + bool ignore_protocol_validation;
152686 + /**< Ignore protocol validation */
152687 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
152688 + IP. Otherwise should be cleared.*/
152689 + ioc_fm_pcd_extract_by_hdr_type type; /**< Header extraction type select */
152690 + union {
152691 + ioc_fm_pcd_from_hdr_t from_hdr; /**< Extract bytes from header parameters */
152692 + ioc_fm_pcd_from_field_t from_field; /**< Extract bytes from field parameters */
152693 + ioc_fm_pcd_fields_u full_field; /**< Extract full field parameters */
152694 + } extract_by_hdr_type;
152695 + } extract_by_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
152696 + struct {
152697 + ioc_fm_pcd_extract_from src; /**< Non-header extraction source */
152698 + ioc_fm_pcd_action action; /**< Relevant for CC Only */
152699 + uint16_t ic_indx_mask; /**< Relevant only for CC when
152700 + action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP;
152701 + Note that the number of bits that are set within
152702 + this mask must be log2 of the CC-node 'num_of_keys'.
152703 + Note that the mask cannot be set on the lower bits. */
152704 + uint8_t offset; /**< Byte offset */
152705 + uint8_t size; /**< Size in bytes */
152706 + } extract_non_hdr; /**< Used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
152707 + } extract_params;
152708 +} ioc_fm_pcd_extract_entry_t;
152709 +
152710 +/**************************************************************************//**
152711 + @Description A structure for defining masks for each extracted
152712 + field in the key.
152713 +*//***************************************************************************/
152714 +typedef struct ioc_fm_pcd_kg_extract_mask_t {
152715 + uint8_t extract_array_index; /**< Index in the extraction array, as initialized by user */
152716 + uint8_t offset; /**< Byte offset */
152717 + uint8_t mask; /**< A byte mask (selected bits will be ignored) */
152718 +} ioc_fm_pcd_kg_extract_mask_t;
152719 +
152720 +/**************************************************************************//**
152721 + @Description A structure for defining default selection per groups
152722 + of fields
152723 +*//***************************************************************************/
152724 +typedef struct ioc_fm_pcd_kg_extract_dflt_t {
152725 + ioc_fm_pcd_kg_known_fields_dflt_types type; /**< Default type select*/
152726 + ioc_fm_pcd_kg_extract_dflt_select dflt_select; /**< Default register select */
152727 +} ioc_fm_pcd_kg_extract_dflt_t;
152728 +
152729 +
152730 +/**************************************************************************//**
152731 + @Description A structure for defining all parameters needed for
152732 + generation a key and using a hash function
152733 +*//***************************************************************************/
152734 +typedef struct ioc_fm_pcd_kg_key_extract_and_hash_params_t {
152735 + uint32_t private_dflt0; /**< Scheme default register 0 */
152736 + uint32_t private_dflt1; /**< Scheme default register 1 */
152737 + uint8_t num_of_used_extracts; /**< defines the valid size of the following array */
152738 + ioc_fm_pcd_extract_entry_t extract_array [IOC_FM_PCD_KG_MAX_NUM_OF_EXTRACTS_PER_KEY];
152739 + /**< An array of extraction definitions. */
152740 + uint8_t num_of_used_dflts; /**< defines the valid size of the following array */
152741 + ioc_fm_pcd_kg_extract_dflt_t dflts[IOC_FM_PCD_KG_NUM_OF_DEFAULT_GROUPS];
152742 + /**< For each extraction used in this scheme, specify the required
152743 + default register to be used when header is not found.
152744 + types not specified in this array will get undefined value. */
152745 + uint8_t num_of_used_masks; /**< Defines the valid size of the following array */
152746 + ioc_fm_pcd_kg_extract_mask_t masks[IOC_FM_PCD_KG_NUM_OF_EXTRACT_MASKS];
152747 + uint8_t hash_shift; /**< Hash result right shift.
152748 + Selects the 24 bits out of the 64 hash result.
152749 + 0 means using the 24 LSB's, otherwise use the
152750 + 24 LSB's after shifting right.*/
152751 + uint32_t hash_distribution_num_of_fqids; /**< must be > 1 and a power of 2. Represents the range
152752 + of queues for the key and hash functionality */
152753 + uint8_t hash_distribution_fqids_shift; /**< selects the FQID bits that will be effected by the hash */
152754 + bool symmetric_hash; /**< TRUE to generate the same hash for frames with swapped source and
152755 + destination fields on all layers; If TRUE, driver will check that for
152756 + all layers, if SRC extraction is selected, DST extraction must also be
152757 + selected, and vice versa. */
152758 +} ioc_fm_pcd_kg_key_extract_and_hash_params_t;
152759 +
152760 +/**************************************************************************//**
152761 + @Description A structure of parameters for defining a single
152762 + Qid mask (extracted OR).
152763 +*//***************************************************************************/
152764 +typedef struct ioc_fm_pcd_kg_extracted_or_params_t {
152765 + ioc_fm_pcd_extract_type type; /**< Extraction type select */
152766 + union {
152767 + struct { /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_BY_HDR */
152768 + ioc_net_header_type hdr;
152769 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled
152770 + IP. Otherwise should be cleared.*/
152771 + bool ignore_protocol_validation;
152772 +
152773 + } extract_by_hdr;
152774 + ioc_fm_pcd_extract_from src; /**< used when type = e_IOC_FM_PCD_KG_EXTRACT_NON_HDR */
152775 + } extract_params;
152776 + uint8_t extraction_offset; /**< Offset for extraction */
152777 + ioc_fm_pcd_kg_extract_dflt_select dflt_value; /**< Select register from which extraction is taken if
152778 + field not found */
152779 + uint8_t mask; /**< Mask LSB byte of extraction (specified bits are ignored) */
152780 + uint8_t bit_offset_in_fqid; /**< 0-31, Selects which bits of the 24 FQID bits to effect using
152781 + the extracted byte; Assume byte is placed as the 8 MSB's in
152782 + a 32 bit word where the lower bits
152783 + are the FQID; i.e if bitOffsetInFqid=1 than its LSB
152784 + will effect the FQID MSB, if bitOffsetInFqid=24 than the
152785 + extracted byte will effect the 8 LSB's of the FQID,
152786 + if bitOffsetInFqid=31 than the byte's MSB will effect
152787 + the FQID's LSB; 0 means - no effect on FQID;
152788 + Note that one, and only one of
152789 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
152790 + extracted byte must effect either FQID or Policer profile).*/
152791 + uint8_t bit_offset_in_plcr_profile;
152792 + /**< 0-15, Selects which bits of the 8 policer profile id bits to
152793 + effect using the extracted byte; Assume byte is placed
152794 + as the 8 MSB's in a 16 bit word where the lower bits
152795 + are the policer profile id; i.e if bitOffsetInPlcrProfile=1
152796 + than its LSB will effect the profile MSB, if bitOffsetInFqid=8
152797 + than the extracted byte will effect the whole policer profile id,
152798 + if bitOffsetInFqid=15 than the byte's MSB will effect
152799 + the Policer Profile id's LSB;
152800 + 0 means - no effect on policer profile; Note that one, and only one of
152801 + bitOffsetInFqid or bitOffsetInPlcrProfile must be set (i.e,
152802 + extracted byte must effect either FQID or Policer profile).*/
152803 +} ioc_fm_pcd_kg_extracted_or_params_t;
152804 +
152805 +/**************************************************************************//**
152806 + @Description A structure for configuring scheme counter
152807 +*//***************************************************************************/
152808 +typedef struct ioc_fm_pcd_kg_scheme_counter_t {
152809 + bool update; /**< FALSE to keep the current counter state
152810 + and continue from that point, TRUE to update/reset
152811 + the counter when the scheme is written. */
152812 + uint32_t value; /**< If update=TRUE, this value will be written into the
152813 + counter; clear this field to reset the counter. */
152814 +} ioc_fm_pcd_kg_scheme_counter_t;
152815 +
152816 +
152817 +/**************************************************************************//**
152818 + @Description A structure for retrieving FMKG_SE_SPC
152819 +*//***************************************************************************/
152820 +typedef struct ioc_fm_pcd_kg_scheme_spc_t {
152821 + uint32_t val; /**< return value */
152822 + void *id; /**< scheme handle */
152823 +} ioc_fm_pcd_kg_scheme_spc_t;
152824 +
152825 +/**************************************************************************//**
152826 + @Description A structure for defining policer profile parameters as required by keygen
152827 + (when policer is the next engine after this scheme).
152828 + (Must match struct t_FmPcdKgPlcrProfile defined in fm_pcd_ext.h)
152829 +*//***************************************************************************/
152830 +typedef struct ioc_fm_pcd_kg_plcr_profile_t {
152831 + bool shared_profile; /**< TRUE if this profile is shared between ports
152832 + (i.e. managed by master partition) May not be TRUE
152833 + if profile is after Coarse Classification*/
152834 + bool direct; /**< If TRUE, direct_relative_profile_id only selects the profile
152835 + id, if FALSE fqid_offset_relative_profile_id_base is used
152836 + together with fqid_offset_shift and num_of_profiles
152837 + parameters, to define a range of profiles from
152838 + which the KeyGen result will determine the
152839 + destination policer profile. */
152840 + union {
152841 + uint16_t direct_relative_profile_id; /**< Used if 'direct' is TRUE, to select policer profile.
152842 + This parameter should indicate the policer profile offset within the port's
152843 + policer profiles or SHARED window. */
152844 + struct {
152845 + uint8_t fqid_offset_shift; /**< Shift of KG results without the qid base */
152846 + uint8_t fqid_offset_relative_profile_id_base;
152847 + /**< OR of KG results without the qid base
152848 + This parameter should indicate the policer profile
152849 + offset within the port's policer profiles window
152850 + or SHARED window depends on shared_profile */
152851 + uint8_t num_of_profiles; /**< Range of profiles starting at base */
152852 + } indirect_profile; /**< Indirect profile parameters */
152853 + } profile_select; /**< Direct/indirect profile selection and parameters */
152854 +} ioc_fm_pcd_kg_plcr_profile_t;
152855 +
152856 +#if DPAA_VERSION >= 11
152857 +/**************************************************************************//**
152858 + @Description Parameters for configuring a storage profile for a KeyGen scheme.
152859 +*//***************************************************************************/
152860 +typedef struct ioc_fm_pcd_kg_storage_profile_t {
152861 + bool direct; /**< If TRUE, directRelativeProfileId only selects the
152862 + profile id;
152863 + If FALSE, fqidOffsetRelativeProfileIdBase is used
152864 + together with fqidOffsetShift and numOfProfiles
152865 + parameters to define a range of profiles from which
152866 + the KeyGen result will determine the destination
152867 + storage profile. */
152868 + union {
152869 + uint16_t direct_relative_profileId; /**< Used when 'direct' is TRUE, to select a storage profile;
152870 + should indicate the storage profile offset within the
152871 + port's storage profiles window. */
152872 + struct {
152873 + uint8_t fqid_offset_shift; /**< Shift of KeyGen results without the FQID base */
152874 + uint8_t fqid_offset_relative_profile_id_base;
152875 + /**< OR of KeyGen results without the FQID base;
152876 + should indicate the policer profile offset within the
152877 + port's storage profiles window. */
152878 + uint8_t num_of_profiles; /**< Range of profiles starting at base. */
152879 + } indirect_profile; /**< Indirect profile parameters. */
152880 + } profile_select; /**< Direct/indirect profile selection and parameters. */
152881 +} ioc_fm_pcd_kg_storage_profile_t;
152882 +#endif /* DPAA_VERSION >= 11 */
152883 +
152884 +/**************************************************************************//**
152885 + @Description Parameters for defining CC as the next engine after KeyGen
152886 + (Must match struct t_FmPcdKgCc defined in fm_pcd_ext.h)
152887 +*//***************************************************************************/
152888 +typedef struct ioc_fm_pcd_kg_cc_t {
152889 + void *tree_id; /**< CC Tree id */
152890 + uint8_t grp_id; /**< CC group id within the CC tree */
152891 + bool plcr_next; /**< TRUE if after CC, in case of data frame,
152892 + policing is required. */
152893 + bool bypass_plcr_profile_generation;
152894 + /**< TRUE to bypass KeyGen policer profile generation;
152895 + selected profile is the one set at port initialization. */
152896 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Valid only if plcr_next = TRUE and
152897 + bypass_plcr_profile_generation = FALSE */
152898 +} ioc_fm_pcd_kg_cc_t;
152899 +
152900 +/**************************************************************************//**
152901 + @Description Parameters for defining initializing a KeyGen scheme
152902 + (Must match struct t_FmPcdKgSchemeParams defined in fm_pcd_ext.h)
152903 +*//***************************************************************************/
152904 +typedef struct ioc_fm_pcd_kg_scheme_params_t {
152905 + bool modify; /**< TRUE to change an existing scheme */
152906 + union {
152907 + uint8_t relative_scheme_id;
152908 + /**< if modify=FALSE: partition-relative scheme id */
152909 + void *scheme_id; /**< if modify=TRUE: the id of an existing scheme */
152910 + } scm_id;
152911 + bool always_direct; /**< This scheme is reached only directly, i.e. no need
152912 + for match vector; KeyGen will ignore it when matching */
152913 + struct { /**< HL relevant only if always_direct=FALSE */
152914 + void *net_env_id; /**< The id of the Network Environment as returned
152915 + by FM_PCD_NetEnvCharacteristicsSet() */
152916 + uint8_t num_of_distinction_units;
152917 + /**< Number of NetEnv units listed in unit_ids array */
152918 + uint8_t unit_ids[IOC_FM_PCD_MAX_NUM_OF_DISTINCTION_UNITS];
152919 + /**< Indexes as passed to SetNetEnvCharacteristics (?) array */
152920 + } net_env_params;
152921 + bool use_hash; /**< use the KG Hash functionality */
152922 + ioc_fm_pcd_kg_key_extract_and_hash_params_t key_extract_and_hash_params;
152923 + /**< used only if useHash = TRUE */
152924 + bool bypass_fqid_generation;
152925 + /**< Normally - FALSE, TRUE to avoid FQID update in the IC;
152926 + In such a case FQID after KG will be the default FQID
152927 + defined for the relevant port, or the FQID defined by CC
152928 + in cases where CC was the previous engine. */
152929 + uint32_t base_fqid; /**< Base FQID; Relevant only if bypass_fqid_generation = FALSE;
152930 + If hash is used and an even distribution is expected
152931 + according to hash_distribution_num_of_fqids, base_fqid must be aligned to
152932 + hash_distribution_num_of_fqids. */
152933 + uint8_t num_of_used_extracted_ors;
152934 + /**< Number of FQID masks listed in extracted_ors array*/
152935 + ioc_fm_pcd_kg_extracted_or_params_t extracted_ors[IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS];
152936 + /**< IOC_FM_PCD_KG_NUM_OF_GENERIC_REGS
152937 + registers are shared between qid_masks
152938 + functionality and some of the extraction
152939 + actions; Normally only some will be used
152940 + for qid_mask. Driver will return error if
152941 + resource is full at initialization time. */
152942 +#if DPAA_VERSION >= 11
152943 + bool override_storage_profile;
152944 + /**< TRUE if KeyGen override previously decided storage profile */
152945 + ioc_fm_pcd_kg_storage_profile_t storage_profile;/**< Used when override_storage_profile=TRUE */
152946 +#endif /* DPAA_VERSION >= 11 */
152947 + ioc_fm_pcd_engine next_engine; /**< may be BMI, PLCR or CC */
152948 + union { /**< depends on nextEngine */
152949 + ioc_fm_pcd_done_action done_action; /**< Used when next engine is BMI (done) */
152950 + ioc_fm_pcd_kg_plcr_profile_t plcr_profile; /**< Used when next engine is PLCR */
152951 + ioc_fm_pcd_kg_cc_t cc; /**< Used when next engine is CC */
152952 + } kg_next_engine_params;
152953 + ioc_fm_pcd_kg_scheme_counter_t scheme_counter; /**< A structure of parameters for updating
152954 + the scheme counter */
152955 + void *id; /**< Returns the scheme Id to be used */
152956 +} ioc_fm_pcd_kg_scheme_params_t;
152957 +
152958 +/**************************************************************************//**
152959 + @Collection
152960 +*//***************************************************************************/
152961 +#if DPAA_VERSION >= 11
152962 +#define IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR 10 /* Maximal supported number of frame length ranges */
152963 +#define IOC_FM_PCD_CC_STATS_FLR_SIZE 2 /* Size in bytes of a frame length range limit */
152964 +#endif /* DPAA_VERSION >= 11 */
152965 +#define IOC_FM_PCD_CC_STATS_FLR_COUNT_SIZE 4 /* Size in bytes of a frame length range counter */
152966 +/* @} */
152967 +
152968 +/**************************************************************************//**
152969 + @Description Parameters for defining CC as the next engine after a CC node.
152970 + (Must match struct t_FmPcdCcNextCcParams defined in fm_pcd_ext.h)
152971 +*//***************************************************************************/
152972 +typedef struct ioc_fm_pcd_cc_next_cc_params_t {
152973 + void *cc_node_id; /**< Id of the next CC node */
152974 +} ioc_fm_pcd_cc_next_cc_params_t;
152975 +
152976 +#if DPAA_VERSION >= 11
152977 +/**************************************************************************//**
152978 + @Description A structure for defining Frame Replicator as the next engine after a CC node.
152979 + (Must match struct t_FmPcdCcNextFrParams defined in fm_pcd_ext.h)
152980 +*//***************************************************************************/
152981 +typedef struct ioc_fm_pcd_cc_next_fr_params_t {
152982 + void* frm_replic_id; /**< The id of the next frame replicator group */
152983 +} ioc_fm_pcd_cc_next_fr_params_t;
152984 +#endif /* DPAA_VERSION >= 11 */
152985 +
152986 +/**************************************************************************//**
152987 + @Description A structure for defining PLCR params when PLCR is the
152988 + next engine after a CC node
152989 + (Must match struct t_FmPcdCcNextPlcrParams defined in fm_pcd_ext.h)
152990 +*//***************************************************************************/
152991 +typedef struct ioc_fm_pcd_cc_next_plcr_params_t {
152992 + bool override_params; /**< TRUE if CC override previously decided parameters*/
152993 + bool shared_profile; /**< Relevant only if overrideParams=TRUE:
152994 + TRUE if this profile is shared between ports */
152995 + uint16_t new_relative_profile_id; /**< Relevant only if overrideParams=TRUE:
152996 + (otherwise profile id is taken from keygen);
152997 + This parameter should indicate the policer
152998 + profile offset within the port's
152999 + policer profiles or from SHARED window.*/
153000 + uint32_t new_fqid; /**< Relevant only if overrideParams=TRUE:
153001 + FQID for enquing the frame;
153002 + In earlier chips if policer next engine is KEYGEN,
153003 + this parameter can be 0, because the KEYGEN always decides
153004 + the enqueue FQID.*/
153005 +#if DPAA_VERSION >= 11
153006 + uint8_t new_relative_storage_profile_id;
153007 + /**< Indicates the relative storage profile offset within
153008 + the port's storage profiles window;
153009 + Relevant only if the port was configured with VSP. */
153010 +#endif /* DPAA_VERSION >= 11 */
153011 +} ioc_fm_pcd_cc_next_plcr_params_t;
153012 +
153013 +/**************************************************************************//**
153014 + @Description A structure for defining enqueue params when BMI is the
153015 + next engine after a CC node
153016 + (Must match struct t_FmPcdCcNextEnqueueParams defined in fm_pcd_ext.h)
153017 +*//***************************************************************************/
153018 +typedef struct ioc_fm_pcd_cc_next_enqueue_params_t {
153019 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
153020 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
153021 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME */
153022 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
153023 + (otherwise FQID is taken from KeyGen),
153024 + relevant if action = e_IOC_FM_PCD_ENQ_FRAME*/
153025 +#if DPAA_VERSION >= 11
153026 + uint8_t new_relative_storage_profile_id;
153027 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
153028 + storage profile offset within the port's storage profiles
153029 + window; Relevant only if the port was configured with VSP. */
153030 +#endif /* DPAA_VERSION >= 11 */
153031 +
153032 +} ioc_fm_pcd_cc_next_enqueue_params_t;
153033 +
153034 +/**************************************************************************//**
153035 + @Description A structure for defining KG params when KG is the next engine after a CC node
153036 + (Must match struct t_FmPcdCcNextKgParams defined in fm_pcd_ext.h)
153037 +*//***************************************************************************/
153038 +typedef struct ioc_fm_pcd_cc_next_kg_params_t {
153039 + bool override_fqid; /**< TRUE if CC override previously decided fqid and vspid,
153040 + Note - this parameters are irrelevant for earlier chips */
153041 + uint32_t new_fqid; /**< Valid if overrideFqid=TRUE, FQID for enqueuing the frame
153042 + (otherwise FQID is taken from KeyGen),
153043 + Note - this parameters are irrelevant for earlier chips */
153044 +#if DPAA_VERSION >= 11
153045 + uint8_t new_relative_storage_profile_id;
153046 + /**< Valid if override_fqid=TRUE, Indicates the relative virtual
153047 + storage profile offset within the port's storage profiles
153048 + window; Relevant only if the port was configured with VSP. */
153049 +#endif /* DPAA_VERSION >= 11 */
153050 + void *p_direct_scheme; /**< Direct scheme id to go to. */
153051 +} ioc_fm_pcd_cc_next_kg_params_t;
153052 +
153053 +/**************************************************************************//**
153054 + @Description Parameters for defining the next engine after a CC node.
153055 + (Must match struct t_FmPcdCcNextEngineParams defined in fm_pcd_ext.h)
153056 +*//***************************************************************************/
153057 +typedef struct ioc_fm_pcd_cc_next_engine_params_t {
153058 + ioc_fm_pcd_engine next_engine; /**< User has to initialize parameters
153059 + according to nextEngine definition */
153060 + union {
153061 + ioc_fm_pcd_cc_next_cc_params_t cc_params; /**< Parameters in case next engine is CC */
153062 + ioc_fm_pcd_cc_next_plcr_params_t plcr_params; /**< Parameters in case next engine is PLCR */
153063 + ioc_fm_pcd_cc_next_enqueue_params_t enqueue_params; /**< Parameters in case next engine is BMI */
153064 + ioc_fm_pcd_cc_next_kg_params_t kg_params; /**< Parameters in case next engine is KG */
153065 +#if DPAA_VERSION >= 11
153066 + ioc_fm_pcd_cc_next_fr_params_t fr_params; /**< Parameters in case next engine is FR */
153067 +#endif /* DPAA_VERSION >= 11 */
153068 + } params; /**< Union used for all the next-engine parameters options */
153069 + void *manip_id; /**< Handle to Manipulation object.
153070 + Relevant if next engine is of type result
153071 + (e_IOC_FM_PCD_PLCR, e_IOC_FM_PCD_KG, e_IOC_FM_PCD_DONE) */
153072 + bool statistics_en; /**< If TRUE, statistics counters are incremented
153073 + for each frame passing through this
153074 + Coarse Classification entry. */
153075 +} ioc_fm_pcd_cc_next_engine_params_t;
153076 +
153077 +/**************************************************************************//**
153078 + @Description Parameters for defining a single CC key
153079 +*//***************************************************************************/
153080 +typedef struct ioc_fm_pcd_cc_key_params_t {
153081 + uint8_t *p_key; /**< pointer to the key of the size defined in key_size */
153082 + uint8_t *p_mask; /**< pointer to the Mask per key of the size defined
153083 + in keySize. p_key and p_mask (if defined) has to be
153084 + of the same size defined in the key_size */
153085 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
153086 + /**< parameters for the next for the defined Key in p_key */
153087 +
153088 +} ioc_fm_pcd_cc_key_params_t;
153089 +
153090 +/**************************************************************************//**
153091 + @Description Parameters for defining CC keys parameters
153092 + The driver supports two methods for CC node allocation: dynamic and static.
153093 + Static mode was created in order to prevent runtime alloc/free
153094 + of FMan memory (MURAM), which may cause fragmentation; in this mode,
153095 + the driver automatically allocates the memory according to
153096 + 'max_num_of_keys' parameter. The driver calculates the maximal memory
153097 + size that may be used for this CC-Node taking into consideration
153098 + 'mask_support' and 'statistics_mode' parameters.
153099 + When 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP in the extraction
153100 + parameters of this node, 'max_num_of_keys' must be equal to 'num_of_keys'.
153101 + In dynamic mode, 'max_num_of_keys' must be zero. At initialization,
153102 + all required structures are allocated according to 'num_of_keys'
153103 + parameter. During runtime modification, these structures are
153104 + re-allocated according to the updated number of keys.
153105 +
153106 + Please note that 'action' and 'ic_indx_mask' mentioned in the
153107 + specific parameter explanations are passed in the extraction
153108 + parameters of the node (fields of extractccparams.extractnonhdr).
153109 +*//***************************************************************************/
153110 +typedef struct ioc_keys_params_t {
153111 + uint16_t max_num_of_keys;/**< Maximum number of keys that will (ever) be used in this CC-Node;
153112 + A value of zero may be used for dynamic memory allocation. */
153113 + bool mask_support; /**< This parameter is relevant only if a node is initialized with
153114 + action = e_IOC_FM_PCD_ACTION_EXACT_MATCH and max_num_of_keys > 0;
153115 + Should be TRUE to reserve table memory for key masks, even if
153116 + initial keys do not contain masks, or if the node was initialized
153117 + as 'empty' (without keys); this will allow user to add keys with
153118 + masks at runtime. */
153119 + ioc_fm_pcd_cc_stats_mode statistics_mode;/**< Determines the supported statistics mode for all node's keys.
153120 + To enable statistics gathering, statistics should be enabled per
153121 + every key, using 'statistics_en' in next engine parameters structure
153122 + of that key;
153123 + If 'max_num_of_keys' is set, all required structures will be
153124 + preallocated for all keys. */
153125 +#if (DPAA_VERSION >= 11)
153126 + uint16_t frame_length_ranges[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
153127 + /**< Relevant only for 'RMON' statistics mode
153128 + (this feature is supported only on B4860 device);
153129 + Holds a list of programmable thresholds. For each received frame,
153130 + its length in bytes is examined against these range thresholds and
153131 + the appropriate counter is incremented by 1. For example, to belong
153132 + to range i, the following should hold:
153133 + range i-1 threshold < frame length <= range i threshold
153134 + Each range threshold must be larger then its preceding range
153135 + threshold. Last range threshold must be 0xFFFF. */
153136 +#endif /* (DPAA_VERSION >= 11) */
153137 + uint16_t num_of_keys; /**< Number of initial keys;
153138 + Note that in case of 'action' = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP,
153139 + this field should be power-of-2 of the number of bits that are
153140 + set in 'ic_indx_mask'. */
153141 + uint8_t key_size; /**< Size of key - for extraction of type FULL_FIELD, 'key_size' has
153142 + to be the standard size of the selected key; For other extraction
153143 + types, 'key_size' has to be as size of extraction; When 'action' =
153144 + e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP, 'keySize' must be 2. */
153145 + ioc_fm_pcd_cc_key_params_t key_params[IOC_FM_PCD_MAX_NUM_OF_KEYS];
153146 + /**< An array with 'num_of_keys' entries, each entry specifies the
153147 + corresponding key parameters;
153148 + When 'action' = e_IOC_FM_PCD_ACTION_EXACT_MATCH, this value must not
153149 + exceed 255 (IOC_FM_PCD_MAX_NUM_OF_KEYS-1) as the last entry is saved
153150 + for the 'miss' entry. */
153151 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
153152 + /**< Parameters for defining the next engine when a key is not matched;
153153 + Not relevant if action = e_IOC_FM_PCD_ACTION_INDEXED_LOOKUP. */
153154 +} ioc_keys_params_t;
153155 +
153156 +/**************************************************************************//**
153157 + @Description Parameters for defining a CC node
153158 +*//***************************************************************************/
153159 +typedef struct ioc_fm_pcd_cc_node_params_t {
153160 + ioc_fm_pcd_extract_entry_t extract_cc_params; /**< Extraction parameters */
153161 + ioc_keys_params_t keys_params; /**< Keys definition matching the selected extraction */
153162 + void *id; /**< Output parameter; returns the CC node Id to be used */
153163 +} ioc_fm_pcd_cc_node_params_t;
153164 +
153165 +/**************************************************************************//**
153166 + @Description Parameters for defining a hash table
153167 + (Must match struct t_FmPcdHashTableParams defined in fm_pcd_ext.h)
153168 +*//***************************************************************************/
153169 +typedef struct ioc_fm_pcd_hash_table_params_t {
153170 + uint16_t max_num_of_keys; /**< Maximum Number Of Keys that will (ever) be used in this Hash-table */
153171 + ioc_fm_pcd_cc_stats_mode statistics_mode; /**< If not e_IOC_FM_PCD_CC_STATS_MODE_NONE, the required structures for the
153172 + requested statistics mode will be allocated according to max_num_of_keys. */
153173 + uint8_t kg_hash_shift; /**< KG-Hash-shift as it was configured in the KG-scheme
153174 + that leads to this hash-table. */
153175 + uint16_t hash_res_mask; /**< Mask that will be used on the hash-result;
153176 + The number-of-sets for this hash will be calculated
153177 + as (2^(number of bits set in 'hash_res_mask'));
153178 + The 4 lower bits must be cleared. */
153179 + uint8_t hash_shift; /**< Byte offset from the beginning of the KeyGen hash result to the
153180 + 2-bytes to be used as hash index. */
153181 + uint8_t match_key_size; /**< Size of the exact match keys held by the hash buckets */
153182 +
153183 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params_for_miss;
153184 + /**< Parameters for defining the next engine when a key is not matched */
153185 + void *id;
153186 +} ioc_fm_pcd_hash_table_params_t;
153187 +
153188 +/**************************************************************************//**
153189 + @Description A structure with the arguments for the FM_PCD_HashTableAddKey ioctl() call
153190 +*//***************************************************************************/
153191 +typedef struct ioc_fm_pcd_hash_table_add_key_params_t {
153192 + void *p_hash_tbl;
153193 + uint8_t key_size;
153194 + ioc_fm_pcd_cc_key_params_t key_params;
153195 +} ioc_fm_pcd_hash_table_add_key_params_t;
153196 +
153197 +/**************************************************************************//**
153198 + @Description Parameters for defining a CC tree group.
153199 +
153200 + This structure defines a CC group in terms of NetEnv units
153201 + and the action to be taken in each case. The unit_ids list must
153202 + be given in order from low to high indices.
153203 +
153204 + ioc_fm_pcd_cc_next_engine_params_t is a list of 2^num_of_distinction_units
153205 + structures where each defines the next action to be taken for
153206 + each units combination. for example:
153207 + num_of_distinction_units = 2
153208 + unit_ids = {1,3}
153209 + next_engine_per_entries_in_grp[0] = ioc_fm_pcd_cc_next_engine_params_t for the case that
153210 + unit 1 - not found; unit 3 - not found;
153211 + next_engine_per_entries_in_grp[1] = ioc_fm_pcd_cc_next_engine_params_t for the case that
153212 + unit 1 - not found; unit 3 - found;
153213 + next_engine_per_entries_in_grp[2] = ioc_fm_pcd_cc_next_engine_params_t for the case that
153214 + unit 1 - found; unit 3 - not found;
153215 + next_engine_per_entries_in_grp[3] = ioc_fm_pcd_cc_next_engine_params_t for the case that
153216 + unit 1 - found; unit 3 - found;
153217 +*//***************************************************************************/
153218 +typedef struct ioc_fm_pcd_cc_grp_params_t {
153219 + uint8_t num_of_distinction_units; /**< Up to 4 */
153220 + uint8_t unit_ids [IOC_FM_PCD_MAX_NUM_OF_CC_UNITS];
153221 + /**< Indexes of the units as defined in
153222 + FM_PCD_NetEnvCharacteristicsSet() */
153223 + ioc_fm_pcd_cc_next_engine_params_t next_engine_per_entries_in_grp[IOC_FM_PCD_MAX_NUM_OF_CC_ENTRIES_IN_GRP];
153224 + /**< Maximum entries per group is 16 */
153225 +} ioc_fm_pcd_cc_grp_params_t;
153226 +
153227 +/**************************************************************************//**
153228 + @Description Parameters for defining the CC tree groups
153229 + (Must match struct t_FmPcdCcTreeParams defined in fm_pcd_ext.h)
153230 +*//***************************************************************************/
153231 +typedef struct ioc_fm_pcd_cc_tree_params_t {
153232 + void *net_env_id; /**< Id of the Network Environment as returned
153233 + by FM_PCD_NetEnvCharacteristicsSet() */
153234 + uint8_t num_of_groups; /**< Number of CC groups within the CC tree */
153235 + ioc_fm_pcd_cc_grp_params_t fm_pcd_cc_group_params [IOC_FM_PCD_MAX_NUM_OF_CC_GROUPS];
153236 + /**< Parameters for each group. */
153237 + void *id; /**< Output parameter; Returns the tree Id to be used */
153238 +} ioc_fm_pcd_cc_tree_params_t;
153239 +
153240 +/**************************************************************************//**
153241 + @Description Parameters for defining policer byte rate
153242 +*//***************************************************************************/
153243 +typedef struct ioc_fm_pcd_plcr_byte_rate_mode_param_t {
153244 + ioc_fm_pcd_plcr_frame_length_select frame_length_selection; /**< Frame length selection */
153245 + ioc_fm_pcd_plcr_roll_back_frame_select roll_back_frame_selection; /**< relevant option only e_IOC_FM_PCD_PLCR_L2_FRM_LEN,
153246 + e_IOC_FM_PCD_PLCR_FULL_FRM_LEN */
153247 +} ioc_fm_pcd_plcr_byte_rate_mode_param_t;
153248 +
153249 +/**************************************************************************//**
153250 + @Description Parameters for defining the policer profile (based on
153251 + RFC-2698 or RFC-4115 attributes).
153252 +*//***************************************************************************/
153253 +typedef struct ioc_fm_pcd_plcr_non_passthrough_alg_param_t {
153254 + ioc_fm_pcd_plcr_rate_mode rate_mode; /**< Byte / Packet */
153255 + ioc_fm_pcd_plcr_byte_rate_mode_param_t byte_mode_param; /**< Valid for Byte NULL for Packet */
153256 + uint32_t committed_info_rate; /**< KBits/Sec or Packets/Sec */
153257 + uint32_t committed_burst_size; /**< KBits or Packets */
153258 + uint32_t peak_or_excess_info_rate; /**< KBits/Sec or Packets/Sec */
153259 + uint32_t peak_or_excess_burst_size; /**< KBits or Packets */
153260 +} ioc_fm_pcd_plcr_non_passthrough_alg_param_t;
153261 +
153262 +/**************************************************************************//**
153263 + @Description Parameters for defining the next engine after policer
153264 +*//***************************************************************************/
153265 +typedef union ioc_fm_pcd_plcr_next_engine_params_u {
153266 + ioc_fm_pcd_done_action action; /**< Action - when next engine is BMI (done) */
153267 + void *p_profile; /**< Policer profile handle - used when next engine
153268 + is PLCR, must be a SHARED profile */
153269 + void *p_direct_scheme; /**< Direct scheme select - when next engine is Keygen */
153270 +} ioc_fm_pcd_plcr_next_engine_params_u;
153271 +
153272 +typedef struct ioc_fm_pcd_port_params_t {
153273 + ioc_fm_port_type port_type; /**< Type of port for this profile */
153274 + uint8_t port_id; /**< FM-Port id of port for this profile */
153275 +} ioc_fm_pcd_port_params_t;
153276 +
153277 +/**************************************************************************//**
153278 + @Description Parameters for defining the policer profile entry
153279 + (Must match struct t_FmPcdPlcrProfileParams defined in fm_pcd_ext.h)
153280 +*//***************************************************************************/
153281 +typedef struct ioc_fm_pcd_plcr_profile_params_t {
153282 + bool modify; /**< TRUE to change an existing profile */
153283 + union {
153284 + struct {
153285 + ioc_fm_pcd_profile_type_selection profile_type; /**< Type of policer profile */
153286 + ioc_fm_pcd_port_params_t *p_fm_port; /**< Relevant for per-port profiles only */
153287 + uint16_t relative_profile_id; /**< Profile id - relative to shared group or to port */
153288 + } new_params; /**< Use it when modify = FALSE */
153289 + void *p_profile; /**< A handle to a profile - use it when modify=TRUE */
153290 + } profile_select;
153291 + ioc_fm_pcd_plcr_algorithm_selection alg_selection; /**< Profile Algorithm PASS_THROUGH, RFC_2698, RFC_4115 */
153292 + ioc_fm_pcd_plcr_color_mode color_mode; /**< COLOR_BLIND, COLOR_AWARE */
153293 +
153294 + union {
153295 + ioc_fm_pcd_plcr_color dflt_color; /**< For Color-Blind Pass-Through mode; the policer will re-color
153296 + any incoming packet with the default value. */
153297 + ioc_fm_pcd_plcr_color override; /**< For Color-Aware modes; the profile response to a
153298 + pre-color value of 2'b11. */
153299 + } color;
153300 +
153301 + ioc_fm_pcd_plcr_non_passthrough_alg_param_t non_passthrough_alg_param; /**< RFC2698 or RFC4115 parameters */
153302 +
153303 + ioc_fm_pcd_engine next_engine_on_green; /**< Next engine for green-colored frames */
153304 + ioc_fm_pcd_plcr_next_engine_params_u params_on_green; /**< Next engine parameters for green-colored frames */
153305 +
153306 + ioc_fm_pcd_engine next_engine_on_yellow; /**< Next engine for yellow-colored frames */
153307 + ioc_fm_pcd_plcr_next_engine_params_u params_on_yellow; /**< Next engine parameters for yellow-colored frames */
153308 +
153309 + ioc_fm_pcd_engine next_engine_on_red; /**< Next engine for red-colored frames */
153310 + ioc_fm_pcd_plcr_next_engine_params_u params_on_red; /**< Next engine parameters for red-colored frames */
153311 +
153312 + bool trap_profile_on_flow_A; /**< Obsolete - do not use */
153313 + bool trap_profile_on_flow_B; /**< Obsolete - do not use */
153314 + bool trap_profile_on_flow_C; /**< Obsolete - do not use */
153315 +
153316 + void *id; /**< output parameter; Returns the profile Id to be used */
153317 +} ioc_fm_pcd_plcr_profile_params_t;
153318 +
153319 +/**************************************************************************//**
153320 + @Description A structure for modifying CC tree next engine
153321 +*//***************************************************************************/
153322 +typedef struct ioc_fm_pcd_cc_tree_modify_next_engine_params_t {
153323 + void *id; /**< CC tree Id to be used */
153324 + uint8_t grp_indx; /**< A Group index in the tree */
153325 + uint8_t indx; /**< Entry index in the group defined by grp_index */
153326 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
153327 + /**< Parameters for the next for the defined Key in the p_Key */
153328 +} ioc_fm_pcd_cc_tree_modify_next_engine_params_t;
153329 +
153330 +/**************************************************************************//**
153331 + @Description A structure for modifying CC node next engine
153332 +*//***************************************************************************/
153333 +typedef struct ioc_fm_pcd_cc_node_modify_next_engine_params_t {
153334 + void *id; /**< CC node Id to be used */
153335 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
153336 + NOTE: This parameter is IGNORED for miss-key! */
153337 + uint8_t key_size; /**< Key size of added key */
153338 + ioc_fm_pcd_cc_next_engine_params_t cc_next_engine_params;
153339 + /**< parameters for the next for the defined Key in the p_Key */
153340 +} ioc_fm_pcd_cc_node_modify_next_engine_params_t;
153341 +
153342 +/**************************************************************************//**
153343 + @Description A structure for remove CC node key
153344 +*//***************************************************************************/
153345 +typedef struct ioc_fm_pcd_cc_node_remove_key_params_t {
153346 + void *id; /**< CC node Id to be used */
153347 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
153348 + NOTE: This parameter is IGNORED for miss-key! */
153349 +} ioc_fm_pcd_cc_node_remove_key_params_t;
153350 +
153351 +/**************************************************************************//**
153352 + @Description A structure for modifying CC node key and next engine
153353 +*//***************************************************************************/
153354 +typedef struct ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t {
153355 + void *id; /**< CC node Id to be used */
153356 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
153357 + NOTE: This parameter is IGNORED for miss-key! */
153358 + uint8_t key_size; /**< Key size of added key */
153359 + ioc_fm_pcd_cc_key_params_t key_params; /**< it's array with numOfKeys entries each entry in
153360 + the array of the type ioc_fm_pcd_cc_key_params_t */
153361 +} ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t;
153362 +
153363 +/**************************************************************************//**
153364 + @Description A structure for modifying CC node key
153365 +*//***************************************************************************/
153366 +typedef struct ioc_fm_pcd_cc_node_modify_key_params_t {
153367 + void *id; /**< CC node Id to be used */
153368 + uint16_t key_indx; /**< Key index for Next Engine Params modifications;
153369 + NOTE: This parameter is IGNORED for miss-key! */
153370 + uint8_t key_size; /**< Key size of added key */
153371 + uint8_t *p_key; /**< Pointer to the key of the size defined in key_size */
153372 + uint8_t *p_mask; /**< Pointer to the Mask per key of the size defined
153373 + in keySize. p_Key and p_Mask (if defined) have to be
153374 + of the same size as defined in the key_size */
153375 +} ioc_fm_pcd_cc_node_modify_key_params_t;
153376 +
153377 +/**************************************************************************//**
153378 + @Description A structure with the arguments for the FM_PCD_HashTableRemoveKey ioctl() call
153379 +*//***************************************************************************/
153380 +typedef struct ioc_fm_pcd_hash_table_remove_key_params_t {
153381 + void *p_hash_tbl; /**< The id of the hash table */
153382 + uint8_t key_size; /**< The size of the key to remove */
153383 + uint8_t *p_key; /**< Pointer to the key to remove */
153384 +} ioc_fm_pcd_hash_table_remove_key_params_t;
153385 +
153386 +/**************************************************************************//**
153387 + @Description Parameters for selecting a location for requested manipulation
153388 +*//***************************************************************************/
153389 +typedef struct ioc_fm_manip_hdr_info_t {
153390 + ioc_net_header_type hdr; /**< Header selection */
153391 + ioc_fm_pcd_hdr_index hdr_index; /**< Relevant only for MPLS, VLAN and tunneled IP. Otherwise should be cleared. */
153392 + bool by_field; /**< TRUE if the location of manipulation is according to some field in the specific header*/
153393 + ioc_fm_pcd_fields_u full_field; /**< Relevant only when by_field = TRUE: Extract field */
153394 +} ioc_fm_manip_hdr_info_t;
153395 +
153396 +/**************************************************************************//**
153397 + @Description Parameters for defining header removal by header type
153398 +*//***************************************************************************/
153399 +typedef struct ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t {
153400 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_type type; /**< Selection of header removal location */
153401 + union {
153402 +#if ((DPAA_VERSION == 10) && defined(FM_CAPWAP_SUPPORT))
153403 + struct {
153404 + bool include;/**< If FALSE, remove until the specified header (not including the header);
153405 + If TRUE, remove also the specified header. */
153406 + ioc_fm_manip_hdr_info_t hdr_info;
153407 + } from_start_by_hdr; /**< Relevant when type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
153408 +#endif /* FM_CAPWAP_SUPPORT */
153409 +#if (DPAA_VERSION >= 11)
153410 + ioc_fm_manip_hdr_info_t hdr_info; /**< Relevant when type = e_FM_PCD_MANIP_RMV_BY_HDR_FROM_START */
153411 +#endif /* (DPAA_VERSION >= 11) */
153412 + ioc_fm_pcd_manip_hdr_rmv_specific_l2 specific_l2;/**< Relevant when type = e_IOC_FM_PCD_MANIP_BY_HDR_SPECIFIC_L2;
153413 + Defines which L2 headers to remove. */
153414 + } u;
153415 +} ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t;
153416 +
153417 +/**************************************************************************//**
153418 + @Description Parameters for configuring IP fragmentation manipulation
153419 +*//***************************************************************************/
153420 +typedef struct ioc_fm_pcd_manip_frag_ip_params_t {
153421 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
153422 + IP fragmentation will be executed.*/
153423 +#if DPAA_VERSION == 10
153424 + uint8_t scratch_bpid; /**< Absolute buffer pool id according to BM configuration.*/
153425 +#endif /* DPAA_VERSION == 10 */
153426 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
153427 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
153428 + received frame's buffer. */
153429 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
153430 + This parameter is relevant when 'sg_bpid_en=TRUE';
153431 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
153432 + of this pool need to be allocated in the same memory area as the received buffers.
153433 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
153434 + mutual to all these sources. */
153435 + ioc_fm_pcd_manip_dont_frag_action dont_frag_action; /**< Dont Fragment Action - If an IP packet is larger
153436 + than MTU and its DF bit is set, then this field will
153437 + determine the action to be taken.*/
153438 +} ioc_fm_pcd_manip_frag_ip_params_t;
153439 +
153440 +/**************************************************************************//**
153441 + @Description Parameters for configuring IP reassembly manipulation.
153442 +
153443 + This is a common structure for both IPv4 and IPv6 reassembly
153444 + manipulation. For reassembly of both IPv4 and IPv6, make sure to
153445 + set the 'hdr' field in ioc_fm_pcd_manip_reassem_params_t to IOC_HEADER_TYPE_IPv6.
153446 +*//***************************************************************************/
153447 +typedef struct ioc_fm_pcd_manip_reassem_ip_params_t {
153448 + uint8_t relative_scheme_id[2]; /**< Partition relative scheme id:
153449 + relativeSchemeId[0] - Relative scheme ID for IPV4 Reassembly manipulation;
153450 + relativeSchemeId[1] - Relative scheme ID for IPV6 Reassembly manipulation;
153451 + NOTE: The following comment is relevant only for FMAN v2 devices:
153452 + Relative scheme ID for IPv4/IPv6 Reassembly manipulation must be smaller than
153453 + the user schemes id to ensure that the reassembly's schemes will be first match.
153454 + The remaining schemes, if defined, should have higher relative scheme ID. */
153455 +#if DPAA_VERSION >= 11
153456 + uint32_t non_consistent_sp_fqid; /**< In case that other fragments of the frame corresponds to different storage
153457 + profile than the opening fragment (Non-Consistent-SP state)
153458 + then one of two possible scenarios occurs:
153459 + if 'nonConsistentSpFqid != 0', the reassembled frame will be enqueued to
153460 + this fqid, otherwise a 'Non Consistent SP' bit will be set in the FD[status].*/
153461 +#else
153462 + uint8_t sg_bpid; /**< Buffer pool id for the S/G frame created by the reassembly process */
153463 +#endif /* DPAA_VERSION >= 11 */
153464 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
153465 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
153466 + uint16_t min_frag_size[2]; /**< Minimum fragment size:
153467 + minFragSize[0] - for ipv4, minFragSize[1] - for ipv6 */
153468 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry[2];
153469 + /**< Number of frames per hash entry needed for reassembly process:
153470 + numOfFramesPerHashEntry[0] - for ipv4 (max value is e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH);
153471 + numOfFramesPerHashEntry[1] - for ipv6 (max value is e_IOC_FM_PCD_MANIP_SIX_WAYS_HASH). */
153472 + uint16_t max_num_frames_in_process;/**< Number of frames which can be processed by Reassembly in the same time;
153473 + Must be power of 2;
153474 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_FOUR_WAYS_HASH,
153475 + maxNumFramesInProcess has to be in the range of 4 - 512;
153476 + In the case numOfFramesPerHashEntry == e_IOC_FM_PCD_MANIP_EIGHT_WAYS_HASH,
153477 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
153478 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
153479 + uint32_t fqid_for_time_out_frames;/**< FQID in which time out frames will enqueue during Time Out Process */
153480 + uint32_t timeout_threshold_for_reassm_process;
153481 + /**< Represents the time interval in microseconds which defines
153482 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
153483 +} ioc_fm_pcd_manip_reassem_ip_params_t;
153484 +
153485 +/**************************************************************************//**
153486 + @Description Parameters for defining IPSEC manipulation
153487 +*//***************************************************************************/
153488 +typedef struct ioc_fm_pcd_manip_special_offload_ipsec_params_t {
153489 + bool decryption; /**< TRUE if being used in decryption direction;
153490 + FALSE if being used in encryption direction. */
153491 + bool ecn_copy; /**< TRUE to copy the ECN bits from inner/outer to outer/inner
153492 + (direction depends on the 'decryption' field). */
153493 + bool dscp_copy; /**< TRUE to copy the DSCP bits from inner/outer to outer/inner
153494 + (direction depends on the 'decryption' field). */
153495 + bool variable_ip_hdr_len; /**< TRUE for supporting variable IP header length in decryption. */
153496 + bool variable_ip_version; /**< TRUE for supporting both IP version on the same SA in encryption */
153497 + uint8_t outer_ip_hdr_len; /**< If 'variable_ip_version == TRUE' than this field must be set to non-zero value;
153498 + It is specifies the length of the outer IP header that was configured in the
153499 + corresponding SA. */
153500 + uint16_t arw_size; /**< if <> '0' then will perform ARW check for this SA;
153501 + The value must be a multiplication of 16 */
153502 + void *arw_addr; /**< if arwSize <> '0' then this field must be set to non-zero value;
153503 + MUST be allocated from FMAN's MURAM that the post-sec op-port belong
153504 + Must be 4B aligned. Required MURAM size is '(NEXT_POWER_OF_2(arwSize+32))/8+4' Bytes */
153505 +} ioc_fm_pcd_manip_special_offload_ipsec_params_t;
153506 +
153507 +#if (DPAA_VERSION >= 11)
153508 +/**************************************************************************//**
153509 + @Description Parameters for configuring CAPWAP fragmentation manipulation
153510 +
153511 + Restrictions:
153512 + - Maximum number of fragments per frame is 16.
153513 + - Transmit confirmation is not supported.
153514 + - Fragmentation nodes must be set as the last PCD action (i.e. the
153515 + corresponding CC node key must have next engine set to e_FM_PCD_DONE).
153516 + - Only BMan buffers shall be used for frames to be fragmented.
153517 + - NOTE: The following comment is relevant only for FMAN v3 devices: IPF
153518 + does not support VSP. Therefore, on the same port where we have IPF we
153519 + cannot support VSP.
153520 +*//***************************************************************************/
153521 +typedef struct ioc_fm_pcd_manip_frag_capwap_params_t {
153522 + uint16_t size_for_fragmentation; /**< If length of the frame is greater than this value,
153523 + CAPWAP fragmentation will be executed.*/
153524 + bool sg_bpid_en; /**< Enable a dedicated buffer pool id for the Scatter/Gather buffer allocation;
153525 + If disabled, the Scatter/Gather buffer will be allocated from the same pool as the
153526 + received frame's buffer. */
153527 + uint8_t sg_bpid; /**< Scatter/Gather buffer pool id;
153528 + This parameters is relevant when 'sgBpidEn=TRUE';
153529 + Same LIODN number is used for these buffers as for the received frames buffers, so buffers
153530 + of this pool need to be allocated in the same memory area as the received buffers.
153531 + If the received buffers arrive from different sources, the Scatter/Gather BP id should be
153532 + mutual to all these sources. */
153533 + bool compress_mode_en; /**< CAPWAP Header Options Compress Enable mode;
153534 + When this mode is enabled then only the first fragment include the CAPWAP header options
153535 + field (if user provides it in the input frame) and all other fragments exclude the CAPWAP
153536 + options field (CAPWAP header is updated accordingly).*/
153537 +} ioc_fm_pcd_manip_frag_capwap_params_t;
153538 +
153539 +/**************************************************************************//**
153540 + @Description Parameters for configuring CAPWAP reassembly manipulation.
153541 +
153542 + Restrictions:
153543 + - Application must define one scheme to catch the reassembled frames.
153544 + - Maximum number of fragments per frame is 16.
153545 +
153546 +*//***************************************************************************/
153547 +typedef struct ioc_fm_pcd_manip_reassem_capwap_params_t {
153548 + uint8_t relative_scheme_id; /**< Partition relative scheme id;
153549 + NOTE: this id must be smaller than the user schemes id to ensure that the reassembly scheme will be first match;
153550 + Rest schemes, if defined, should have higher relative scheme ID. */
153551 + uint8_t data_mem_id; /**< Memory partition ID for the IPR's external tables structure */
153552 + uint16_t data_liodn_offset; /**< LIODN offset for access the IPR's external tables structure. */
153553 + uint16_t max_reassembled_frame_length;/**< The maximum CAPWAP reassembled frame length in bytes;
153554 + If maxReassembledFrameLength == 0, any successful reassembled frame length is
153555 + considered as a valid length;
153556 + if maxReassembledFrameLength > 0, a successful reassembled frame which its length
153557 + exceeds this value is considered as an error frame (FD status[CRE] bit is set). */
153558 + ioc_fm_pcd_manip_reassem_ways_number num_of_frames_per_hash_entry;
153559 + /**< Number of frames per hash entry needed for reassembly process */
153560 + uint16_t max_num_frames_in_process; /**< Number of frames which can be processed by reassembly in the same time;
153561 + Must be power of 2;
153562 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_FOUR_WAYS_HASH,
153563 + maxNumFramesInProcess has to be in the range of 4 - 512;
153564 + In the case numOfFramesPerHashEntry == e_FM_PCD_MANIP_EIGHT_WAYS_HASH,
153565 + maxNumFramesInProcess has to be in the range of 8 - 2048. */
153566 + ioc_fm_pcd_manip_reassem_time_out_mode time_out_mode; /**< Expiration delay initialized by Reassembly process */
153567 + uint32_t fqid_for_time_out_frames; /**< FQID in which time out frames will enqueue during Time Out Process;
153568 + Recommended value for this field is 0; in this way timed-out frames will be discarded */
153569 + uint32_t timeout_threshold_for_reassm_process;
153570 + /**< Represents the time interval in microseconds which defines
153571 + if opened frame (at least one fragment was processed but not all the fragments)is found as too old*/
153572 +} ioc_fm_pcd_manip_reassem_capwap_params_t;
153573 +
153574 +/**************************************************************************//**
153575 + @Description structure for defining CAPWAP manipulation
153576 +*//***************************************************************************/
153577 +typedef struct ioc_fm_pcd_manip_special_offload_capwap_params_t {
153578 + bool dtls; /**< TRUE if continue to SEC DTLS encryption */
153579 + ioc_fm_pcd_manip_hdr_qos_src qos_src; /**< TODO */
153580 +} ioc_fm_pcd_manip_special_offload_capwap_params_t;
153581 +
153582 +#endif /* (DPAA_VERSION >= 11) */
153583 +
153584 +/**************************************************************************//**
153585 + @Description Parameters for defining special offload manipulation
153586 +*//***************************************************************************/
153587 +typedef struct ioc_fm_pcd_manip_special_offload_params_t {
153588 + ioc_fm_pcd_manip_special_offload_type type; /**< Type of special offload manipulation */
153589 + union
153590 + {
153591 + ioc_fm_pcd_manip_special_offload_ipsec_params_t ipsec; /**< Parameters for IPSec; Relevant when
153592 + type = e_IOC_FM_PCD_MANIP_SPECIAL_OFFLOAD_IPSEC */
153593 +
153594 +#if (DPAA_VERSION >= 11)
153595 + ioc_fm_pcd_manip_special_offload_capwap_params_t capwap; /**< Parameters for CAPWAP; Relevant when
153596 + type = e_FM_PCD_MANIP_SPECIAL_OFFLOAD_CAPWAP */
153597 +#endif /* (DPAA_VERSION >= 11) */
153598 + } u;
153599 +} ioc_fm_pcd_manip_special_offload_params_t;
153600 +
153601 +/**************************************************************************//**
153602 + @Description Parameters for defining generic removal manipulation
153603 +*//***************************************************************************/
153604 +typedef struct ioc_fm_pcd_manip_hdr_rmv_generic_params_t {
153605 + uint8_t offset; /**< Offset from beginning of header to the start
153606 + location of the removal */
153607 + uint8_t size; /**< Size of removed section */
153608 +} ioc_fm_pcd_manip_hdr_rmv_generic_params_t;
153609 +
153610 +/**************************************************************************//**
153611 + @Description Parameters for defining insertion manipulation
153612 +*//***************************************************************************/
153613 +typedef struct ioc_fm_pcd_manip_hdr_insrt_t {
153614 + uint8_t size; /**< size of inserted section */
153615 + uint8_t *p_data; /**< data to be inserted */
153616 +} ioc_fm_pcd_manip_hdr_insrt_t;
153617 +
153618 +/**************************************************************************//**
153619 + @Description Parameters for defining generic insertion manipulation
153620 +*//***************************************************************************/
153621 +typedef struct ioc_fm_pcd_manip_hdr_insrt_generic_params_t {
153622 + uint8_t offset; /**< Offset from beginning of header to the start
153623 + location of the insertion */
153624 + uint8_t size; /**< Size of inserted section */
153625 + bool replace; /**< TRUE to override (replace) existing data at
153626 + 'offset', FALSE to insert */
153627 + uint8_t *p_data; /**< Pointer to data to be inserted */
153628 +} ioc_fm_pcd_manip_hdr_insrt_generic_params_t;
153629 +
153630 +/**************************************************************************//**
153631 + @Description Parameters for defining header manipulation VLAN DSCP To Vpri translation
153632 +*//***************************************************************************/
153633 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t {
153634 + uint8_t dscp_to_vpri_table[IOC_FM_PCD_MANIP_DSCP_TO_VLAN_TRANS];
153635 + /**< A table of VPri values for each DSCP value;
153636 + The index is the D_SCP value (0-0x3F) and the
153637 + value is the corresponding VPRI (0-15). */
153638 + uint8_t vpri_def_val; /**< 0-7, Relevant only if if update_type =
153639 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN,
153640 + this field is the Q Tag default value if the
153641 + IP header is not found. */
153642 +} ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t;
153643 +
153644 +/**************************************************************************//**
153645 + @Description Parameters for defining header manipulation VLAN fields updates
153646 +*//***************************************************************************/
153647 +typedef struct ioc_fm_pcd_manip_hdr_field_update_vlan_t {
153648 + ioc_fm_pcd_manip_hdr_field_update_vlan update_type; /**< Selects VLAN update type */
153649 + union {
153650 + uint8_t vpri; /**< 0-7, Relevant only if If update_type =
153651 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN_PRI, this
153652 + is the new VLAN pri. */
153653 + ioc_fm_pcd_manip_hdr_field_update_vlan_dscp_to_vpri_t dscp_to_vpri;
153654 + /**< Parameters structure, Relevant only if update_type =
153655 + e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_DSCP_TO_VLAN. */
153656 + } u;
153657 +} ioc_fm_pcd_manip_hdr_field_update_vlan_t;
153658 +
153659 +/**************************************************************************//**
153660 + @Description Parameters for defining header manipulation IPV4 fields updates
153661 +*//***************************************************************************/
153662 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv4_t {
153663 + ioc_ipv4_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
153664 + uint8_t tos; /**< 8 bit New TOS; Relevant if valid_updates contains
153665 + IOC_HDR_MANIP_IPV4_TOS */
153666 + uint16_t id; /**< 16 bit New IP ID; Relevant only if valid_updates
153667 + contains IOC_HDR_MANIP_IPV4_ID */
153668 + uint32_t src; /**< 32 bit New IP SRC; Relevant only if valid_updates
153669 + contains IOC_HDR_MANIP_IPV4_SRC */
153670 + uint32_t dst; /**< 32 bit New IP DST; Relevant only if valid_updates
153671 + contains IOC_HDR_MANIP_IPV4_DST */
153672 +} ioc_fm_pcd_manip_hdr_field_update_ipv4_t;
153673 +
153674 +/**************************************************************************//**
153675 + @Description Parameters for defining header manipulation IPV6 fields updates
153676 +*//***************************************************************************/
153677 +typedef struct ioc_fm_pcd_manip_hdr_field_update_ipv6_t {
153678 + ioc_ipv6_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
153679 + uint8_t traffic_class; /**< 8 bit New Traffic Class; Relevant if valid_updates contains
153680 + IOC_HDR_MANIP_IPV6_TC */
153681 + uint8_t src[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
153682 + /**< 16 byte new IP SRC; Relevant only if valid_updates
153683 + contains IOC_HDR_MANIP_IPV6_SRC */
153684 + uint8_t dst[IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE];
153685 + /**< 16 byte new IP DST; Relevant only if valid_updates
153686 + contains IOC_HDR_MANIP_IPV6_DST */
153687 +} ioc_fm_pcd_manip_hdr_field_update_ipv6_t;
153688 +
153689 +/**************************************************************************//**
153690 + @Description Parameters for defining header manipulation TCP/UDP fields updates
153691 +*//***************************************************************************/
153692 +typedef struct ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t {
153693 + ioc_tcp_udp_hdr_manip_update_flags_t valid_updates; /**< ORed flag, selecting the required updates */
153694 + uint16_t src; /**< 16 bit New TCP/UDP SRC; Relevant only if valid_updates
153695 + contains IOC_HDR_MANIP_TCP_UDP_SRC */
153696 + uint16_t dst; /**< 16 bit New TCP/UDP DST; Relevant only if valid_updates
153697 + contains IOC_HDR_MANIP_TCP_UDP_DST */
153698 +} ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t;
153699 +
153700 +/**************************************************************************//**
153701 + @Description Parameters for defining header manipulation fields updates
153702 +*//***************************************************************************/
153703 +typedef struct ioc_fm_pcd_manip_hdr_field_update_params_t {
153704 + ioc_fm_pcd_manip_hdr_field_update_type type; /**< Type of header field update manipulation */
153705 + union {
153706 + ioc_fm_pcd_manip_hdr_field_update_vlan_t vlan; /**< Parameters for VLAN update. Relevant when
153707 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_VLAN */
153708 + ioc_fm_pcd_manip_hdr_field_update_ipv4_t ipv4; /**< Parameters for IPv4 update. Relevant when
153709 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV4 */
153710 + ioc_fm_pcd_manip_hdr_field_update_ipv6_t ipv6; /**< Parameters for IPv6 update. Relevant when
153711 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_IPV6 */
153712 + ioc_fm_pcd_manip_hdr_field_update_tcp_udp_t tcp_udp;/**< Parameters for TCP/UDP update. Relevant when
153713 + type = e_IOC_FM_PCD_MANIP_HDR_FIELD_UPDATE_TCP_UDP */
153714 + } u;
153715 +} ioc_fm_pcd_manip_hdr_field_update_params_t;
153716 +
153717 +/**************************************************************************//**
153718 + @Description Parameters for defining custom header manipulation for IP replacement
153719 +*//***************************************************************************/
153720 +typedef struct ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t {
153721 + ioc_fm_pcd_manip_hdr_custom_ip_replace replace_type; /**< Selects replace update type */
153722 + bool dec_ttl_hl; /**< Decrement TTL (IPV4) or Hop limit (IPV6) by 1 */
153723 + bool update_ipv4_id; /**< Relevant when replace_type =
153724 + e_IOC_FM_PCD_MANIP_HDR_CUSTOM_REPLACE_IPV6_BY_IPV4 */
153725 + uint16_t id; /**< 16 bit New IP ID; Relevant only if
153726 + update_ipv4_id = TRUE */
153727 + uint8_t hdr_size; /**< The size of the new IP header */
153728 + uint8_t hdr[IOC_FM_PCD_MANIP_MAX_HDR_SIZE];
153729 + /**< The new IP header */
153730 +} ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t;
153731 +
153732 +/**************************************************************************//**
153733 + @Description Parameters for defining custom header manipulation
153734 +*//***************************************************************************/
153735 +typedef struct ioc_fm_pcd_manip_hdr_custom_params_t {
153736 + ioc_fm_pcd_manip_hdr_custom_type type; /**< Type of header field update manipulation */
153737 + union {
153738 + ioc_fm_pcd_manip_hdr_custom_ip_hdr_replace_t ip_hdr_replace;
153739 + /**< Parameters IP header replacement */
153740 + } u;
153741 +} ioc_fm_pcd_manip_hdr_custom_params_t;
153742 +
153743 +/**************************************************************************//**
153744 + @Description Parameters for defining specific L2 insertion manipulation
153745 +*//***************************************************************************/
153746 +typedef struct ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t {
153747 + ioc_fm_pcd_manip_hdr_insrt_specific_l2 specific_l2; /**< Selects which L2 headers to insert */
153748 + bool update; /**< TRUE to update MPLS header */
153749 + uint8_t size; /**< size of inserted section */
153750 + uint8_t *p_data; /**< data to be inserted */
153751 +} ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t;
153752 +
153753 +#if (DPAA_VERSION >= 11)
153754 +/**************************************************************************//**
153755 + @Description Parameters for defining IP insertion manipulation
153756 +*//***************************************************************************/
153757 +typedef struct ioc_fm_pcd_manip_hdr_insrt_ip_params_t {
153758 + bool calc_l4_checksum; /**< Calculate L4 checksum. */
153759 + ioc_fm_pcd_manip_hdr_qos_mapping_mode mapping_mode; /**< TODO */
153760 + uint8_t last_pid_offset; /**< the offset of the last Protocol within
153761 + the inserted header */
153762 + uint16_t id; /**< 16 bit New IP ID */
153763 + bool dont_frag_overwrite;
153764 + /**< IPv4 only. DF is overwritten with the hash-result next-to-last byte.
153765 + * This byte is configured to be overwritten when RPD is set. */
153766 + uint8_t last_dst_offset;
153767 + /**< IPv6 only. if routing extension exist, user should set the offset of the destination address
153768 + * in order to calculate UDP checksum pseudo header;
153769 + * Otherwise set it to '0'. */
153770 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< size and data to be inserted. */
153771 +} ioc_fm_pcd_manip_hdr_insrt_ip_params_t;
153772 +#endif /* (DPAA_VERSION >= 11) */
153773 +
153774 +/**************************************************************************//**
153775 + @Description Parameters for defining header insertion manipulation by header type
153776 +*//***************************************************************************/
153777 +typedef struct ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t {
153778 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_type type; /**< Selects manipulation type */
153779 + union {
153780 + ioc_fm_pcd_manip_hdr_insrt_specific_l2_params_t specific_l2_params;
153781 + /**< Used when type = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR_SPECIFIC_L2:
153782 + Selects which L2 headers to remove */
153783 +#if (DPAA_VERSION >= 11)
153784 + ioc_fm_pcd_manip_hdr_insrt_ip_params_t ip_params; /**< Used when type = e_FM_PCD_MANIP_INSRT_BY_HDR_IP */
153785 + ioc_fm_pcd_manip_hdr_insrt_t insrt; /**< Used when type is one of e_FM_PCD_MANIP_INSRT_BY_HDR_UDP,
153786 + e_FM_PCD_MANIP_INSRT_BY_HDR_UDP_LITE, or
153787 + e_FM_PCD_MANIP_INSRT_BY_HDR_CAPWAP */
153788 +#endif /* (DPAA_VERSION >= 11) */
153789 + } u;
153790 +} ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t;
153791 +
153792 +/**************************************************************************//**
153793 + @Description Parameters for defining header insertion manipulation
153794 +*//***************************************************************************/
153795 +typedef struct ioc_fm_pcd_manip_hdr_insrt_params_t {
153796 + ioc_fm_pcd_manip_hdr_insrt_type type; /**< Type of insertion manipulation */
153797 + union {
153798 + ioc_fm_pcd_manip_hdr_insrt_by_hdr_params_t by_hdr; /**< Parameters for defining header insertion manipulation by header type,
153799 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_HDR */
153800 + ioc_fm_pcd_manip_hdr_insrt_generic_params_t generic;/**< Parameters for defining generic header insertion manipulation,
153801 + relevant if type = e_IOC_FM_PCD_MANIP_INSRT_GENERIC */
153802 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153803 + ioc_fm_pcd_manip_hdr_insrt_by_template_params_t by_template;
153804 + /**< Parameters for defining header insertion manipulation by template,
153805 + relevant if 'type' = e_IOC_FM_PCD_MANIP_INSRT_BY_TEMPLATE */
153806 +#endif /* FM_CAPWAP_SUPPORT */
153807 + } u;
153808 +} ioc_fm_pcd_manip_hdr_insrt_params_t;
153809 +
153810 +/**************************************************************************//**
153811 + @Description Parameters for defining header removal manipulation
153812 +*//***************************************************************************/
153813 +typedef struct ioc_fm_pcd_manip_hdr_rmv_params_t {
153814 + ioc_fm_pcd_manip_hdr_rmv_type type; /**< Type of header removal manipulation */
153815 + union {
153816 + ioc_fm_pcd_manip_hdr_rmv_by_hdr_params_t by_hdr; /**< Parameters for defining header removal manipulation by header type,
153817 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_BY_HDR */
153818 + ioc_fm_pcd_manip_hdr_rmv_generic_params_t generic; /**< Parameters for defining generic header removal manipulation,
153819 + relevant if type = e_IOC_FM_PCD_MANIP_RMV_GENERIC */
153820 + } u;
153821 +} ioc_fm_pcd_manip_hdr_rmv_params_t;
153822 +
153823 +/**************************************************************************//**
153824 + @Description Parameters for defining header manipulation node
153825 +*//***************************************************************************/
153826 +typedef struct ioc_fm_pcd_manip_hdr_params_t {
153827 + bool rmv; /**< TRUE, to define removal manipulation */
153828 + ioc_fm_pcd_manip_hdr_rmv_params_t rmv_params; /**< Parameters for removal manipulation, relevant if 'rmv' = TRUE */
153829 +
153830 + bool insrt; /**< TRUE, to define insertion manipulation */
153831 + ioc_fm_pcd_manip_hdr_insrt_params_t insrt_params; /**< Parameters for insertion manipulation, relevant if 'insrt' = TRUE */
153832 +
153833 + bool field_update; /**< TRUE, to define field update manipulation */
153834 + ioc_fm_pcd_manip_hdr_field_update_params_t field_update_params; /**< Parameters for field update manipulation, relevant if 'fieldUpdate' = TRUE */
153835 +
153836 + bool custom; /**< TRUE, to define custom manipulation */
153837 + ioc_fm_pcd_manip_hdr_custom_params_t custom_params; /**< Parameters for custom manipulation, relevant if 'custom' = TRUE */
153838 +
153839 + bool dont_parse_after_manip;/**< FALSE to activate the parser a second time after
153840 + completing the manipulation on the frame */
153841 +} ioc_fm_pcd_manip_hdr_params_t;
153842 +
153843 +
153844 +/**************************************************************************//**
153845 + @Description structure for defining fragmentation manipulation
153846 +*//***************************************************************************/
153847 +typedef struct ioc_fm_pcd_manip_frag_params_t {
153848 + ioc_net_header_type hdr; /**< Header selection */
153849 + union {
153850 +#if (DPAA_VERSION >= 11)
153851 + ioc_fm_pcd_manip_frag_capwap_params_t capwap_frag; /**< Parameters for defining CAPWAP fragmentation,
153852 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
153853 +#endif /* (DPAA_VERSION >= 11) */
153854 + ioc_fm_pcd_manip_frag_ip_params_t ip_frag; /**< Parameters for defining IP fragmentation,
153855 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
153856 + } u;
153857 +} ioc_fm_pcd_manip_frag_params_t;
153858 +
153859 +/**************************************************************************//**
153860 + @Description structure for defining reassemble manipulation
153861 +*//***************************************************************************/
153862 +typedef struct ioc_fm_pcd_manip_reassem_params_t {
153863 + ioc_net_header_type hdr; /**< Header selection */
153864 + union {
153865 +#if (DPAA_VERSION >= 11)
153866 + ioc_fm_pcd_manip_reassem_capwap_params_t capwap_reassem; /**< Parameters for defining CAPWAP reassembly,
153867 + relevant if 'hdr' = HEADER_TYPE_CAPWAP */
153868 +#endif /* (DPAA_VERSION >= 11) */
153869 + ioc_fm_pcd_manip_reassem_ip_params_t ip_reassem; /**< Parameters for defining IP reassembly,
153870 + relevant if 'hdr' = HEADER_TYPE_Ipv4 or HEADER_TYPE_Ipv6 */
153871 + } u;
153872 +} ioc_fm_pcd_manip_reassem_params_t;
153873 +
153874 +/**************************************************************************//**
153875 + @Description Parameters for defining a manipulation node
153876 +*//***************************************************************************/
153877 +typedef struct ioc_fm_pcd_manip_params_t {
153878 + ioc_fm_pcd_manip_type type; /**< Selects type of manipulation node */
153879 + union {
153880 + ioc_fm_pcd_manip_hdr_params_t hdr; /**< Parameters for defining header manipulation node */
153881 + ioc_fm_pcd_manip_reassem_params_t reassem;/**< Parameters for defining reassembly manipulation node */
153882 + ioc_fm_pcd_manip_frag_params_t frag; /**< Parameters for defining fragmentation manipulation node */
153883 + ioc_fm_pcd_manip_special_offload_params_t special_offload;/**< Parameters for defining special offload manipulation node */
153884 + } u;
153885 + void *p_next_manip;/**< Handle to another (previously defined) manipulation node;
153886 + Allows concatenation of manipulation actions
153887 + This parameter is optional and may be NULL. */
153888 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
153889 + bool frag_or_reasm;/**< TRUE, if defined fragmentation/reassembly manipulation */
153890 + ioc_fm_pcd_manip_frag_or_reasm_params_t frag_or_reasm_params;/**< Parameters for fragmentation/reassembly manipulation,
153891 + relevant if frag_or_reasm = TRUE */
153892 +#endif /* FM_CAPWAP_SUPPORT */
153893 + void *id;
153894 +} ioc_fm_pcd_manip_params_t;
153895 +
153896 +/**************************************************************************//**
153897 + @Description Structure for retrieving IP reassembly statistics
153898 +*//***************************************************************************/
153899 +typedef struct ioc_fm_pcd_manip_reassem_ip_stats_t {
153900 + /* common counters for both IPv4 and IPv6 */
153901 + uint32_t timeout; /**< Counts the number of TimeOut occurrences */
153902 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
153903 + a Reassembly Frame Descriptor */
153904 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
153905 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
153906 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
153907 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
153908 +#if (DPAA_VERSION >= 11)
153909 + uint32_t non_consistent_sp; /**< Counts the number of Non Consistent Storage Profile events for
153910 + successfully reassembled frames */
153911 +#endif /* (DPAA_VERSION >= 11) */
153912 +struct {
153913 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
153914 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
153915 + have been processed for all frames */
153916 + uint32_t processed_fragments; /**< Counts the number of processed fragments
153917 + (valid and error fragments) for all frames */
153918 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
153919 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
153920 + uint32_t auto_learn_busy; /**< Counts the number of times a busy condition occurs when attempting
153921 + to access an IP-Reassembly Automatic Learning Hash set */
153922 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
153923 + exceeds 16 */
153924 + } specific_hdr_statistics[2]; /**< slot '0' is for IPv4, slot '1' is for IPv6 */
153925 +} ioc_fm_pcd_manip_reassem_ip_stats_t;
153926 +
153927 +/**************************************************************************//**
153928 + @Description Structure for retrieving IP fragmentation statistics
153929 +*//***************************************************************************/
153930 +typedef struct ioc_fm_pcd_manip_frag_ip_stats_t {
153931 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
153932 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
153933 + uint32_t generated_fragments; /**< Number of fragments that were generated */
153934 +} ioc_fm_pcd_manip_frag_ip_stats_t;
153935 +
153936 +#if (DPAA_VERSION >= 11)
153937 +/**************************************************************************//**
153938 + @Description Structure for retrieving CAPWAP reassembly statistics
153939 +*//***************************************************************************/
153940 +typedef struct ioc_fm_pcd_manip_reassem_capwap_stats_t {
153941 + uint32_t timeout; /**< Counts the number of timeout occurrences */
153942 + uint32_t rfd_pool_busy; /**< Counts the number of failed attempts to allocate
153943 + a Reassembly Frame Descriptor */
153944 + uint32_t internal_buffer_busy; /**< Counts the number of times an internal buffer busy occurred */
153945 + uint32_t external_buffer_busy; /**< Counts the number of times external buffer busy occurred */
153946 + uint32_t sg_fragments; /**< Counts the number of Scatter/Gather fragments */
153947 + uint32_t dma_semaphore_depletion; /**< Counts the number of failed attempts to allocate a DMA semaphore */
153948 + uint32_t successfully_reassembled; /**< Counts the number of successfully reassembled frames */
153949 + uint32_t valid_fragments; /**< Counts the total number of valid fragments that
153950 + have been processed for all frames */
153951 + uint32_t processed_fragments; /**< Counts the number of processed fragments
153952 + (valid and error fragments) for all frames */
153953 + uint32_t malformed_fragments; /**< Counts the number of malformed fragments processed for all frames */
153954 + uint32_t autoLearn_busy; /**< Counts the number of times a busy condition occurs when attempting
153955 + to access an Reassembly Automatic Learning Hash set */
153956 + uint32_t discarded_fragments; /**< Counts the number of fragments discarded by the reassembly process */
153957 + uint32_t more_than16fragments; /**< Counts the fragment occurrences in which the number of fragments-per-frame
153958 + exceeds 16 */
153959 + uint32_t exceed_max_reassembly_frame_len;/**< ounts the number of times that a successful reassembled frame
153960 + length exceeds MaxReassembledFrameLength value */
153961 +} ioc_fm_pcd_manip_reassem_capwap_stats_t;
153962 +
153963 +/**************************************************************************//**
153964 + @Description Structure for retrieving CAPWAP fragmentation statistics
153965 +*//***************************************************************************/
153966 +typedef struct ioc_fm_pcd_manip_frag_capwap_stats_t {
153967 + uint32_t total_frames; /**< Number of frames that passed through the manipulation node */
153968 + uint32_t fragmented_frames; /**< Number of frames that were fragmented */
153969 + uint32_t generated_fragments; /**< Number of fragments that were generated */
153970 +#if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
153971 + uint8_t sg_allocation_failure; /**< Number of allocation failure of s/g buffers */
153972 +#endif /* (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0)) */
153973 +} ioc_fm_pcd_manip_frag_capwap_stats_t;
153974 +#endif /* (DPAA_VERSION >= 11) */
153975 +
153976 +/**************************************************************************//**
153977 + @Description Structure for retrieving reassembly statistics
153978 +*//***************************************************************************/
153979 +typedef struct ioc_fm_pcd_manip_reassem_stats_t {
153980 + union {
153981 + ioc_fm_pcd_manip_reassem_ip_stats_t ip_reassem; /**< Structure for IP reassembly statistics */
153982 +#if (DPAA_VERSION >= 11)
153983 + ioc_fm_pcd_manip_reassem_capwap_stats_t capwap_reassem; /**< Structure for CAPWAP reassembly statistics */
153984 +#endif /* (DPAA_VERSION >= 11) */
153985 + } u;
153986 +} ioc_fm_pcd_manip_reassem_stats_t;
153987 +
153988 +/**************************************************************************//**
153989 + @Description structure for retrieving fragmentation statistics
153990 +*//***************************************************************************/
153991 +typedef struct ioc_fm_pcd_manip_frag_stats_t {
153992 + union {
153993 + ioc_fm_pcd_manip_frag_ip_stats_t ip_frag; /**< Structure for IP fragmentation statistics */
153994 +#if (DPAA_VERSION >= 11)
153995 + ioc_fm_pcd_manip_frag_capwap_stats_t capwap_frag; /**< Structure for CAPWAP fragmentation statistics */
153996 +#endif /* (DPAA_VERSION >= 11) */
153997 + } u;
153998 +} ioc_fm_pcd_manip_frag_stats_t;
153999 +
154000 +/**************************************************************************//**
154001 + @Description structure for defining manipulation statistics
154002 +*//***************************************************************************/
154003 +typedef struct ioc_fm_pcd_manip_stats_t {
154004 + union {
154005 + ioc_fm_pcd_manip_reassem_stats_t reassem; /**< Structure for reassembly statistics */
154006 + ioc_fm_pcd_manip_frag_stats_t frag; /**< Structure for fragmentation statistics */
154007 + } u;
154008 +} ioc_fm_pcd_manip_stats_t;
154009 +
154010 +/**************************************************************************//**
154011 + @Description Parameters for acquiring manipulation statistics
154012 +*//***************************************************************************/
154013 +typedef struct ioc_fm_pcd_manip_get_stats_t {
154014 + void *id;
154015 + ioc_fm_pcd_manip_stats_t stats;
154016 +} ioc_fm_pcd_manip_get_stats_t;
154017 +
154018 +#if DPAA_VERSION >= 11
154019 +/**************************************************************************//**
154020 + @Description Parameters for defining frame replicator group and its members
154021 +*//***************************************************************************/
154022 +typedef struct ioc_fm_pcd_frm_replic_group_params_t {
154023 + uint8_t max_num_of_entries; /**< Maximal number of members in the group - must be at least two */
154024 + uint8_t num_of_entries; /**< Number of members in the group - must be at least 1 */
154025 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params[IOC_FM_PCD_FRM_REPLIC_MAX_NUM_OF_ENTRIES];
154026 + /**< Array of members' parameters */
154027 + void *id;
154028 +} ioc_fm_pcd_frm_replic_group_params_t;
154029 +
154030 +typedef struct ioc_fm_pcd_frm_replic_member_t {
154031 + void *h_replic_group;
154032 + uint16_t member_index;
154033 +} ioc_fm_pcd_frm_replic_member_t;
154034 +
154035 +typedef struct ioc_fm_pcd_frm_replic_member_params_t {
154036 + ioc_fm_pcd_frm_replic_member_t member;
154037 + ioc_fm_pcd_cc_next_engine_params_t next_engine_params;
154038 +} ioc_fm_pcd_frm_replic_member_params_t;
154039 +#endif /* DPAA_VERSION >= 11 */
154040 +
154041 +
154042 +typedef struct ioc_fm_pcd_cc_key_statistics_t {
154043 + uint32_t byte_count; /**< This counter reflects byte count of frames that
154044 + were matched by this key. */
154045 + uint32_t frame_count; /**< This counter reflects count of frames that
154046 + were matched by this key. */
154047 +#if (DPAA_VERSION >= 11)
154048 + uint32_t frame_length_range_count[IOC_FM_PCD_CC_STATS_MAX_NUM_OF_FLR];
154049 + /**< These counters reflect how many frames matched
154050 + this key in 'RMON' statistics mode:
154051 + Each counter holds the number of frames of a
154052 + specific frames length range, according to the
154053 + ranges provided at initialization. */
154054 +#endif /* (DPAA_VERSION >= 11) */
154055 +} ioc_fm_pcd_cc_key_statistics_t;
154056 +
154057 +
154058 +typedef struct ioc_fm_pcd_cc_tbl_get_stats_t {
154059 + void *id;
154060 + uint16_t key_index;
154061 + ioc_fm_pcd_cc_key_statistics_t statistics;
154062 +} ioc_fm_pcd_cc_tbl_get_stats_t;
154063 +
154064 +/**************************************************************************//**
154065 + @Function FM_PCD_MatchTableGetKeyStatistics
154066 +
154067 + @Description This routine may be used to get statistics counters of specific key
154068 + in a CC Node.
154069 +
154070 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
154071 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
154072 + these counters reflect how many frames passed that were matched
154073 + this key; The total frames count will be returned in the counter
154074 + of the first range (as only one frame length range was defined).
154075 + If 'e_FM_PCD_CC_STATS_MODE_RMON' was set for this node, the total
154076 + frame count will be separated to frame length counters, based on
154077 + provided frame length ranges.
154078 +
154079 + @Param[in] h_CcNode A handle to the node
154080 + @Param[in] keyIndex Key index for adding
154081 + @Param[out] p_KeyStatistics Key statistics counters
154082 +
154083 + @Return The specific key statistics.
154084 +
154085 + @Cautions Allowed only following FM_PCD_MatchTableSet().
154086 +*//***************************************************************************/
154087 +
154088 +#if defined(CONFIG_COMPAT)
154089 +#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)
154090 +#endif
154091 +#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)
154092 +
154093 +/**************************************************************************//**
154094 + @Function FM_PCD_MatchTableGetMissStatistics
154095 +
154096 + @Description This routine may be used to get statistics counters of miss entry
154097 + in a CC Node.
154098 +
154099 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
154100 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
154101 + these counters reflect how many frames were not matched to any
154102 + existing key and therefore passed through the miss entry; The
154103 + total frames count will be returned in the counter of the
154104 + first range (as only one frame length range was defined).
154105 +
154106 + @Param[in] h_CcNode A handle to the node
154107 + @Param[out] p_MissStatistics Statistics counters for 'miss'
154108 +
154109 + @Return E_OK on success; Error code otherwise.
154110 +
154111 + @Cautions Allowed only following FM_PCD_MatchTableSet().
154112 +*//***************************************************************************/
154113 +
154114 +#if defined(CONFIG_COMPAT)
154115 +#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)
154116 +#endif
154117 +#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)
154118 +
154119 +/**************************************************************************//**
154120 + @Function FM_PCD_HashTableGetMissStatistics
154121 +
154122 + @Description This routine may be used to get statistics counters of 'miss'
154123 + entry of the a hash table.
154124 +
154125 + If 'e_FM_PCD_CC_STATS_MODE_FRAME' and
154126 + 'e_FM_PCD_CC_STATS_MODE_BYTE_AND_FRAME' were set for this node,
154127 + these counters reflect how many frames were not matched to any
154128 + existing key and therefore passed through the miss entry;
154129 +
154130 + @Param[in] h_HashTbl A handle to a hash table
154131 + @Param[out] p_MissStatistics Statistics counters for 'miss'
154132 +
154133 + @Return E_OK on success; Error code otherwise.
154134 +
154135 + @Cautions Allowed only following FM_PCD_HashTableSet().
154136 +*//***************************************************************************/
154137 +
154138 +#if defined(CONFIG_COMPAT)
154139 +#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)
154140 +#endif
154141 +#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)
154142 +
154143 +
154144 +/**************************************************************************//**
154145 + @Function FM_PCD_NetEnvCharacteristicsSet
154146 +
154147 + @Description Define a set of Network Environment Characteristics.
154148 +
154149 + When setting an environment it is important to understand its
154150 + application. It is not meant to describe the flows that will run
154151 + on the ports using this environment, but what the user means TO DO
154152 + with the PCD mechanisms in order to parse-classify-distribute those
154153 + frames.
154154 + By specifying a distinction unit, the user means it would use that option
154155 + for distinction between frames at either a KeyGen scheme or a coarse
154156 + classification action descriptor. Using interchangeable headers to define a
154157 + unit means that the user is indifferent to which of the interchangeable
154158 + headers is present in the frame, and wants the distinction to be based
154159 + on the presence of either one of them.
154160 +
154161 + Depending on context, there are limitations to the use of environments. A
154162 + port using the PCD functionality is bound to an environment. Some or even
154163 + all ports may share an environment but also an environment per port is
154164 + possible. When initializing a scheme, a classification plan group (see below),
154165 + or a coarse classification tree, one of the initialized environments must be
154166 + stated and related to. When a port is bound to a scheme, a classification
154167 + plan group, or a coarse classification tree, it MUST be bound to the same
154168 + environment.
154169 +
154170 + The different PCD modules, may relate (for flows definition) ONLY on
154171 + distinction units as defined by their environment. When initializing a
154172 + scheme for example, it may not choose to select IPV4 as a match for
154173 + recognizing flows unless it was defined in the relating environment. In
154174 + fact, to guide the user through the configuration of the PCD, each module's
154175 + characterization in terms of flows is not done using protocol names, but using
154176 + environment indexes.
154177 +
154178 + In terms of HW implementation, the list of distinction units sets the LCV vectors
154179 + and later used for match vector, classification plan vectors and coarse classification
154180 + indexing.
154181 +
154182 + @Param[in,out] ioc_fm_pcd_net_env_params_t A structure defining the distiction units for this configuration.
154183 +
154184 + @Return 0 on success; Error code otherwise.
154185 +*//***************************************************************************/
154186 +#if defined(CONFIG_COMPAT)
154187 +#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)
154188 +#endif
154189 +#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)
154190 +
154191 +/**************************************************************************//**
154192 + @Function FM_PCD_NetEnvCharacteristicsDelete
154193 +
154194 + @Description Deletes a set of Network Environment Charecteristics.
154195 +
154196 + @Param[in] ioc_fm_obj_t - The id of a Network Environment object.
154197 +
154198 + @Return 0 on success; Error code otherwise.
154199 +*//***************************************************************************/
154200 +#if defined(CONFIG_COMPAT)
154201 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_compat_fm_obj_t)
154202 +#endif
154203 +#define FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(21), ioc_fm_obj_t)
154204 +
154205 +/**************************************************************************//**
154206 + @Function FM_PCD_KgSchemeSet
154207 +
154208 + @Description Initializing or modifying and enabling a scheme for the KeyGen.
154209 + This routine should be called for adding or modifying a scheme.
154210 + When a scheme needs modifying, the API requires that it will be
154211 + rewritten. In such a case 'modify' should be TRUE. If the
154212 + routine is called for a valid scheme and 'modify' is FALSE,
154213 + it will return error.
154214 +
154215 + @Param[in,out] ioc_fm_pcd_kg_scheme_params_t A structure of parameters for defining the scheme
154216 +
154217 + @Return 0 on success; Error code otherwise.
154218 +*//***************************************************************************/
154219 +#if defined(CONFIG_COMPAT)
154220 +#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)
154221 +#endif
154222 +#define FM_PCD_IOC_KG_SCHEME_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(24), ioc_fm_pcd_kg_scheme_params_t)
154223 +
154224 +/**************************************************************************//**
154225 + @Function FM_PCD_KgSchemeDelete
154226 +
154227 + @Description Deleting an initialized scheme.
154228 +
154229 + @Param[in] ioc_fm_obj_t scheme id as initalized by application at FM_PCD_IOC_KG_SET_SCHEME
154230 +
154231 + @Return 0 on success; Error code otherwise.
154232 +*//***************************************************************************/
154233 +#if defined(CONFIG_COMPAT)
154234 +#define FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_compat_fm_obj_t)
154235 +#endif
154236 +#define FM_PCD_IOC_KG_SCHEME_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(25), ioc_fm_obj_t)
154237 +
154238 +/**************************************************************************//**
154239 + @Function FM_PCD_CcRootBuild
154240 +
154241 + @Description This routine must be called to define a complete coarse
154242 + classification tree. This is the way to define coarse
154243 + classification to a certain flow - the KeyGen schemes
154244 + may point only to trees defined in this way.
154245 +
154246 + @Param[in,out] ioc_fm_pcd_cc_tree_params_t A structure of parameters to define the tree.
154247 +
154248 + @Return 0 on success; Error code otherwise.
154249 +*//***************************************************************************/
154250 +#if defined(CONFIG_COMPAT)
154251 +#define FM_PCD_IOC_CC_ROOT_BUILD_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), compat_uptr_t)
154252 +#endif
154253 +#define FM_PCD_IOC_CC_ROOT_BUILD _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(26), void *) /* workaround ...*/
154254 +
154255 +/**************************************************************************//**
154256 + @Function FM_PCD_CcRootDelete
154257 +
154258 + @Description Deleting a built tree.
154259 +
154260 + @Param[in] ioc_fm_obj_t - The id of a CC tree.
154261 +*//***************************************************************************/
154262 +#if defined(CONFIG_COMPAT)
154263 +#define FM_PCD_IOC_CC_ROOT_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_compat_fm_obj_t)
154264 +#endif
154265 +#define FM_PCD_IOC_CC_ROOT_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(27), ioc_fm_obj_t)
154266 +
154267 +/**************************************************************************//**
154268 + @Function FM_PCD_MatchTableSet
154269 +
154270 + @Description This routine should be called for each CC (coarse classification)
154271 + node. The whole CC tree should be built bottom up so that each
154272 + node points to already defined nodes. p_NodeId returns the node
154273 + Id to be used by other nodes.
154274 +
154275 + @Param[in,out] ioc_fm_pcd_cc_node_params_t A structure for defining the CC node params
154276 +
154277 + @Return 0 on success; Error code otherwise.
154278 +*//***************************************************************************/
154279 +#if defined(CONFIG_COMPAT)
154280 +#define FM_PCD_IOC_MATCH_TABLE_SET_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), compat_uptr_t)
154281 +#endif
154282 +#define FM_PCD_IOC_MATCH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(28), void *) /* workaround ...*/
154283 +
154284 +/**************************************************************************//**
154285 + @Function FM_PCD_MatchTableDelete
154286 +
154287 + @Description Deleting a built node.
154288 +
154289 + @Param[in] ioc_fm_obj_t - The id of a CC node.
154290 +
154291 + @Return 0 on success; Error code otherwise.
154292 +*//***************************************************************************/
154293 +#if defined(CONFIG_COMPAT)
154294 +#define FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_compat_fm_obj_t)
154295 +#endif
154296 +#define FM_PCD_IOC_MATCH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(29), ioc_fm_obj_t)
154297 +
154298 +/**************************************************************************//**
154299 + @Function FM_PCD_CcRootModifyNextEngine
154300 +
154301 + @Description Modify the Next Engine Parameters in the entry of the tree.
154302 +
154303 + @Param[in] ioc_fm_pcd_cc_tree_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
154304 +
154305 + @Return 0 on success; Error code otherwise.
154306 +
154307 + @Cautions Allowed only following FM_PCD_CcRootBuild().
154308 +*//***************************************************************************/
154309 +#if defined(CONFIG_COMPAT)
154310 +#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)
154311 +#endif
154312 +#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)
154313 +
154314 +/**************************************************************************//**
154315 + @Function FM_PCD_MatchTableModifyNextEngine
154316 +
154317 + @Description Modify the Next Engine Parameters in the relevant key entry of the node.
154318 +
154319 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t A pointer to a structure with the relevant parameters
154320 +
154321 + @Return 0 on success; Error code otherwise.
154322 +
154323 + @Cautions Allowed only following FM_PCD_MatchTableSet().
154324 +*//***************************************************************************/
154325 +#if defined(CONFIG_COMPAT)
154326 +#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)
154327 +#endif
154328 +#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)
154329 +
154330 +/**************************************************************************//**
154331 + @Function FM_PCD_MatchTableModifyMissNextEngine
154332 +
154333 + @Description Modify the Next Engine Parameters of the Miss key case of the node.
154334 +
154335 + @Param[in] ioc_fm_pcd_cc_node_modify_next_engine_params_t - Pointer to a structure with the relevant parameters
154336 +
154337 + @Return 0 on success; Error code otherwise.
154338 +
154339 + @Cautions Allowed only following FM_PCD_MatchTableSet().
154340 +*//***************************************************************************/
154341 +#if defined(CONFIG_COMPAT)
154342 +#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)
154343 +#endif
154344 +#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)
154345 +
154346 +/**************************************************************************//**
154347 + @Function FM_PCD_MatchTableRemoveKey
154348 +
154349 + @Description Remove the key (including next engine parameters of this key)
154350 + defined by the index of the relevant node.
154351 +
154352 + @Param[in] ioc_fm_pcd_cc_node_remove_key_params_t A pointer to a structure with the relevant parameters
154353 +
154354 + @Return 0 on success; Error code otherwise.
154355 +
154356 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
154357 + node and for all of the nodes that lead to it.
154358 +*//***************************************************************************/
154359 +#if defined(CONFIG_COMPAT)
154360 +#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)
154361 +#endif
154362 +#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)
154363 +
154364 +/**************************************************************************//**
154365 + @Function FM_PCD_MatchTableAddKey
154366 +
154367 + @Description Add the key (including next engine parameters of this key in the
154368 + index defined by the keyIndex. Note that 'FM_PCD_LAST_KEY_INDEX'
154369 + may be used when the user doesn't care about the position of the
154370 + key in the table - in that case, the key will be automatically
154371 + added by the driver in the last available entry.
154372 +
154373 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
154374 +
154375 + @Return 0 on success; Error code otherwise.
154376 +
154377 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
154378 + node and for all of the nodes that lead to it.
154379 +*//***************************************************************************/
154380 +#if defined(CONFIG_COMPAT)
154381 +#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)
154382 +#endif
154383 +#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)
154384 +
154385 +/**************************************************************************//**
154386 + @Function FM_PCD_MatchTableModifyKeyAndNextEngine
154387 +
154388 + @Description Modify the key and Next Engine Parameters of this key in the index defined by key_index.
154389 +
154390 + @Param[in] ioc_fm_pcd_cc_node_modify_key_and_next_engine_params_t A pointer to a structure with the relevant parameters
154391 +
154392 + @Return 0 on success; Error code otherwise.
154393 +
154394 + @Cautions Allowed only following FM_PCD_MatchTableSet() not only of the relevnt node but also
154395 + the node that points to this node
154396 +*//***************************************************************************/
154397 +#if defined(CONFIG_COMPAT)
154398 +#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)
154399 +#endif
154400 +#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)
154401 +
154402 +/**************************************************************************//**
154403 + @Function FM_PCD_MatchTableModifyKey
154404 +
154405 + @Description Modify the key at the index defined by key_index.
154406 +
154407 + @Param[in] ioc_fm_pcd_cc_node_modify_key_params_t - Pointer to a structure with the relevant parameters
154408 +
154409 + @Return 0 on success; Error code otherwise.
154410 +
154411 + @Cautions Allowed only after FM_PCD_MatchTableSet() has been called for this
154412 + node and for all of the nodes that lead to it.
154413 +*//***************************************************************************/
154414 +#if defined(CONFIG_COMPAT)
154415 +#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)
154416 +#endif
154417 +#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)
154418 +
154419 +/**************************************************************************//**
154420 + @Function FM_PCD_HashTableSet
154421 +
154422 + @Description This routine initializes a hash table structure.
154423 + KeyGen hash result determines the hash bucket.
154424 + Next, KeyGen key is compared against all keys of this
154425 + bucket (exact match).
154426 + Number of sets (number of buckets) of the hash equals to the
154427 + number of 1-s in 'hash_res_mask' in the provided parameters.
154428 + Number of hash table ways is then calculated by dividing
154429 + 'max_num_of_keys' equally between the hash sets. This is the maximal
154430 + number of keys that a hash bucket may hold.
154431 + The hash table is initialized empty and keys may be
154432 + added to it following the initialization. Keys masks are not
154433 + supported in current hash table implementation.
154434 + The initialized hash table can be integrated as a node in a
154435 + CC tree.
154436 +
154437 + @Param[in,out] ioc_fm_pcd_hash_table_params_t - Pointer to a structure with the relevant parameters
154438 +
154439 + @Return 0 on success; Error code otherwise.
154440 +*//***************************************************************************/
154441 +#if defined(CONFIG_COMPAT)
154442 +#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)
154443 +#endif
154444 +#define FM_PCD_IOC_HASH_TABLE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_pcd_hash_table_params_t)
154445 +
154446 +
154447 +/**************************************************************************//**
154448 + @Function FM_PCD_HashTableDelete
154449 +
154450 + @Description This routine deletes the provided hash table and released all
154451 + its allocated resources.
154452 +
154453 + @Param[in] ioc_fm_obj_t - The ID of a hash table.
154454 +
154455 + @Return 0 on success; Error code otherwise.
154456 +
154457 + @Cautions Allowed only following FM_PCD_HashTableSet().
154458 +*//***************************************************************************/
154459 +#if defined(CONFIG_COMPAT)
154460 +#define FM_PCD_IOC_HASH_TABLE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_compat_fm_obj_t)
154461 +#endif
154462 +#define FM_PCD_IOC_HASH_TABLE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(37), ioc_fm_obj_t)
154463 +
154464 +/**************************************************************************//**
154465 + @Function FM_PCD_HashTableAddKey
154466 +
154467 + @Description This routine adds the provided key (including next engine
154468 + parameters of this key) to the hash table.
154469 + The key is added as the last key of the bucket that it is
154470 + mapped to.
154471 +
154472 + @Param[in] ioc_fm_pcd_hash_table_add_key_params_t - Pointer to a structure with the relevant parameters
154473 +
154474 + @Return 0 on success; error code otherwise.
154475 +
154476 + @Cautions Allowed only following FM_PCD_HashTableSet().
154477 +*//***************************************************************************/
154478 +#if defined(CONFIG_COMPAT)
154479 +#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)
154480 +#endif
154481 +#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)
154482 +
154483 +/**************************************************************************//**
154484 + @Function FM_PCD_HashTableRemoveKey
154485 +
154486 + @Description This routine removes the requested key (including next engine
154487 + parameters of this key) from the hash table.
154488 +
154489 + @Param[in] ioc_fm_pcd_hash_table_remove_key_params_t - Pointer to a structure with the relevant parameters
154490 +
154491 + @Return 0 on success; Error code otherwise.
154492 +
154493 + @Cautions Allowed only following FM_PCD_HashTableSet().
154494 +*//***************************************************************************/
154495 +#if defined(CONFIG_COMPAT)
154496 +#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)
154497 +#endif
154498 +#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)
154499 +
154500 +/**************************************************************************//**
154501 + @Function FM_PCD_PlcrProfileSet
154502 +
154503 + @Description Sets a profile entry in the policer profile table.
154504 + The routine overrides any existing value.
154505 +
154506 + @Param[in,out] ioc_fm_pcd_plcr_profile_params_t A structure of parameters for defining a
154507 + policer profile entry.
154508 +
154509 + @Return 0 on success; Error code otherwise.
154510 +*//***************************************************************************/
154511 +#if defined(CONFIG_COMPAT)
154512 +#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)
154513 +#endif
154514 +#define FM_PCD_IOC_PLCR_PROFILE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_pcd_plcr_profile_params_t)
154515 +
154516 +/**************************************************************************//**
154517 + @Function FM_PCD_PlcrProfileDelete
154518 +
154519 + @Description Delete a profile entry in the policer profile table.
154520 + The routine set entry to invalid.
154521 +
154522 + @Param[in] ioc_fm_obj_t The id of a policer profile.
154523 +
154524 + @Return 0 on success; Error code otherwise.
154525 +*//***************************************************************************/
154526 +#if defined(CONFIG_COMPAT)
154527 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_compat_fm_obj_t)
154528 +#endif
154529 +#define FM_PCD_IOC_PLCR_PROFILE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(41), ioc_fm_obj_t)
154530 +
154531 +/**************************************************************************//**
154532 + @Function FM_PCD_ManipNodeSet
154533 +
154534 + @Description This routine should be called for defining a manipulation
154535 + node. A manipulation node must be defined before the CC node
154536 + that precedes it.
154537 +
154538 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
154539 +
154540 + @Return A handle to the initialized object on success; NULL code otherwise.
154541 +*//***************************************************************************/
154542 +#if defined(CONFIG_COMPAT)
154543 +#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)
154544 +#endif
154545 +#define FM_PCD_IOC_MANIP_NODE_SET _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(43), ioc_fm_pcd_manip_params_t)
154546 +
154547 +/**************************************************************************//**
154548 + @Function FM_PCD_ManipNodeReplace
154549 +
154550 + @Description Change existing manipulation node to be according to new requirement.
154551 + (Here, it's implemented as a variant of the same IOCTL as for
154552 + FM_PCD_ManipNodeSet(), and one that when called, the 'id' member
154553 + in its 'ioc_fm_pcd_manip_params_t' argument is set to contain
154554 + the manip node's handle)
154555 +
154556 + @Param[in] ioc_fm_pcd_manip_params_t - A structure of parameters defining the manipulation
154557 +
154558 + @Return 0 on success; error code otherwise.
154559 +
154560 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
154561 +*//***************************************************************************/
154562 +#if defined(CONFIG_COMPAT)
154563 +#define FM_PCD_IOC_MANIP_NODE_REPLACE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
154564 +#endif
154565 +#define FM_PCD_IOC_MANIP_NODE_REPLACE FM_PCD_IOC_MANIP_NODE_SET
154566 +
154567 +/**************************************************************************//**
154568 + @Function FM_PCD_ManipNodeDelete
154569 +
154570 + @Description Delete an existing manipulation node.
154571 +
154572 + @Param[in] ioc_fm_obj_t The id of the manipulation node to delete.
154573 +
154574 + @Return 0 on success; error code otherwise.
154575 +
154576 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
154577 +*//***************************************************************************/
154578 +#if defined(CONFIG_COMPAT)
154579 +#define FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_compat_fm_obj_t)
154580 +#endif
154581 +#define FM_PCD_IOC_MANIP_NODE_DELETE _IOW(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(44), ioc_fm_obj_t)
154582 +
154583 +/**************************************************************************//**
154584 + @Function FM_PCD_ManipGetStatistics
154585 +
154586 + @Description Retrieve the manipulation statistics.
154587 +
154588 + @Param[in] h_ManipNode A handle to a manipulation node.
154589 + @Param[out] p_FmPcdManipStats A structure for retrieving the manipulation statistics
154590 +
154591 + @Return E_OK on success; Error code otherwise.
154592 +
154593 + @Cautions Allowed only following FM_PCD_ManipNodeSet().
154594 +*//***************************************************************************/
154595 +#if defined(CONFIG_COMPAT)
154596 +#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)
154597 +#endif
154598 +#define FM_PCD_IOC_MANIP_GET_STATS _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(50), ioc_fm_pcd_manip_get_stats_t)
154599 +
154600 +/**************************************************************************//**
154601 +@Function FM_PCD_SetAdvancedOffloadSupport
154602 +
154603 +@Description This routine must be called in order to support the following features:
154604 + IP-fragmentation, IP-reassembly, IPsec, Header-manipulation, frame-replicator.
154605 +
154606 +@Param[in] h_FmPcd FM PCD module descriptor.
154607 +
154608 +@Return 0 on success; error code otherwise.
154609 +
154610 +@Cautions Allowed only when PCD is disabled.
154611 +*//***************************************************************************/
154612 +#define FM_PCD_IOC_SET_ADVANCED_OFFLOAD_SUPPORT _IO(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45))
154613 +
154614 +#if (DPAA_VERSION >= 11)
154615 +/**************************************************************************//**
154616 + @Function FM_PCD_FrmReplicSetGroup
154617 +
154618 + @Description Initialize a Frame Replicator group.
154619 +
154620 + @Param[in] h_FmPcd FM PCD module descriptor.
154621 + @Param[in] p_FrmReplicGroupParam A structure of parameters for the initialization of
154622 + the frame replicator group.
154623 +
154624 + @Return A handle to the initialized object on success; NULL code otherwise.
154625 +
154626 + @Cautions Allowed only following FM_PCD_Init().
154627 +*//***************************************************************************/
154628 +#if defined(CONFIG_COMPAT)
154629 +#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)
154630 +#endif
154631 +#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)
154632 +
154633 +/**************************************************************************//**
154634 + @Function FM_PCD_FrmReplicDeleteGroup
154635 +
154636 + @Description Delete a Frame Replicator group.
154637 +
154638 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
154639 +
154640 + @Return E_OK on success; Error code otherwise.
154641 +
154642 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup().
154643 +*//***************************************************************************/
154644 +#if defined(CONFIG_COMPAT)
154645 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_compat_fm_obj_t)
154646 +#endif
154647 +#define FM_PCD_IOC_FRM_REPLIC_GROUP_DELETE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(47), ioc_fm_obj_t)
154648 +
154649 +/**************************************************************************//**
154650 + @Function FM_PCD_FrmReplicAddMember
154651 +
154652 + @Description Add the member in the index defined by the memberIndex.
154653 +
154654 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
154655 + @Param[in] memberIndex member index for adding.
154656 + @Param[in] p_MemberParams A pointer to the new member parameters.
154657 +
154658 + @Return E_OK on success; Error code otherwise.
154659 +
154660 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
154661 +*//***************************************************************************/
154662 +#if defined(CONFIG_COMPAT)
154663 +#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)
154664 +#endif
154665 +#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)
154666 +
154667 +/**************************************************************************//**
154668 + @Function FM_PCD_FrmReplicRemoveMember
154669 +
154670 + @Description Remove the member defined by the index from the relevant group.
154671 +
154672 + @Param[in] h_FrmReplicGroup A handle to the frame replicator group.
154673 + @Param[in] memberIndex member index for removing.
154674 +
154675 + @Return E_OK on success; Error code otherwise.
154676 +
154677 + @Cautions Allowed only following FM_PCD_FrmReplicSetGroup() of this group.
154678 +*//***************************************************************************/
154679 +#if defined(CONFIG_COMPAT)
154680 +#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)
154681 +#endif
154682 +#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)
154683 +
154684 +#endif
154685 +
154686 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
154687 +/**************************************************************************//**
154688 + @Function FM_PCD_StatisticsSetNode
154689 +
154690 + @Description This routine should be called for defining a statistics node.
154691 +
154692 + @Param[in,out] ioc_fm_pcd_stats_params_t A structure of parameters defining the statistics
154693 +
154694 + @Return 0 on success; Error code otherwise.
154695 +*//***************************************************************************/
154696 +#if defined(CONFIG_COMPAT)
154697 +#define FM_PCD_IOC_STATISTICS_SET_NODE_COMPAT _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
154698 +#endif
154699 +#define FM_PCD_IOC_STATISTICS_SET_NODE _IOWR(FM_IOC_TYPE_BASE, FM_PCD_IOC_NUM(45), void *)
154700 +
154701 +#endif /* FM_CAPWAP_SUPPORT */
154702 +
154703 +#ifdef NCSW_BACKWARD_COMPATIBLE_API
154704 +#if defined(CONFIG_COMPAT)
154705 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS_COMPAT \
154706 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET_COMPAT
154707 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS_COMPAT \
154708 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE_COMPAT
154709 +#define FM_PCD_IOC_KG_SET_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_SET_COMPAT
154710 +#define FM_PCD_IOC_KG_DEL_SCHEME_COMPAT FM_PCD_IOC_KG_SCHEME_DELETE_COMPAT
154711 +#define FM_PCD_IOC_CC_BUILD_TREE_COMPAT FM_PCD_IOC_CC_ROOT_BUILD_COMPAT
154712 +#define FM_PCD_IOC_CC_DELETE_TREE_COMPAT FM_PCD_IOC_CC_ROOT_DELETE_COMPAT
154713 +#define FM_PCD_IOC_CC_DELETE_NODE_COMPAT FM_PCD_IOC_MATCH_TABLE_DELETE_COMPAT
154714 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE_COMPAT \
154715 + FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE_COMPAT
154716 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE_COMPAT \
154717 + FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE_COMPAT
154718 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE_COMPAT \
154719 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE_COMPAT
154720 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY_COMPAT
154721 +#define FM_PCD_IOC_CC_NODE_ADD_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_ADD_KEY_COMPAT
154722 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT \
154723 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE_COMPAT
154724 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_COMPAT FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_COMPAT
154725 +#define FM_PCD_IOC_PLCR_SET_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_SET_COMPAT
154726 +#define FM_PCD_IOC_PLCR_DEL_PROFILE_COMPAT FM_PCD_IOC_PLCR_PROFILE_DELETE_COMPAT
154727 +#define FM_PCD_IOC_MANIP_SET_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_SET_COMPAT
154728 +#define FM_PCD_IOC_MANIP_DELETE_NODE_COMPAT FM_PCD_IOC_MANIP_NODE_DELETE_COMPAT
154729 +#endif
154730 +#define FM_PCD_IOC_SET_NET_ENV_CHARACTERISTICS FM_PCD_IOC_NET_ENV_CHARACTERISTICS_SET
154731 +#define FM_PCD_IOC_DELETE_NET_ENV_CHARACTERISTICS \
154732 + FM_PCD_IOC_NET_ENV_CHARACTERISTICS_DELETE
154733 +#define FM_PCD_IOC_KG_SET_SCHEME FM_PCD_IOC_KG_SCHEME_SET
154734 +#define FM_PCD_IOC_KG_DEL_SCHEME FM_PCD_IOC_KG_SCHEME_DELETE
154735 +#define FM_PCD_IOC_CC_BUILD_TREE FM_PCD_IOC_CC_ROOT_BUILD
154736 +#define FM_PCD_IOC_CC_DELETE_TREE FM_PCD_IOC_CC_ROOT_DELETE
154737 +#define FM_PCD_IOC_CC_DELETE_NODE FM_PCD_IOC_MATCH_TABLE_DELETE
154738 +#define FM_PCD_IOC_CC_TREE_MODIFY_NEXT_ENGINE FM_PCD_IOC_CC_ROOT_MODIFY_NEXT_ENGINE
154739 +#define FM_PCD_IOC_CC_NODE_MODIFY_NEXT_ENGINE FM_PCD_IOC_MATCH_TABLE_MODIFY_NEXT_ENGINE
154740 +#define FM_PCD_IOC_CC_NODE_MODIFY_MISS_NEXT_ENGINE \
154741 + FM_PCD_IOC_MATCH_TABLE_MODIFY_MISS_NEXT_ENGINE
154742 +#define FM_PCD_IOC_CC_NODE_REMOVE_KEY FM_PCD_IOC_MATCH_TABLE_REMOVE_KEY
154743 +#define FM_PCD_IOC_CC_NODE_ADD_KEY FM_PCD_IOC_MATCH_TABLE_ADD_KEY
154744 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY_AND_NEXT_ENGINE \
154745 + FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY_AND_NEXT_ENGINE
154746 +#define FM_PCD_IOC_CC_NODE_MODIFY_KEY FM_PCD_IOC_MATCH_TABLE_MODIFY_KEY
154747 +#define FM_PCD_IOC_PLCR_SET_PROFILE FM_PCD_IOC_PLCR_PROFILE_SET
154748 +#define FM_PCD_IOC_PLCR_DEL_PROFILE FM_PCD_IOC_PLCR_PROFILE_DELETE
154749 +#define FM_PCD_IOC_MANIP_SET_NODE FM_PCD_IOC_MANIP_NODE_SET
154750 +#define FM_PCD_IOC_MANIP_DELETE_NODE FM_PCD_IOC_MANIP_NODE_DELETE
154751 +#endif /* NCSW_BACKWARD_COMPATIBLE_API */
154752 +
154753 +#endif /* __FM_PCD_IOCTLS_H */
154754 +/** @} */ /* end of lnx_ioctl_FM_PCD_Runtime_grp group */
154755 +/** @} */ /* end of lnx_ioctl_FM_PCD_grp group */
154756 +/** @} */ /* end of lnx_ioctl_FM_grp group */
154757 --- /dev/null
154758 +++ b/include/uapi/linux/fmd/Peripherals/fm_port_ioctls.h
154759 @@ -0,0 +1,973 @@
154760 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
154761 + * All rights reserved.
154762 + *
154763 + * Redistribution and use in source and binary forms, with or without
154764 + * modification, are permitted provided that the following conditions are met:
154765 + * * Redistributions of source code must retain the above copyright
154766 + * notice, this list of conditions and the following disclaimer.
154767 + * * Redistributions in binary form must reproduce the above copyright
154768 + * notice, this list of conditions and the following disclaimer in the
154769 + * documentation and/or other materials provided with the distribution.
154770 + * * Neither the name of Freescale Semiconductor nor the
154771 + * names of its contributors may be used to endorse or promote products
154772 + * derived from this software without specific prior written permission.
154773 + *
154774 + *
154775 + * ALTERNATIVELY, this software may be distributed under the terms of the
154776 + * GNU General Public License ("GPL") as published by the Free Software
154777 + * Foundation, either version 2 of that License or (at your option) any
154778 + * later version.
154779 + *
154780 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
154781 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
154782 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
154783 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
154784 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
154785 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
154786 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
154787 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
154788 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
154789 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154790 + */
154791 +
154792 +/******************************************************************************
154793 + @File fm_port_ioctls.h
154794 +
154795 + @Description FM Port routines
154796 +*//***************************************************************************/
154797 +#ifndef __FM_PORT_IOCTLS_H
154798 +#define __FM_PORT_IOCTLS_H
154799 +
154800 +#include "enet_ext.h"
154801 +#include "net_ioctls.h"
154802 +#include "fm_ioctls.h"
154803 +#include "fm_pcd_ioctls.h"
154804 +
154805 +
154806 +/**************************************************************************//**
154807 +
154808 + @Group lnx_ioctl_FM_grp Frame Manager Linux IOCTL API
154809 +
154810 + @Description FM Linux ioctls definitions and enums
154811 +
154812 + @{
154813 +*//***************************************************************************/
154814 +
154815 +/**************************************************************************//**
154816 + @Group lnx_ioctl_FM_PORT_grp FM Port
154817 +
154818 + @Description FM Port API
154819 +
154820 + The FM uses a general module called "port" to represent a Tx port
154821 + (MAC), an Rx port (MAC), offline parsing flow or host command
154822 + flow. There may be up to 17 (may change) ports in an FM - 5 Tx
154823 + ports (4 for the 1G MACs, 1 for the 10G MAC), 5 Rx Ports, and 7
154824 + Host command/Offline parsing ports. The SW driver manages these
154825 + ports as sub-modules of the FM, i.e. after an FM is initialized,
154826 + its ports may be initialized and operated upon.
154827 +
154828 + The port is initialized aware of its type, but other functions on
154829 + a port may be indifferent to its type. When necessary, the driver
154830 + verifies coherency and returns error if applicable.
154831 +
154832 + On initialization, user specifies the port type and it's index
154833 + (relative to the port's type). Host command and Offline parsing
154834 + ports share the same id range, I.e user may not initialized host
154835 + command port 0 and offline parsing port 0.
154836 +
154837 + @{
154838 +*//***************************************************************************/
154839 +
154840 +/**************************************************************************//**
154841 + @Description An enum for defining port PCD modes.
154842 + (Must match enum e_FmPortPcdSupport defined in fm_port_ext.h)
154843 +
154844 + This enum defines the superset of PCD engines support - i.e. not
154845 + all engines have to be used, but all have to be enabled. The real
154846 + flow of a specific frame depends on the PCD configuration and the
154847 + frame headers and payload.
154848 + Note: the first engine and the first engine after the parser (if
154849 + exists) should be in order, the order is important as it will
154850 + define the flow of the port. However, as for the rest engines
154851 + (the ones that follows), the order is not important anymore as
154852 + it is defined by the PCD graph itself.
154853 +*//***************************************************************************/
154854 +typedef enum ioc_fm_port_pcd_support {
154855 + e_IOC_FM_PORT_PCD_SUPPORT_NONE = 0 /**< BMI to BMI, PCD is not used */
154856 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_ONLY /**< Use only Parser */
154857 + , e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY /**< Use only Policer */
154858 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR /**< Use Parser and Policer */
154859 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG /**< Use Parser and Keygen */
154860 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC /**< Use Parser, Keygen and Coarse Classification */
154861 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_CC_AND_PLCR
154862 + /**< Use all PCD engines */
154863 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_KG_AND_PLCR /**< Use Parser, Keygen and Policer */
154864 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC /**< Use Parser and Coarse Classification */
154865 + , e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_CC_AND_PLCR /**< Use Parser and Coarse Classification and Policer */
154866 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_ONLY /**< Use only Coarse Classification */
154867 +#if (defined(FM_CAPWAP_SUPPORT) && (DPAA_VERSION == 10))
154868 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG /**< Use Coarse Classification,and Keygen */
154869 + , e_IOC_FM_PORT_PCD_SUPPORT_CC_AND_KG_AND_PLCR /**< Use Coarse Classification, Keygen and Policer */
154870 +#endif /* FM_CAPWAP_SUPPORT */
154871 +} ioc_fm_port_pcd_support;
154872 +
154873 +
154874 +/**************************************************************************//**
154875 + @Collection FM Frame error
154876 +*//***************************************************************************/
154877 +typedef uint32_t ioc_fm_port_frame_err_select_t; /**< typedef for defining Frame Descriptor errors */
154878 +
154879 +/* @} */
154880 +
154881 +
154882 +/**************************************************************************//**
154883 + @Description An enum for defining Dual Tx rate limiting scale.
154884 + (Must match e_FmPortDualRateLimiterScaleDown defined in fm_port_ext.h)
154885 +*//***************************************************************************/
154886 +typedef enum ioc_fm_port_dual_rate_limiter_scale_down {
154887 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_NONE = 0, /**< Use only single rate limiter */
154888 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_2, /**< Divide high rate limiter by 2 */
154889 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_4, /**< Divide high rate limiter by 4 */
154890 + e_IOC_FM_PORT_DUAL_RATE_LIMITER_SCALE_DOWN_BY_8 /**< Divide high rate limiter by 8 */
154891 +} ioc_fm_port_dual_rate_limiter_scale_down;
154892 +
154893 +/**************************************************************************//**
154894 + @Description A structure for defining Tx rate limiting
154895 + (Must match struct t_FmPortRateLimit defined in fm_port_ext.h)
154896 +*//***************************************************************************/
154897 +typedef struct ioc_fm_port_rate_limit_t {
154898 + uint16_t max_burst_size; /**< in KBytes for Tx ports, in frames
154899 + for offline parsing ports. (note that
154900 + for early chips burst size is
154901 + rounded up to a multiply of 1000 frames).*/
154902 + uint32_t rate_limit; /**< in Kb/sec for Tx ports, in frame/sec for
154903 + offline parsing ports. Rate limit refers to
154904 + data rate (rather than line rate). */
154905 + ioc_fm_port_dual_rate_limiter_scale_down rate_limit_divider; /**< For offline parsing ports only. Not-valid
154906 + for some earlier chip revisions */
154907 +} ioc_fm_port_rate_limit_t;
154908 +
154909 +
154910 +
154911 +/**************************************************************************//**
154912 + @Group lnx_ioctl_FM_PORT_runtime_control_grp FM Port Runtime Control Unit
154913 +
154914 + @Description FM Port Runtime control unit API functions, definitions and enums.
154915 +
154916 + @{
154917 +*//***************************************************************************/
154918 +
154919 +/**************************************************************************//**
154920 + @Description An enum for defining FM Port counters.
154921 + (Must match enum e_FmPortCounters defined in fm_port_ext.h)
154922 +*//***************************************************************************/
154923 +typedef enum ioc_fm_port_counters {
154924 + e_IOC_FM_PORT_COUNTERS_CYCLE, /**< BMI performance counter */
154925 + e_IOC_FM_PORT_COUNTERS_TASK_UTIL, /**< BMI performance counter */
154926 + e_IOC_FM_PORT_COUNTERS_QUEUE_UTIL, /**< BMI performance counter */
154927 + e_IOC_FM_PORT_COUNTERS_DMA_UTIL, /**< BMI performance counter */
154928 + e_IOC_FM_PORT_COUNTERS_FIFO_UTIL, /**< BMI performance counter */
154929 + e_IOC_FM_PORT_COUNTERS_RX_PAUSE_ACTIVATION, /**< BMI Rx only performance counter */
154930 + e_IOC_FM_PORT_COUNTERS_FRAME, /**< BMI statistics counter */
154931 + e_IOC_FM_PORT_COUNTERS_DISCARD_FRAME, /**< BMI statistics counter */
154932 + e_IOC_FM_PORT_COUNTERS_DEALLOC_BUF, /**< BMI deallocate buffer statistics counter */
154933 + e_IOC_FM_PORT_COUNTERS_RX_BAD_FRAME, /**< BMI Rx only statistics counter */
154934 + e_IOC_FM_PORT_COUNTERS_RX_LARGE_FRAME, /**< BMI Rx only statistics counter */
154935 + e_IOC_FM_PORT_COUNTERS_RX_FILTER_FRAME, /**< BMI Rx & OP only statistics counter */
154936 + e_IOC_FM_PORT_COUNTERS_RX_LIST_DMA_ERR, /**< BMI Rx, OP & HC only statistics counter */
154937 + e_IOC_FM_PORT_COUNTERS_RX_OUT_OF_BUFFERS_DISCARD, /**< BMI Rx, OP & HC statistics counter */
154938 + e_IOC_FM_PORT_COUNTERS_PREPARE_TO_ENQUEUE_COUNTER, /**< BMI Rx, OP & HC only statistics counter */
154939 + e_IOC_FM_PORT_COUNTERS_WRED_DISCARD, /**< BMI OP & HC only statistics counter */
154940 + e_IOC_FM_PORT_COUNTERS_LENGTH_ERR, /**< BMI non-Rx statistics counter */
154941 + e_IOC_FM_PORT_COUNTERS_UNSUPPRTED_FORMAT, /**< BMI non-Rx statistics counter */
154942 + e_IOC_FM_PORT_COUNTERS_DEQ_TOTAL, /**< QMI total QM dequeues counter */
154943 + e_IOC_FM_PORT_COUNTERS_ENQ_TOTAL, /**< QMI total QM enqueues counter */
154944 + e_IOC_FM_PORT_COUNTERS_DEQ_FROM_DEFAULT, /**< QMI counter */
154945 + e_IOC_FM_PORT_COUNTERS_DEQ_CONFIRM /**< QMI counter */
154946 +} ioc_fm_port_counters;
154947 +
154948 +typedef struct ioc_fm_port_bmi_stats_t {
154949 + uint32_t cnt_cycle;
154950 + uint32_t cnt_task_util;
154951 + uint32_t cnt_queue_util;
154952 + uint32_t cnt_dma_util;
154953 + uint32_t cnt_fifo_util;
154954 + uint32_t cnt_rx_pause_activation;
154955 + uint32_t cnt_frame;
154956 + uint32_t cnt_discard_frame;
154957 + uint32_t cnt_dealloc_buf;
154958 + uint32_t cnt_rx_bad_frame;
154959 + uint32_t cnt_rx_large_frame;
154960 + uint32_t cnt_rx_filter_frame;
154961 + uint32_t cnt_rx_list_dma_err;
154962 + uint32_t cnt_rx_out_of_buffers_discard;
154963 + uint32_t cnt_wred_discard;
154964 + uint32_t cnt_length_err;
154965 + uint32_t cnt_unsupported_format;
154966 +} ioc_fm_port_bmi_stats_t;
154967 +
154968 +/**************************************************************************//**
154969 + @Description Structure for Port id parameters.
154970 + (Description may be inaccurate;
154971 + must match struct t_FmPortCongestionGrps defined in fm_port_ext.h)
154972 +
154973 + Fields commented 'IN' are passed by the port module to be used
154974 + by the FM module.
154975 + Fields commented 'OUT' will be filled by FM before returning to port.
154976 +*//***************************************************************************/
154977 +typedef struct ioc_fm_port_congestion_groups_t {
154978 + uint16_t num_of_congestion_grps_to_consider; /**< The number of required congestion groups
154979 + to define the size of the following array */
154980 + uint8_t congestion_grps_to_consider [FM_PORT_NUM_OF_CONGESTION_GRPS];
154981 + /**< An array of CG indexes;
154982 + Note that the size of the array should be
154983 + 'num_of_congestion_grps_to_consider'. */
154984 +#if DPAA_VERSION >= 11
154985 + bool pfc_priorities_enable[FM_PORT_NUM_OF_CONGESTION_GRPS][FM_MAX_NUM_OF_PFC_PRIORITIES];
154986 + /**< A matrix that represents the map between the CG ids
154987 + defined in 'congestion_grps_to_consider' to the priorities
154988 + mapping array. */
154989 +#endif /* DPAA_VERSION >= 11 */
154990 +} ioc_fm_port_congestion_groups_t;
154991 +
154992 +
154993 +
154994 +/**************************************************************************//**
154995 + @Function FM_PORT_Disable
154996 +
154997 + @Description Gracefully disable an FM port. The port will not start new tasks after all
154998 + tasks associated with the port are terminated.
154999 +
155000 + @Return 0 on success; error code otherwise.
155001 +
155002 + @Cautions This is a blocking routine, it returns after port is
155003 + gracefully stopped, i.e. the port will not except new frames,
155004 + but it will finish all frames or tasks which were already began
155005 +*//***************************************************************************/
155006 +#define FM_PORT_IOC_DISABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(1))
155007 +
155008 +/**************************************************************************//**
155009 + @Function FM_PORT_Enable
155010 +
155011 + @Description A runtime routine provided to allow disable/enable of port.
155012 +
155013 + @Return 0 on success; error code otherwise.
155014 +*//***************************************************************************/
155015 +#define FM_PORT_IOC_ENABLE _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(2))
155016 +
155017 +/**************************************************************************//**
155018 + @Function FM_PORT_SetRateLimit
155019 +
155020 + @Description Calling this routine enables rate limit algorithm.
155021 + By default, this functionality is disabled.
155022 + Note that rate-limit mechanism uses the FM time stamp.
155023 + The selected rate limit specified here would be
155024 + rounded DOWN to the nearest 16M.
155025 +
155026 + May be used for Tx and offline parsing ports only
155027 +
155028 + @Param[in] ioc_fm_port_rate_limit A structure of rate limit parameters
155029 +
155030 + @Return 0 on success; error code otherwise.
155031 +*//***************************************************************************/
155032 +#define FM_PORT_IOC_SET_RATE_LIMIT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(3), ioc_fm_port_rate_limit_t)
155033 +
155034 +/**************************************************************************//**
155035 + @Function FM_PORT_DeleteRateLimit
155036 +
155037 + @Description Calling this routine disables the previously enabled rate limit.
155038 +
155039 + May be used for Tx and offline parsing ports only
155040 +
155041 + @Return 0 on success; error code otherwise.
155042 +*//***************************************************************************/
155043 +#define FM_PORT_IOC_DELETE_RATE_LIMIT _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(5))
155044 +#define FM_PORT_IOC_REMOVE_RATE_LIMIT FM_PORT_IOC_DELETE_RATE_LIMIT
155045 +
155046 +
155047 +/**************************************************************************//**
155048 + @Function FM_PORT_AddCongestionGrps
155049 +
155050 + @Description This routine effects the corresponding Tx port.
155051 + It should be called in order to enable pause
155052 + frame transmission in case of congestion in one or more
155053 + of the congestion groups relevant to this port.
155054 + Each call to this routine may add one or more congestion
155055 + groups to be considered relevant to this port.
155056 +
155057 + May be used for Rx, or RX+OP ports only (depending on chip)
155058 +
155059 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
155060 + congestion group ids to consider.
155061 +
155062 + @Return 0 on success; error code otherwise.
155063 +*//***************************************************************************/
155064 +#define FM_PORT_IOC_ADD_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(34), ioc_fm_port_congestion_groups_t)
155065 +
155066 +/**************************************************************************//**
155067 + @Function FM_PORT_RemoveCongestionGrps
155068 +
155069 + @Description This routine effects the corresponding Tx port. It should be
155070 + called when congestion groups were
155071 + defined for this port and are no longer relevant, or pause
155072 + frames transmitting is not required on their behalf.
155073 + Each call to this routine may remove one or more congestion
155074 + groups to be considered relevant to this port.
155075 +
155076 + May be used for Rx, or RX+OP ports only (depending on chip)
155077 +
155078 + @Param[in] ioc_fm_port_congestion_groups_t - A pointer to an array of
155079 + congestion group ids to consider.
155080 +
155081 + @Return 0 on success; error code otherwise.
155082 +*//***************************************************************************/
155083 +#define FM_PORT_IOC_REMOVE_CONGESTION_GRPS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(35), ioc_fm_port_congestion_groups_t)
155084 +
155085 +/**************************************************************************//**
155086 + @Function FM_PORT_SetErrorsRoute
155087 +
155088 + @Description Errors selected for this routine will cause a frame with that error
155089 + to be enqueued to error queue.
155090 + Errors not selected for this routine will cause a frame with that error
155091 + to be enqueued to the one of the other port queues.
155092 + By default all errors are defined to be enqueued to error queue.
155093 + Errors that were configured to be discarded (at initialization)
155094 + may not be selected here.
155095 +
155096 + May be used for Rx and offline parsing ports only
155097 +
155098 + @Param[in] ioc_fm_port_frame_err_select_t A list of errors to enqueue to error queue
155099 +
155100 + @Return 0 on success; error code otherwise.
155101 +
155102 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
155103 + (szbs001: How is it possible to have one function that needs to be
155104 + called BEFORE FM_PORT_Init() implemented as an ioctl,
155105 + which will ALWAYS be called AFTER the FM_PORT_Init()
155106 + for that port!?!?!?!???!?!??!?!?)
155107 +*//***************************************************************************/
155108 +#define FM_PORT_IOC_SET_ERRORS_ROUTE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(4), ioc_fm_port_frame_err_select_t)
155109 +
155110 +
155111 +/**************************************************************************//**
155112 + @Group lnx_ioctl_FM_PORT_pcd_runtime_control_grp FM Port PCD Runtime Control Unit
155113 +
155114 + @Description FM Port PCD Runtime control unit API functions, definitions and enums.
155115 +
155116 + @{
155117 +*//***************************************************************************/
155118 +
155119 +/**************************************************************************//**
155120 + @Description A structure defining the KG scheme after the parser.
155121 + (Must match struct t_FmPcdKgSchemeSelect defined in fm_port_ext.h)
155122 +
155123 + This is relevant only to change scheme selection mode - from
155124 + direct to indirect and vice versa, or when the scheme is selected directly,
155125 + to select the scheme id.
155126 +
155127 +*//***************************************************************************/
155128 +typedef struct ioc_fm_pcd_kg_scheme_select_t {
155129 + bool direct; /**< TRUE to use 'scheme_id' directly, FALSE to use LCV.*/
155130 + void *scheme_id; /**< Relevant for 'direct'=TRUE only.
155131 + 'scheme_id' selects the scheme after parser. */
155132 +} ioc_fm_pcd_kg_scheme_select_t;
155133 +
155134 +/**************************************************************************//**
155135 + @Description Scheme IDs structure
155136 + (Must match struct t_FmPcdPortSchemesParams defined in fm_port_ext.h)
155137 +*//***************************************************************************/
155138 +typedef struct ioc_fm_pcd_port_schemes_params_t {
155139 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
155140 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES]; /**< Array of 'num_of_schemes' schemes for the
155141 + port to be bound to */
155142 +} ioc_fm_pcd_port_schemes_params_t;
155143 +
155144 +/**************************************************************************//**
155145 + @Description A union for defining port protocol parameters for parser
155146 + (Must match union u_FmPcdHdrPrsOpts defined in fm_port_ext.h)
155147 +*//***************************************************************************/
155148 +typedef union ioc_fm_pcd_hdr_prs_opts_u {
155149 + /* MPLS */
155150 + struct {
155151 + bool label_interpretation_enable;/**< When this bit is set, the last MPLS label will be
155152 + interpreted as described in HW spec table. When the bit
155153 + is cleared, the parser will advance to MPLS next parse */
155154 + ioc_net_header_type next_parse; /**< must be equal or higher than IPv4 */
155155 + } mpls_prs_options;
155156 +
155157 + /* VLAN */
155158 + struct {
155159 + uint16_t tag_protocol_id1; /**< User defined Tag Protocol Identifier, to be recognized
155160 + on VLAN TAG on top of 0x8100 and 0x88A8 */
155161 + uint16_t tag_protocol_id2; /**< User defined Tag Protocol Identifier, to be recognized
155162 + on VLAN TAG on top of 0x8100 and 0x88A8 */
155163 + } vlan_prs_options;
155164 +
155165 + /* PPP */
155166 + struct{
155167 + bool enable_mtu_check; /**< Check validity of MTU according to RFC2516 */
155168 + } pppoe_prs_options;
155169 +
155170 + /* IPV6 */
155171 + struct {
155172 + bool routing_hdr_disable; /**< Disable routing header */
155173 + } ipv6_prs_options;
155174 +
155175 + /* UDP */
155176 + struct {
155177 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
155178 + } udp_prs_options;
155179 +
155180 + /* TCP */
155181 + struct {
155182 + bool pad_ignore_checksum; /**< TRUE to ignore pad in checksum */
155183 + } tcp_prs_options;
155184 +} ioc_fm_pcd_hdr_prs_opts_u;
155185 +
155186 +/**************************************************************************//**
155187 + @Description A structure for defining each header for the parser
155188 + (must match struct t_FmPcdPrsAdditionalHdrParams defined in fm_port_ext.h)
155189 +*//***************************************************************************/
155190 +typedef struct ioc_fm_pcd_prs_additional_hdr_params_t {
155191 + ioc_net_header_type hdr; /**< Selected header */
155192 + bool err_disable; /**< TRUE to disable error indication */
155193 + bool soft_prs_enable; /**< Enable jump to SW parser when this
155194 + header is recognized by the HW parser. */
155195 + uint8_t index_per_hdr; /**< Normally 0, if more than one sw parser
155196 + attachments exists for the same header,
155197 + (in the main sw parser code) use this
155198 + index to distinguish between them. */
155199 + bool use_prs_opts; /**< TRUE to use parser options. */
155200 + ioc_fm_pcd_hdr_prs_opts_u prs_opts; /**< A unuion according to header type,
155201 + defining the parser options selected.*/
155202 +} ioc_fm_pcd_prs_additional_hdr_params_t;
155203 +
155204 +/**************************************************************************//**
155205 + @Description A structure for defining port PCD parameters
155206 + (Must match t_FmPortPcdPrsParams defined in fm_port_ext.h)
155207 +*//***************************************************************************/
155208 +typedef struct ioc_fm_port_pcd_prs_params_t {
155209 + uint8_t prs_res_priv_info; /**< The private info provides a method of inserting
155210 + port information into the parser result. This information
155211 + may be extracted by KeyGen and be used for frames
155212 + distribution when a per-port distinction is required,
155213 + it may also be used as a port logical id for analyzing
155214 + incoming frames. */
155215 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to start parsing */
155216 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at 'parsing_offset' */
155217 + bool include_in_prs_statistics; /**< TRUE to include this port in the parser statistics */
155218 + uint8_t num_of_hdrs_with_additional_params;
155219 + /**< Normally 0, some headers may get special parameters */
155220 + ioc_fm_pcd_prs_additional_hdr_params_t additional_params[IOC_FM_PCD_PRS_NUM_OF_HDRS];
155221 + /**< 'num_of_hdrs_with_additional_params' structures
155222 + additional parameters for each header that requires them */
155223 + bool set_vlan_tpid1; /**< TRUE to configure user selection of Ethertype to
155224 + indicate a VLAN tag (in addition to the TPID values
155225 + 0x8100 and 0x88A8). */
155226 + uint16_t vlan_tpid1; /**< extra tag to use if set_vlan_tpid1=TRUE. */
155227 + bool set_vlan_tpid2; /**< TRUE to configure user selection of Ethertype to
155228 + indicate a VLAN tag (in addition to the TPID values
155229 + 0x8100 and 0x88A8). */
155230 + uint16_t vlan_tpid2; /**< extra tag to use if set_vlan_tpid1=TRUE. */
155231 +} ioc_fm_port_pcd_prs_params_t;
155232 +
155233 +/**************************************************************************//**
155234 + @Description A structure for defining coarse alassification parameters
155235 + (Must match t_FmPortPcdCcParams defined in fm_port_ext.h)
155236 +*//***************************************************************************/
155237 +typedef struct ioc_fm_port_pcd_cc_params_t {
155238 + void *cc_tree_id; /**< CC tree id */
155239 +} ioc_fm_port_pcd_cc_params_t;
155240 +
155241 +/**************************************************************************//**
155242 + @Description A structure for defining keygen parameters
155243 + (Must match t_FmPortPcdKgParams defined in fm_port_ext.h)
155244 +*//***************************************************************************/
155245 +typedef struct ioc_fm_port_pcd_kg_params_t {
155246 + uint8_t num_of_schemes; /**< Number of schemes for port to be bound to. */
155247 + void *scheme_ids[FM_PCD_KG_NUM_OF_SCHEMES];
155248 + /**< Array of 'num_of_schemes' schemes for the
155249 + port to be bound to */
155250 + bool direct_scheme; /**< TRUE for going from parser to a specific scheme,
155251 + regardless of parser result */
155252 + void *direct_scheme_id; /**< Scheme id, as returned by FM_PCD_KgSetScheme;
155253 + relevant only if direct=TRUE. */
155254 +} ioc_fm_port_pcd_kg_params_t;
155255 +
155256 +/**************************************************************************//**
155257 + @Description A structure for defining policer parameters
155258 + (Must match t_FmPortPcdPlcrParams defined in fm_port_ext.h)
155259 +*//***************************************************************************/
155260 +typedef struct ioc_fm_port_pcd_plcr_params_t {
155261 + void *plcr_profile_id; /**< Selected profile handle;
155262 + relevant in one of the following cases:
155263 + e_IOC_FM_PORT_PCD_SUPPORT_PLCR_ONLY or
155264 + e_IOC_FM_PORT_PCD_SUPPORT_PRS_AND_PLCR were selected,
155265 + or if any flow uses a KG scheme where policer
155266 + profile is not generated (bypass_plcr_profile_generation selected) */
155267 +} ioc_fm_port_pcd_plcr_params_t;
155268 +
155269 +/**************************************************************************//**
155270 + @Description A structure for defining port PCD parameters
155271 + (Must match struct t_FmPortPcdParams defined in fm_port_ext.h)
155272 +*//***************************************************************************/
155273 +typedef struct ioc_fm_port_pcd_params_t {
155274 + ioc_fm_port_pcd_support pcd_support; /**< Relevant for Rx and offline ports only.
155275 + Describes the active PCD engines for this port. */
155276 + void *net_env_id; /**< HL Unused in PLCR only mode */
155277 + ioc_fm_port_pcd_prs_params_t *p_prs_params; /**< Parser parameters for this port */
155278 + ioc_fm_port_pcd_cc_params_t *p_cc_params; /**< Coarse classification parameters for this port */
155279 + ioc_fm_port_pcd_kg_params_t *p_kg_params; /**< Keygen parameters for this port */
155280 + ioc_fm_port_pcd_plcr_params_t *p_plcr_params; /**< Policer parameters for this port */
155281 + void *p_ip_reassembly_manip;/**< IP Reassembly manipulation */
155282 +#if (DPAA_VERSION >= 11)
155283 + void *p_capwap_reassembly_manip;/**< CAPWAP Reassembly manipulation */
155284 +#endif /* (DPAA_VERSION >= 11) */
155285 +} ioc_fm_port_pcd_params_t;
155286 +
155287 +/**************************************************************************//**
155288 + @Description A structure for defining the Parser starting point
155289 + (Must match struct t_FmPcdPrsStart defined in fm_port_ext.h)
155290 +*//***************************************************************************/
155291 +typedef struct ioc_fm_pcd_prs_start_t {
155292 + uint8_t parsing_offset; /**< Number of bytes from begining of packet to
155293 + start parsing */
155294 + ioc_net_header_type first_prs_hdr; /**< The type of the first header axpected at
155295 + 'parsing_offset' */
155296 +} ioc_fm_pcd_prs_start_t;
155297 +
155298 +
155299 +/**************************************************************************//**
155300 + @Description FQID parameters structure
155301 +*//***************************************************************************/
155302 +typedef struct ioc_fm_port_pcd_fqids_params_t {
155303 + uint32_t num_fqids; /**< Number of fqids to be allocated for the port */
155304 + uint8_t alignment; /**< Alignment required for this port */
155305 + uint32_t base_fqid; /**< output parameter - the base fqid */
155306 +} ioc_fm_port_pcd_fqids_params_t;
155307 +
155308 +
155309 +/**************************************************************************//**
155310 + @Function FM_PORT_IOC_ALLOC_PCD_FQIDS
155311 +
155312 + @Description Allocates FQID's
155313 +
155314 + May be used for Rx and offline parsing ports only
155315 +
155316 + @Param[in,out] ioc_fm_port_pcd_fqids_params_t Parameters for allocating FQID's
155317 +
155318 + @Return 0 on success; error code otherwise.
155319 +*//***************************************************************************/
155320 +#define FM_PORT_IOC_ALLOC_PCD_FQIDS _IOWR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), ioc_fm_port_pcd_fqids_params_t)
155321 +
155322 +/**************************************************************************//**
155323 + @Function FM_PORT_IOC_FREE_PCD_FQIDS
155324 +
155325 + @Description Frees previously-allocated FQIDs
155326 +
155327 + May be used for Rx and offline parsing ports only
155328 +
155329 + @Param[in] uint32_t Base FQID of previously allocated range.
155330 +
155331 + @Return 0 on success; error code otherwise.
155332 +*//***************************************************************************/
155333 +#define FM_PORT_IOC_FREE_PCD_FQIDS _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(19), uint32_t)
155334 +
155335 +
155336 +/**************************************************************************//**
155337 + @Function FM_PORT_SetPCD
155338 +
155339 + @Description Calling this routine defines the port's PCD configuration.
155340 + It changes it from its default configuration which is PCD
155341 + disabled (BMI to BMI) and configures it according to the passed
155342 + parameters.
155343 +
155344 + May be used for Rx and offline parsing ports only
155345 +
155346 + @Param[in] ioc_fm_port_pcd_params_t A Structure of parameters defining the port's PCD
155347 + configuration.
155348 +
155349 + @Return 0 on success; error code otherwise.
155350 +*//***************************************************************************/
155351 +#if defined(CONFIG_COMPAT)
155352 +#define FM_PORT_IOC_SET_PCD_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_compat_fm_port_pcd_params_t)
155353 +#endif
155354 +#define FM_PORT_IOC_SET_PCD _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(20), ioc_fm_port_pcd_params_t)
155355 +
155356 +/**************************************************************************//**
155357 + @Function FM_PORT_DeletePCD
155358 +
155359 + @Description Calling this routine releases the port's PCD configuration.
155360 + The port returns to its default configuration which is PCD
155361 + disabled (BMI to BMI) and all PCD configuration is removed.
155362 +
155363 + May be used for Rx and offline parsing ports which are
155364 + in PCD mode only
155365 +
155366 + @Return 0 on success; error code otherwise.
155367 +*//***************************************************************************/
155368 +#define FM_PORT_IOC_DELETE_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(21))
155369 +
155370 +/**************************************************************************//**
155371 + @Function FM_PORT_AttachPCD
155372 +
155373 + @Description This routine may be called after FM_PORT_DetachPCD was called,
155374 + to return to the originally configured PCD support flow.
155375 + The couple of routines are used to allow PCD configuration changes
155376 + that demand that PCD will not be used while changes take place.
155377 +
155378 + May be used for Rx and offline parsing ports which are
155379 + in PCD mode only
155380 +
155381 + @Return 0 on success; error code otherwise.
155382 +*//***************************************************************************/
155383 +#define FM_PORT_IOC_ATTACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(23))
155384 +
155385 +/**************************************************************************//**
155386 + @Function FM_PORT_DetachPCD
155387 +
155388 + @Description Calling this routine detaches the port from its PCD functionality.
155389 + The port returns to its default flow which is BMI to BMI.
155390 +
155391 + May be used for Rx and offline parsing ports which are
155392 + in PCD mode only
155393 +
155394 + @Return 0 on success; error code otherwise.
155395 +*//***************************************************************************/
155396 +#define FM_PORT_IOC_DETACH_PCD _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(22))
155397 +
155398 +/**************************************************************************//**
155399 + @Function FM_PORT_PcdPlcrAllocProfiles
155400 +
155401 + @Description This routine may be called only for ports that use the Policer in
155402 + order to allocate private policer profiles.
155403 +
155404 + @Param[in] uint16_t The number of required policer profiles
155405 +
155406 + @Return 0 on success; error code otherwise.
155407 +
155408 + @Cautions Allowed before FM_PORT_SetPCD() only.
155409 +*//***************************************************************************/
155410 +#define FM_PORT_IOC_PCD_PLCR_ALLOC_PROFILES _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(24), uint16_t)
155411 +
155412 +/**************************************************************************//**
155413 + @Function FM_PORT_PcdPlcrFreeProfiles
155414 +
155415 + @Description This routine should be called for freeing private policer profiles.
155416 +
155417 + @Return 0 on success; error code otherwise.
155418 +
155419 + @Cautions Allowed before FM_PORT_SetPCD() only.
155420 +*//***************************************************************************/
155421 +#define FM_PORT_IOC_PCD_PLCR_FREE_PROFILES _IO(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(25))
155422 +
155423 +/**************************************************************************//**
155424 + @Function FM_PORT_PcdKgModifyInitialScheme
155425 +
155426 + @Description This routine may be called only for ports that use the keygen in
155427 + order to change the initial scheme frame should be routed to.
155428 + The change may be of a scheme id (in case of direct mode),
155429 + from direct to indirect, or from indirect to direct - specifying the scheme id.
155430 +
155431 + @Param[in] ioc_fm_pcd_kg_scheme_select_t A structure of parameters for defining whether
155432 + a scheme is direct/indirect, and if direct - scheme id.
155433 +
155434 + @Return 0 on success; error code otherwise.
155435 +*//***************************************************************************/
155436 +#if defined(CONFIG_COMPAT)
155437 +#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)
155438 +#endif
155439 +#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)
155440 +
155441 +/**************************************************************************//**
155442 + @Function FM_PORT_PcdPlcrModifyInitialProfile
155443 +
155444 + @Description This routine may be called for ports with flows
155445 + e_IOC_FM_PCD_SUPPORT_PLCR_ONLY or e_IOC_FM_PCD_SUPPORT_PRS_AND_PLCR only,
155446 + to change the initial Policer profile frame should be routed to.
155447 + The change may be of a profile and/or absolute/direct mode selection.
155448 +
155449 + @Param[in] ioc_fm_obj_t Policer profile Id as returned from FM_PCD_PlcrSetProfile.
155450 +
155451 + @Return 0 on success; error code otherwise.
155452 +*//***************************************************************************/
155453 +#if defined(CONFIG_COMPAT)
155454 +#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)
155455 +#endif
155456 +#define FM_PORT_IOC_PCD_PLCR_MODIFY_INITIAL_PROFILE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(27), ioc_fm_obj_t)
155457 +
155458 +/**************************************************************************//**
155459 + @Function FM_PORT_PcdCcModifyTree
155460 +
155461 + @Description This routine may be called to change this port connection to
155462 + a pre-initializes coarse classification Tree.
155463 +
155464 + @Param[in] ioc_fm_obj_t Id of new coarse classification tree selected for this port.
155465 +
155466 + @Return 0 on success; error code otherwise.
155467 +
155468 + @Cautions Allowed only following FM_PORT_SetPCD() and FM_PORT_DetachPCD()
155469 +*//***************************************************************************/
155470 +#if defined(CONFIG_COMPAT)
155471 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE_COMPAT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_compat_fm_obj_t)
155472 +#endif
155473 +#define FM_PORT_IOC_PCD_CC_MODIFY_TREE _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(28), ioc_fm_obj_t)
155474 +
155475 +/**************************************************************************//**
155476 + @Function FM_PORT_PcdKgBindSchemes
155477 +
155478 + @Description These routines may be called for modifying the binding of ports
155479 + to schemes. The scheme itself is not added,
155480 + just this specific port starts using it.
155481 +
155482 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
155483 +
155484 + @Return 0 on success; error code otherwise.
155485 +
155486 + @Cautions Allowed only following FM_PORT_SetPCD().
155487 +*//***************************************************************************/
155488 +#if defined(CONFIG_COMPAT)
155489 +#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)
155490 +#endif
155491 +#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)
155492 +
155493 +/**************************************************************************//**
155494 + @Function FM_PORT_PcdKgUnbindSchemes
155495 +
155496 + @Description These routines may be called for modifying the binding of ports
155497 + to schemes. The scheme itself is not removed or invalidated,
155498 + just this specific port stops using it.
155499 +
155500 + @Param[in] ioc_fm_pcd_port_schemes_params_t Schemes parameters structre
155501 +
155502 + @Return 0 on success; error code otherwise.
155503 +
155504 + @Cautions Allowed only following FM_PORT_SetPCD().
155505 +*//***************************************************************************/
155506 +#if defined(CONFIG_COMPAT)
155507 +#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)
155508 +#endif
155509 +#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)
155510 +
155511 +typedef struct ioc_fm_port_mac_addr_params_t {
155512 + uint8_t addr[ENET_NUM_OCTETS_PER_ADDRESS];
155513 +} ioc_fm_port_mac_addr_params_t;
155514 +
155515 +/**************************************************************************//**
155516 + @Function FM_MAC_AddHashMacAddr
155517 +
155518 + @Description Add an Address to the hash table. This is for filter purpose only.
155519 +
155520 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
155521 +
155522 + @Return E_OK on success; Error code otherwise.
155523 +
155524 + @Cautions Allowed only following FM_MAC_Init(). It is a filter only address.
155525 + @Cautions Some address need to be filtered out in upper FM blocks.
155526 +*//***************************************************************************/
155527 +#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)
155528 +
155529 +/**************************************************************************//**
155530 + @Function FM_MAC_RemoveHashMacAddr
155531 +
155532 + @Description Delete an Address to the hash table. This is for filter purpose only.
155533 +
155534 + @Param[in] ioc_fm_port_mac_addr_params_t - Ethernet Mac address
155535 +
155536 + @Return E_OK on success; Error code otherwise.
155537 +
155538 + @Cautions Allowed only following FM_MAC_Init().
155539 +*//***************************************************************************/
155540 +#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)
155541 +
155542 +typedef struct ioc_fm_port_tx_pause_frames_params_t {
155543 + uint8_t priority;
155544 + uint16_t pause_time;
155545 + uint16_t thresh_time;
155546 +} ioc_fm_port_tx_pause_frames_params_t;
155547 +
155548 +/**************************************************************************//**
155549 + @Function FM_MAC_SetTxPauseFrames
155550 +
155551 + @Description Enable/Disable transmission of Pause-Frames.
155552 + The routine changes the default configuration:
155553 + pause-time - [0xf000]
155554 + threshold-time - [0]
155555 +
155556 + @Param[in] ioc_fm_port_tx_pause_frames_params_t A structure holding the required parameters.
155557 +
155558 + @Return E_OK on success; Error code otherwise.
155559 +
155560 + @Cautions Allowed only following FM_MAC_Init().
155561 + PFC is supported only on new mEMAC; i.e. in MACs that don't have
155562 + PFC support (10G-MAC and dTSEC), user should use 'FM_MAC_NO_PFC'
155563 + in the 'priority' field.
155564 +*//***************************************************************************/
155565 +#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)
155566 +
155567 +typedef struct ioc_fm_port_mac_statistics_t {
155568 + /* RMON */
155569 + uint64_t e_stat_pkts_64; /**< r-10G tr-DT 64 byte frame counter */
155570 + uint64_t e_stat_pkts_65_to_127; /**< r-10G 65 to 127 byte frame counter */
155571 + uint64_t e_stat_pkts_128_to_255; /**< r-10G 128 to 255 byte frame counter */
155572 + uint64_t e_stat_pkts_256_to_511; /**< r-10G 256 to 511 byte frame counter */
155573 + uint64_t e_stat_pkts_512_to_1023; /**< r-10G 512 to 1023 byte frame counter */
155574 + uint64_t e_stat_pkts_1024_to_1518; /**< r-10G 1024 to 1518 byte frame counter */
155575 + uint64_t e_stat_pkts_1519_to_1522; /**< r-10G 1519 to 1522 byte good frame count */
155576 + /* */
155577 + uint64_t e_stat_fragments; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
155578 + uint64_t e_stat_jabbers; /**< Total number of packets longer than valid maximum length octets */
155579 + uint64_t e_stat_drop_events; /**< number of dropped packets due to internal errors of the MAC Client (during recieve). */
155580 + uint64_t e_stat_CRC_align_errors; /**< Incremented when frames of correct length but with CRC error are received.*/
155581 + uint64_t e_stat_undersize_pkts; /**< Incremented for frames under 64 bytes with a valid FCS and otherwise well formed;
155582 + This count does not include range length errors */
155583 + uint64_t e_stat_oversize_pkts; /**< Incremented for frames which exceed 1518 (non VLAN) or 1522 (VLAN) and contains
155584 + a valid FCS and otherwise well formed */
155585 + /* Pause */
155586 + uint64_t te_stat_pause; /**< Pause MAC Control received */
155587 + uint64_t re_stat_pause; /**< Pause MAC Control sent */
155588 + /* MIB II */
155589 + uint64_t if_in_octets; /**< Total number of byte received. */
155590 + uint64_t if_in_pkts; /**< Total number of packets received.*/
155591 + uint64_t if_in_ucast_pkts; /**< Total number of unicast frame received;
155592 + NOTE: this counter is not supported on dTSEC MAC */
155593 + uint64_t if_in_mcast_pkts; /**< Total number of multicast frame received*/
155594 + uint64_t if_in_bcast_pkts; /**< Total number of broadcast frame received */
155595 + uint64_t if_in_discards; /**< Frames received, but discarded due to problems within the MAC RX. */
155596 + uint64_t if_in_errors; /**< Number of frames received with error:
155597 + - FIFO Overflow Error
155598 + - CRC Error
155599 + - Frame Too Long Error
155600 + - Alignment Error
155601 + - The dedicated Error Code (0xfe, not a code error) was received */
155602 + uint64_t if_out_octets; /**< Total number of byte sent. */
155603 + uint64_t if_out_pkts; /**< Total number of packets sent .*/
155604 + uint64_t if_out_ucast_pkts; /**< Total number of unicast frame sent;
155605 + NOTE: this counter is not supported on dTSEC MAC */
155606 + uint64_t if_out_mcast_pkts; /**< Total number of multicast frame sent */
155607 + uint64_t if_out_bcast_pkts; /**< Total number of multicast frame sent */
155608 + uint64_t if_out_discards; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
155609 + uint64_t if_out_errors; /**< Number of frames transmitted with error:
155610 + - FIFO Overflow Error
155611 + - FIFO Underflow Error
155612 + - Other */
155613 +} ioc_fm_port_mac_statistics_t;
155614 +
155615 +/**************************************************************************//**
155616 + @Function FM_MAC_GetStatistics
155617 +
155618 + @Description get all MAC statistics counters
155619 +
155620 + @Param[out] ioc_fm_port_mac_statistics_t A structure holding the statistics
155621 +
155622 + @Return E_OK on success; Error code otherwise.
155623 +
155624 + @Cautions Allowed only following FM_Init().
155625 +*//***************************************************************************/
155626 +#define FM_PORT_IOC_GET_MAC_STATISTICS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(41), ioc_fm_port_mac_statistics_t)
155627 +
155628 +/**************************************************************************//**
155629 + @Function FM_PORT_ConfigBufferPrefixContent
155630 +
155631 + @Description Defines the structure, size and content of the application buffer.
155632 + The prefix will
155633 + In Tx ports, if 'passPrsResult', the application
155634 + should set a value to their offsets in the prefix of
155635 + the FM will save the first 'privDataSize', than,
155636 + depending on 'passPrsResult' and 'passTimeStamp', copy parse result
155637 + and timeStamp, and the packet itself (in this order), to the
155638 + application buffer, and to offset.
155639 + Calling this routine changes the buffer margins definitions
155640 + in the internal driver data base from its default
155641 + configuration: Data size: [DEFAULT_FM_SP_bufferPrefixContent_privDataSize]
155642 + Pass Parser result: [DEFAULT_FM_SP_bufferPrefixContent_passPrsResult].
155643 + Pass timestamp: [DEFAULT_FM_SP_bufferPrefixContent_passTimeStamp].
155644 +
155645 + May be used for all ports
155646 +
155647 + @Param[in] ioc_fm_buffer_prefix_content_t A structure holding the required parameters.
155648 +
155649 + @Return E_OK on success; Error code otherwise.
155650 +
155651 + @Cautions Allowed only following FM_PORT_Config() and before FM_PORT_Init().
155652 +*//***************************************************************************/
155653 +#define FM_PORT_IOC_CONFIG_BUFFER_PREFIX_CONTENT _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(39), ioc_fm_buffer_prefix_content_t)
155654 +
155655 +#if (DPAA_VERSION >= 11)
155656 +typedef struct ioc_fm_port_vsp_alloc_params_t {
155657 + uint8_t num_of_profiles; /**< Number of Virtual Storage Profiles */
155658 + uint8_t dflt_relative_id; /**< The default Virtual-Storage-Profile-id dedicated to Rx/OP port
155659 + The same default Virtual-Storage-Profile-id will be for coupled Tx port
155660 + if relevant function called for Rx port */
155661 + void *p_fm_tx_port; /**< Handle to coupled Tx Port; not relevant for OP port. */
155662 +}ioc_fm_port_vsp_alloc_params_t;
155663 +
155664 +/**************************************************************************//**
155665 + @Function FM_PORT_VSPAlloc
155666 +
155667 + @Description This routine allocated VSPs per port and forces the port to work
155668 + in VSP mode. Note that the port is initialized by default with the
155669 + physical-storage-profile only.
155670 +
155671 + @Param[in] h_FmPort A handle to a FM Port module.
155672 + @Param[in] p_Params A structure of parameters for allocation VSP's per port
155673 +
155674 + @Return E_OK on success; Error code otherwise.
155675 +
155676 + @Cautions Allowed only following FM_PORT_Init(), and before FM_PORT_SetPCD()
155677 + and also before FM_PORT_Enable() (i.e. the port should be disabled).
155678 +*//***************************************************************************/
155679 +#if defined(CONFIG_COMPAT)
155680 +#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)
155681 +#endif
155682 +#define FM_PORT_IOC_VSP_ALLOC _IOW(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(38), ioc_fm_port_vsp_alloc_params_t)
155683 +#endif /* (DPAA_VERSION >= 11) */
155684 +
155685 +/**************************************************************************//**
155686 + @Function FM_PORT_GetBmiCounters
155687 +
155688 + @Description Read port's BMI stat counters and place them into
155689 + a designated structure of counters.
155690 +
155691 + @Param[in] h_FmPort A handle to a FM Port module.
155692 + @Param[out] p_BmiStats counters structure
155693 +
155694 + @Return E_OK on success; Error code otherwise.
155695 +
155696 + @Cautions Allowed only following FM_PORT_Init().
155697 +*//***************************************************************************/
155698 +
155699 +#define FM_PORT_IOC_GET_BMI_COUNTERS _IOR(FM_IOC_TYPE_BASE, FM_PORT_IOC_NUM(42), ioc_fm_port_bmi_stats_t)
155700 +
155701 +typedef struct ioc_fm_port_mac_frame_size_counters_t {
155702 +
155703 + e_CommMode type;
155704 + uint64_t count_pkts_64; /**< 64 byte frame counter */
155705 + uint64_t count_pkts_65_to_127; /**< 65 to 127 byte frame counter */
155706 + uint64_t count_pkts_128_to_255; /**< 128 to 255 byte frame counter */
155707 + uint64_t count_pkts_256_to_511; /**< 256 to 511 byte frame counter */
155708 + uint64_t count_pkts_512_to_1023; /**< 512 to 1023 byte frame counter */
155709 + uint64_t count_pkts_1024_to_1518; /**< 1024 to 1518 byte frame counter */
155710 + uint64_t count_pkts_1519_to_1522; /**< 1519 to 1522 byte good frame count */
155711 +} ioc_fm_port_mac_frame_size_counters_t;
155712 +
155713 +/**************************************************************************//**
155714 + @Function FM_MAC_GetFrameSizeCounters
155715 +
155716 + @Description get MAC statistics counters for different frame size
155717 +
155718 + @Param[out] ioc_fm_port_mac_frame_size_counters_t A structure holding the counters
155719 +
155720 + @Return E_OK on success; Error code otherwise.
155721 +
155722 + @Cautions Allowed only following FM_Init().
155723 +*//***************************************************************************/
155724 +#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)
155725 +
155726 +
155727 +/** @} */ /* end of lnx_ioctl_FM_PORT_pcd_runtime_control_grp group */
155728 +/** @} */ /* end of lnx_ioctl_FM_PORT_runtime_control_grp group */
155729 +
155730 +/** @} */ /* end of lnx_ioctl_FM_PORT_grp group */
155731 +/** @} */ /* end of lnx_ioctl_FM_grp group */
155732 +#endif /* __FM_PORT_IOCTLS_H */
155733 --- /dev/null
155734 +++ b/include/uapi/linux/fmd/Peripherals/fm_test_ioctls.h
155735 @@ -0,0 +1,208 @@
155736 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
155737 + * All rights reserved.
155738 + *
155739 + * Redistribution and use in source and binary forms, with or without
155740 + * modification, are permitted provided that the following conditions are met:
155741 + * * Redistributions of source code must retain the above copyright
155742 + * notice, this list of conditions and the following disclaimer.
155743 + * * Redistributions in binary form must reproduce the above copyright
155744 + * notice, this list of conditions and the following disclaimer in the
155745 + * documentation and/or other materials provided with the distribution.
155746 + * * Neither the name of Freescale Semiconductor nor the
155747 + * names of its contributors may be used to endorse or promote products
155748 + * derived from this software without specific prior written permission.
155749 + *
155750 + *
155751 + * ALTERNATIVELY, this software may be distributed under the terms of the
155752 + * GNU General Public License ("GPL") as published by the Free Software
155753 + * Foundation, either version 2 of that License or (at your option) any
155754 + * later version.
155755 + *
155756 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
155757 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155758 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
155759 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
155760 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
155761 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
155762 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
155763 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
155764 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
155765 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
155766 + */
155767 +
155768 +/**************************************************************************//**
155769 + @File fm_test_ioctls.h
155770 +
155771 + @Description FM Char device ioctls
155772 +*//***************************************************************************/
155773 +#ifndef __FM_TEST_IOCTLS_H
155774 +#define __FM_TEST_IOCTLS_H
155775 +
155776 +#include "ioctls.h"
155777 +
155778 +
155779 +/**************************************************************************//**
155780 + @Group lnx_ioctl_FMT_grp Frame Manager Test Linux IOCTL API
155781 +
155782 + @Description FM-Test Linux ioctls definitions and enums
155783 +
155784 + @{
155785 +*//***************************************************************************/
155786 +
155787 +#define IOC_FMT_MAX_NUM_OF_PORTS 26
155788 +
155789 +/**************************************************************************//**
155790 + @Collection TEST Parameters
155791 +*//***************************************************************************/
155792 +/**************************************************************************//**
155793 + @Description: Name of the FM-Test chardev
155794 +*//***************************************************************************/
155795 +#define DEV_FM_TEST_NAME "fm-test-port"
155796 +
155797 +#define DEV_FM_TEST_PORTS_MINOR_BASE 0
155798 +#define DEV_FM_TEST_MAX_MINORS (DEV_FM_TEST_PORTS_MINOR_BASE + IOC_FMT_MAX_NUM_OF_PORTS)
155799 +
155800 +#define FMT_PORT_IOC_NUM(n) n
155801 +/* @} */
155802 +
155803 +/**************************************************************************//**
155804 + @Group lnx_ioctl_FMT_lib_grp FM-Test library
155805 +
155806 + @Description TODO
155807 +
155808 + @{
155809 +*//***************************************************************************/
155810 +
155811 +/**************************************************************************//**
155812 + @Description TODO
155813 +*//***************************************************************************/
155814 +typedef uint8_t ioc_fmt_xxx_t;
155815 +
155816 +#define FM_PRS_MAX 32
155817 +#define FM_TIME_STAMP_MAX 8
155818 +
155819 +/**************************************************************************//**
155820 + @Description FM Port buffer content description
155821 +*//***************************************************************************/
155822 +typedef struct ioc_fmt_buff_context_t {
155823 + void *p_user_priv;
155824 + uint8_t fm_prs_res[FM_PRS_MAX];
155825 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
155826 +} ioc_fmt_buff_context_t;
155827 +
155828 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
155829 +typedef struct ioc_fmt_compat_buff_context_t {
155830 + compat_uptr_t p_user_priv;
155831 + uint8_t fm_prs_res[FM_PRS_MAX];
155832 + uint8_t fm_time_stamp[FM_TIME_STAMP_MAX];
155833 +} ioc_fmt_compat_buff_context_t;
155834 +#endif
155835 +
155836 +/**************************************************************************//**
155837 + @Description Buffer descriptor
155838 +*//***************************************************************************/
155839 +typedef struct ioc_fmt_buff_desc_t {
155840 + uint32_t qid;
155841 + void *p_data;
155842 + uint32_t size;
155843 + uint32_t status;
155844 + ioc_fmt_buff_context_t buff_context;
155845 +} ioc_fmt_buff_desc_t;
155846 +
155847 +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
155848 +typedef struct ioc_fmt_compat_buff_desc_t {
155849 + uint32_t qid;
155850 + compat_uptr_t p_data;
155851 + uint32_t size;
155852 + uint32_t status;
155853 + ioc_fmt_compat_buff_context_t buff_context;
155854 +} ioc_fmt_compat_buff_desc_t;
155855 +#endif
155856 +
155857 +/**************************************************************************//**
155858 + @Group lnx_ioctl_FMT_runtime_control_grp FM-Test Runtime Control Unit
155859 +
155860 + @Description TODO
155861 + @{
155862 +*//***************************************************************************/
155863 +
155864 +/** @} */ /* end of lnx_ioctl_FMT_runtime_control_grp group */
155865 +
155866 +
155867 +/**************************************************************************//**
155868 + @Group lnx_ioctl_FMTP_lib_grp FM-Port-Test library
155869 +
155870 + @Description TODO
155871 +
155872 + @{
155873 +*//***************************************************************************/
155874 +
155875 +/**************************************************************************//**
155876 + @Description FM-Test FM port type
155877 +*//***************************************************************************/
155878 +typedef enum ioc_fmt_port_type {
155879 + e_IOC_FMT_PORT_T_RXTX, /**< Standard port */
155880 + e_IOC_FMT_PORT_T_OP, /**< Offline-parsing port */
155881 +} ioc_fmt_port_type;
155882 +
155883 +/**************************************************************************//**
155884 + @Description TODO
155885 +*//***************************************************************************/
155886 +typedef struct ioc_fmt_port_param_t {
155887 + uint8_t fm_id;
155888 + ioc_fmt_port_type fm_port_type;
155889 + uint8_t fm_port_id;
155890 + uint32_t num_tx_queues;
155891 +} ioc_fmt_port_param_t;
155892 +
155893 +
155894 +/**************************************************************************//**
155895 + @Function FMT_PORT_IOC_INIT
155896 +
155897 + @Description TODO
155898 +
155899 + @Param[in] ioc_fmt_port_param_t TODO
155900 +
155901 + @Cautions Allowed only after the FM equivalent port is already initialized.
155902 +*//***************************************************************************/
155903 +#define FMT_PORT_IOC_INIT _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(0), ioc_fmt_port_param_t)
155904 +
155905 +/**************************************************************************//**
155906 + @Function FMT_PORT_IOC_SET_DIAG_MODE
155907 +
155908 + @Description TODO
155909 +
155910 + @Param[in] ioc_diag_mode TODO
155911 +
155912 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
155913 +*//***************************************************************************/
155914 +#define FMT_PORT_IOC_SET_DIAG_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(1), ioc_diag_mode)
155915 +
155916 +/**************************************************************************//**
155917 + @Function FMT_PORT_IOC_SET_IP_HEADER_MANIP
155918 +
155919 + @Description Set IP header manipulations for this port.
155920 +
155921 + @Param[in] int 1 to enable; 0 to disable
155922 +
155923 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
155924 +*//***************************************************************************/
155925 +#define FMT_PORT_IOC_SET_IP_HEADER_MANIP _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(2), int)
155926 +
155927 +/**************************************************************************//**
155928 + @Function FMT_PORT_IOC_SET_DPAECHO_MODE
155929 +
155930 + @Description Set DPA in echo mode - all frame are sent back.
155931 +
155932 + @Param[in] int 1 to enable; 0 to disable
155933 +
155934 + @Cautions Allowed only following FMT_PORT_IOC_INIT().
155935 +*//***************************************************************************/
155936 +#define FMT_PORT_IOC_SET_DPAECHO_MODE _IOW(FMT_IOC_TYPE_BASE, FMT_PORT_IOC_NUM(3), int)
155937 +
155938 +/** @} */ /* end of lnx_ioctl_FMTP_lib_grp group */
155939 +/** @} */ /* end of lnx_ioctl_FMT_lib_grp group */
155940 +/** @} */ /* end of lnx_ioctl_FMT_grp */
155941 +
155942 +
155943 +#endif /* __FM_TEST_IOCTLS_H */
155944 --- /dev/null
155945 +++ b/include/uapi/linux/fmd/integrations/Kbuild
155946 @@ -0,0 +1 @@
155947 +header-y += integration_ioctls.h
155948 --- /dev/null
155949 +++ b/include/uapi/linux/fmd/integrations/integration_ioctls.h
155950 @@ -0,0 +1,56 @@
155951 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
155952 + * All rights reserved.
155953 + *
155954 + * Redistribution and use in source and binary forms, with or without
155955 + * modification, are permitted provided that the following conditions are met:
155956 + * * Redistributions of source code must retain the above copyright
155957 + * notice, this list of conditions and the following disclaimer.
155958 + * * Redistributions in binary form must reproduce the above copyright
155959 + * notice, this list of conditions and the following disclaimer in the
155960 + * documentation and/or other materials provided with the distribution.
155961 + * * Neither the name of Freescale Semiconductor nor the
155962 + * names of its contributors may be used to endorse or promote products
155963 + * derived from this software without specific prior written permission.
155964 + *
155965 + *
155966 + * ALTERNATIVELY, this software may be distributed under the terms of the
155967 + * GNU General Public License ("GPL") as published by the Free Software
155968 + * Foundation, either version 2 of that License or (at your option) any
155969 + * later version.
155970 + *
155971 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
155972 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
155973 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
155974 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
155975 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
155976 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
155977 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
155978 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
155979 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
155980 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
155981 + */
155982 +
155983 +/**************************************************************************//**
155984 + @File integration_ioctls.h
155985 +
155986 + @Description External header file for Integration unit routines.
155987 +*//***************************************************************************/
155988 +
155989 +#ifndef __INTG_IOCTLS_H
155990 +#define __INTG_IOCTLS_H
155991 +
155992 +
155993 +#define FM_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+1)
155994 +#define FMT_IOC_TYPE_BASE (NCSW_IOC_TYPE_BASE+3)
155995 +
155996 +/*#define FM_IOCTL_DBG*/
155997 +
155998 +#if defined(FM_IOCTL_DBG)
155999 + #define _fm_ioctl_dbg(format, arg...) \
156000 + printk("fm ioctl [%s:%u](cpu:%u) - " format, \
156001 + __func__, __LINE__, smp_processor_id(), ##arg)
156002 +#else
156003 +# define _fm_ioctl_dbg(arg...)
156004 +#endif
156005 +
156006 +#endif /* __INTG_IOCTLS_H */
156007 --- /dev/null
156008 +++ b/include/uapi/linux/fmd/ioctls.h
156009 @@ -0,0 +1,96 @@
156010 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
156011 + * All rights reserved.
156012 + *
156013 + * Redistribution and use in source and binary forms, with or without
156014 + * modification, are permitted provided that the following conditions are met:
156015 + * * Redistributions of source code must retain the above copyright
156016 + * notice, this list of conditions and the following disclaimer.
156017 + * * Redistributions in binary form must reproduce the above copyright
156018 + * notice, this list of conditions and the following disclaimer in the
156019 + * documentation and/or other materials provided with the distribution.
156020 + * * Neither the name of Freescale Semiconductor nor the
156021 + * names of its contributors may be used to endorse or promote products
156022 + * derived from this software without specific prior written permission.
156023 + *
156024 + *
156025 + * ALTERNATIVELY, this software may be distributed under the terms of the
156026 + * GNU General Public License ("GPL") as published by the Free Software
156027 + * Foundation, either version 2 of that License or (at your option) any
156028 + * later version.
156029 + *
156030 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
156031 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
156032 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
156033 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
156034 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
156035 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
156036 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
156037 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
156038 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
156039 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
156040 + */
156041 +
156042 +/**************************************************************************//**
156043 + @File ioctls.h
156044 +
156045 + @Description Structures and definitions for Command Relay Ioctls
156046 +*//***************************************************************************/
156047 +
156048 +#ifndef __IOCTLS_H__
156049 +#define __IOCTLS_H__
156050 +
156051 +#include <asm/ioctl.h>
156052 +
156053 +#include "integration_ioctls.h"
156054 +
156055 +
156056 +/**************************************************************************//**
156057 + @Group lnx_ioctl_ncsw_grp NetCommSw Linux User-Space (IOCTL) API
156058 + @{
156059 +*//***************************************************************************/
156060 +
156061 +#define NCSW_IOC_TYPE_BASE 0xe0 /**< defines the IOCTL type for all
156062 + the NCSW Linux module commands */
156063 +
156064 +
156065 +/**************************************************************************//**
156066 + @Description IOCTL Memory allocation types.
156067 +*//***************************************************************************/
156068 +typedef enum ioc_mem_type {
156069 + e_IOC_MEM_INVALID = 0x00000000, /**< Invalid memory type (error) */
156070 + e_IOC_MEM_CACHABLE_SYS = 0x00000001, /**< Primary DDR, cacheable segment */
156071 + e_IOC_MEM_NOCACHE_SYS = 0x00000004, /**< Primary DDR, non-cacheable segment */
156072 + e_IOC_MEM_SECONDARY = 0x00000002, /**< Either secondary DDR or SDRAM */
156073 + e_IOC_MEM_PRAM = 0x00000008 /**< Multi-user RAM identifier */
156074 +} ioc_mem_type;
156075 +
156076 +/**************************************************************************//**
156077 + @Description Enumeration (bit flags) of communication modes (Transmit,
156078 + receive or both).
156079 +*//***************************************************************************/
156080 +typedef enum ioc_comm_mode {
156081 + e_IOC_COMM_MODE_NONE = 0 /**< No transmit/receive communication */
156082 + , e_IOC_COMM_MODE_RX = 1 /**< Only receive communication */
156083 + , e_IOC_COMM_MODE_TX = 2 /**< Only transmit communication */
156084 + , e_IOC_COMM_MODE_RX_AND_TX = 3 /**< Both transmit and receive communication */
156085 +} ioc_comm_mode;
156086 +
156087 +/**************************************************************************//**
156088 + @Description General Diagnostic Mode
156089 +*//***************************************************************************/
156090 +typedef enum ioc_diag_mode
156091 +{
156092 + e_IOC_DIAG_MODE_NONE = 0,
156093 + e_IOC_DIAG_MODE_CTRL_LOOPBACK, /**< loopback in the controller; E.g. MAC, TDM, etc. */
156094 + e_IOC_DIAG_MODE_CHIP_LOOPBACK, /**< loopback in the chip but not in controller;
156095 + E.g. IO-pins, SerDes, etc. */
156096 + e_IOC_DIAG_MODE_PHY_LOOPBACK, /**< loopback in the external PHY */
156097 + e_IOC_DIAG_MODE_LINE_LOOPBACK, /**< loopback in the external line */
156098 + e_IOC_DIAG_MODE_CTRL_ECHO, /**< */
156099 + e_IOC_DIAG_MODE_PHY_ECHO /**< */
156100 +} ioc_diag_mode;
156101 +
156102 +/** @} */ /* end of lnx_ioctl_ncsw_grp */
156103 +
156104 +
156105 +#endif /* __IOCTLS_H__ */
156106 --- /dev/null
156107 +++ b/include/uapi/linux/fmd/net_ioctls.h
156108 @@ -0,0 +1,430 @@
156109 +/* Copyright (c) 2008-2012 Freescale Semiconductor, Inc.
156110 + * All rights reserved.
156111 + *
156112 + * Redistribution and use in source and binary forms, with or without
156113 + * modification, are permitted provided that the following conditions are met:
156114 + * * Redistributions of source code must retain the above copyright
156115 + * notice, this list of conditions and the following disclaimer.
156116 + * * Redistributions in binary form must reproduce the above copyright
156117 + * notice, this list of conditions and the following disclaimer in the
156118 + * documentation and/or other materials provided with the distribution.
156119 + * * Neither the name of Freescale Semiconductor nor the
156120 + * names of its contributors may be used to endorse or promote products
156121 + * derived from this software without specific prior written permission.
156122 + *
156123 + *
156124 + * ALTERNATIVELY, this software may be distributed under the terms of the
156125 + * GNU General Public License ("GPL") as published by the Free Software
156126 + * Foundation, either version 2 of that License or (at your option) any
156127 + * later version.
156128 + *
156129 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
156130 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
156131 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
156132 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
156133 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
156134 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
156135 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
156136 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
156137 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
156138 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
156139 + */
156140 +
156141 +
156142 +/**************************************************************************//**
156143 + @File net_ioctls.h
156144 +
156145 + @Description This file contains common and general netcomm headers definitions.
156146 +*//***************************************************************************/
156147 +#ifndef __NET_IOCTLS_H
156148 +#define __NET_IOCTLS_H
156149 +
156150 +#include "ioctls.h"
156151 +
156152 +
156153 +typedef uint8_t ioc_header_field_ppp_t;
156154 +
156155 +#define IOC_NET_HEADER_FIELD_PPP_PID (1)
156156 +#define IOC_NET_HEADER_FIELD_PPP_COMPRESSED (IOC_NET_HEADER_FIELD_PPP_PID << 1)
156157 +#define IOC_NET_HEADER_FIELD_PPP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPP_PID << 2) - 1)
156158 +
156159 +
156160 +typedef uint8_t ioc_header_field_pppoe_t;
156161 +
156162 +#define IOC_NET_HEADER_FIELD_PPPoE_VER (1)
156163 +#define IOC_NET_HEADER_FIELD_PPPoE_TYPE (IOC_NET_HEADER_FIELD_PPPoE_VER << 1)
156164 +#define IOC_NET_HEADER_FIELD_PPPoE_CODE (IOC_NET_HEADER_FIELD_PPPoE_VER << 2)
156165 +#define IOC_NET_HEADER_FIELD_PPPoE_SID (IOC_NET_HEADER_FIELD_PPPoE_VER << 3)
156166 +#define IOC_NET_HEADER_FIELD_PPPoE_LEN (IOC_NET_HEADER_FIELD_PPPoE_VER << 4)
156167 +#define IOC_NET_HEADER_FIELD_PPPoE_SESSION (IOC_NET_HEADER_FIELD_PPPoE_VER << 5)
156168 +#define IOC_NET_HEADER_FIELD_PPPoE_PID (IOC_NET_HEADER_FIELD_PPPoE_VER << 6)
156169 +#define IOC_NET_HEADER_FIELD_PPPoE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPoE_VER << 7) - 1)
156170 +
156171 +#define IOC_NET_HEADER_FIELD_PPPMUX_PID (1)
156172 +#define IOC_NET_HEADER_FIELD_PPPMUX_CKSUM (IOC_NET_HEADER_FIELD_PPPMUX_PID << 1)
156173 +#define IOC_NET_HEADER_FIELD_PPPMUX_COMPRESSED (IOC_NET_HEADER_FIELD_PPPMUX_PID << 2)
156174 +#define IOC_NET_HEADER_FIELD_PPPMUX_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_PID << 3) - 1)
156175 +
156176 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF (1)
156177 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LXT (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 1)
156178 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_LEN (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 2)
156179 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 3)
156180 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_USE_PID (IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 4)
156181 +#define IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PPPMUX_SUBFRAME_PFF << 5) - 1)
156182 +
156183 +
156184 +typedef uint8_t ioc_header_field_eth_t;
156185 +
156186 +#define IOC_NET_HEADER_FIELD_ETH_DA (1)
156187 +#define IOC_NET_HEADER_FIELD_ETH_SA (IOC_NET_HEADER_FIELD_ETH_DA << 1)
156188 +#define IOC_NET_HEADER_FIELD_ETH_LENGTH (IOC_NET_HEADER_FIELD_ETH_DA << 2)
156189 +#define IOC_NET_HEADER_FIELD_ETH_TYPE (IOC_NET_HEADER_FIELD_ETH_DA << 3)
156190 +#define IOC_NET_HEADER_FIELD_ETH_FINAL_CKSUM (IOC_NET_HEADER_FIELD_ETH_DA << 4)
156191 +#define IOC_NET_HEADER_FIELD_ETH_PADDING (IOC_NET_HEADER_FIELD_ETH_DA << 5)
156192 +#define IOC_NET_HEADER_FIELD_ETH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ETH_DA << 6) - 1)
156193 +
156194 +#define IOC_NET_HEADER_FIELD_ETH_ADDR_SIZE 6
156195 +
156196 +typedef uint16_t ioc_header_field_ip_t;
156197 +
156198 +#define IOC_NET_HEADER_FIELD_IP_VER (1)
156199 +#define IOC_NET_HEADER_FIELD_IP_DSCP (IOC_NET_HEADER_FIELD_IP_VER << 2)
156200 +#define IOC_NET_HEADER_FIELD_IP_ECN (IOC_NET_HEADER_FIELD_IP_VER << 3)
156201 +#define IOC_NET_HEADER_FIELD_IP_PROTO (IOC_NET_HEADER_FIELD_IP_VER << 4)
156202 +
156203 +#define IOC_NET_HEADER_FIELD_IP_PROTO_SIZE 1
156204 +
156205 +typedef uint16_t ioc_header_field_ipv4_t;
156206 +
156207 +#define IOC_NET_HEADER_FIELD_IPv4_VER (1)
156208 +#define IOC_NET_HEADER_FIELD_IPv4_HDR_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 1)
156209 +#define IOC_NET_HEADER_FIELD_IPv4_TOS (IOC_NET_HEADER_FIELD_IPv4_VER << 2)
156210 +#define IOC_NET_HEADER_FIELD_IPv4_TOTAL_LEN (IOC_NET_HEADER_FIELD_IPv4_VER << 3)
156211 +#define IOC_NET_HEADER_FIELD_IPv4_ID (IOC_NET_HEADER_FIELD_IPv4_VER << 4)
156212 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_D (IOC_NET_HEADER_FIELD_IPv4_VER << 5)
156213 +#define IOC_NET_HEADER_FIELD_IPv4_FLAG_M (IOC_NET_HEADER_FIELD_IPv4_VER << 6)
156214 +#define IOC_NET_HEADER_FIELD_IPv4_OFFSET (IOC_NET_HEADER_FIELD_IPv4_VER << 7)
156215 +#define IOC_NET_HEADER_FIELD_IPv4_TTL (IOC_NET_HEADER_FIELD_IPv4_VER << 8)
156216 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO (IOC_NET_HEADER_FIELD_IPv4_VER << 9)
156217 +#define IOC_NET_HEADER_FIELD_IPv4_CKSUM (IOC_NET_HEADER_FIELD_IPv4_VER << 10)
156218 +#define IOC_NET_HEADER_FIELD_IPv4_SRC_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 11)
156219 +#define IOC_NET_HEADER_FIELD_IPv4_DST_IP (IOC_NET_HEADER_FIELD_IPv4_VER << 12)
156220 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS (IOC_NET_HEADER_FIELD_IPv4_VER << 13)
156221 +#define IOC_NET_HEADER_FIELD_IPv4_OPTS_COUNT (IOC_NET_HEADER_FIELD_IPv4_VER << 14)
156222 +#define IOC_NET_HEADER_FIELD_IPv4_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv4_VER << 15) - 1)
156223 +
156224 +#define IOC_NET_HEADER_FIELD_IPv4_ADDR_SIZE 4
156225 +#define IOC_NET_HEADER_FIELD_IPv4_PROTO_SIZE 1
156226 +
156227 +
156228 +typedef uint8_t ioc_header_field_ipv6_t;
156229 +
156230 +#define IOC_NET_HEADER_FIELD_IPv6_VER (1)
156231 +#define IOC_NET_HEADER_FIELD_IPv6_TC (IOC_NET_HEADER_FIELD_IPv6_VER << 1)
156232 +#define IOC_NET_HEADER_FIELD_IPv6_SRC_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 2)
156233 +#define IOC_NET_HEADER_FIELD_IPv6_DST_IP (IOC_NET_HEADER_FIELD_IPv6_VER << 3)
156234 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR (IOC_NET_HEADER_FIELD_IPv6_VER << 4)
156235 +#define IOC_NET_HEADER_FIELD_IPv6_FL (IOC_NET_HEADER_FIELD_IPv6_VER << 5)
156236 +#define IOC_NET_HEADER_FIELD_IPv6_HOP_LIMIT (IOC_NET_HEADER_FIELD_IPv6_VER << 6)
156237 +#define IOC_NET_HEADER_FIELD_IPv6_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPv6_VER << 7) - 1)
156238 +
156239 +#define IOC_NET_HEADER_FIELD_IPv6_ADDR_SIZE 16
156240 +#define IOC_NET_HEADER_FIELD_IPv6_NEXT_HDR_SIZE 1
156241 +
156242 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE (1)
156243 +#define IOC_NET_HEADER_FIELD_ICMP_CODE (IOC_NET_HEADER_FIELD_ICMP_TYPE << 1)
156244 +#define IOC_NET_HEADER_FIELD_ICMP_CKSUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 2)
156245 +#define IOC_NET_HEADER_FIELD_ICMP_ID (IOC_NET_HEADER_FIELD_ICMP_TYPE << 3)
156246 +#define IOC_NET_HEADER_FIELD_ICMP_SQ_NUM (IOC_NET_HEADER_FIELD_ICMP_TYPE << 4)
156247 +#define IOC_NET_HEADER_FIELD_ICMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ICMP_TYPE << 5) - 1)
156248 +
156249 +#define IOC_NET_HEADER_FIELD_ICMP_CODE_SIZE 1
156250 +#define IOC_NET_HEADER_FIELD_ICMP_TYPE_SIZE 1
156251 +
156252 +#define IOC_NET_HEADER_FIELD_IGMP_VERSION (1)
156253 +#define IOC_NET_HEADER_FIELD_IGMP_TYPE (IOC_NET_HEADER_FIELD_IGMP_VERSION << 1)
156254 +#define IOC_NET_HEADER_FIELD_IGMP_CKSUM (IOC_NET_HEADER_FIELD_IGMP_VERSION << 2)
156255 +#define IOC_NET_HEADER_FIELD_IGMP_DATA (IOC_NET_HEADER_FIELD_IGMP_VERSION << 3)
156256 +#define IOC_NET_HEADER_FIELD_IGMP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IGMP_VERSION << 4) - 1)
156257 +
156258 +
156259 +typedef uint16_t ioc_header_field_tcp_t;
156260 +
156261 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SRC (1)
156262 +#define IOC_NET_HEADER_FIELD_TCP_PORT_DST (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 1)
156263 +#define IOC_NET_HEADER_FIELD_TCP_SEQ (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 2)
156264 +#define IOC_NET_HEADER_FIELD_TCP_ACK (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 3)
156265 +#define IOC_NET_HEADER_FIELD_TCP_OFFSET (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 4)
156266 +#define IOC_NET_HEADER_FIELD_TCP_FLAGS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 5)
156267 +#define IOC_NET_HEADER_FIELD_TCP_WINDOW (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 6)
156268 +#define IOC_NET_HEADER_FIELD_TCP_CKSUM (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 7)
156269 +#define IOC_NET_HEADER_FIELD_TCP_URGPTR (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 8)
156270 +#define IOC_NET_HEADER_FIELD_TCP_OPTS (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 9)
156271 +#define IOC_NET_HEADER_FIELD_TCP_OPTS_COUNT (IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 10)
156272 +#define IOC_NET_HEADER_FIELD_TCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_TCP_PORT_SRC << 11) - 1)
156273 +
156274 +#define IOC_NET_HEADER_FIELD_TCP_PORT_SIZE 2
156275 +
156276 +
156277 +typedef uint8_t ioc_header_field_sctp_t;
156278 +
156279 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SRC (1)
156280 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_DST (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 1)
156281 +#define IOC_NET_HEADER_FIELD_SCTP_VER_TAG (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 2)
156282 +#define IOC_NET_HEADER_FIELD_SCTP_CKSUM (IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 3)
156283 +#define IOC_NET_HEADER_FIELD_SCTP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_PORT_SRC << 4) - 1)
156284 +
156285 +#define IOC_NET_HEADER_FIELD_SCTP_PORT_SIZE 2
156286 +
156287 +typedef uint8_t ioc_header_field_dccp_t;
156288 +
156289 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SRC (1)
156290 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_DST (IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 1)
156291 +#define IOC_NET_HEADER_FIELD_DCCP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_DCCP_PORT_SRC << 2) - 1)
156292 +
156293 +#define IOC_NET_HEADER_FIELD_DCCP_PORT_SIZE 2
156294 +
156295 +
156296 +typedef uint8_t ioc_header_field_udp_t;
156297 +
156298 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SRC (1)
156299 +#define IOC_NET_HEADER_FIELD_UDP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 1)
156300 +#define IOC_NET_HEADER_FIELD_UDP_LEN (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 2)
156301 +#define IOC_NET_HEADER_FIELD_UDP_CKSUM (IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 3)
156302 +#define IOC_NET_HEADER_FIELD_UDP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_PORT_SRC << 4) - 1)
156303 +
156304 +#define IOC_NET_HEADER_FIELD_UDP_PORT_SIZE 2
156305 +
156306 +typedef uint8_t ioc_header_field_udp_lite_t;
156307 +
156308 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC (1)
156309 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_DST (IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 1)
156310 +#define IOC_NET_HEADER_FIELD_UDP_LITE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SRC << 2) - 1)
156311 +
156312 +#define IOC_NET_HEADER_FIELD_UDP_LITE_PORT_SIZE 2
156313 +
156314 +typedef uint8_t ioc_header_field_udp_encap_esp_t;
156315 +
156316 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC (1)
156317 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_DST (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 1)
156318 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_LEN (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 2)
156319 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_CKSUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 3)
156320 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 4)
156321 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 5)
156322 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SRC << 6) - 1)
156323 +
156324 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_PORT_SIZE 2
156325 +#define IOC_NET_HEADER_FIELD_UDP_ENCAP_ESP_SPI_SIZE 4
156326 +
156327 +#define IOC_NET_HEADER_FIELD_IPHC_CID (1)
156328 +#define IOC_NET_HEADER_FIELD_IPHC_CID_TYPE (IOC_NET_HEADER_FIELD_IPHC_CID << 1)
156329 +#define IOC_NET_HEADER_FIELD_IPHC_HCINDEX (IOC_NET_HEADER_FIELD_IPHC_CID << 2)
156330 +#define IOC_NET_HEADER_FIELD_IPHC_GEN (IOC_NET_HEADER_FIELD_IPHC_CID << 3)
156331 +#define IOC_NET_HEADER_FIELD_IPHC_D_BIT (IOC_NET_HEADER_FIELD_IPHC_CID << 4)
156332 +#define IOC_NET_HEADER_FIELD_IPHC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPHC_CID << 5) - 1)
156333 +
156334 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE (1)
156335 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_FLAGS (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 1)
156336 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_LENGTH (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 2)
156337 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TSN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 3)
156338 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_ID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 4)
156339 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_STREAM_SQN (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 5)
156340 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_PAYLOAD_PID (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 6)
156341 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_UNORDERED (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 7)
156342 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_BEGGINING (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 8)
156343 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_END (IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 9)
156344 +#define IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SCTP_CHUNK_DATA_TYPE << 10) - 1)
156345 +
156346 +#define IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT (1)
156347 +#define IOC_NET_HEADER_FIELD_L2TPv2_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 1)
156348 +#define IOC_NET_HEADER_FIELD_L2TPv2_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 2)
156349 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 3)
156350 +#define IOC_NET_HEADER_FIELD_L2TPv2_PRIORITY_BIT (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 4)
156351 +#define IOC_NET_HEADER_FIELD_L2TPv2_VERSION (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 5)
156352 +#define IOC_NET_HEADER_FIELD_L2TPv2_LEN (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 6)
156353 +#define IOC_NET_HEADER_FIELD_L2TPv2_TUNNEL_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 7)
156354 +#define IOC_NET_HEADER_FIELD_L2TPv2_SESSION_ID (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 8)
156355 +#define IOC_NET_HEADER_FIELD_L2TPv2_NS (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 9)
156356 +#define IOC_NET_HEADER_FIELD_L2TPv2_NR (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 10)
156357 +#define IOC_NET_HEADER_FIELD_L2TPv2_OFFSET_SIZE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 11)
156358 +#define IOC_NET_HEADER_FIELD_L2TPv2_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 12)
156359 +#define IOC_NET_HEADER_FIELD_L2TPv2_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv2_TYPE_BIT << 13) - 1)
156360 +
156361 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT (1)
156362 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 1)
156363 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SEQUENCE_BIT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 2)
156364 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 3)
156365 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_LENGTH (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 4)
156366 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_CONTROL (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 5)
156367 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_SENT (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 6)
156368 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_RECV (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 7)
156369 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_FIRST_BYTE (IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 8)
156370 +#define IOC_NET_HEADER_FIELD_L2TPv3_CTRL_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_CTRL_TYPE_BIT << 9) - 1)
156371 +
156372 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT (1)
156373 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_VERSION (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 1)
156374 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ID (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 2)
156375 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_COOKIE (IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 3)
156376 +#define IOC_NET_HEADER_FIELD_L2TPv3_SESS_ALL_FIELDS ((IOC_NET_HEADER_FIELD_L2TPv3_SESS_TYPE_BIT << 4) - 1)
156377 +
156378 +
156379 +typedef uint8_t ioc_header_field_vlan_t;
156380 +
156381 +#define IOC_NET_HEADER_FIELD_VLAN_VPRI (1)
156382 +#define IOC_NET_HEADER_FIELD_VLAN_CFI (IOC_NET_HEADER_FIELD_VLAN_VPRI << 1)
156383 +#define IOC_NET_HEADER_FIELD_VLAN_VID (IOC_NET_HEADER_FIELD_VLAN_VPRI << 2)
156384 +#define IOC_NET_HEADER_FIELD_VLAN_LENGTH (IOC_NET_HEADER_FIELD_VLAN_VPRI << 3)
156385 +#define IOC_NET_HEADER_FIELD_VLAN_TYPE (IOC_NET_HEADER_FIELD_VLAN_VPRI << 4)
156386 +#define IOC_NET_HEADER_FIELD_VLAN_ALL_FIELDS ((IOC_NET_HEADER_FIELD_VLAN_VPRI << 5) - 1)
156387 +
156388 +#define IOC_NET_HEADER_FIELD_VLAN_TCI (IOC_NET_HEADER_FIELD_VLAN_VPRI | \
156389 + IOC_NET_HEADER_FIELD_VLAN_CFI | \
156390 + IOC_NET_HEADER_FIELD_VLAN_VID)
156391 +
156392 +
156393 +typedef uint8_t ioc_header_field_llc_t;
156394 +
156395 +#define IOC_NET_HEADER_FIELD_LLC_DSAP (1)
156396 +#define IOC_NET_HEADER_FIELD_LLC_SSAP (IOC_NET_HEADER_FIELD_LLC_DSAP << 1)
156397 +#define IOC_NET_HEADER_FIELD_LLC_CTRL (IOC_NET_HEADER_FIELD_LLC_DSAP << 2)
156398 +#define IOC_NET_HEADER_FIELD_LLC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_DSAP << 3) - 1)
156399 +
156400 +#define IOC_NET_HEADER_FIELD_NLPID_NLPID (1)
156401 +#define IOC_NET_HEADER_FIELD_NLPID_ALL_FIELDS ((IOC_NET_HEADER_FIELD_NLPID_NLPID << 1) - 1)
156402 +
156403 +
156404 +typedef uint8_t ioc_header_field_snap_t;
156405 +
156406 +#define IOC_NET_HEADER_FIELD_SNAP_OUI (1)
156407 +#define IOC_NET_HEADER_FIELD_SNAP_PID (IOC_NET_HEADER_FIELD_SNAP_OUI << 1)
156408 +#define IOC_NET_HEADER_FIELD_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_SNAP_OUI << 2) - 1)
156409 +
156410 +
156411 +typedef uint8_t ioc_header_field_llc_snap_t;
156412 +
156413 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE (1)
156414 +#define IOC_NET_HEADER_FIELD_LLC_SNAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_LLC_SNAP_TYPE << 1) - 1)
156415 +
156416 +#define IOC_NET_HEADER_FIELD_ARP_HTYPE (1)
156417 +#define IOC_NET_HEADER_FIELD_ARP_PTYPE (IOC_NET_HEADER_FIELD_ARP_HTYPE << 1)
156418 +#define IOC_NET_HEADER_FIELD_ARP_HLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 2)
156419 +#define IOC_NET_HEADER_FIELD_ARP_PLEN (IOC_NET_HEADER_FIELD_ARP_HTYPE << 3)
156420 +#define IOC_NET_HEADER_FIELD_ARP_OPER (IOC_NET_HEADER_FIELD_ARP_HTYPE << 4)
156421 +#define IOC_NET_HEADER_FIELD_ARP_SHA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 5)
156422 +#define IOC_NET_HEADER_FIELD_ARP_SPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 6)
156423 +#define IOC_NET_HEADER_FIELD_ARP_THA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 7)
156424 +#define IOC_NET_HEADER_FIELD_ARP_TPA (IOC_NET_HEADER_FIELD_ARP_HTYPE << 8)
156425 +#define IOC_NET_HEADER_FIELD_ARP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_ARP_HTYPE << 9) - 1)
156426 +
156427 +#define IOC_NET_HEADER_FIELD_RFC2684_LLC (1)
156428 +#define IOC_NET_HEADER_FIELD_RFC2684_NLPID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 1)
156429 +#define IOC_NET_HEADER_FIELD_RFC2684_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 2)
156430 +#define IOC_NET_HEADER_FIELD_RFC2684_PID (IOC_NET_HEADER_FIELD_RFC2684_LLC << 3)
156431 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_OUI (IOC_NET_HEADER_FIELD_RFC2684_LLC << 4)
156432 +#define IOC_NET_HEADER_FIELD_RFC2684_VPN_IDX (IOC_NET_HEADER_FIELD_RFC2684_LLC << 5)
156433 +#define IOC_NET_HEADER_FIELD_RFC2684_ALL_FIELDS ((IOC_NET_HEADER_FIELD_RFC2684_LLC << 6) - 1)
156434 +
156435 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT (1)
156436 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_PCDID (IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 1)
156437 +#define IOC_NET_HEADER_FIELD_USER_DEFINED_ALL_FIELDS ((IOC_NET_HEADER_FIELD_USER_DEFINED_SRCPORT << 2) - 1)
156438 +
156439 +#define IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER (1)
156440 +#define IOC_NET_HEADER_FIELD_PAYLOAD_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 1)
156441 +#define IOC_NET_HEADER_FIELD_MAX_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 2)
156442 +#define IOC_NET_HEADER_FIELD_MIN_FRM_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 3)
156443 +#define IOC_NET_HEADER_FIELD_PAYLOAD_TYPE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 4)
156444 +#define IOC_NET_HEADER_FIELD_FRAME_SIZE (IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 5)
156445 +#define IOC_NET_HEADER_FIELD_PAYLOAD_ALL_FIELDS ((IOC_NET_HEADER_FIELD_PAYLOAD_BUFFER << 6) - 1)
156446 +
156447 +
156448 +typedef uint8_t ioc_header_field_gre_t;
156449 +
156450 +#define IOC_NET_HEADER_FIELD_GRE_TYPE (1)
156451 +#define IOC_NET_HEADER_FIELD_GRE_ALL_FIELDS ((IOC_NET_HEADER_FIELD_GRE_TYPE << 1) - 1)
156452 +
156453 +
156454 +typedef uint8_t ioc_header_field_minencap_t;
156455 +
156456 +#define IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP (1)
156457 +#define IOC_NET_HEADER_FIELD_MINENCAP_DST_IP (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 1)
156458 +#define IOC_NET_HEADER_FIELD_MINENCAP_TYPE (IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 2)
156459 +#define IOC_NET_HEADER_FIELD_MINENCAP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MINENCAP_SRC_IP << 3) - 1)
156460 +
156461 +
156462 +typedef uint8_t ioc_header_field_ipsec_ah_t;
156463 +
156464 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_SPI (1)
156465 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_NH (IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 1)
156466 +#define IOC_NET_HEADER_FIELD_IPSEC_AH_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_AH_SPI << 2) - 1)
156467 +
156468 +
156469 +typedef uint8_t ioc_header_field_ipsec_esp_t;
156470 +
156471 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI (1)
156472 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SEQUENCE_NUM (IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 1)
156473 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_ALL_FIELDS ((IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI << 2) - 1)
156474 +
156475 +#define IOC_NET_HEADER_FIELD_IPSEC_ESP_SPI_SIZE 4
156476 +
156477 +
156478 +typedef uint8_t ioc_header_field_mpls_t;
156479 +
156480 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK (1)
156481 +#define IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MPLS_LABEL_STACK << 1) - 1)
156482 +
156483 +
156484 +typedef uint8_t ioc_header_field_macsec_t;
156485 +
156486 +#define IOC_NET_HEADER_FIELD_MACSEC_SECTAG (1)
156487 +#define IOC_NET_HEADER_FIELD_MACSEC_ALL_FIELDS ((IOC_NET_HEADER_FIELD_MACSEC_SECTAG << 1) - 1)
156488 +
156489 +
156490 +typedef enum {
156491 + e_IOC_NET_HEADER_TYPE_NONE = 0,
156492 + e_IOC_NET_HEADER_TYPE_PAYLOAD,
156493 + e_IOC_NET_HEADER_TYPE_ETH,
156494 + e_IOC_NET_HEADER_TYPE_VLAN,
156495 + e_IOC_NET_HEADER_TYPE_IPv4,
156496 + e_IOC_NET_HEADER_TYPE_IPv6,
156497 + e_IOC_NET_HEADER_TYPE_IP,
156498 + e_IOC_NET_HEADER_TYPE_TCP,
156499 + e_IOC_NET_HEADER_TYPE_UDP,
156500 + e_IOC_NET_HEADER_TYPE_UDP_LITE,
156501 + e_IOC_NET_HEADER_TYPE_IPHC,
156502 + e_IOC_NET_HEADER_TYPE_SCTP,
156503 + e_IOC_NET_HEADER_TYPE_SCTP_CHUNK_DATA,
156504 + e_IOC_NET_HEADER_TYPE_PPPoE,
156505 + e_IOC_NET_HEADER_TYPE_PPP,
156506 + e_IOC_NET_HEADER_TYPE_PPPMUX,
156507 + e_IOC_NET_HEADER_TYPE_PPPMUX_SUBFRAME,
156508 + e_IOC_NET_HEADER_TYPE_L2TPv2,
156509 + e_IOC_NET_HEADER_TYPE_L2TPv3_CTRL,
156510 + e_IOC_NET_HEADER_TYPE_L2TPv3_SESS,
156511 + e_IOC_NET_HEADER_TYPE_LLC,
156512 + e_IOC_NET_HEADER_TYPE_LLC_SNAP,
156513 + e_IOC_NET_HEADER_TYPE_NLPID,
156514 + e_IOC_NET_HEADER_TYPE_SNAP,
156515 + e_IOC_NET_HEADER_TYPE_MPLS,
156516 + e_IOC_NET_HEADER_TYPE_IPSEC_AH,
156517 + e_IOC_NET_HEADER_TYPE_IPSEC_ESP,
156518 + e_IOC_NET_HEADER_TYPE_UDP_ENCAP_ESP, /* RFC 3948 */
156519 + e_IOC_NET_HEADER_TYPE_MACSEC,
156520 + e_IOC_NET_HEADER_TYPE_GRE,
156521 + e_IOC_NET_HEADER_TYPE_MINENCAP,
156522 + e_IOC_NET_HEADER_TYPE_DCCP,
156523 + e_IOC_NET_HEADER_TYPE_ICMP,
156524 + e_IOC_NET_HEADER_TYPE_IGMP,
156525 + e_IOC_NET_HEADER_TYPE_ARP,
156526 + e_IOC_NET_HEADER_TYPE_CAPWAP,
156527 + e_IOC_NET_HEADER_TYPE_CAPWAP_DTLS,
156528 + e_IOC_NET_HEADER_TYPE_RFC2684,
156529 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L2,
156530 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L3,
156531 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_L4,
156532 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM1,
156533 + e_IOC_NET_HEADER_TYPE_USER_DEFINED_SHIM2,
156534 + e_IOC_NET_MAX_HEADER_TYPE_COUNT
156535 +} ioc_net_header_type;
156536 +
156537 +
156538 +#endif /* __NET_IOCTLS_H */
156539 --- a/net/sched/sch_generic.c
156540 +++ b/net/sched/sch_generic.c
156541 @@ -313,6 +313,13 @@ static void dev_watchdog(unsigned long a
156542 txq->trans_timeout++;
156543 break;
156544 }
156545 +
156546 + /* Devices with HW_ACCEL_MQ have multiple txqs
156547 + * but update only the first one's transmission
156548 + * timestamp so avoid checking the rest.
156549 + */
156550 + if (dev->features & NETIF_F_HW_ACCEL_MQ)
156551 + break;
156552 }
156553
156554 if (some_queue_timedout) {